00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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
00236 if( err != 0 )
00237 return NULL;
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 if( LOBYTE( wsaData.wVersion ) != 2 ||
00248 HIBYTE( wsaData.wVersion ) != 2 ) {
00249
00250
00251
00252
00253
00254 WSACleanup( );
00255 return NULL;
00256 }
00257
00258
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
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
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
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
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
00398
00399 count = 0;
00400 inHeaders = 1;
00401 while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0)
00402 {
00403 count++;
00404
00405
00406
00407
00408
00409 if (count == 1)
00410 {
00411
00412
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
00447
00448 if (inHeaders)
00449 {
00450 if (*buf == 0)
00451 {
00452
00453
00454
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
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
00529
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
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
00577
00578
00579
00580
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
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
00674 newEntry->path = strdup(path);
00675 }
00676 else
00677 {
00678
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
00712 newEntry->path = strdup(path);
00713 }
00714 else
00715 {
00716
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 }