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 1239 2007-05-30 19:21:21Z david $
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
00462 
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 #if 0
00576         /* XXX: For WifiDog, we only process the query string parameters
00577            but keep the GET variables in the request.query!
00578         */
00579         /*
00580         ** Process and POST data
00581         */
00582         if (r->request.contentLength > 0)
00583         {
00584                 bzero(buf, HTTP_MAX_LEN);
00585                 _httpd_readBuf(r, buf, r->request.contentLength);
00586                 _httpd_storeData(r, buf);
00587                 
00588         }
00589 #endif
00590 
00591         /*
00592         ** Process any URL data
00593         */
00594         cp = index(r->request.path,'?');
00595         if (cp != NULL)
00596         {
00597                 *cp++ = 0;
00598                 strncpy(r->request.query, cp, sizeof(r->request.query));
00599                 _httpd_storeData(r, cp);
00600         }
00601 
00602         return(0);
00603 }
00604 
00605 
00606 void httpdEndRequest(request *r)
00607 {
00608         _httpd_freeVariables(r->variables);
00609         shutdown(r->clientSock,2);
00610         close(r->clientSock);
00611         free(r);
00612 }
00613 
00614 
00615 void httpdFreeVariables(request *r)
00616 {
00617         _httpd_freeVariables(r->variables);
00618 }
00619 
00620 
00621 
00622 void httpdDumpVariables(request *r)
00623 {
00624         httpVar *curVar,
00625                 *curVal;
00626 
00627         curVar = r->variables;
00628         while(curVar)
00629         {
00630                 printf("Variable '%s'\n", curVar->name);
00631                 curVal = curVar;
00632                 while(curVal)
00633                 {
00634                         printf("\t= '%s'\n",curVal->value);
00635                         curVal = curVal->nextValue;
00636                 }
00637                 curVar = curVar->nextVariable;
00638         }
00639 }
00640 
00641 void httpdSetFileBase(server, path)
00642         httpd   *server;
00643         char    *path;
00644 {
00645         strncpy(server->fileBasePath, path, HTTP_MAX_URL);
00646 }
00647 
00648 
00649 int httpdAddFileContent(server, dir, name, indexFlag, preload, path)
00650         httpd   *server;
00651         char    *dir,
00652                 *name;
00653         int     (*preload)();
00654         int     indexFlag;
00655         char    *path;
00656 {
00657         httpDir *dirPtr;
00658         httpContent *newEntry;
00659 
00660         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00661         newEntry =  malloc(sizeof(httpContent));
00662         if (newEntry == NULL)
00663                 return(-1);
00664         bzero(newEntry,sizeof(httpContent));
00665         newEntry->name = strdup(name);
00666         newEntry->type = HTTP_FILE;
00667         newEntry->indexFlag = indexFlag;
00668         newEntry->preload = preload;
00669         newEntry->next = dirPtr->entries;
00670         dirPtr->entries = newEntry;
00671         if (*path == '/')
00672         {
00673                 /* Absolute path */
00674                 newEntry->path = strdup(path);
00675         }
00676         else
00677         {
00678                 /* Path relative to base path */
00679                 newEntry->path = malloc(strlen(server->fileBasePath) +
00680                         strlen(path) + 2);
00681                 snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
00682                         server->fileBasePath, path);
00683         }
00684         return(0);
00685 }
00686 
00687 
00688 
00689 int httpdAddWildcardContent(server, dir, preload, path)
00690         httpd   *server;
00691         char    *dir;
00692         int     (*preload)();
00693         char    *path;
00694 {
00695         httpDir *dirPtr;
00696         httpContent *newEntry;
00697 
00698         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00699         newEntry =  malloc(sizeof(httpContent));
00700         if (newEntry == NULL)
00701                 return(-1);
00702         bzero(newEntry,sizeof(httpContent));
00703         newEntry->name = NULL;
00704         newEntry->type = HTTP_WILDCARD;
00705         newEntry->indexFlag = HTTP_FALSE;
00706         newEntry->preload = preload;
00707         newEntry->next = dirPtr->entries;
00708         dirPtr->entries = newEntry;
00709         if (*path == '/')
00710         {
00711                 /* Absolute path */
00712                 newEntry->path = strdup(path);
00713         }
00714         else
00715         {
00716                 /* Path relative to base path */
00717                 newEntry->path = malloc(strlen(server->fileBasePath) +
00718                         strlen(path) + 2);
00719                 snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
00720                         server->fileBasePath, path);
00721         }
00722         return(0);
00723 }
00724 
00725 
00726 
00727 
00728 int httpdAddC404Content(server, function)
00729         httpd   *server;
00730         void    (*function)();
00731 {
00732         if (!server->handle404) {
00733                 server->handle404 = (http404*)malloc(sizeof(http404));
00734         }
00735 
00736         if (!server->handle404) {
00737                 return(-1);
00738         }
00739 
00740         server->handle404->function = function;
00741         return(0);
00742 }
00743 
00744 int httpdAddCContent(server, dir, name, indexFlag, preload, function)
00745         httpd   *server;
00746         char    *dir;
00747         char    *name;
00748         int     (*preload)();
00749         void    (*function)();
00750 {
00751         httpDir *dirPtr;
00752         httpContent *newEntry;
00753 
00754                 dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00755         newEntry =  malloc(sizeof(httpContent));
00756         if (newEntry == NULL)
00757                 return(-1);
00758         bzero(newEntry,sizeof(httpContent));
00759         newEntry->name = strdup(name);
00760         newEntry->type = HTTP_C_FUNCT;
00761         newEntry->indexFlag = indexFlag;
00762         newEntry->function = function;
00763         newEntry->preload = preload;
00764         newEntry->next = dirPtr->entries;
00765         dirPtr->entries = newEntry;
00766         return(0);
00767 }
00768 
00769 
00770 int httpdAddCWildcardContent(server, dir, preload, function)
00771         httpd   *server;
00772         char    *dir;
00773         int     (*preload)();
00774         void    (*function)();
00775 {
00776         httpDir *dirPtr;
00777         httpContent *newEntry;
00778 
00779         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00780         newEntry =  malloc(sizeof(httpContent));
00781         if (newEntry == NULL)
00782                 return(-1);
00783         bzero(newEntry,sizeof(httpContent));
00784         newEntry->name = NULL;
00785         newEntry->type = HTTP_C_WILDCARD;
00786         newEntry->indexFlag = HTTP_FALSE;
00787         newEntry->function = function;
00788         newEntry->preload = preload;
00789         newEntry->next = dirPtr->entries;
00790         dirPtr->entries = newEntry;
00791         return(0);
00792 }
00793 
00794 int httpdAddStaticContent(server, dir, name, indexFlag, preload, data)
00795         httpd   *server;
00796         char    *dir;
00797         char    *name;
00798         int     (*preload)();
00799         char    *data;
00800 {
00801         httpDir *dirPtr;
00802         httpContent *newEntry;
00803 
00804         dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
00805         newEntry =  malloc(sizeof(httpContent));
00806         if (newEntry == NULL)
00807                 return(-1);
00808         bzero(newEntry,sizeof(httpContent));
00809         newEntry->name = strdup(name);
00810         newEntry->type = HTTP_STATIC;
00811         newEntry->indexFlag = indexFlag;
00812         newEntry->data = data;
00813         newEntry->preload = preload;
00814         newEntry->next = dirPtr->entries;
00815         dirPtr->entries = newEntry;
00816         return(0);
00817 }
00818 
00819 void httpdSendHeaders(request *r)
00820 {
00821         _httpd_sendHeaders(r, 0, 0);
00822 }
00823 
00824 void httpdSetResponse(request *r, char *msg)
00825 {
00826         strncpy(r->response.response, msg, HTTP_MAX_URL);
00827 }
00828 
00829 void httpdSetContentType(request *r, char *type)
00830 {
00831         strcpy(r->response.contentType, type);
00832 }
00833 
00834 
00835 void httpdAddHeader(request *r, char *msg)
00836 {
00837         strcat(r->response.headers,msg);
00838         if (msg[strlen(msg) - 1] != '\n')
00839                 strcat(r->response.headers,"\n");
00840 }
00841 
00842 void httpdSetCookie(request *r, char *name, char *value)
00843 {
00844         char    buf[HTTP_MAX_URL];
00845 
00846         snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value);
00847         httpdAddHeader(r, buf);
00848 }
00849 
00850 void httpdOutput(request *r, char *msg)
00851 {
00852         char    buf[HTTP_MAX_LEN],
00853                 varName[80],
00854                 *src,
00855                 *dest;
00856         int     count;
00857 
00858         src = msg;
00859         dest = buf;
00860         count = 0;
00861         while(*src && count < HTTP_MAX_LEN)
00862         {
00863                 if (*src == '$')
00864                 {
00865                         char    *cp,
00866                                 *tmp;
00867                         int     count2;
00868                         httpVar *curVar;
00869 
00870                         tmp = src + 1;
00871                         cp = varName;
00872                         count2 = 0;
00873                         while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80)
00874                         {
00875                                 *cp++ = *tmp++;
00876                                 count2++;
00877                         }
00878                         *cp = 0;
00879                         curVar = httpdGetVariableByName(r,varName);
00880                         if (curVar)
00881                         {
00882                                 strcpy(dest, curVar->value);
00883                                 dest = dest + strlen(dest);
00884                                 count += strlen(dest);
00885                         }
00886                         else
00887                         {
00888                                 *dest++ = '$';
00889                                 strcpy(dest, varName);
00890                                 dest += strlen(varName);
00891                                 count += 1 + strlen(varName);
00892                         }
00893                         src = src + strlen(varName) + 1;
00894                         continue;
00895                 }
00896                 *dest++ = *src++;
00897                 count++;
00898         }       
00899         *dest = 0;
00900         r->response.responseLength += strlen(buf);
00901         if (r->response.headersSent == 0)
00902                 httpdSendHeaders(r);
00903         _httpd_net_write( r->clientSock, buf, strlen(buf));
00904 }
00905 
00906 
00907 
00908 #ifdef HAVE_STDARG_H
00909 void httpdPrintf(request *r, char *fmt, ...)
00910 {
00911 #else
00912 void httpdPrintf(va_alist)
00913         va_dcl
00914 {
00915         request         *r;;
00916         char            *fmt;
00917 #endif
00918         va_list         args;
00919         char            buf[HTTP_MAX_LEN];
00920 
00921 #ifdef HAVE_STDARG_H
00922         va_start(args, fmt);
00923 #else
00924         va_start(args);
00925         r = (request *) va_arg(args, request * );
00926         fmt = (char *) va_arg(args, char *);
00927 #endif
00928         if (r->response.headersSent == 0)
00929                 httpdSendHeaders(r);
00930         vsnprintf(buf, HTTP_MAX_LEN, fmt, args);
00931         r->response.responseLength += strlen(buf);
00932         _httpd_net_write( r->clientSock, buf, strlen(buf));
00933 }
00934 
00935 
00936 
00937 
00938 void httpdProcessRequest(httpd *server, request *r)
00939 {
00940         char    dirName[HTTP_MAX_URL],
00941                 entryName[HTTP_MAX_URL],
00942                 *cp;
00943         httpDir *dir;
00944         httpContent *entry;
00945 
00946         r->response.responseLength = 0;
00947         strncpy(dirName, httpdRequestPath(r), HTTP_MAX_URL);
00948         cp = rindex(dirName, '/');
00949         if (cp == NULL)
00950         {
00951                 printf("Invalid request path '%s'\n",dirName);
00952                 return;
00953         }
00954         strncpy(entryName, cp + 1, HTTP_MAX_URL);
00955         if (cp != dirName)
00956                 *cp = 0;
00957         else
00958                 *(cp+1) = 0;
00959         dir = _httpd_findContentDir(server, dirName, HTTP_FALSE);
00960         if (dir == NULL)
00961         {
00962                 _httpd_send404(server, r);
00963                 _httpd_writeAccessLog(server, r);
00964                 return;
00965         }
00966         entry = _httpd_findContentEntry(r, dir, entryName);
00967         if (entry == NULL)
00968         {
00969                 _httpd_send404(server, r);
00970                 _httpd_writeAccessLog(server, r);
00971                 return;
00972         }
00973         if (entry->preload)
00974         {
00975                 if ((entry->preload)(server) < 0)
00976                 {
00977                         _httpd_writeAccessLog(server, r);
00978                         return;
00979                 }
00980         }
00981         switch(entry->type)
00982         {
00983                 case HTTP_C_FUNCT:
00984                 case HTTP_C_WILDCARD:
00985                         (entry->function)(server, r);
00986                         break;
00987 
00988                 case HTTP_STATIC:
00989                         _httpd_sendStatic(server, r, entry->data);
00990                         break;
00991 
00992                 case HTTP_FILE:
00993                         _httpd_sendFile(server, r, entry->path);
00994                         break;
00995 
00996                 case HTTP_WILDCARD:
00997                         if (_httpd_sendDirectoryEntry(server, r, entry,
00998                                                 entryName)<0)
00999                         {
01000                                 _httpd_send404(server, r);
01001                         }
01002                         break;
01003         }
01004         _httpd_writeAccessLog(server, r);
01005 }
01006 
01007 void httpdSetAccessLog(server, fp)
01008         httpd   *server;
01009         FILE    *fp;
01010 {
01011         server->accessLog = fp;
01012 }
01013 
01014 void httpdSetErrorLog(server, fp)
01015         httpd   *server;
01016         FILE    *fp;
01017 {
01018         server->errorLog = fp;
01019 }
01020 
01021 void httpdAuthenticate(request *r, char *realm)
01022 {
01023         char    buffer[255];
01024 
01025         if (r->request.authLength == 0)
01026         {
01027                 httpdSetResponse(r, "401 Please Authenticate");
01028                 snprintf(buffer,sizeof(buffer), 
01029                         "WWW-Authenticate: Basic realm=\"%s\"\n", realm);
01030                 httpdAddHeader(r, buffer);
01031                 httpdOutput(r,"\n");
01032         }
01033 }
01034 
01035 
01036 void httpdForceAuthenticate(request *r, char *realm)
01037 {
01038         char    buffer[255];
01039 
01040         httpdSetResponse(r, "401 Please Authenticate");
01041         snprintf(buffer,sizeof(buffer), 
01042                 "WWW-Authenticate: Basic realm=\"%s\"\n", realm);
01043         httpdAddHeader(r, buffer);
01044         httpdOutput(r,"\n");
01045 }

Generated on Sun Jun 24 00:29:52 2007 for WifiDog by  doxygen 1.5.1