Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the action codes in the althttpd.c log to be consistent numbers, rather than source code line numbers. Include text at the end of a file that will generate a cross-reference table in SQLite. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8aafa56bb9eb1ef7be3477bdfb152e78 |
User & Date: | drh 2018-02-25 17:25:30.277 |
Context
2018-02-25
| ||
17:29 | Fix some missing error codes from the previous althttpd.c check-in. (check-in: 5f2e54c6c1 user: drh tags: trunk) | |
17:25 | Change the action codes in the althttpd.c log to be consistent numbers, rather than source code line numbers. Include text at the end of a file that will generate a cross-reference table in SQLite. (check-in: 8aafa56bb9 user: drh tags: trunk) | |
01:29 | Add support for Last-Modified and If-Modified-Since in althttpd.c. (check-in: 130feb0aa0 user: drh tags: trunk) | |
Changes
Changes to misc/althttpd.c.
︙ | ︙ | |||
391 392 393 394 395 396 397 | */ static char *SafeMalloc( int size ){ char *p; p = (char*)malloc(size); if( p==0 ){ strcpy(zReplyStatus, "998"); | | | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | */ static char *SafeMalloc( int size ){ char *p; p = (char*)malloc(size); if( p==0 ){ strcpy(zReplyStatus, "998"); MakeLogEntry(1,100); /* LOG: Malloc() failed */ exit(1); } return p; } /* ** Set the value of environment variable zVar to zValue. |
︙ | ︙ | |||
623 624 625 626 627 628 629 | "WWW-Authenticate: Basic realm=\"%s\"\r\n" "Content-type: text/html\r\n" "\r\n" "<head><title>Not Authorized</title></head>\n" "<body><h1>401 Not Authorized</h1>\n" "A login and password are required for this document\n" "</body>\n", zRealm); | | | | | | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | "WWW-Authenticate: Basic realm=\"%s\"\r\n" "Content-type: text/html\r\n" "\r\n" "<head><title>Not Authorized</title></head>\n" "<body><h1>401 Not Authorized</h1>\n" "A login and password are required for this document\n" "</body>\n", zRealm); MakeLogEntry(0, 110); /* LOG: Not authorized */ } /* ** Tell the client that there is an error in the script. */ static void CgiError(void){ StartResponse("500 Error"); nOut += printf( "Content-type: text/html\r\n" "\r\n" "<head><title>CGI Program Error</title></head>\n" "<body><h1>CGI Program Error</h1>\n" "The CGI program %s generated an error\n" "</body>\n", zScript); MakeLogEntry(0, 120); /* LOG: CGI Error */ exit(0); } /* ** This is called if we timeout or catch some other kind of signal. ** Log an error code which is 900+iSig and then quit. */ static void Timeout(int iSig){ if( !debugFlag ){ if( zScript && zScript[0] ){ char zBuf[10]; zBuf[0] = '9'; zBuf[1] = '0' + (iSig/10)%10; zBuf[2] = '0' + iSig%10; zBuf[3] = 0; strcpy(zReplyStatus, zBuf); MakeLogEntry(0, 130); /* LOG: Timeout */ } exit(0); } } /* ** Tell the client that there is an error in the script. */ static void CgiScriptWritable(void){ StartResponse("500 CGI Configuration Error"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "The CGI program %s is writable by users other than its owner.\n", zRealScript); MakeLogEntry(0, 140); /* LOG: CGI script is writable */ exit(0); } /* ** Tell the client that the server malfunctioned. */ static void Malfunction(int linenum, const char *zFormat, ...){ |
︙ | ︙ | |||
785 786 787 788 789 790 791 | char *zRealm = "unknown realm"; char *zLoginPswd; char *zName; char zLine[2000]; in = fopen(zAuthFile, "r"); if( in==0 ){ | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | char *zRealm = "unknown realm"; char *zLoginPswd; char *zName; char zLine[2000]; in = fopen(zAuthFile, "r"); if( in==0 ){ NotFound(150); /* LOG: Cannot open -auth file */ return 0; } if( zAuthArg ) Decode64(zAuthArg); while( fgets(zLine, sizeof(zLine), in) ){ char *zFieldName; char *zVal; |
︙ | ︙ | |||
811 812 813 814 815 816 817 | if( zAuthArg && strcmp(zAuthArg,zLoginPswd)==0 ){ zRemoteUser = StrDup(zName); fclose(in); return 1; } }else if( strcmp(zFieldName,"https-only")==0 ){ if( !useHttps ){ | | | | | 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | if( zAuthArg && strcmp(zAuthArg,zLoginPswd)==0 ){ zRemoteUser = StrDup(zName); fclose(in); return 1; } }else if( strcmp(zFieldName,"https-only")==0 ){ if( !useHttps ){ NotFound(160); /* LOG: http request on https-only page */ fclose(in); return 0; } }else if( strcmp(zFieldName,"http-redirect")==0 ){ if( !useHttps ){ zHttp = "https"; sprintf(zLine, "%s%s", zScript, zPathInfo); Redirect(zLine, 1, 170); /* LOG: -auth redirect */ fclose(in); return 0; } }else{ NotFound(180); /* LOG: malformed entry in -auth file */ fclose(in); return 0; } } fclose(in); NotAuthorized(zRealm); return 0; |
︙ | ︙ | |||
1159 1160 1161 1162 1163 1164 1165 | #endif char zLine[1000]; /* A buffer for input lines or forming names */ /* Change directories to the root of the HTTP filesystem */ if( chdir(zRoot[0] ? zRoot : "/")!=0 ){ char zBuf[1000]; | | | 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 | #endif char zLine[1000]; /* A buffer for input lines or forming names */ /* Change directories to the root of the HTTP filesystem */ if( chdir(zRoot[0] ? zRoot : "/")!=0 ){ char zBuf[1000]; Malfunction(190, /* LOG: chdir() failed */ "cannot chdir to [%s] from [%s]", zRoot, getcwd(zBuf,999)); } nRequest++; /* ** We must receive a complete header within 15 seconds |
︙ | ︙ | |||
1193 1194 1195 1196 1197 1198 1199 | if( zProtocol==0 || strncmp(zProtocol,"HTTP/",5)!=0 || strlen(zProtocol)!=8 ){ StartResponse("400 Bad Request"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "This server does not understand the requested protocol\n" ); | | | | | 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 | if( zProtocol==0 || strncmp(zProtocol,"HTTP/",5)!=0 || strlen(zProtocol)!=8 ){ StartResponse("400 Bad Request"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "This server does not understand the requested protocol\n" ); MakeLogEntry(0, 200); /* LOG: bad protocol in HTTP header */ exit(0); } if( zScript[0]==0 ) NotFound(210); /* LOG: Empty request URI */ if( forceClose ){ closeConnection = 1; }else if( zProtocol[5]<'1' || zProtocol[7]<'1' ){ closeConnection = 1; } /* This very simple server only understands the GET, POST ** and HEAD methods */ if( strcmp(zMethod,"GET")!=0 && strcmp(zMethod,"POST")!=0 && strcmp(zMethod,"HEAD")!=0 ){ StartResponse("501 Not Implemented"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "The %s method is not implemented on this server.\n", zMethod); MakeLogEntry(0, 220); /* LOG: Unknown request method */ exit(0); } /* If there is a log file (if zLogFile!=0) and if the pathname in ** the first line of the http request contains the magic string ** "FullHeaderLog" then write the complete header text into the ** file %s(zLogFile)-hdr. Overwrite the file. This is for protocol |
︙ | ︙ | |||
1268 1269 1270 1271 1272 1273 1274 | }else if( strcasecmp(zFieldName,"Content-length:")==0 ){ zContentLength = StrDup(zVal); }else if( strcasecmp(zFieldName,"Content-type:")==0 ){ zContentType = StrDup(zVal); }else if( strcasecmp(zFieldName,"Referer:")==0 ){ zReferer = StrDup(zVal); if( strstr(zVal, "devids.net/")!=0 ){ zReferer = "devids.net.smut"; | | | | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | }else if( strcasecmp(zFieldName,"Content-length:")==0 ){ zContentLength = StrDup(zVal); }else if( strcasecmp(zFieldName,"Content-type:")==0 ){ zContentType = StrDup(zVal); }else if( strcasecmp(zFieldName,"Referer:")==0 ){ zReferer = StrDup(zVal); if( strstr(zVal, "devids.net/")!=0 ){ zReferer = "devids.net.smut"; Forbidden(230); /* LOG: Referrer is devids.net */ } }else if( strcasecmp(zFieldName,"Cookie:")==0 ){ zCookie = StrAppend(zCookie,"; ",zVal); }else if( strcasecmp(zFieldName,"Connection:")==0 ){ if( strcasecmp(zVal,"close")==0 ){ closeConnection = 1; }else if( !forceClose && strcasecmp(zVal, "keep-alive")==0 ){ closeConnection = 0; } }else if( strcasecmp(zFieldName,"Host:")==0 ){ int inSquare = 0; char c; if( sanitizeString(zVal) ){ Forbidden(240); /* LOG: Illegal content in HOST: parameter */ } zHttpHost = StrDup(zVal); zServerPort = zServerName = StrDup(zHttpHost); while( zServerPort && (c = *zServerPort)!=0 && (c!=':' || inSquare) ){ if( c=='[' ) inSquare = 1; if( c==']' ) inSquare = 0; |
︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 | if( zAgent ){ if( strstr(zAgent, "Windows_9")!=0 || strstr(zAgent, "Download_Master")!=0 || strstr(zAgent, "Ezooms/")!=0 || strstr(zAgent, "HTTrack")!=0 || strstr(zAgent, "AhrefsBot")!=0 ){ | | | | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 | if( zAgent ){ if( strstr(zAgent, "Windows_9")!=0 || strstr(zAgent, "Download_Master")!=0 || strstr(zAgent, "Ezooms/")!=0 || strstr(zAgent, "HTTrack")!=0 || strstr(zAgent, "AhrefsBot")!=0 ){ Forbidden(250); /* LOG: Disallowed user agent */ } } #if 0 if( zReferer ){ static const char *azDisallow[] = { "skidrowcrack.com", "hoshiyuugi.tistory.com", "skidrowgames.net", }; int i; for(i=0; i<sizeof(azDisallow)/sizeof(azDisallow[0]); i++){ if( strstr(zReferer, azDisallow[i])!=0 ){ NotFound(260); /* LOG: Disallowed referrer */ } } } #endif /* Make an extra effort to get a valid server name and port number. ** Only Netscape provides this information. If the browser is |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | if( len>MAX_CONTENT_LENGTH ){ StartResponse("500 Request too large"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "Too much POST data\n" ); | | | | | 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 | if( len>MAX_CONTENT_LENGTH ){ StartResponse("500 Request too large"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "Too much POST data\n" ); MakeLogEntry(0, 270); /* LOG: Request too large */ exit(0); } sprintf(zTmpNamBuf, "/tmp/-post-data-XXXXXX"); zTmpNam = zTmpNamBuf; if( mkstemp(zTmpNam)<0 ){ Malfunction(280, /* LOG: mkstemp() failed */ "Cannot create a temp file in which to store POST data"); } out = fopen(zTmpNam,"w"); if( out==0 ){ StartResponse("500 Cannot create /tmp file"); nOut += printf( "Content-type: text/plain\r\n" "\r\n" "Could not open \"%s\" for writing\n", zTmpNam ); MakeLogEntry(0, 290); /* LOG: cannot create temp file for POST */ exit(0); } zBuf = SafeMalloc( len+1 ); if( useTimeout ) alarm(15 + len/2000); n = fread(zBuf,1,len,stdin); nIn += n; fwrite(zBuf,1,n,out); |
︙ | ︙ | |||
1430 1431 1432 1433 1434 1435 1436 | ** Exception: Allow the "/.well-known/" prefix in accordance with ** RFC-5785 */ for(z=zScript; *z; z++){ if( *z=='/' && (z[1]=='.' || z[1]=='-') && (z>zScript || strncmp(z,"/.well-known/",13)!=0) ){ | | | | | | | | | 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 | ** Exception: Allow the "/.well-known/" prefix in accordance with ** RFC-5785 */ for(z=zScript; *z; z++){ if( *z=='/' && (z[1]=='.' || z[1]=='-') && (z>zScript || strncmp(z,"/.well-known/",13)!=0) ){ NotFound(300); /* LOG: Path element begins with "." or "-" */ } } /* Figure out what the root of the filesystem should be. If the ** HTTP_HOST parameter exists (stored in zHttpHost) then remove the ** port number from the end (if any), convert all characters to lower ** case, and convert all "." to "_". Then try to find a directory ** with that name and the extension .website. If not found, look ** for "default.website". */ if( zScript[0]!='/' ){ NotFound(310); /* LOG: URI does not start with "/" */ } if( strlen(zRoot)+40 >= sizeof(zLine) ){ NotFound(320); /* LOG: URI too long */ } if( zHttpHost==0 || zHttpHost[0]==0 ){ NotFound(330); /* LOG: Missing HOST: parameter */ }else if( strlen(zHttpHost)+strlen(zRoot)+10 >= sizeof(zLine) ){ NotFound(340); /* LOG: HOST parameter too long */ }else{ sprintf(zLine, "%s/%s", zRoot, zHttpHost); for(i=strlen(zRoot)+1; zLine[i] && zLine[i]!=':'; i++){ int c = zLine[i]; if( !isalnum(c) ){ zLine[i] = '_'; }else if( isupper(c) ){ zLine[i] = tolower(c); } } strcpy(&zLine[i], ".website"); } if( stat(zLine,&statbuf) || !S_ISDIR(statbuf.st_mode) ){ sprintf(zLine, "%s/default.website", zRoot); if( stat(zLine,&statbuf) || !S_ISDIR(statbuf.st_mode) ){ if( standalone ){ sprintf(zLine, "%s", zRoot); }else{ NotFound(350); /* LOG: *.website permissions */ } } } zHome = StrDup(zLine); /* Change directories to the root of the HTTP filesystem */ if( chdir(zHome)!=0 ){ char zBuf[1000]; Malfunction(360, /* LOG: chdir() failed */ "cannot chdir to [%s] from [%s]", zHome, getcwd(zBuf,999)); } /* Locate the file in the filesystem. We might have to append ** the name "index.html" in order to find it. Any excess path ** information is put into the zPathInfo variable. |
︙ | ︙ | |||
1504 1505 1506 1507 1508 1509 1510 | int stillSearching = 1; while( stillSearching && i>0 && j>j0 ){ while( j>j0 && zLine[j-1]!='/' ){ j--; } strcpy(&zLine[j-1], "/not-found.html"); if( stat(zLine,&statbuf)==0 && S_ISREG(statbuf.st_mode) && access(zLine,R_OK)==0 ){ zRealScript = StrDup(&zLine[j0]); | | | | | | | 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 | int stillSearching = 1; while( stillSearching && i>0 && j>j0 ){ while( j>j0 && zLine[j-1]!='/' ){ j--; } strcpy(&zLine[j-1], "/not-found.html"); if( stat(zLine,&statbuf)==0 && S_ISREG(statbuf.st_mode) && access(zLine,R_OK)==0 ){ zRealScript = StrDup(&zLine[j0]); Redirect(zRealScript, 1, 370); /* LOG: redirect to not-found */ return; }else{ j--; } } if( stillSearching ) NotFound(380); /* LOG: URI not found */ break; } if( S_ISREG(statbuf.st_mode) ){ if( access(zLine,R_OK) ){ NotFound(390); /* LOG: File not readable */ } zRealScript = StrDup(&zLine[j0]); break; } if( zScript[i]==0 || zScript[i+1]==0 ){ int k = j>0 && zLine[j-1]=='/' ? j-1 : j; strcpy(&zLine[k],"/index.html"); if( stat(zLine,&statbuf)!=0 || !S_ISREG(statbuf.st_mode) || access(zLine,R_OK) ){ strcpy(&zLine[k],"/index.cgi"); if( stat(zLine,&statbuf)!=0 || !S_ISREG(statbuf.st_mode) || access(zLine,R_OK) ){ NotFound(400); /* LOG: URI is a directory w/o index.html */ } } zRealScript = StrDup(&zLine[j0]); if( zScript[i]==0 ){ /* If the requested URL does not end with "/" but we had to ** append "index.html", then a redirect is necessary. Otherwise ** none of the relative URLs in the delivered document will be ** correct. */ Redirect(zRealScript,1,410); /* LOG: redirect to add trailing / */ return; } break; } zLine[j] = zScript[i]; i++; j++; } |
︙ | ︙ | |||
1614 1615 1616 1617 1618 1619 1620 | char *aRes = 0; /* Payload */ /* If its executable, it must be a CGI program. Start by ** changing directories to the directory holding the program. */ if( chdir(zDir) ){ char zBuf[1000]; | | | 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 | char *aRes = 0; /* Payload */ /* If its executable, it must be a CGI program. Start by ** changing directories to the directory holding the program. */ if( chdir(zDir) ){ char zBuf[1000]; Malfunction(420, /* LOG: chdir() failed */ "cannot chdir to [%s] from [%s]", zDir, getcwd(zBuf,999)); } /* Setup the environment appropriately. */ for(i=0; i<(int)(sizeof(cgienv)/sizeof(cgienv[0])); i++){ |
︙ | ︙ | |||
1643 1644 1645 1646 1647 1648 1649 | } /* For the POST method all input has been written to a temporary file, ** so we have to redirect input to the CGI script from that file. */ if( zMethod[0]=='P' ){ if( dup(0)<0 ){ | | | 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 | } /* For the POST method all input has been written to a temporary file, ** so we have to redirect input to the CGI script from that file. */ if( zMethod[0]=='P' ){ if( dup(0)<0 ){ Malfunction(430, /* LOG: dup(0) failed */ "Unable to duplication file descriptor 0"); } close(0); open(zTmpNam, O_RDONLY); } for(i=strlen(zFile)-1; i>=0 && zFile[i]!='/'; i--){} |
︙ | ︙ | |||
1671 1672 1673 1674 1675 1676 1677 | ** Open a pipe to receive the output from the CGI process. Then ** fork the CGI process. Once everything is done, we should be ** able to read the output of CGI on the "in" stream. */ { int px[2]; if( pipe(px) ){ | | | | 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 | ** Open a pipe to receive the output from the CGI process. Then ** fork the CGI process. Once everything is done, we should be ** able to read the output of CGI on the "in" stream. */ { int px[2]; if( pipe(px) ){ Malfunction(440, /* LOG: pipe() failed */ "Unable to create a pipe for the CGI program"); } if( fork()==0 ){ close(px[0]); close(1); if( dup(px[1])!=1 ){ Malfunction(450, /* LOG: dup(1) failed */ "Unable to duplicate file descriptor %d to 1", px[1]); } close(px[1]); execl(zBaseFilename, zBaseFilename, (char*)0); exit(0); } |
︙ | ︙ | |||
1753 1754 1755 1756 1757 1758 1759 | nOut += printf("Content-length: %d\r\n\r\n%s", nRes, aRes); free(aRes); } fclose(in); }else if( countSlashes(zRealScript)!=countSlashes(zScript) ){ /* If the request URI for static content contains material past the ** actual content file name, report that as a 404 error. */ | | | 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 | nOut += printf("Content-length: %d\r\n\r\n%s", nRes, aRes); free(aRes); } fclose(in); }else if( countSlashes(zRealScript)!=countSlashes(zScript) ){ /* If the request URI for static content contains material past the ** actual content file name, report that as a 404 error. */ NotFound(460); /* LOG: Excess URI content past static file name */ }else{ /* If it isn't executable then it ** must a simple file that needs to be copied to output. */ const char *zContentType = GetMimeType(zFile, lenFile); time_t t; char zETag[100]; |
︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 | ){ StartResponse("304 Not Modified"); nOut += DateTag("Last-Modified", statbuf.st_mtime); nOut += printf("Cache-Control: max-age=%d\r\n", mxAge); nOut += printf("ETag: \"%s\"\r\n", zETag); nOut += printf("\r\n"); fflush(stdout); | | | | | | 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 | ){ StartResponse("304 Not Modified"); nOut += DateTag("Last-Modified", statbuf.st_mtime); nOut += printf("Cache-Control: max-age=%d\r\n", mxAge); nOut += printf("ETag: \"%s\"\r\n", zETag); nOut += printf("\r\n"); fflush(stdout); MakeLogEntry(0, 470); /* LOG: ETag Cache Hit */ return; } in = fopen(zFile,"r"); if( in==0 ) NotFound(480); /* LOG: fopen() failed for static content */ StartResponse("200 OK"); nOut += DateTag("Last-Modified", statbuf.st_mtime); nOut += printf("Cache-Control: max-age=%d\r\n", mxAge); nOut += printf("ETag: \"%s\"\r\n", zETag); nOut += printf("Content-type: %s\r\n",zContentType); nOut += printf("Content-length: %d\r\n\r\n",(int)statbuf.st_size); fflush(stdout); if( strcmp(zMethod,"HEAD")==0 ){ MakeLogEntry(0, 2); /* LOG: Normal HEAD reply */ fclose(in); fflush(stdout); return; } if( useTimeout ) alarm(30 + statbuf.st_size/1000); #ifdef linux { off_t offset = 0; nOut += sendfile(fileno(stdout), fileno(in), &offset, statbuf.st_size); } #else while( (c = getc(in))!=EOF ){ putc(c,stdout); nOut++; } #endif fclose(in); } fflush(stdout); MakeLogEntry(0, 0); /* LOG: Normal reply */ /* The next request must arrive within 30 seconds or we close the connection */ omitLog = 1; if( useTimeout ) alarm(30); } |
︙ | ︙ | |||
1994 1995 1996 1997 1998 1999 2000 | standalone = 1; }else if( strcmp(z, "-family")==0 ){ if( strcmp(zArg, "ipv4")==0 ){ ipv4Only = 1; }else if( strcmp(zArg, "ipv6")==0 ){ ipv6Only = 1; }else{ | | | | | | | | | | | | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 | standalone = 1; }else if( strcmp(z, "-family")==0 ){ if( strcmp(zArg, "ipv4")==0 ){ ipv4Only = 1; }else if( strcmp(zArg, "ipv6")==0 ){ ipv6Only = 1; }else{ Malfunction(500, /* LOG: unknown IP protocol */ "unknown IP protocol: [%s]\n", zArg); } }else if( strcmp(z, "-jail")==0 ){ if( atoi(zArg)==0 ){ useChrootJail = 0; } }else if( strcmp(z, "-debug")==0 ){ if( atoi(zArg) ){ useTimeout = 0; } }else if( strcmp(z, "-datetest")==0 ){ TestParseRfc822Date(); printf("Ok\n"); exit(0); }else{ Malfunction(510, /* LOG: unknown command-line argument on launch */ "unknown argument: [%s]\n", z); } argv += 2; argc -= 2; } if( zRoot==0 ){ if( standalone ){ zRoot = "."; }else{ Malfunction(520, /* LOG: --root argument missing */ "no --root specified"); } } /* Change directories to the root of the HTTP filesystem. Then ** create a chroot jail there. */ if( chdir(zRoot)!=0 ){ Malfunction(530, /* LOG: chdir() failed */ "cannot change to directory [%s]", zRoot); } /* Get information about the user if available */ if( zPermUser ) pwd = getpwnam(zPermUser); /* Enter the chroot jail if requested */ if( zPermUser && useChrootJail && getuid()==0 ){ if( chroot(".")<0 ){ Malfunction(540, /* LOG: chroot() failed */ "unable to create chroot jail"); }else{ zRoot = ""; } } /* Activate the server, if requested */ if( zPort && http_server(zPort, 0) ){ Malfunction(550, /* LOG: server startup failed */ "failed to start server"); } /* Drop root privileges. */ if( zPermUser ){ if( pwd ){ if( setgid(pwd->pw_gid) ){ Malfunction(560, /* LOG: setgid() failed */ "cannot set group-id to %d", pwd->pw_gid); } if( setuid(pwd->pw_uid) ){ Malfunction(570, /* LOG: setuid() failed */ "cannot set user-id to %d", pwd->pw_uid); } }else{ Malfunction(580, /* LOG: unknown user */ "no such user [%s]", zPermUser); } } if( getuid()==0 ){ Malfunction(590, /* LOG: cannot run as root */ "cannot run as root"); } /* Get the IP address from whence the request originates */ if( zRemoteAddr==0 ){ address remoteAddr; |
︙ | ︙ | |||
2101 2102 2103 2104 2105 2106 2107 | /* Process the input stream */ for(i=0; i<100; i++){ ProcessOneRequest(0); } ProcessOneRequest(1); exit(0); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 | /* Process the input stream */ for(i=0; i<100; i++){ ProcessOneRequest(0); } ProcessOneRequest(1); exit(0); } #if 0 /* Copy/paste the following text into SQLite to generate the xref ** table that describes all error codes. */ BEGIN; CREATE TABLE IF NOT EXISTS xref(lineno INTEGER PRIMARY KEY, desc TEXT); DELETE FROM Xref; INSERT INTO xref VALUES(100,'Malloc() failed'); INSERT INTO xref VALUES(110,'Not authorized'); INSERT INTO xref VALUES(120,'CGI Error'); INSERT INTO xref VALUES(130,'Timeout'); INSERT INTO xref VALUES(140,'CGI script is writable'); INSERT INTO xref VALUES(150,'Cannot open -auth file'); INSERT INTO xref VALUES(160,'http request on https-only page'); INSERT INTO xref VALUES(170,'-auth redirect'); INSERT INTO xref VALUES(180,'malformed entry in -auth file'); INSERT INTO xref VALUES(190,'chdir() failed'); INSERT INTO xref VALUES(200,'bad protocol in HTTP header'); INSERT INTO xref VALUES(210,'Empty request URI'); INSERT INTO xref VALUES(220,'Unknown request method'); INSERT INTO xref VALUES(230,'Referrer is devids.net'); INSERT INTO xref VALUES(240,'Illegal content in HOST: parameter'); INSERT INTO xref VALUES(250,'Disallowed user agent'); INSERT INTO xref VALUES(260,'Disallowed referrer'); INSERT INTO xref VALUES(270,'Request too large'); INSERT INTO xref VALUES(280,'mkstemp() failed'); INSERT INTO xref VALUES(290,'cannot create temp file for POST content'); INSERT INTO xref VALUES(300,'Path element begins with . or -'); INSERT INTO xref VALUES(310,'URI does not start with /'); INSERT INTO xref VALUES(320,'URI too long'); INSERT INTO xref VALUES(330,'Missing HOST: parameter'); INSERT INTO xref VALUES(340,'HOST parameter too long'); INSERT INTO xref VALUES(350,'*.website permissions'); INSERT INTO xref VALUES(360,'chdir() failed'); INSERT INTO xref VALUES(370,'redirect to not-found page'); INSERT INTO xref VALUES(380,'URI not found'); INSERT INTO xref VALUES(390,'File not readable'); INSERT INTO xref VALUES(400,'URI is a directory w/o index.html'); INSERT INTO xref VALUES(410,'redirect to add trailing /'); INSERT INTO xref VALUES(420,'chdir() failed'); INSERT INTO xref VALUES(430,'dup(0) failed'); INSERT INTO xref VALUES(440,'pipe() failed'); INSERT INTO xref VALUES(450,'dup(1) failed'); INSERT INTO xref VALUES(460,'Excess URI content past static file name'); INSERT INTO xref VALUES(470,'ETag Cache Hit'); INSERT INTO xref VALUES(480,'fopen() failed for static content'); INSERT INTO xref VALUES(2,'Normal HEAD reply'); INSERT INTO xref VALUES(0,'Normal reply'); INSERT INTO xref VALUES(500,'unknown IP protocol'); INSERT INTO xref VALUES(510,'unknown command-line argument on launch'); INSERT INTO xref VALUES(520,'--root argument missing'); INSERT INTO xref VALUES(530,'chdir() failed'); INSERT INTO xref VALUES(540,'chroot() failed'); INSERT INTO xref VALUES(550,'server startup failed'); INSERT INTO xref VALUES(560,'setgid() failed'); INSERT INTO xref VALUES(570,'setuid() failed'); INSERT INTO xref VALUES(580,'unknown user'); INSERT INTO xref VALUES(590,'cannot run as root'); COMMIT; #endif /* SQL */ |