Main Page | Data Structures | Directories | File List | Data Fields

api.c

00001 /*
00002 ** Copyright (c) 2002  Hughes Technologies Pty Ltd.  All rights
00003 ** reserved.
00004 **
00005 ** Terms under which this software may be used or copied are
00006 ** provided in the  specific license associated with this product.
00007 **
00008 ** Hughes Technologies disclaims all warranties with regard to this
00009 ** software, including all implied warranties of merchantability and
00010 ** fitness, in no event shall Hughes Technologies be liable for any
00011 ** special, indirect or consequential damages or any damages whatsoever
00012 ** resulting from loss of use, data or profits, whether in an action of
00013 ** contract, negligence or other tortious action, arising out of or in
00014 ** connection with the use or performance of this software.
00015 **
00016 **
00017 ** $Id: api.c,v 1.8 2004/11/22 21:45:57 alexcv Exp $
00018 **
00019 */
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <ctype.h>
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <time.h>
00028 
00029 #if defined(_WIN32)
00030 #include <winsock2.h>
00031 #else
00032 #include <unistd.h> 
00033 #include <sys/file.h>
00034 #include <netinet/in.h> 
00035 #include <arpa/inet.h> 
00036 #include <netdb.h>
00037 #include <sys/socket.h> 
00038 #include <netdb.h>
00039 #endif
00040 
00041 #include "config.h"
00042 #include "httpd.h"
00043 #include "httpd_priv.h"
00044 
00045 #ifdef HAVE_STDARG_H
00046 #  include <stdarg.h>
00047 #else
00048 #  include <varargs.h>
00049 #endif
00050 
00051 
00052 char *httpdUrlEncode(str)
00053         char    *str;
00054 {
00055         char    *new,
00056                 *cp;
00057 
00058         new = (char *)_httpd_escape(str);
00059         if (new == NULL)
00060         {
00061                 return(NULL);
00062         }
00063         cp = new;
00064         while(*cp)
00065         {
00066                 if (*cp == ' ')
00067                         *cp = '+';
00068                 cp++;
00069         }
00070         return(new);
00071 }
00072 
00073 
00074 
00075 char *httpdRequestMethodName(request *r)
00076 {
00077         static  char    tmpBuf[255];
00078 
00079         switch(r->request.method)
00080         {
00081                 case HTTP_GET: return("GET");
00082                 case HTTP_POST: return("POST");
00083                 default: 
00084                         snprintf(tmpBuf,255,"Invalid method '%d'", 
00085                                 r->request.method);
00086                         return(tmpBuf);
00087         }
00088 }
00089 
00090 
00091 httpVar *httpdGetVariableByName(request *r, char *name)
00092 {
00093         httpVar *curVar;
00094 
00095         curVar = r->variables;
00096         while(curVar)
00097         {
00098                 if (strcmp(curVar->name, name) == 0)
00099                         return(curVar);
00100                 curVar = curVar->nextVariable;
00101         }
00102         return(NULL);
00103 }
00104 
00105 
00106 
00107 httpVar *httpdGetVariableByPrefix(request *r, char *prefix)
00108 {
00109         httpVar *curVar;
00110 
00111         if (prefix == NULL)
00112                 return(r->variables);
00113         curVar = r->variables;
00114         while(curVar)
00115         {
00116                 if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
00117                         return(curVar);
00118                 curVar = curVar->nextVariable;
00119         }
00120         return(NULL);
00121 }
00122 
00123 
00124 httpVar *httpdGetVariableByPrefixedName(request *r, char *prefix, char *name)
00125 {
00126         httpVar *curVar;
00127         int     prefixLen;
00128 
00129         if (prefix == NULL)
00130                 return(r->variables);
00131         curVar = r->variables;
00132         prefixLen = strlen(prefix);
00133         while(curVar)
00134         {
00135                 if (strncmp(curVar->name, prefix, prefixLen) == 0 &&
00136                         strcmp(curVar->name + prefixLen, name) == 0)
00137                 {
00138                         return(curVar);
00139                 }
00140                 curVar = curVar->nextVariable;
00141         }
00142         return(NULL);
00143 }
00144 
00145 
00146 httpVar *httpdGetNextVariableByPrefix(curVar, prefix)
00147         httpVar *curVar;
00148         char    *prefix;
00149 {
00150         if(curVar)
00151                 curVar = curVar->nextVariable;
00152         while(curVar)
00153         {
00154                 if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
00155                         return(curVar);
00156                 curVar = curVar->nextVariable;
00157         }
00158         return(NULL);
00159 }
00160 
00161 
00162 int httpdAddVariable(request *r, char *name, char *value)
00163 {
00164         httpVar *curVar, *lastVar, *newVar;
00165 
00166         while(*name == ' ' || *name == '\t')
00167                 name++;
00168         newVar = malloc(sizeof(httpVar));
00169         bzero(newVar, sizeof(httpVar));
00170         newVar->name = strdup(name);
00171         newVar->value = strdup(value);
00172         lastVar = NULL;
00173         curVar = r->variables;
00174         while(curVar)
00175         {
00176                 if (strcmp(curVar->name, name) != 0)
00177                 {
00178                         lastVar = curVar;
00179                         curVar = curVar->nextVariable;
00180                         continue;
00181                 }
00182                 while(curVar)
00183                 {
00184                         lastVar = curVar;
00185                         curVar = curVar->nextValue;
00186                 }
00187                 lastVar->nextValue = newVar;
00188                 return(0);
00189         }
00190         if (lastVar)
00191                 lastVar->nextVariable = newVar;
00192         else
00193                 r->variables = newVar;
00194         return(0);
00195 }
00196 
00197 httpd *httpdCreate(host, port)
00198         char    *host;
00199         int     port;
00200 {
00201         httpd   *new;
00202         int     sock,
00203                 opt;
00204         struct  sockaddr_in     addr;
00205 
00206         /*
00207         ** Create the handle and setup it's basic config
00208         */
00209         new = malloc(sizeof(httpd));
00210         if (new == NULL)
00211                 return(NULL);
00212         bzero(new, sizeof(httpd));
00213         new->port = port;
00214         if (host == HTTP_ANY_ADDR)
00215                 new->host = HTTP_ANY_ADDR;
00216         else
00217                 new->host = strdup(host);
00218         new->content = (httpDir*)malloc(sizeof(httpDir));
00219         bzero(new->content,sizeof(httpDir));
00220         new->content->name = strdup("");
00221 
00222         /*
00223         ** Setup the socket
00224         */
00225 #ifdef _WIN32
00226         { 
00227         WORD    wVersionRequested;
00228         WSADATA wsaData;
00229         int     err;
00230 
00231         wVersionRequested = MAKEWORD( 2, 2 );
00232 
00233         err = WSAStartup( wVersionRequested, &wsaData );
00234         
00235         /* Found a usable winsock dll? */
00236         if( err != 0 ) 
00237            return NULL;
00238 
00239         /* 
00240         ** Confirm that the WinSock DLL supports 2.2.
00241         ** Note that if the DLL supports versions greater 
00242         ** than 2.2 in addition to 2.2, it will still return
00243         ** 2.2 in wVersion since that is the version we
00244         ** requested.
00245         */
00246 
00247         if( LOBYTE( wsaData.wVersion ) != 2 || 
00248             HIBYTE( wsaData.wVersion ) != 2 ) {
00249 
00250                 /* 
00251                 ** Tell the user that we could not find a usable
00252                 ** WinSock DLL.
00253                 */
00254                 WSACleanup( );
00255                 return NULL;
00256         }
00257 
00258         /* The WinSock DLL is acceptable. Proceed. */
00259         }
00260 #endif
00261 
00262         sock = socket(AF_INET, SOCK_STREAM, 0);
00263         if (sock  < 0)
00264         {
00265                 free(new);
00266                 return(NULL);
00267         }
00268 #       ifdef SO_REUSEADDR
00269         opt = 1;
00270         setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int));
00271 #       endif
00272         new->serverSock = sock;
00273         bzero(&addr, sizeof(addr));
00274         addr.sin_family = AF_INET;
00275         if (new->host == HTTP_ANY_ADDR)
00276         {
00277                 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00278         }
00279         else
00280         {
00281                 addr.sin_addr.s_addr = inet_addr(new->host);
00282         }
00283         addr.sin_port = htons((u_short)new->port);
00284         if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0)
00285         {
00286                 close(sock);
00287                 free(new);
00288                 return(NULL);
00289         }
00290         listen(sock, 128);
00291         new->startTime = time(NULL);
00292         return(new);
00293 }
00294 
00295 void httpdDestroy(server)
00296         httpd   *server;
00297 {
00298         if (server == NULL)
00299                 return;
00300         if (server->host)
00301                 free(server->host);
00302         free(server);
00303 }
00304 
00305 
00306 
00307 request *httpdGetConnection(server, timeout)
00308         httpd   *server;
00309         struct  timeval *timeout;
00310 {
00311         int     result;
00312         fd_set  fds;
00313         struct  sockaddr_in     addr;
00314         size_t  addrLen;
00315         char    *ipaddr;
00316         request *r;
00317 
00318         FD_ZERO(&fds);
00319         FD_SET(server->serverSock, &fds);
00320         result = 0;
00321         while(result == 0)
00322         {
00323                 result = select(server->serverSock + 1, &fds, 0, 0, timeout);
00324                 if (result < 0)
00325                 {
00326                         server->lastError = -1;
00327                         return(NULL);
00328                 }
00329                 if (timeout != 0 && result == 0)
00330                 {
00331                         return(NULL);
00332                         server->lastError = 0;
00333                 }
00334                 if (result > 0)
00335                 {
00336                         break;
00337                 }
00338         }
00339         /* Allocate request struct */
00340         r = (request *)malloc(sizeof(request));
00341         if (r == NULL) {
00342                 server->lastError = -3;
00343                 return(NULL);
00344         }
00345         memset((void *)r, 0, sizeof(request));
00346         /* Get on with it */
00347         bzero(&addr, sizeof(addr));
00348         addrLen = sizeof(addr);
00349         r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr,
00350                 &addrLen);
00351         ipaddr = inet_ntoa(addr.sin_addr);
00352         if (ipaddr)
00353                 strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN);
00354         else
00355                 *r->clientAddr = 0;
00356         r->readBufRemain = 0;
00357         r->readBufPtr = NULL;
00358 
00359         /*
00360         ** Check the default ACL
00361         */
00362         if (server->defaultAcl)
00363         {
00364                 if (httpdCheckAcl(server, r, server->defaultAcl)
00365                                 == HTTP_ACL_DENY)
00366                 {
00367                         httpdEndRequest(r);
00368                         server->lastError = 2;
00369                         return(NULL);
00370                 }
00371         }
00372         return(r);
00373 }
00374 
00375 
00376 
00377 int httpdReadRequest(httpd *server, request *r)
00378 {
00379         static  char    buf[HTTP_MAX_LEN];
00380         int     count,
00381                 inHeaders;
00382         char    *cp, *cp2;
00383         int     _httpd_decode();
00384 
00385 
00386         /*
00387         ** Setup for a standard response
00388         */
00389         strcpy(r->response.headers,
00390                 "Server: Hughes Technologies Embedded Server\n"); 
00391         strcpy(r->response.contentType, "text/html");
00392         strcpy(r->response.response,"200 Output Follows\n");
00393         r->response.headersSent = 0;
00394 
00395 
00396         /*
00397         ** Read the request
00398         */
00399         count = 0;
00400         inHeaders = 1;
00401         while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0)
00402         {
00403                 count++;
00404 
00405                 /*
00406                 ** Special case for the first line.  Scan the request
00407                 ** method and path etc
00408                 */
00409                 if (count == 1)
00410                 {
00411                         /*
00412                         ** First line.  Scan the request info
00413                         */
00414                         cp = cp2 = buf;
00415                         while(isalpha(*cp2))
00416                                 cp2++;
00417                         *cp2 = 0;
00418                         if (strcasecmp(cp,"GET") == 0)
00419                                 r->request.method = HTTP_GET;
00420                         if (strcasecmp(cp,"POST") == 0)
00421                                 r->request.method = HTTP_POST;
00422                         if (r->request.method == 0)
00423                         {
00424                                 _httpd_net_write( r->clientSock,
00425                                       HTTP_METHOD_ERROR,
00426                                       strlen(HTTP_METHOD_ERROR));
00427                                 _httpd_net_write( r->clientSock, cp, 
00428                                       strlen(cp));
00429                                 _httpd_writeErrorLog(server, r, LEVEL_ERROR, 
00430                                         "Invalid method received");
00431                                 return(-1);
00432                         }
00433                         cp = cp2+1;
00434                         while(*cp == ' ')
00435                                 cp++;
00436                         cp2 = cp;
00437                         while(*cp2 != ' ' && *cp2 != 0)
00438                                 cp2++;
00439                         *cp2 = 0;
00440                         strncpy(r->request.path,cp,HTTP_MAX_URL);
00441                         _httpd_sanitiseUrl(r->request.path);
00442                         continue;
00443                 }
00444 
00445                 /*
00446                 ** Process the headers
00447                 */
00448                 if (inHeaders)
00449                 {
00450                         if (*buf == 0)
00451                         {
00452                                 /*
00453                                 ** End of headers.  Continue if there's
00454                                 ** data to read
00455                                 */
00456                                 if (r->request.contentLength == 0)
00457                                         break;
00458                                 inHeaders = 0;
00459                                 break;
00460                         }
00461 #if 0
00487 #endif
00488 #if 0
00489                         if (strncasecmp(buf,"Authorization: ",15) == 0)
00490                         {
00491                                 cp = index(buf,':') + 2;
00492                                 if (strncmp(cp,"Basic ", 6) != 0)
00493                                 {
00494                                         /* Unknown auth method */
00495                                 }
00496                                 else
00497                                 {
00498                                         char    authBuf[100];
00499 
00500                                         cp = index(cp,' ') + 1;
00501                                         _httpd_decode(cp, authBuf, 100);
00502                                         r->request.authLength = 
00503                                                 strlen(authBuf);
00504                                         cp = index(authBuf,':');
00505                                         if (cp)
00506                                         {
00507                                                 *cp = 0;
00508                                                 strncpy(
00509                                                    r->request.authPassword,
00510                                                    cp+1, HTTP_MAX_AUTH);
00511                                         }
00512                                         strncpy(r->request.authUser, 
00513                                                 authBuf, HTTP_MAX_AUTH);
00514                                 }
00515                         }
00516 #endif
00517 #if 0
00518                         if (strncasecmp(buf,"Referer: ",9) == 0)
00519                         {
00520                                 cp = index(buf,':') + 2;
00521                                 if(cp)
00522                                 {
00523                                         strncpy(r->request.referer,cp,
00524                                                 HTTP_MAX_URL);
00525                                 }
00526                         }
00527 #endif
00528                         /* acv@acv.ca/wifidog: Added decoding of host: if
00529                          * present. */
00530                         if (strncasecmp(buf,"Host: ",6) == 0)
00531                         {
00532                                 cp = index(buf,':') + 2;
00533                                 if(cp)
00534                                 {
00535                                         strncpy(r->request.host,cp,
00536                                                 HTTP_MAX_URL);
00537                                 }
00538                         }
00539                         /* End modification */
00540 #if 0
00541                         if (strncasecmp(buf,"If-Modified-Since: ",19) == 0)
00542                         {
00543                                 cp = index(buf,':') + 2;
00544                                 if(cp)
00545                                 {
00546                                         strncpy(r->request.ifModified,cp,
00547                                                 HTTP_MAX_URL);
00548                                         cp = index(r->request.ifModified,
00549                                                 ';');
00550                                         if (cp)
00551                                                 *cp = 0;
00552                                 }
00553                         }
00554                         if (strncasecmp(buf,"Content-Type: ",14) == 0)
00555                         {
00556                                 cp = index(buf,':') + 2;
00557                                 if(cp)
00558                                 {
00559                                         strncpy(r->request.contentType,cp,
00560                                                 HTTP_MAX_URL);
00561                                 }
00562                         }
00563                         if (strncasecmp(buf,"Content-Length: ",16) == 0)
00564                         {
00565                                 cp = index(buf,':') + 2;
00566                                 if(cp)
00567                                         r->request.contentLength=atoi(cp);
00568                         }
00569 #endif
00570                         continue;
00571                 }
00572         }
00573 
00574         /*
00575         ** Process and POST data
00576         */
00577 #if 0
00578         if (r->request.contentLength > 0)
00579         {
00580                 bzero(buf, HTTP_MAX_LEN);
00581                 _httpd_readBuf(r, buf, r->request.contentLength);
00582                 _httpd_storeData(r, buf);
00583                 
00584         }
00585 #endif
00586         
00587         /*
00588         ** Process any URL data
00589         */
00590         cp = index(r->request.path,'?');
00591         if (cp != NULL)
00592         {
00593                 *cp = 0;
00594                 cp++;
00595                 _httpd_storeData(r, cp);
00596         }
00597         return(0);
00598 }
00599 
00600 
00601 void httpdEndRequest(request *r)
00602 {
00603         _httpd_freeVariables(r->variables);
00604         shutdown(r->clientSock,2);
00605         close(r->clientSock);
00606         free(r);
00607 }
00608 
00609 
00610 void httpdFreeVariables(request *r)
00611 {
00612         _httpd_freeVariables(r->variables);
00613 }
00614 
00615 
00616 
00617 void httpdDumpVariables(request *r)
00618 {
00619         httpVar *curVar,
00620                 *curVal;
00621 
00622         curVar = r->variables;
00623         while(curVar)
00624         {
00625                 printf("Variable '%s'\n", curVar->name);
00626                 curVal = curVar;
00627                 while(curVal)
00628                 {
00629                         printf("\t= '%s'\n",curVal->value);
00630                         curVal = curVal->nextValue;
00631                 }
00632                 curVar = curVar->nextVariable;
00633         }
00634 }
00635 
00636 void httpdSetFileBase(server, path)
00637         httpd   *server;
00638         char    *path;
00639 {
00640         strncpy(server->fileBasePath, path, HTTP_MAX_URL);
00641 }
00642 
00643 
00644 int httpdAddFileContent(server, dir, name, indexFlag, preload, path)
00645         httpd   *server;
00646         char    *dir,
00647                 *name;
00648         int     (*preload)();
00649         int     indexFlag;
00650         char    *path;
00651 {
00652         httpDir *dirPtr;
00653         httpContent *newEntry;
00654 
00655         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00656         newEntry =  malloc(sizeof(httpContent));
00657         if (newEntry == NULL)
00658                 return(-1);
00659         bzero(newEntry,sizeof(httpContent));
00660         newEntry->name = strdup(name);
00661         newEntry->type = HTTP_FILE;
00662         newEntry->indexFlag = indexFlag;
00663         newEntry->preload = preload;
00664         newEntry->next = dirPtr->entries;
00665         dirPtr->entries = newEntry;
00666         if (*path == '/')
00667         {
00668                 /* Absolute path */
00669                 newEntry->path = strdup(path);
00670         }
00671         else
00672         {
00673                 /* Path relative to base path */
00674                 newEntry->path = malloc(strlen(server->fileBasePath) +
00675                         strlen(path) + 2);
00676                 snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
00677                         server->fileBasePath, path);
00678         }
00679         return(0);
00680 }
00681 
00682 
00683 
00684 int httpdAddWildcardContent(server, dir, preload, path)
00685         httpd   *server;
00686         char    *dir;
00687         int     (*preload)();
00688         char    *path;
00689 {
00690         httpDir *dirPtr;
00691         httpContent *newEntry;
00692 
00693         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00694         newEntry =  malloc(sizeof(httpContent));
00695         if (newEntry == NULL)
00696                 return(-1);
00697         bzero(newEntry,sizeof(httpContent));
00698         newEntry->name = NULL;
00699         newEntry->type = HTTP_WILDCARD;
00700         newEntry->indexFlag = HTTP_FALSE;
00701         newEntry->preload = preload;
00702         newEntry->next = dirPtr->entries;
00703         dirPtr->entries = newEntry;
00704         if (*path == '/')
00705         {
00706                 /* Absolute path */
00707                 newEntry->path = strdup(path);
00708         }
00709         else
00710         {
00711                 /* Path relative to base path */
00712                 newEntry->path = malloc(strlen(server->fileBasePath) +
00713                         strlen(path) + 2);
00714                 snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
00715                         server->fileBasePath, path);
00716         }
00717         return(0);
00718 }
00719 
00720 
00721 
00722 
00723 int httpdAddC404Content(server, function)
00724         httpd   *server;
00725         void    (*function)();
00726 {
00727         if (!server->handle404) {
00728                 server->handle404 = (http404*)malloc(sizeof(http404));
00729         }
00730 
00731         if (!server->handle404) {
00732                 return(-1);
00733         }
00734 
00735         server->handle404->function = function;
00736         return(0);
00737 }
00738 
00739 int httpdAddCContent(server, dir, name, indexFlag, preload, function)
00740         httpd   *server;
00741         char    *dir;
00742         char    *name;
00743         int     (*preload)();
00744         void    (*function)();
00745 {
00746         httpDir *dirPtr;
00747         httpContent *newEntry;
00748 
00749                 dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00750         newEntry =  malloc(sizeof(httpContent));
00751         if (newEntry == NULL)
00752                 return(-1);
00753         bzero(newEntry,sizeof(httpContent));
00754         newEntry->name = strdup(name);
00755         newEntry->type = HTTP_C_FUNCT;
00756         newEntry->indexFlag = indexFlag;
00757         newEntry->function = function;
00758         newEntry->preload = preload;
00759         newEntry->next = dirPtr->entries;
00760         dirPtr->entries = newEntry;
00761         return(0);
00762 }
00763 
00764 
00765 int httpdAddCWildcardContent(server, dir, preload, function)
00766         httpd   *server;
00767         char    *dir;
00768         int     (*preload)();
00769         void    (*function)();
00770 {
00771         httpDir *dirPtr;
00772         httpContent *newEntry;
00773 
00774         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00775         newEntry =  malloc(sizeof(httpContent));
00776         if (newEntry == NULL)
00777                 return(-1);
00778         bzero(newEntry,sizeof(httpContent));
00779         newEntry->name = NULL;
00780         newEntry->type = HTTP_C_WILDCARD;
00781         newEntry->indexFlag = HTTP_FALSE;
00782         newEntry->function = function;
00783         newEntry->preload = preload;
00784         newEntry->next = dirPtr->entries;
00785         dirPtr->entries = newEntry;
00786         return(0);
00787 }
00788 
00789 int httpdAddStaticContent(server, dir, name, indexFlag, preload, data)
00790         httpd   *server;
00791         char    *dir;
00792         char    *name;
00793         int     (*preload)();
00794         char    *data;
00795 {
00796         httpDir *dirPtr;
00797         httpContent *newEntry;
00798 
00799         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00800         newEntry =  malloc(sizeof(httpContent));
00801         if (newEntry == NULL)
00802                 return(-1);
00803         bzero(newEntry,sizeof(httpContent));
00804         newEntry->name = strdup(name);
00805         newEntry->type = HTTP_STATIC;
00806         newEntry->indexFlag = indexFlag;
00807         newEntry->data = data;
00808         newEntry->preload = preload;
00809         newEntry->next = dirPtr->entries;
00810         dirPtr->entries = newEntry;
00811         return(0);
00812 }
00813 
00814 void httpdSendHeaders(request *r)
00815 {
00816         _httpd_sendHeaders(r, 0, 0);
00817 }
00818 
00819 void httpdSetResponse(request *r, char *msg)
00820 {
00821         strncpy(r->response.response, msg, HTTP_MAX_URL);
00822 }
00823 
00824 void httpdSetContentType(request *r, char *type)
00825 {
00826         strcpy(r->response.contentType, type);
00827 }
00828 
00829 
00830 void httpdAddHeader(request *r, char *msg)
00831 {
00832         strcat(r->response.headers,msg);
00833         if (msg[strlen(msg) - 1] != '\n')
00834                 strcat(r->response.headers,"\n");
00835 }
00836 
00837 void httpdSetCookie(request *r, char *name, char *value)
00838 {
00839         char    buf[HTTP_MAX_URL];
00840 
00841         snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value);
00842         httpdAddHeader(r, buf);
00843 }
00844 
00845 void httpdOutput(request *r, char *msg)
00846 {
00847         char    buf[HTTP_MAX_LEN],
00848                 varName[80],
00849                 *src,
00850                 *dest;
00851         int     count;
00852 
00853         src = msg;
00854         dest = buf;
00855         count = 0;
00856         while(*src && count < HTTP_MAX_LEN)
00857         {
00858                 if (*src == '$')
00859                 {
00860                         char    *cp,
00861                                 *tmp;
00862                         int     count2;
00863                         httpVar *curVar;
00864 
00865                         tmp = src + 1;
00866                         cp = varName;
00867                         count2 = 0;
00868                         while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80)
00869                         {
00870                                 *cp++ = *tmp++;
00871                                 count2++;
00872                         }
00873                         *cp = 0;
00874                         curVar = httpdGetVariableByName(r,varName);
00875                         if (curVar)
00876                         {
00877                                 strcpy(dest, curVar->value);
00878                                 dest = dest + strlen(dest);
00879                                 count += strlen(dest);
00880                         }
00881                         else
00882                         {
00883                                 *dest++ = '$';
00884                                 strcpy(dest, varName);
00885                                 dest += strlen(varName);
00886                                 count += 1 + strlen(varName);
00887                         }
00888                         src = src + strlen(varName) + 1;
00889                         continue;
00890                 }
00891                 *dest++ = *src++;
00892                 count++;
00893         }       
00894         *dest = 0;
00895         r->response.responseLength += strlen(buf);
00896         if (r->response.headersSent == 0)
00897                 httpdSendHeaders(r);
00898         _httpd_net_write( r->clientSock, buf, strlen(buf));
00899 }
00900 
00901 
00902 
00903 #ifdef HAVE_STDARG_H
00904 void httpdPrintf(request *r, char *fmt, ...)
00905 {
00906 #else
00907 void httpdPrintf(va_alist)
00908         va_dcl
00909 {
00910         request         *r;;
00911         char            *fmt;
00912 #endif
00913         va_list         args;
00914         char            buf[HTTP_MAX_LEN];
00915 
00916 #ifdef HAVE_STDARG_H
00917         va_start(args, fmt);
00918 #else
00919         va_start(args);
00920         r = (request *) va_arg(args, request * );
00921         fmt = (char *) va_arg(args, char *);
00922 #endif
00923         if (r->response.headersSent == 0)
00924                 httpdSendHeaders(r);
00925         vsnprintf(buf, HTTP_MAX_LEN, fmt, args);
00926         r->response.responseLength += strlen(buf);
00927         _httpd_net_write( r->clientSock, buf, strlen(buf));
00928 }
00929 
00930 
00931 
00932 
00933 void httpdProcessRequest(httpd *server, request *r)
00934 {
00935         char    dirName[HTTP_MAX_URL],
00936                 entryName[HTTP_MAX_URL],
00937                 *cp;
00938         httpDir *dir;
00939         httpContent *entry;
00940 
00941         r->response.responseLength = 0;
00942         strncpy(dirName, httpdRequestPath(r), HTTP_MAX_URL);
00943         cp = rindex(dirName, '/');
00944         if (cp == NULL)
00945         {
00946                 printf("Invalid request path '%s'\n",dirName);
00947                 return;
00948         }
00949         strncpy(entryName, cp + 1, HTTP_MAX_URL);
00950         if (cp != dirName)
00951                 *cp = 0;
00952         else
00953                 *(cp+1) = 0;
00954         dir = _httpd_findContentDir(server, dirName, HTTP_FALSE);
00955         if (dir == NULL)
00956         {
00957                 _httpd_send404(server, r);
00958                 _httpd_writeAccessLog(server, r);
00959                 return;
00960         }
00961         entry = _httpd_findContentEntry(r, dir, entryName);
00962         if (entry == NULL)
00963         {
00964                 _httpd_send404(server, r);
00965                 _httpd_writeAccessLog(server, r);
00966                 return;
00967         }
00968         if (entry->preload)
00969         {
00970                 if ((entry->preload)(server) < 0)
00971                 {
00972                         _httpd_writeAccessLog(server, r);
00973                         return;
00974                 }
00975         }
00976         switch(entry->type)
00977         {
00978                 case HTTP_C_FUNCT:
00979                 case HTTP_C_WILDCARD:
00980                         (entry->function)(server, r);
00981                         break;
00982 
00983                 case HTTP_STATIC:
00984                         _httpd_sendStatic(server, r, entry->data);
00985                         break;
00986 
00987                 case HTTP_FILE:
00988                         _httpd_sendFile(server, r, entry->path);
00989                         break;
00990 
00991                 case HTTP_WILDCARD:
00992                         if (_httpd_sendDirectoryEntry(server, r, entry,
00993                                                 entryName)<0)
00994                         {
00995                                 _httpd_send404(server, r);
00996                         }
00997                         break;
00998         }
00999         _httpd_writeAccessLog(server, r);
01000 }
01001 
01002 void httpdSetAccessLog(server, fp)
01003         httpd   *server;
01004         FILE    *fp;
01005 {
01006         server->accessLog = fp;
01007 }
01008 
01009 void httpdSetErrorLog(server, fp)
01010         httpd   *server;
01011         FILE    *fp;
01012 {
01013         server->errorLog = fp;
01014 }
01015 
01016 void httpdAuthenticate(request *r, char *realm)
01017 {
01018         char    buffer[255];
01019 
01020         if (r->request.authLength == 0)
01021         {
01022                 httpdSetResponse(r, "401 Please Authenticate");
01023                 snprintf(buffer,sizeof(buffer), 
01024                         "WWW-Authenticate: Basic realm=\"%s\"\n", realm);
01025                 httpdAddHeader(r, buffer);
01026                 httpdOutput(r,"\n");
01027         }
01028 }
01029 
01030 
01031 void httpdForceAuthenticate(request *r, char *realm)
01032 {
01033         char    buffer[255];
01034 
01035         httpdSetResponse(r, "401 Please Authenticate");
01036         snprintf(buffer,sizeof(buffer), 
01037                 "WWW-Authenticate: Basic realm=\"%s\"\n", realm);
01038         httpdAddHeader(r, buffer);
01039         httpdOutput(r,"\n");
01040 }

Generated on Sun Apr 3 20:04:45 2005 for WifiDog by  doxygen 1.4.1