Annotation of embedaddon/php/sapi/thttpd/thttpd_patch, revision 1.1
1.1 ! misho 1: diff -ur thttpd-2.21b/Makefile.in thttpd-2.21b-cool/Makefile.in
! 2: --- thttpd-2.21b/Makefile.in Thu Mar 29 20:36:21 2001
! 3: +++ thttpd-2.21b-cool/Makefile.in Sat Sep 20 14:43:20 2003
! 4: @@ -46,13 +46,15 @@
! 5:
! 6: # You shouldn't need to edit anything below here.
! 7:
! 8: +include php_makefile
! 9: +
! 10: CC = @CC@
! 11: CCOPT = @V_CCOPT@
! 12: DEFS = @DEFS@
! 13: -INCLS = -I.
! 14: +INCLS = -I. $(PHP_CFLAGS)
! 15: CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
! 16: -LDFLAGS = @LDFLAGS@
! 17: -LIBS = @LIBS@
! 18: +LDFLAGS = @LDFLAGS@ $(PHP_LDFLAGS)
! 19: +LIBS = @LIBS@ $(PHP_LIBS)
! 20: NETLIBS = @V_NETLIBS@
! 21: INSTALL = @INSTALL@
! 22:
! 23: @@ -62,7 +64,7 @@
! 24: @rm -f $@
! 25: $(CC) $(CFLAGS) -c $*.c
! 26:
! 27: -SRC = thttpd.c libhttpd.c fdwatch.c mmc.c timers.c match.c tdate_parse.c syslog.c
! 28: +SRC = thttpd.c libhttpd.c fdwatch.c mmc.c timers.c match.c tdate_parse.c syslog.c php_thttpd.c
! 29:
! 30: OBJ = $(SRC:.c=.o) @LIBOBJS@
! 31:
! 32: @@ -77,7 +79,7 @@
! 33: all: this subdirs
! 34: this: $(ALL)
! 35:
! 36: -thttpd: $(OBJ)
! 37: +thttpd: $(OBJ) libphp5.a
! 38: @rm -f $@
! 39: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(NETLIBS)
! 40:
! 41: diff -ur thttpd-2.21b/config.h thttpd-2.21b-cool/config.h
! 42: --- thttpd-2.21b/config.h Mon Apr 9 23:57:36 2001
! 43: +++ thttpd-2.21b-cool/config.h Sat Sep 20 14:43:20 2003
! 44: @@ -82,6 +82,11 @@
! 45: */
! 46: #define IDLE_READ_TIMELIMIT 60
! 47:
! 48: +/* CONFIGURE: How many seconds to allow for reading the subsequent requests
! 49: +** on a keep-alive connection. Should be simiar to LINGER_TIME
! 50: +*/
! 51: +#define IDLE_KEEPALIVE_TIMELIMIT 2
! 52: +
! 53: /* CONFIGURE: How many seconds before an idle connection gets closed.
! 54: */
! 55: #define IDLE_SEND_TIMELIMIT 300
! 56: @@ -316,7 +321,7 @@
! 57: /* CONFIGURE: A list of index filenames to check. The files are searched
! 58: ** for in this order.
! 59: */
! 60: -#define INDEX_NAMES "index.html", "index.htm", "Default.htm", "index.cgi"
! 61: +#define INDEX_NAMES "index.php", "index.html", "index.htm", "Default.htm", "index.cgi"
! 62:
! 63: /* CONFIGURE: If this is defined then thttpd will automatically generate
! 64: ** index pages for directories that don't have an explicit index file.
! 65: diff -ur thttpd-2.21b/configure thttpd-2.21b-cool/configure
! 66: --- thttpd-2.21b/configure Sat Apr 21 02:07:14 2001
! 67: +++ thttpd-2.21b-cool/configure Sat Sep 20 14:43:20 2003
! 68: @@ -1021,7 +1021,7 @@
! 69: fi
! 70: echo "$ac_t""$CPP" 1>&6
! 71:
! 72: -for ac_hdr in fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h
! 73: +for ac_hdr in fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h netinet/tcp.h
! 74: do
! 75: ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
! 76: echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
! 77: diff -ur thttpd-2.21b/configure.in thttpd-2.21b-cool/configure.in
! 78: --- thttpd-2.21b/configure.in Sat Apr 21 02:06:23 2001
! 79: +++ thttpd-2.21b-cool/configure.in Sat Sep 20 14:43:20 2003
! 80: @@ -64,7 +64,7 @@
! 81: AC_MSG_RESULT(no)
! 82: fi
! 83:
! 84: -AC_CHECK_HEADERS(fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h)
! 85: +AC_CHECK_HEADERS(fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h netinet/tcp.h)
! 86: AC_HEADER_TIME
! 87: AC_HEADER_DIRENT
! 88:
! 89: diff -ur thttpd-2.21b/fdwatch.c thttpd-2.21b-cool/fdwatch.c
! 90: --- thttpd-2.21b/fdwatch.c Fri Apr 13 07:36:08 2001
! 91: +++ thttpd-2.21b-cool/fdwatch.c Sat Sep 20 14:43:20 2003
! 92: @@ -419,6 +419,7 @@
! 93: if ( pollfds == (struct pollfd*) 0 || poll_fdidx == (int*) 0 ||
! 94: poll_rfdidx == (int*) 0 )
! 95: return -1;
! 96: + memset(pollfds, 0, sizeof(struct pollfd) * nfiles);
! 97: return 0;
! 98: }
! 99:
! 100: @@ -460,7 +461,7 @@
! 101:
! 102: ridx = 0;
! 103: for ( i = 0; i < npollfds; ++i )
! 104: - if ( pollfds[i].revents & ( POLLIN | POLLOUT ) )
! 105: + if ( pollfds[i].revents & ( POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL ) )
! 106: poll_rfdidx[ridx++] = pollfds[i].fd;
! 107:
! 108: return r;
! 109: @@ -472,8 +473,8 @@
! 110: {
! 111: switch ( fd_rw[fd] )
! 112: {
! 113: - case FDW_READ: return pollfds[poll_fdidx[fd]].revents & POLLIN;
! 114: - case FDW_WRITE: return pollfds[poll_fdidx[fd]].revents & POLLOUT;
! 115: + case FDW_READ: return pollfds[poll_fdidx[fd]].revents & ( POLLIN | POLLERR | POLLHUP | POLLNVAL );
! 116: + case FDW_WRITE: return pollfds[poll_fdidx[fd]].revents & ( POLLOUT | POLLERR | POLLHUP | POLLNVAL );
! 117: default: return 0;
! 118: }
! 119: }
! 120: diff -ur thttpd-2.21b/libhttpd.c thttpd-2.21b-cool/libhttpd.c
! 121: --- thttpd-2.21b/libhttpd.c Tue Apr 24 00:42:40 2001
! 122: +++ thttpd-2.21b-cool/libhttpd.c Sat Sep 20 14:43:29 2003
! 123: @@ -56,6 +56,10 @@
! 124: #include <unistd.h>
! 125: #include <stdarg.h>
! 126:
! 127: +#ifdef HAVE_NETINET_TCP_H
! 128: +#include <netinet/tcp.h>
! 129: +#endif
! 130: +
! 131: #ifdef HAVE_OSRELDATE_H
! 132: #include <osreldate.h>
! 133: #endif /* HAVE_OSRELDATE_H */
! 134: @@ -85,6 +89,12 @@
! 135: #include "match.h"
! 136: #include "tdate_parse.h"
! 137:
! 138: +#include "php_thttpd.h"
! 139: +
! 140: +#ifdef __CYGWIN__
! 141: +# define timezone _timezone
! 142: +#endif
! 143: +
! 144: #ifndef STDIN_FILENO
! 145: #define STDIN_FILENO 0
! 146: #endif
! 147: @@ -111,7 +121,7 @@
! 148: static int initialize_listen_socket( httpd_sockaddr* saP );
! 149: static void unlisten( httpd_server* hs );
! 150: static void add_response( httpd_conn* hc, char* str );
! 151: -static void send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod );
! 152: +static void send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod, const char *, size_t );
! 153: static void send_response( httpd_conn* hc, int status, char* title, char* extraheads, char* form, char* arg );
! 154: static void send_response_tail( httpd_conn* hc );
! 155: static void defang( char* str, char* dfstr, int dfsize );
! 156: @@ -242,6 +252,10 @@
! 157: free( (void*) hs->cwd );
! 158: if ( hs->cgi_pattern != (char*) 0 )
! 159: free( (void*) hs->cgi_pattern );
! 160: + if ( hs->php_pattern != (char*) 0 )
! 161: + free( (void*) hs->php_pattern );
! 162: + if ( hs->phps_pattern != (char*) 0 )
! 163: + free( (void*) hs->phps_pattern );
! 164: if ( hs->charset != (char*) 0 )
! 165: free( (void*) hs->charset );
! 166: if ( hs->url_pattern != (char*) 0 )
! 167: @@ -249,6 +263,7 @@
! 168: if ( hs->local_pattern != (char*) 0 )
! 169: free( (void*) hs->local_pattern );
! 170: free( (void*) hs );
! 171: + thttpd_php_shutdown();
! 172: }
! 173:
! 174:
! 175: @@ -257,7 +272,8 @@
! 176: char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port,
! 177: char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp,
! 178: int no_symlink, int vhost, int global_passwd, char* url_pattern,
! 179: - char* local_pattern, int no_empty_referers )
! 180: + char* local_pattern, int no_empty_referers, char* php_pattern,
! 181: + char* phps_pattern )
! 182: {
! 183: httpd_server* hs;
! 184: static char ghnbuf[256];
! 185: @@ -312,6 +328,8 @@
! 186: }
! 187:
! 188: hs->port = port;
! 189: + hs->php_pattern = strdup(php_pattern);
! 190: + hs->phps_pattern = strdup(phps_pattern);
! 191: if ( cgi_pattern == (char*) 0 )
! 192: hs->cgi_pattern = (char*) 0;
! 193: else
! 194: @@ -329,7 +347,7 @@
! 195: while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 )
! 196: (void) strcpy( cp + 1, cp + 2 );
! 197: }
! 198: - hs->charset = strdup( charset );
! 199: + hs->charset = strdup( charset );
! 200: hs->cwd = strdup( cwd );
! 201: if ( hs->cwd == (char*) 0 )
! 202: {
! 203: @@ -385,6 +403,8 @@
! 204: return (httpd_server*) 0;
! 205: }
! 206:
! 207: + thttpd_php_init();
! 208: +
! 209: /* Done initializing. */
! 210: if ( hs->binding_hostname == (char*) 0 )
! 211: syslog( LOG_INFO, "%.80s starting on port %d", SERVER_SOFTWARE, hs->port );
! 212: @@ -418,6 +438,11 @@
! 213: }
! 214: (void) fcntl( listen_fd, F_SETFD, 1 );
! 215:
! 216: +#if defined(TCP_DEFER_ACCEPT) && defined(SOL_TCP)
! 217: + on = 30; /* give clients 30s to send first data packet */
! 218: + setsockopt(listen_fd, SOL_TCP, TCP_DEFER_ACCEPT, &on, sizeof(on));
! 219: +#endif
! 220: +
! 221: /* Allow reuse of local addresses. */
! 222: on = 1;
! 223: if ( setsockopt(
! 224: @@ -582,6 +607,9 @@
! 225: /* And send it, if necessary. */
! 226: if ( hc->responselen > 0 )
! 227: {
! 228: +/*
! 229: +printf("**RESPONSE [%d]** len = %d\n%*.*s\n", hc->conn_fd, hc->responselen, hc->responselen, hc->responselen, hc->response);
! 230: +*/
! 231: (void) write( hc->conn_fd, hc->response, hc->responselen );
! 232: hc->responselen = 0;
! 233: }
! 234: @@ -619,18 +647,22 @@
! 235: }
! 236: }
! 237:
! 238: +extern time_t httpd_time_now;
! 239: +extern char httpd_now_buf[];
! 240: +
! 241: +#define SMART_STR_USE_REALLOC
! 242: +
! 243: +#include "ext/standard/php_smart_str.h"
! 244:
! 245: static void
! 246: -send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod )
! 247: +send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod, const char *last_modified, size_t last_modified_len)
! 248: {
! 249: - time_t now;
! 250: const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
! 251: - char nowbuf[100];
! 252: char modbuf[100];
! 253: - char fixed_type[500];
! 254: - char buf[1000];
! 255: int partial_content;
! 256: -
! 257: + smart_str s = {0};
! 258: + int type_len;
! 259: +
! 260: hc->status = status;
! 261: hc->bytes_to_send = length;
! 262: if ( hc->mime_flag )
! 263: @@ -649,41 +681,89 @@
! 264: else
! 265: partial_content = 0;
! 266:
! 267: - now = time( (time_t*) 0 );
! 268: if ( mod == (time_t) 0 )
! 269: - mod = now;
! 270: - (void) strftime( nowbuf, sizeof(nowbuf), rfc1123fmt, gmtime( &now ) );
! 271: - (void) strftime( modbuf, sizeof(modbuf), rfc1123fmt, gmtime( &mod ) );
! 272: - (void) my_snprintf(
! 273: - fixed_type, sizeof(fixed_type), type, hc->hs->charset );
! 274: - (void) my_snprintf( buf, sizeof(buf),
! 275: - "%.20s %d %s\r\nServer: %s\r\nContent-Type: %s\r\nDate: %s\r\nLast-Modified: %s\r\nAccept-Ranges: bytes\r\nConnection: close\r\n",
! 276: - hc->protocol, status, title, EXPOSED_SERVER_SOFTWARE, fixed_type,
! 277: - nowbuf, modbuf );
! 278: - add_response( hc, buf );
! 279: + mod = httpd_time_now;
! 280: +
! 281: + if (last_modified == 0) {
! 282: + (void) strftime( modbuf, sizeof(modbuf), rfc1123fmt, gmtime( &mod ) );
! 283: + last_modified = modbuf;
! 284: + last_modified_len = strlen(modbuf);
! 285: + }
! 286: +
! 287: + type_len = strlen(type);
! 288: +
! 289: + if (hc->response) {
! 290: + s.c = hc->response;
! 291: + s.len = 0;
! 292: + s.a = hc->maxresponse;
! 293: + hc->response = 0;
! 294: + hc->maxresponse = 0;
! 295: + }
! 296: +
! 297: + smart_str_appends(&s, "HTTP/1.1 ");
! 298: + smart_str_append_long(&s, status);
! 299: + smart_str_appends(&s, " HTTP\r\nServer: " EXPOSED_SERVER_SOFTWARE "\r\n"
! 300: + "Content-Type: ");
! 301: +
! 302: + if (type[type_len-2] == '%' && type[type_len-1] == 's') {
! 303: + smart_str_appendl(&s, type, type_len - 2);
! 304: + smart_str_appends(&s, hc->hs->charset);
! 305: + } else {
! 306: + smart_str_appendl(&s, type, type_len);
! 307: + }
! 308: +
! 309: +
! 310: + smart_str_appends(&s, "\r\nDate: ");
! 311: + smart_str_appends(&s, httpd_now_buf);
! 312: + smart_str_appends(&s, "\r\nLast-Modified: ");
! 313: + smart_str_appendl(&s, last_modified, last_modified_len);
! 314: + smart_str_appends(&s, "\r\nAccept-Ranges: bytes\r\n");
! 315: +
! 316: if ( encodings[0] != '\0' )
! 317: {
! 318: - (void) my_snprintf( buf, sizeof(buf),
! 319: - "Content-Encoding: %s\r\n", encodings );
! 320: - add_response( hc, buf );
! 321: + smart_str_appends(&s, "Content-Encoding: ");
! 322: + smart_str_appends(&s, encodings);
! 323: + smart_str_appends(&s, "\r\n");
! 324: }
! 325: if ( partial_content )
! 326: {
! 327: - (void) my_snprintf( buf, sizeof(buf),
! 328: - "Content-Range: bytes %ld-%ld/%d\r\nContent-Length: %ld\r\n",
! 329: - (long) hc->init_byte_loc, (long) hc->end_byte_loc, length,
! 330: - (long) ( hc->end_byte_loc - hc->init_byte_loc + 1 ) );
! 331: - add_response( hc, buf );
! 332: +
! 333: + smart_str_appends(&s, "Content-Range: bytes ");
! 334: + smart_str_append_long(&s, hc->init_byte_loc);
! 335: + smart_str_appendc(&s, '-');
! 336: + smart_str_append_long(&s, hc->end_byte_loc);
! 337: + smart_str_appendc(&s, '/');
! 338: + smart_str_append_long(&s, length);
! 339: + smart_str_appends(&s, "\r\nContent-Length: ");
! 340: + smart_str_append_long(&s, hc->end_byte_loc - hc->init_byte_loc + 1);
! 341: + smart_str_appends(&s, "\r\n");
! 342: +
! 343: }
! 344: else if ( length >= 0 )
! 345: {
! 346: - (void) my_snprintf( buf, sizeof(buf),
! 347: - "Content-Length: %d\r\n", length );
! 348: - add_response( hc, buf );
! 349: + smart_str_appends(&s, "Content-Length: ");
! 350: + smart_str_append_long(&s, length);
! 351: + smart_str_appends(&s, "\r\n");
! 352: }
! 353: + else {
! 354: + hc->do_keep_alive = 0;
! 355: + }
! 356: if ( extraheads[0] != '\0' )
! 357: - add_response( hc, extraheads );
! 358: - add_response( hc, "\r\n" );
! 359: + smart_str_appends(&s, extraheads);
! 360: + if (hc->do_keep_alive) {
! 361: + smart_str_appends(&s, "Connection: keep-alive\r\n\r\n" );
! 362: + } else {
! 363: + smart_str_appends(&s, "Connection: close\r\n\r\n" );
! 364: + }
! 365: + smart_str_0(&s);
! 366: +
! 367: + if (hc->response) {
! 368: + free(hc->response);
! 369: + }
! 370: + hc->response = s.c;
! 371: + hc->maxresponse = s.a;
! 372: + hc->responselen = s.len;
! 373: +
! 374: }
! 375: }
! 376:
! 377: @@ -725,7 +805,7 @@
! 378: {
! 379: char defanged_arg[1000], buf[2000];
! 380:
! 381: - send_mime( hc, status, title, "", extraheads, "text/html", -1, 0 );
! 382: + send_mime( hc, status, title, "", extraheads, "text/html", -1, 0, 0, 0 );
! 383: (void) my_snprintf( buf, sizeof(buf),
! 384: "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n<BODY BGCOLOR=\"#cc9999\"><H2>%d %s</H2>\n",
! 385: status, title, status, title );
! 386: @@ -764,7 +844,7 @@
! 387: char* cp2;
! 388:
! 389: for ( cp1 = str, cp2 = dfstr;
! 390: - *cp1 != '\0' && cp2 - dfstr < dfsize - 1;
! 391: + *cp1 != '\0' && cp2 - dfstr < dfsize - 5;
! 392: ++cp1, ++cp2 )
! 393: {
! 394: switch ( *cp1 )
! 395: @@ -834,7 +914,7 @@
! 396: fp = fopen( filename, "r" );
! 397: if ( fp == (FILE*) 0 )
! 398: return 0;
! 399: - send_mime( hc, status, title, "", extraheads, "text/html", -1, 0 );
! 400: + send_mime( hc, status, title, "", extraheads, "text/html", -1, 0, 0, 0 );
! 401: for (;;)
! 402: {
! 403: r = fread( buf, 1, sizeof(buf) - 1, fp );
! 404: @@ -1336,6 +1416,9 @@
! 405: if ( hc->tildemapped )
! 406: return 1;
! 407:
! 408: + if ( hc->hostname[0] == '.' || strchr( hc->hostname, '/' ) != (char*) 0 )
! 409: + return 0;
! 410: +
! 411: /* Figure out the host directory. */
! 412: #ifdef VHOST_DIRLEVELS
! 413: httpd_realloc_str(
! 414: @@ -1436,7 +1519,7 @@
! 415: restlen = strlen( path );
! 416: httpd_realloc_str( &rest, &maxrest, restlen );
! 417: (void) strcpy( rest, path );
! 418: - if ( rest[restlen - 1] == '/' )
! 419: + if ( restlen > 0 && rest[restlen - 1] == '/' )
! 420: rest[--restlen] = '\0'; /* trim trailing slash */
! 421: if ( ! tildemapped )
! 422: /* Remove any leading slashes. */
! 423: @@ -1603,6 +1686,70 @@
! 424:
! 425:
! 426: int
! 427: +httpd_request_reset(httpd_conn* hc, int preserve_read_buf )
! 428: +{
! 429: + if (!preserve_read_buf) {
! 430: + hc->read_idx = 0;
! 431: + hc->checked_idx = 0;
! 432: + }
! 433: +
! 434: + if (hc->read_buf_is_mmap) {
! 435: + hc->read_buf_is_mmap = 0;
! 436: + munmap(hc->read_buf, hc->read_size);
! 437: + hc->read_buf = NULL;
! 438: + hc->read_size = 0;
! 439: + httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );
! 440: + }
! 441: + hc->checked_state = CHST_FIRSTWORD;
! 442: + hc->method = METHOD_UNKNOWN;
! 443: + hc->status = 0;
! 444: + hc->bytes_to_send = 0;
! 445: + hc->bytes_sent = 0;
! 446: + hc->encodedurl = "";
! 447: + hc->decodedurl[0] = '\0';
! 448: + hc->protocol = "UNKNOWN";
! 449: + hc->origfilename[0] = '\0';
! 450: + hc->expnfilename[0] = '\0';
! 451: + hc->encodings[0] = '\0';
! 452: + hc->pathinfo[0] = '\0';
! 453: + hc->query[0] = '\0';
! 454: + hc->referer = "";
! 455: + hc->useragent = "";
! 456: + hc->accept[0] = '\0';
! 457: + hc->accepte[0] = '\0';
! 458: + hc->acceptl = "";
! 459: + hc->cookie = "";
! 460: + hc->contenttype = "";
! 461: + hc->reqhost[0] = '\0';
! 462: + hc->hdrhost = "";
! 463: + hc->hostdir[0] = '\0';
! 464: + hc->authorization = "";
! 465: + hc->remoteuser[0] = '\0';
! 466: + hc->response[0] = '\0';
! 467: +#ifdef TILDE_MAP_2
! 468: + hc->altdir[0] = '\0';
! 469: +#endif /* TILDE_MAP_2 */
! 470: + hc->responselen = 0;
! 471: + hc->if_modified_since = (time_t) -1;
! 472: + hc->range_if = (time_t) -1;
! 473: + hc->contentlength = -1;
! 474: + hc->type = "";
! 475: + hc->hostname = (char*) 0;
! 476: + hc->mime_flag = 1;
! 477: + hc->one_one = 0;
! 478: + hc->got_range = 0;
! 479: + hc->tildemapped = 0;
! 480: + hc->init_byte_loc = 0;
! 481: + hc->end_byte_loc = -1;
! 482: + hc->keep_alive = 0;
! 483: + hc->do_keep_alive = 0;
! 484: + hc->should_linger = 0;
! 485: + hc->file_address = (char*) 0;
! 486: + hc->read_body_into_mem = 0;
! 487: + return GC_OK;
! 488: +}
! 489: +
! 490: +int
! 491: httpd_get_conn( httpd_server* hs, int listen_fd, httpd_conn* hc )
! 492: {
! 493: httpd_sockaddr sa;
! 494: @@ -1612,6 +1759,7 @@
! 495: {
! 496: hc->read_size = 0;
! 497: httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );
! 498: + hc->read_buf_is_mmap = 0;
! 499: hc->maxdecodedurl =
! 500: hc->maxorigfilename = hc->maxexpnfilename = hc->maxencodings =
! 501: hc->maxpathinfo = hc->maxquery = hc->maxaccept =
! 502: @@ -1631,12 +1779,19 @@
! 503: httpd_realloc_str( &hc->reqhost, &hc->maxreqhost, 0 );
! 504: httpd_realloc_str( &hc->hostdir, &hc->maxhostdir, 0 );
! 505: httpd_realloc_str( &hc->remoteuser, &hc->maxremoteuser, 0 );
! 506: - httpd_realloc_str( &hc->response, &hc->maxresponse, 0 );
! 507: + httpd_realloc_str( &hc->response, &hc->maxresponse, 350 );
! 508: #ifdef TILDE_MAP_2
! 509: httpd_realloc_str( &hc->altdir, &hc->maxaltdir, 0 );
! 510: #endif /* TILDE_MAP_2 */
! 511: hc->initialized = 1;
! 512: }
! 513: + if (hc->read_buf_is_mmap) {
! 514: + hc->read_buf_is_mmap = 0;
! 515: + munmap(hc->read_buf, hc->read_size);
! 516: + hc->read_buf = NULL;
! 517: + hc->read_size = 0;
! 518: + httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );
! 519: + }
! 520:
! 521: /* Accept the new connection. */
! 522: sz = sizeof(sa);
! 523: @@ -1657,53 +1812,12 @@
! 524: hc->hs = hs;
! 525: memset( &hc->client_addr, 0, sizeof(hc->client_addr) );
! 526: memcpy( &hc->client_addr, &sa, sockaddr_len( &sa ) );
! 527: - hc->read_idx = 0;
! 528: - hc->checked_idx = 0;
! 529: - hc->checked_state = CHST_FIRSTWORD;
! 530: - hc->method = METHOD_UNKNOWN;
! 531: - hc->status = 0;
! 532: - hc->bytes_to_send = 0;
! 533: - hc->bytes_sent = 0;
! 534: - hc->encodedurl = "";
! 535: - hc->decodedurl[0] = '\0';
! 536: - hc->protocol = "UNKNOWN";
! 537: - hc->origfilename[0] = '\0';
! 538: - hc->expnfilename[0] = '\0';
! 539: - hc->encodings[0] = '\0';
! 540: - hc->pathinfo[0] = '\0';
! 541: - hc->query[0] = '\0';
! 542: - hc->referer = "";
! 543: - hc->useragent = "";
! 544: - hc->accept[0] = '\0';
! 545: - hc->accepte[0] = '\0';
! 546: - hc->acceptl = "";
! 547: - hc->cookie = "";
! 548: - hc->contenttype = "";
! 549: - hc->reqhost[0] = '\0';
! 550: - hc->hdrhost = "";
! 551: - hc->hostdir[0] = '\0';
! 552: - hc->authorization = "";
! 553: - hc->remoteuser[0] = '\0';
! 554: - hc->response[0] = '\0';
! 555: -#ifdef TILDE_MAP_2
! 556: - hc->altdir[0] = '\0';
! 557: -#endif /* TILDE_MAP_2 */
! 558: - hc->responselen = 0;
! 559: - hc->if_modified_since = (time_t) -1;
! 560: - hc->range_if = (time_t) -1;
! 561: - hc->contentlength = -1;
! 562: - hc->type = "";
! 563: - hc->hostname = (char*) 0;
! 564: - hc->mime_flag = 1;
! 565: - hc->one_one = 0;
! 566: - hc->got_range = 0;
! 567: - hc->tildemapped = 0;
! 568: - hc->init_byte_loc = 0;
! 569: - hc->end_byte_loc = -1;
! 570: - hc->keep_alive = 0;
! 571: - hc->should_linger = 0;
! 572: - hc->file_address = (char*) 0;
! 573: - return GC_OK;
! 574: +
! 575: +/*
! 576: +printf("doing httpd_get_con(%d)\n", hc->conn_fd);
! 577: +*/
! 578: +
! 579: + return httpd_request_reset(hc, 0);
! 580: }
! 581:
! 582:
! 583: @@ -1720,6 +1834,9 @@
! 584: {
! 585: char c;
! 586:
! 587: +/*
! 588: +printf("**REQUEST [%d]**\n%*.*s\n", hc->conn_fd, hc->read_idx, hc->read_idx, hc->read_buf);
! 589: +*/
! 590: for ( ; hc->checked_idx < hc->read_idx; ++hc->checked_idx )
! 591: {
! 592: c = hc->read_buf[hc->checked_idx];
! 593: @@ -1912,8 +2029,11 @@
! 594: eol = strpbrk( protocol, " \t\n\r" );
! 595: if ( eol != (char*) 0 )
! 596: *eol = '\0';
! 597: - if ( strcasecmp( protocol, "HTTP/1.0" ) != 0 )
! 598: + if ( strcasecmp( protocol, "HTTP/1.0" ) != 0 ) {
! 599: hc->one_one = 1;
! 600: + hc->keep_alive = 1;
! 601: + hc->do_keep_alive = 1;
! 602: + }
! 603: }
! 604: }
! 605: /* Check for HTTP/1.1 absolute URL. */
! 606: @@ -2129,6 +2249,7 @@
! 607: cp = &buf[11];
! 608: cp += strspn( cp, " \t" );
! 609: if ( strcasecmp( cp, "keep-alive" ) == 0 )
! 610: + hc->do_keep_alive = 1;
! 611: hc->keep_alive = 1;
! 612: }
! 613: #ifdef LOG_UNKNOWN_HEADERS
! 614: @@ -2168,6 +2289,9 @@
! 615: }
! 616: }
! 617:
! 618: +/*
! 619: +printf("one_one = %d keep_alive = %d\n", hc->one_one, hc->keep_alive);
! 620: +*/
! 621: if ( hc->one_one )
! 622: {
! 623: /* Check that HTTP/1.1 requests specify a host, as required. */
! 624: @@ -2177,14 +2301,14 @@
! 625: return -1;
! 626: }
! 627:
! 628: - /* If the client wants to do keep-alives, it might also be doing
! 629: - ** pipelining. There's no way for us to tell. Since we don't
! 630: - ** implement keep-alives yet, if we close such a connection there
! 631: - ** might be unread pipelined requests waiting. So, we have to
! 632: - ** do a lingering close.
! 633: + /*
! 634: + ** Disable keep alive support for bad browsers,
! 635: + ** list taken from Apache 1.3.19
! 636: */
! 637: - if ( hc->keep_alive )
! 638: - hc->should_linger = 1;
! 639: + if ( hc->do_keep_alive &&
! 640: + ( strstr(hc->useragent, "Mozilla/2") != NULL ||
! 641: + strstr(hc->useragent, "MSIE 4.0b2;") != NULL))
! 642: + hc->do_keep_alive = 0;
! 643: }
! 644:
! 645: /* Ok, the request has been parsed. Now we resolve stuff that
! 646: @@ -2349,15 +2473,24 @@
! 647:
! 648:
! 649: void
! 650: -httpd_close_conn( httpd_conn* hc, struct timeval* nowP )
! 651: - {
! 652: - make_log_entry( hc, nowP );
! 653: +httpd_complete_request( httpd_conn* hc, struct timeval* nowP)
! 654: +{
! 655: + if (hc->method != METHOD_UNKNOWN)
! 656: + make_log_entry( hc, nowP );
! 657:
! 658: - if ( hc->file_address != (char*) 0 )
! 659: + if ( hc->file_address == (char*) 1 )
! 660: + {
! 661: + thttpd_closed_conn(hc->conn_fd);
! 662: + } else if ( hc->file_address != (char*) 0 )
! 663: {
! 664: mmc_unmap( hc->file_address, &(hc->sb), nowP );
! 665: hc->file_address = (char*) 0;
! 666: }
! 667: + }
! 668: +
! 669: +void
! 670: +httpd_close_conn( httpd_conn* hc, struct timeval* nowP )
! 671: +{
! 672: if ( hc->conn_fd >= 0 )
! 673: {
! 674: (void) close( hc->conn_fd );
! 675: @@ -2370,7 +2503,12 @@
! 676: {
! 677: if ( hc->initialized )
! 678: {
! 679: - free( (void*) hc->read_buf );
! 680: +
! 681: + if ( hc->read_buf_is_mmap ) {
! 682: + munmap( hc->read_buf, hc->read_size );
! 683: + } else {
! 684: + free( (void*) hc->read_buf );
! 685: + }
! 686: free( (void*) hc->decodedurl );
! 687: free( (void*) hc->origfilename );
! 688: free( (void*) hc->expnfilename );
! 689: @@ -2556,7 +2694,7 @@
! 690: return -1;
! 691: }
! 692:
! 693: - send_mime( hc, 200, ok200title, "", "", "text/html", -1, hc->sb.st_mtime );
! 694: + send_mime( hc, 200, ok200title, "", "", "text/html", -1, hc->sb.st_mtime, 0, 0 );
! 695: if ( hc->method == METHOD_HEAD )
! 696: closedir( dirp );
! 697: else if ( hc->method == METHOD_GET )
! 698: @@ -3026,11 +3164,9 @@
! 699: post_post_garbage_hack( httpd_conn* hc )
! 700: {
! 701: char buf[2];
! 702: - int r;
! 703:
! 704: - r = recv( hc->conn_fd, buf, sizeof(buf), MSG_PEEK );
! 705: - if ( r > 0 )
! 706: - (void) read( hc->conn_fd, buf, r );
! 707: + fcntl(hc->conn_fd, F_SETFL, O_NONBLOCK);
! 708: + (void) read( hc->conn_fd, buf, 2 );
! 709: }
! 710:
! 711:
! 712: @@ -3313,6 +3449,11 @@
! 713: int r;
! 714: ClientData client_data;
! 715:
! 716: + /*
! 717: + ** We are not going to leave the socket open after a CGI... too hard
! 718: + */
! 719: + hc->do_keep_alive = 0;
! 720: +
! 721: if ( hc->method == METHOD_GET || hc->method == METHOD_POST )
! 722: {
! 723: httpd_clear_ndelay( hc->conn_fd );
! 724: @@ -3369,6 +3510,7 @@
! 725: int expnlen, indxlen;
! 726: char* cp;
! 727: char* pi;
! 728: + int nocache = 0;
! 729:
! 730: expnlen = strlen( hc->expnfilename );
! 731:
! 732: @@ -3561,6 +3703,16 @@
! 733: match( hc->hs->cgi_pattern, hc->expnfilename ) )
! 734: return cgi( hc );
! 735:
! 736: + if ( hc->hs->php_pattern != (char*) 0 &&
! 737: + match( hc->hs->php_pattern, hc->expnfilename)) {
! 738: + return thttpd_php_request( hc, 0 );
! 739: + }
! 740: +
! 741: + if ( hc->hs->phps_pattern != (char*) 0 &&
! 742: + match( hc->hs->phps_pattern, hc->expnfilename)) {
! 743: + return thttpd_php_request( hc, 1 );
! 744: + }
! 745: +
! 746: /* It's not CGI. If it's executable or there's pathinfo, someone's
! 747: ** trying to either serve or run a non-CGI file as CGI. Either case
! 748: ** is prohibited.
! 749: @@ -3594,32 +3746,46 @@
! 750: hc->end_byte_loc = hc->sb.st_size - 1;
! 751:
! 752: figure_mime( hc );
! 753: + if ( strncmp(hc->decodedurl, "/nocache/", sizeof("/nocache/") - 1 ) == 0 )
! 754: + nocache = 1;
! 755:
! 756: if ( hc->method == METHOD_HEAD )
! 757: {
! 758: send_mime(
! 759: hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
! 760: - hc->sb.st_mtime );
! 761: + hc->sb.st_mtime, 0, 0 );
! 762: }
! 763: - else if ( hc->if_modified_since != (time_t) -1 &&
! 764: + else if ( !nocache && hc->if_modified_since != (time_t) -1 &&
! 765: hc->if_modified_since >= hc->sb.st_mtime )
! 766: {
! 767: - hc->method = METHOD_HEAD;
! 768: send_mime(
! 769: - hc, 304, err304title, hc->encodings, "", hc->type, hc->sb.st_size,
! 770: - hc->sb.st_mtime );
! 771: + hc, 304, err304title, hc->encodings, "", hc->type, -1,
! 772: + hc->sb.st_mtime, 0, 0 );
! 773: }
! 774: else
! 775: {
! 776: - hc->file_address = mmc_map( hc->expnfilename, &(hc->sb), nowP );
! 777: + char *extraheads = "";
! 778: + char *lm;
! 779: + size_t lml;
! 780: +
! 781: + if ( nocache )
! 782: + {
! 783: + extraheads = "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
! 784: + "Cache-Control: no-store, no-cache, must-revalidate, "
! 785: + "post-check=0, pre-check=0\r\n"
! 786: + "Pragma: no-cache\r\n";
! 787: + }
! 788: +
! 789: + hc->file_address = mmc_map( hc->expnfilename, &(hc->sb), nowP, nocache, &lm, &lml );
! 790: if ( hc->file_address == (char*) 0 )
! 791: {
! 792: httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
! 793: return -1;
! 794: }
! 795: +
! 796: send_mime(
! 797: - hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
! 798: - hc->sb.st_mtime );
! 799: + hc, 200, ok200title, hc->encodings, extraheads, hc->type, hc->sb.st_size,
! 800: + hc->sb.st_mtime, lm, lml );
! 801: }
! 802:
! 803: return 0;
! 804: @@ -3638,6 +3804,9 @@
! 805: return r;
! 806: }
! 807:
! 808: +#define smart_str_append_const(a,b) smart_str_appendl(a,b,sizeof(b)-1)
! 809: +
! 810: +static smart_str bentries;
! 811:
! 812: static void
! 813: make_log_entry( httpd_conn* hc, struct timeval* nowP )
! 814: @@ -3648,88 +3817,62 @@
! 815:
! 816: if ( hc->hs->no_log )
! 817: return;
! 818: -
! 819: - /* This is straight CERN Combined Log Format - the only tweak
! 820: - ** being that if we're using syslog() we leave out the date, because
! 821: - ** syslogd puts it in. The included syslogtocern script turns the
! 822: - ** results into true CERN format.
! 823: - */
! 824: -
! 825: /* Format remote user. */
! 826: if ( hc->remoteuser[0] != '\0' )
! 827: - ru = hc->remoteuser;
! 828: + ru = hc->remoteuser;
! 829: else
! 830: - ru = "-";
! 831: + ru = "-";
! 832: /* If we're vhosting, prepend the hostname to the url. This is
! 833: ** a little weird, perhaps writing separate log files for
! 834: ** each vhost would make more sense.
! 835: */
! 836: - if ( hc->hs->vhost && ! hc->tildemapped )
! 837: - (void) my_snprintf( url, sizeof(url),
! 838: - "/%.100s%.200s",
! 839: - hc->hostname == (char*) 0 ? hc->hs->server_hostname : hc->hostname,
! 840: - hc->encodedurl );
! 841: - else
! 842: - (void) my_snprintf( url, sizeof(url),
! 843: - "%.200s", hc->encodedurl );
! 844: - /* Format the bytes. */
! 845: - if ( (long) hc->bytes_sent >= 0 )
! 846: - (void) my_snprintf( bytes, sizeof(bytes),
! 847: - "%ld", (long) hc->bytes_sent );
! 848: - else
! 849: - (void) strcpy( bytes, "-" );
! 850:
! 851: /* Logfile or syslog? */
! 852: if ( hc->hs->logfp != (FILE*) 0 )
! 853: - {
! 854: - time_t now;
! 855: - struct tm* t;
! 856: - const char* cernfmt_nozone = "%d/%b/%Y:%H:%M:%S";
! 857: - char date_nozone[100];
! 858: - int zone;
! 859: - char sign;
! 860: - char date[100];
! 861: -
! 862: - /* Get the current time, if necessary. */
! 863: - if ( nowP != (struct timeval*) 0 )
! 864: - now = nowP->tv_sec;
! 865: - else
! 866: - now = time( (time_t*) 0 );
! 867: - /* Format the time, forcing a numeric timezone (some log analyzers
! 868: - ** are stoooopid about this).
! 869: - */
! 870: - t = localtime( &now );
! 871: - (void) strftime( date_nozone, sizeof(date_nozone), cernfmt_nozone, t );
! 872: -#ifdef HAVE_TM_GMTOFF
! 873: - zone = t->tm_gmtoff / 60L;
! 874: -#else
! 875: - zone = -timezone / 60L;
! 876: - /* Probably have to add something about daylight time here. */
! 877: -#endif
! 878: - if ( zone >= 0 )
! 879: - sign = '+';
! 880: - else
! 881: - {
! 882: - sign = '-';
! 883: - zone = -zone;
! 884: - }
! 885: - zone = ( zone / 60 ) * 100 + zone % 60;
! 886: - (void) my_snprintf( date, sizeof(date),
! 887: - "%s %c%04d", date_nozone, sign, zone );
! 888: - /* And write the log entry. */
! 889: - (void) fprintf( hc->hs->logfp,
! 890: - "%.80s - %.80s [%s] \"%.80s %.300s %.80s\" %d %s \"%.200s\" \"%.80s\"\n",
! 891: - httpd_ntoa( &hc->client_addr ), ru, date,
! 892: - httpd_method_str( hc->method ), url, hc->protocol,
! 893: - hc->status, bytes, hc->referer, hc->useragent );
! 894: - (void) fflush( hc->hs->logfp ); /* don't need to flush every time */
! 895: - }
! 896: - else
! 897: - syslog( LOG_INFO,
! 898: - "%.80s - %.80s \"%.80s %.200s %.80s\" %d %s \"%.200s\" \"%.80s\"",
! 899: - httpd_ntoa( &hc->client_addr ), ru,
! 900: - httpd_method_str( hc->method ), url, hc->protocol,
! 901: - hc->status, bytes, hc->referer, hc->useragent );
! 902: + {
! 903: + /* XXXXXXX */
! 904: +
! 905: + smart_str_appends(&bentries, httpd_ntoa(&hc->client_addr));
! 906: + smart_str_append_const(&bentries, " - ");
! 907: + smart_str_appends(&bentries, ru);
! 908: + smart_str_append_const(&bentries, " [");
! 909: + smart_str_appendl(&bentries, hc->hs->log_date, hc->hs->log_date_len);
! 910: + smart_str_append_const(&bentries, "] \"");
! 911: + smart_str_appends(&bentries, httpd_method_str(hc->method));
! 912: + smart_str_appendc(&bentries, ' ');
! 913: +
! 914: + if (hc->hs->vhost && ! hc->tildemapped) {
! 915: + smart_str_appendc(&bentries, '/');
! 916: + if (hc->hostname)
! 917: + smart_str_appends(&bentries, hc->hostname);
! 918: + else
! 919: + smart_str_appends(&bentries, hc->hs->server_hostname);
! 920: + }
! 921: + smart_str_appends(&bentries, hc->encodedurl);
! 922: +
! 923: + smart_str_appendc(&bentries, ' ');
! 924: + smart_str_appends(&bentries, hc->protocol);
! 925: + smart_str_append_const(&bentries, "\" ");
! 926: + smart_str_append_long(&bentries, hc->status);
! 927: + if (hc->bytes_sent >= 0) {
! 928: + smart_str_appendc(&bentries, ' ');
! 929: + smart_str_append_long(&bentries, hc->bytes_sent);
! 930: + smart_str_append_const(&bentries, " \"");
! 931: + } else {
! 932: + smart_str_append_const(&bentries, " - \"");
! 933: + }
! 934: + smart_str_appends(&bentries, hc->referer);
! 935: + smart_str_append_const(&bentries, "\" \"");
! 936: + smart_str_appends(&bentries, hc->useragent);
! 937: + smart_str_append_const(&bentries, "\"\n");
! 938: +
! 939: + if (bentries.len > 16384) {
! 940: + int fd = fileno(hc->hs->logfp);
! 941: + write(fd, bentries.c, bentries.len);
! 942: + bentries.len = 0;
! 943: + }
! 944: + }
! 945: +
! 946: }
! 947:
! 948:
! 949: @@ -3840,7 +3983,24 @@
! 950: {
! 951: #ifdef HAVE_GETNAMEINFO
! 952: static char str[200];
! 953: + static smart_str httpd_ntoa_buf;
! 954: +
! 955: + if (saP->sa_in.sin_family == AF_INET) {
! 956: + unsigned long n = ntohl(saP->sa_in.sin_addr.s_addr);
! 957:
! 958: + httpd_ntoa_buf.len = 0;
! 959: + smart_str_append_long(&httpd_ntoa_buf, (n >> 24));
! 960: + smart_str_appendc(&httpd_ntoa_buf, '.');
! 961: + smart_str_append_long(&httpd_ntoa_buf, (n >> 16) & 255);
! 962: + smart_str_appendc(&httpd_ntoa_buf, '.');
! 963: + smart_str_append_long(&httpd_ntoa_buf, (n >> 8) & 255);
! 964: + smart_str_appendc(&httpd_ntoa_buf, '.');
! 965: + smart_str_append_long(&httpd_ntoa_buf, (n >> 0) & 255);
! 966: + smart_str_0(&httpd_ntoa_buf);
! 967: +
! 968: + return httpd_ntoa_buf.c;
! 969: + }
! 970: +
! 971: if ( getnameinfo( &saP->sa, sockaddr_len( saP ), str, sizeof(str), 0, 0, NI_NUMERICHOST ) != 0 )
! 972: {
! 973: str[0] = '?';
! 974: diff -ur thttpd-2.21b/libhttpd.h thttpd-2.21b-cool/libhttpd.h
! 975: --- thttpd-2.21b/libhttpd.h Tue Apr 24 00:36:50 2001
! 976: +++ thttpd-2.21b-cool/libhttpd.h Sat Sep 20 14:43:20 2003
! 977: @@ -69,6 +69,8 @@
! 978: char* server_hostname;
! 979: int port;
! 980: char* cgi_pattern;
! 981: + char* php_pattern;
! 982: + char* phps_pattern;
! 983: char* charset;
! 984: char* cwd;
! 985: int listen4_fd, listen6_fd;
! 986: @@ -80,6 +82,8 @@
! 987: char* url_pattern;
! 988: char* local_pattern;
! 989: int no_empty_referers;
! 990: + size_t log_date_len;
! 991: + char log_date[100];
! 992: } httpd_server;
! 993:
! 994: /* A connection. */
! 995: @@ -88,6 +92,7 @@
! 996: httpd_server* hs;
! 997: httpd_sockaddr client_addr;
! 998: char* read_buf;
! 999: + char read_buf_is_mmap;
! 1000: int read_size, read_idx, checked_idx;
! 1001: int checked_state;
! 1002: int method;
! 1003: @@ -132,11 +137,12 @@
! 1004: int got_range;
! 1005: int tildemapped; /* this connection got tilde-mapped */
! 1006: off_t init_byte_loc, end_byte_loc;
! 1007: - int keep_alive;
! 1008: + int keep_alive, do_keep_alive;
! 1009: int should_linger;
! 1010: struct stat sb;
! 1011: int conn_fd;
! 1012: char* file_address;
! 1013: + char read_body_into_mem;
! 1014: } httpd_conn;
! 1015:
! 1016: /* Methods. */
! 1017: @@ -168,7 +174,8 @@
! 1018: char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port,
! 1019: char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp,
! 1020: int no_symlink, int vhost, int global_passwd, char* url_pattern,
! 1021: - char* local_pattern, int no_empty_referers );
! 1022: + char* local_pattern, int no_empty_referers, char* php_pattern,
! 1023: + char* phps_pattern );
! 1024:
! 1025: /* Change the log file. */
! 1026: extern void httpd_set_logfp( httpd_server* hs, FILE* logfp );
! 1027: @@ -229,6 +236,8 @@
! 1028: ** If you don't have a current timeval handy just pass in 0.
! 1029: */
! 1030: extern void httpd_close_conn( httpd_conn* hc, struct timeval* nowP );
! 1031: +void httpd_complete_request( httpd_conn* hc, struct timeval* nowP);
! 1032: +int httpd_request_reset(httpd_conn* hc,int );
! 1033:
! 1034: /* Call this to de-initialize a connection struct and *really* free the
! 1035: ** mallocced strings.
! 1036: diff -ur thttpd-2.21b/mime_encodings.txt thttpd-2.21b-cool/mime_encodings.txt
! 1037: --- thttpd-2.21b/mime_encodings.txt Wed May 10 03:22:28 2000
! 1038: +++ thttpd-2.21b-cool/mime_encodings.txt Sat Sep 20 14:43:20 2003
! 1039: @@ -3,6 +3,6 @@
! 1040: # A list of file extensions followed by the corresponding MIME encoding.
! 1041: # Extensions not found in the table proceed to the mime_types table.
! 1042:
! 1043: -Z x-compress
! 1044: -gz x-gzip
! 1045: +Z compress
! 1046: +gz gzip
! 1047: uu x-uuencode
! 1048: diff -ur thttpd-2.21b/mime_types.txt thttpd-2.21b-cool/mime_types.txt
! 1049: --- thttpd-2.21b/mime_types.txt Sat Apr 14 04:53:30 2001
! 1050: +++ thttpd-2.21b-cool/mime_types.txt Sat Sep 20 14:43:20 2003
! 1051: @@ -1,135 +1,138 @@
! 1052: -# mime_types.txt
! 1053: -#
! 1054: -# A list of file extensions followed by the corresponding MIME type.
! 1055: -# Extensions not found in the table are returned as text/plain.
! 1056: -
! 1057: -html text/html; charset=%s
! 1058: -htm text/html; charset=%s
! 1059: -txt text/plain; charset=%s
! 1060: -rtx text/richtext
! 1061: -etx text/x-setext
! 1062: -tsv text/tab-separated-values
! 1063: -css text/css
! 1064: -xml text/xml
! 1065: -dtd text/xml
! 1066: -
! 1067: -gif image/gif
! 1068: -jpg image/jpeg
! 1069: -jpeg image/jpeg
! 1070: -jpe image/jpeg
! 1071: -jfif image/jpeg
! 1072: -tif image/tiff
! 1073: -tiff image/tiff
! 1074: -pbm image/x-portable-bitmap
! 1075: -pgm image/x-portable-graymap
! 1076: -ppm image/x-portable-pixmap
! 1077: -pnm image/x-portable-anymap
! 1078: -xbm image/x-xbitmap
! 1079: -xpm image/x-xpixmap
! 1080: -xwd image/x-xwindowdump
! 1081: -ief image/ief
! 1082: -png image/png
! 1083: -
! 1084: -au audio/basic
! 1085: -snd audio/basic
! 1086: -aif audio/x-aiff
! 1087: -aiff audio/x-aiff
! 1088: -aifc audio/x-aiff
! 1089: -ra audio/x-pn-realaudio
! 1090: -ram audio/x-pn-realaudio
! 1091: -rm audio/x-pn-realaudio
! 1092: -rpm audio/x-pn-realaudio-plugin
! 1093: -wav audio/wav
! 1094: -mid audio/midi
! 1095: -midi audio/midi
! 1096: -kar audio/midi
! 1097: -mpga audio/mpeg
! 1098: -mp2 audio/mpeg
! 1099: -mp3 audio/mpeg
! 1100: -
! 1101: -mpeg video/mpeg
! 1102: -mpg video/mpeg
! 1103: -mpe video/mpeg
! 1104: -qt video/quicktime
! 1105: -mov video/quicktime
! 1106: -avi video/x-msvideo
! 1107: -movie video/x-sgi-movie
! 1108: -mv video/x-sgi-movie
! 1109: -vx video/x-rad-screenplay
! 1110: -
! 1111: -a application/octet-stream
! 1112: +ez application/andrew-inset
! 1113: +hqx application/mac-binhex40
! 1114: +cpt application/mac-compactpro
! 1115: +doc application/msword
! 1116: bin application/octet-stream
! 1117: +dms application/octet-stream
! 1118: +lha application/octet-stream
! 1119: +lzh application/octet-stream
! 1120: exe application/octet-stream
! 1121: -dump application/octet-stream
! 1122: -o application/octet-stream
! 1123: -class application/java
! 1124: -js application/x-javascript
! 1125: +class application/octet-stream
! 1126: +so application/octet-stream
! 1127: +dll application/octet-stream
! 1128: +oda application/oda
! 1129: +pdf application/pdf
! 1130: ai application/postscript
! 1131: eps application/postscript
! 1132: ps application/postscript
! 1133: -dir application/x-director
! 1134: +smi application/smil
! 1135: +smil application/smil
! 1136: +mif application/vnd.mif
! 1137: +xls application/vnd.ms-excel
! 1138: +ppt application/vnd.ms-powerpoint
! 1139: +wbxml application/vnd.wap.wbxml
! 1140: +wmlc application/vnd.wap.wmlc
! 1141: +wmlsc application/vnd.wap.wmlscriptc
! 1142: +bcpio application/x-bcpio
! 1143: +vcd application/x-cdlink
! 1144: +pgn application/x-chess-pgn
! 1145: +cpio application/x-cpio
! 1146: +csh application/x-csh
! 1147: dcr application/x-director
! 1148: +dir application/x-director
! 1149: dxr application/x-director
! 1150: -fgd application/x-director
! 1151: -aam application/x-authorware-map
! 1152: -aas application/x-authorware-seg
! 1153: -aab application/x-authorware-bin
! 1154: -fh4 image/x-freehand
! 1155: -fh7 image/x-freehand
! 1156: -fh5 image/x-freehand
! 1157: -fhc image/x-freehand
! 1158: -fh image/x-freehand
! 1159: -spl application/futuresplash
! 1160: -swf application/x-shockwave-flash
! 1161: dvi application/x-dvi
! 1162: +spl application/x-futuresplash
! 1163: gtar application/x-gtar
! 1164: hdf application/x-hdf
! 1165: -hqx application/mac-binhex40
! 1166: -iv application/x-inventor
! 1167: +js application/x-javascript
! 1168: +skp application/x-koan
! 1169: +skd application/x-koan
! 1170: +skt application/x-koan
! 1171: +skm application/x-koan
! 1172: latex application/x-latex
! 1173: -man application/x-troff-man
! 1174: -me application/x-troff-me
! 1175: -mif application/x-mif
! 1176: -ms application/x-troff-ms
! 1177: -oda application/oda
! 1178: -pdf application/pdf
! 1179: -rtf application/rtf
! 1180: -bcpio application/x-bcpio
! 1181: -cpio application/x-cpio
! 1182: -sv4cpio application/x-sv4cpio
! 1183: -sv4crc application/x-sv4crc
! 1184: -sh application/x-shar
! 1185: +nc application/x-netcdf
! 1186: +cdf application/x-netcdf
! 1187: +sh application/x-sh
! 1188: shar application/x-shar
! 1189: +swf application/x-shockwave-flash
! 1190: sit application/x-stuffit
! 1191: +sv4cpio application/x-sv4cpio
! 1192: +sv4crc application/x-sv4crc
! 1193: tar application/x-tar
! 1194: +tcl application/x-tcl
! 1195: tex application/x-tex
! 1196: -texi application/x-texinfo
! 1197: texinfo application/x-texinfo
! 1198: +texi application/x-texinfo
! 1199: +t application/x-troff
! 1200: tr application/x-troff
! 1201: roff application/x-troff
! 1202: man application/x-troff-man
! 1203: me application/x-troff-me
! 1204: ms application/x-troff-ms
! 1205: -zip application/x-zip-compressed
! 1206: -tsp application/dsptype
! 1207: -wsrc application/x-wais-source
! 1208: ustar application/x-ustar
! 1209: -cdf application/x-netcdf
! 1210: -nc application/x-netcdf
! 1211: -doc application/msword
! 1212: -ppt application/powerpoint
! 1213: -
! 1214: -crt application/x-x509-ca-cert
! 1215: -crl application/x-pkcs7-crl
! 1216: -
! 1217: +src application/x-wais-source
! 1218: +xhtml application/xhtml+xml
! 1219: +xht application/xhtml+xml
! 1220: +zip application/zip
! 1221: +au audio/basic
! 1222: +snd audio/basic
! 1223: +mid audio/midi
! 1224: +midi audio/midi
! 1225: +kar audio/midi
! 1226: +mpga audio/mpeg
! 1227: +mp2 audio/mpeg
! 1228: +mp3 audio/mpeg
! 1229: +aif audio/x-aiff
! 1230: +aiff audio/x-aiff
! 1231: +aifc audio/x-aiff
! 1232: +m3u audio/x-mpegurl
! 1233: +ram audio/x-pn-realaudio
! 1234: +rm audio/x-pn-realaudio
! 1235: +rpm audio/x-pn-realaudio-plugin
! 1236: +ra audio/x-realaudio
! 1237: +wav audio/x-wav
! 1238: +pdb chemical/x-pdb
! 1239: +xyz chemical/x-xyz
! 1240: +bmp image/bmp
! 1241: +gif image/gif
! 1242: +ief image/ief
! 1243: +jpeg image/jpeg
! 1244: +jpg image/jpeg
! 1245: +jpe image/jpeg
! 1246: +png image/png
! 1247: +tiff image/tiff
! 1248: +tif image/tiff
! 1249: +djvu image/vnd.djvu
! 1250: +djv image/vnd.djvu
! 1251: +wbmp image/vnd.wap.wbmp
! 1252: +ras image/x-cmu-raster
! 1253: +pnm image/x-portable-anymap
! 1254: +pbm image/x-portable-bitmap
! 1255: +pgm image/x-portable-graymap
! 1256: +ppm image/x-portable-pixmap
! 1257: +rgb image/x-rgb
! 1258: +xbm image/x-xbitmap
! 1259: +xpm image/x-xpixmap
! 1260: +xwd image/x-xwindowdump
! 1261: +igs model/iges
! 1262: +iges model/iges
! 1263: +msh model/mesh
! 1264: +mesh model/mesh
! 1265: +silo model/mesh
! 1266: wrl model/vrml
! 1267: vrml model/vrml
! 1268: -mime message/rfc822
! 1269: -
! 1270: -pac application/x-ns-proxy-autoconfig
! 1271: -
! 1272: +css text/css
! 1273: +html text/html; charset=%s
! 1274: +htm text/html; charset=%s
! 1275: +asc text/plain; charset=%s
! 1276: +txt text/plain; charset=%s
! 1277: +rtx text/richtext
! 1278: +rtf text/rtf
! 1279: +sgml text/sgml
! 1280: +sgm text/sgml
! 1281: +tsv text/tab-separated-values
! 1282: wml text/vnd.wap.wml
! 1283: -wmlc application/vnd.wap.wmlc
! 1284: wmls text/vnd.wap.wmlscript
! 1285: -wmlsc application/vnd.wap.wmlscriptc
! 1286: -wbmp image/vnd.wap.wbmp
! 1287: +etx text/x-setext
! 1288: +xml text/xml
! 1289: +xsl text/xml
! 1290: +mpeg video/mpeg
! 1291: +mpg video/mpeg
! 1292: +mpe video/mpeg
! 1293: +qt video/quicktime
! 1294: +mov video/quicktime
! 1295: +mxu video/vnd.mpegurl
! 1296: +avi video/x-msvideo
! 1297: +movie video/x-sgi-movie
! 1298: +ice x-conference/x-cooltalk
! 1299: diff -ur thttpd-2.21b/mmc.c thttpd-2.21b-cool/mmc.c
! 1300: --- thttpd-2.21b/mmc.c Fri Apr 13 23:02:15 2001
! 1301: +++ thttpd-2.21b-cool/mmc.c Sat Sep 20 14:43:20 2003
! 1302: @@ -70,6 +70,9 @@
! 1303: unsigned int hash;
! 1304: int hash_idx;
! 1305: struct MapStruct* next;
! 1306: + char nocache;
! 1307: + size_t last_modified_len;
! 1308: + char last_modified[100];
! 1309: } Map;
! 1310:
! 1311:
! 1312: @@ -93,12 +96,13 @@
! 1313:
! 1314:
! 1315: void*
! 1316: -mmc_map( char* filename, struct stat* sbP, struct timeval* nowP )
! 1317: +mmc_map( char* filename, struct stat* sbP, struct timeval* nowP, int nocache, char **last_modified, size_t *last_modified_len )
! 1318: {
! 1319: time_t now;
! 1320: struct stat sb;
! 1321: Map* m;
! 1322: int fd;
! 1323: + const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
! 1324:
! 1325: /* Stat the file, if necessary. */
! 1326: if ( sbP != (struct stat*) 0 )
! 1327: @@ -130,7 +134,7 @@
! 1328: /* Yep. Just return the existing map */
! 1329: ++m->refcount;
! 1330: m->reftime = now;
! 1331: - return m->addr;
! 1332: + goto done;
! 1333: }
! 1334:
! 1335: /* Open the file. */
! 1336: @@ -167,12 +171,13 @@
! 1337: m->ctime = sb.st_ctime;
! 1338: m->refcount = 1;
! 1339: m->reftime = now;
! 1340: + m->nocache = (char) nocache;
! 1341:
! 1342: /* Avoid doing anything for zero-length files; some systems don't like
! 1343: ** to mmap them, other systems dislike mallocing zero bytes.
! 1344: */
! 1345: if ( m->size == 0 )
! 1346: - m->addr = (void*) 1; /* arbitrary non-NULL address */
! 1347: + m->addr = (void*) 5; /* arbitrary non-NULL address */
! 1348: else
! 1349: {
! 1350: #ifdef HAVE_MMAP
! 1351: @@ -223,6 +228,13 @@
! 1352: maps = m;
! 1353: ++map_count;
! 1354:
! 1355: + strftime( m->last_modified, sizeof(m->last_modified), rfc1123fmt, gmtime( &sb.st_mtime ) );
! 1356: + m->last_modified_len = strlen(m->last_modified);
! 1357: +
! 1358: +done:
! 1359: + *last_modified = m->last_modified;
! 1360: + *last_modified_len = m->last_modified_len;
! 1361: +
! 1362: /* And return the address. */
! 1363: return m->addr;
! 1364: }
! 1365: @@ -231,27 +243,32 @@
! 1366: void
! 1367: mmc_unmap( void* addr, struct stat* sbP, struct timeval* nowP )
! 1368: {
! 1369: - Map* m = (Map*) 0;
! 1370: + Map* m = (Map*) 0, **mm = &maps;
! 1371:
! 1372: /* Find the Map entry for this address. First try a hash. */
! 1373: if ( sbP != (struct stat*) 0 )
! 1374: {
! 1375: m = find_hash( sbP->st_ino, sbP->st_dev, sbP->st_size, sbP->st_ctime );
! 1376: - if ( m != (Map*) 0 && m->addr != addr )
! 1377: + if ( m != (Map*) 0 && ( m->addr != addr || m->nocache == 1 ) )
! 1378: m = (Map*) 0;
! 1379: }
! 1380: /* If that didn't work, try a full search. */
! 1381: if ( m == (Map*) 0 )
! 1382: - for ( m = maps; m != (Map*) 0; m = m->next )
! 1383: + for ( m = maps; m != (Map*) 0; m = m->next ) {
! 1384: if ( m->addr == addr )
! 1385: break;
! 1386: + mm = &m->next;
! 1387: + }
! 1388: if ( m == (Map*) 0 )
! 1389: syslog( LOG_ERR, "mmc_unmap failed to find entry!" );
! 1390: else if ( m->refcount <= 0 )
! 1391: syslog( LOG_ERR, "mmc_unmap found zero or negative refcount!" );
! 1392: else
! 1393: {
! 1394: - --m->refcount;
! 1395: + if ( --m->refcount == 0 && m->nocache == 1 ) {
! 1396: + really_unmap( mm );
! 1397: + return;
! 1398: + }
! 1399: if ( nowP != (struct timeval*) 0 )
! 1400: m->reftime = nowP->tv_sec;
! 1401: else
! 1402: diff -ur thttpd-2.21b/mmc.h thttpd-2.21b-cool/mmc.h
! 1403: --- thttpd-2.21b/mmc.h Fri Apr 13 07:36:54 2001
! 1404: +++ thttpd-2.21b-cool/mmc.h Sat Sep 20 14:43:20 2003
! 1405: @@ -31,8 +31,9 @@
! 1406: /* Returns an mmap()ed area for the given file, or (void*) 0 on errors.
! 1407: ** If you have a stat buffer on the file, pass it in, otherwise pass 0.
! 1408: ** Same for the current time.
! 1409: +** Set nocache to 1, if this entry is supposed to be removed quickly.
! 1410: */
! 1411: -extern void* mmc_map( char* filename, struct stat* sbP, struct timeval* nowP );
! 1412: +extern void* mmc_map( char* filename, struct stat* sbP, struct timeval* nowP, int nocache, char **last_modified, size_t *last_modified_len );
! 1413:
! 1414: /* Done with an mmap()ed area that was returned by mmc_map().
! 1415: ** If you have a stat buffer on the file, pass it in, otherwise pass 0.
! 1416: diff -ur thttpd-2.21b/thttpd.c thttpd-2.21b-cool/thttpd.c
! 1417: --- thttpd-2.21b/thttpd.c Tue Apr 24 00:41:57 2001
! 1418: +++ thttpd-2.21b-cool/thttpd.c Sat Sep 20 14:43:20 2003
! 1419: @@ -53,6 +53,10 @@
! 1420: #endif
! 1421: #include <unistd.h>
! 1422:
! 1423: +#include <sys/mman.h>
! 1424: +
! 1425: +#include <limits.h>
! 1426: +
! 1427: #include "fdwatch.h"
! 1428: #include "libhttpd.h"
! 1429: #include "mmc.h"
! 1430: @@ -66,6 +70,8 @@
! 1431: static char* dir;
! 1432: static int do_chroot, no_log, no_symlink, do_vhost, do_global_passwd;
! 1433: static char* cgi_pattern;
! 1434: +static char* php_pattern;
! 1435: +static char* phps_pattern;
! 1436: static char* url_pattern;
! 1437: static int no_empty_referers;
! 1438: static char* local_pattern;
! 1439: @@ -95,10 +101,10 @@
! 1440: httpd_conn* hc;
! 1441: int tnums[MAXTHROTTLENUMS]; /* throttle indexes */
! 1442: int numtnums;
! 1443: + int keep_alive;
! 1444: long limit;
! 1445: time_t started_at;
! 1446: - Timer* idle_read_timer;
! 1447: - Timer* idle_send_timer;
! 1448: + time_t last_io;
! 1449: Timer* wakeup_timer;
! 1450: Timer* linger_timer;
! 1451: long wouldblock_delay;
! 1452: @@ -106,17 +112,22 @@
! 1453: off_t bytes_sent;
! 1454: off_t bytes_to_send;
! 1455: } connecttab;
! 1456: -static connecttab* connects;
! 1457: +static connecttab* connects, **free_connects;
! 1458: +static int next_free_connect;
! 1459: static int numconnects, maxconnects;
! 1460: static int httpd_conn_count;
! 1461:
! 1462: /* The connection states. */
! 1463: -#define CNST_FREE 0
! 1464: -#define CNST_READING 1
! 1465: -#define CNST_SENDING 2
! 1466: -#define CNST_PAUSING 3
! 1467: -#define CNST_LINGERING 4
! 1468: -
! 1469: +enum {
! 1470: + CNST_FREE = 0,
! 1471: + CNST_READING,
! 1472: + CNST_SENDING,
! 1473: + CNST_PAUSING,
! 1474: + CNST_LINGERING,
! 1475: + CNST_SENDING_RESP,
! 1476: + CNST_READING_BODY,
! 1477: + CNST_TOTAL_NR
! 1478: +};
! 1479:
! 1480: static httpd_server* hs = (httpd_server*) 0;
! 1481: int terminate = 0;
! 1482: @@ -140,23 +151,32 @@
! 1483: static int handle_newconnect( struct timeval* tvP, int listen_fd );
! 1484: static void handle_read( connecttab* c, struct timeval* tvP );
! 1485: static void handle_send( connecttab* c, struct timeval* tvP );
! 1486: +static void handle_send_resp( connecttab* c, struct timeval* tvP );
! 1487: +static void handle_read_body( connecttab* c, struct timeval* tvP );
! 1488: static void handle_linger( connecttab* c, struct timeval* tvP );
! 1489: static int check_throttles( connecttab* c );
! 1490: +static void timeout_conns( ClientData client_data, struct timeval* nowP );
! 1491: static void clear_throttles( connecttab* c, struct timeval* tvP );
! 1492: static void update_throttles( ClientData client_data, struct timeval* nowP );
! 1493: -static void clear_connection( connecttab* c, struct timeval* tvP );
! 1494: +static void clear_connection( connecttab* c, struct timeval* tvP, int );
! 1495: static void really_clear_connection( connecttab* c, struct timeval* tvP );
! 1496: -static void idle_read_connection( ClientData client_data, struct timeval* nowP );
! 1497: -static void idle_send_connection( ClientData client_data, struct timeval* nowP );
! 1498: static void wakeup_connection( ClientData client_data, struct timeval* nowP );
! 1499: static void linger_clear_connection( ClientData client_data, struct timeval* nowP );
! 1500: static void occasional( ClientData client_data, struct timeval* nowP );
! 1501: +static void periodic_jobs( ClientData client_data, struct timeval* nowP );
! 1502: #ifdef STATS_TIME
! 1503: static void show_stats( ClientData client_data, struct timeval* nowP );
! 1504: #endif /* STATS_TIME */
! 1505: static void logstats( struct timeval* nowP );
! 1506: static void thttpd_logstats( long secs );
! 1507: +static void boot_request(connecttab *c, struct timeval *tvP);
! 1508: +
! 1509: +typedef void (*handler_func)(connecttab*, struct timeval *);
! 1510: +
! 1511: +handler_func handler_array[CNST_TOTAL_NR] =
! 1512: +{NULL, handle_read, handle_send, NULL, handle_linger, handle_send_resp, handle_read_body};
! 1513:
! 1514: +#define RUN_HANDLER(type, c) if (handler_array[type]) handler_array[type](c, &tv)
! 1515:
! 1516: static void
! 1517: handle_term( int sig )
! 1518: @@ -177,7 +197,7 @@
! 1519: return;
! 1520:
! 1521: /* Re-open the log file. */
! 1522: - if ( logfile != (char*) 0 )
! 1523: + if ( logfile != (char*) 0 && strcmp(logfile, "-") != 0)
! 1524: {
! 1525: logfp = fopen( logfile, "a" );
! 1526: if ( logfp == (FILE*) 0 )
! 1527: @@ -198,6 +218,8 @@
! 1528: }
! 1529:
! 1530:
! 1531: +time_t httpd_time_now;
! 1532: +
! 1533: static void
! 1534: handle_usr2( int sig )
! 1535: {
! 1536: @@ -217,7 +239,6 @@
! 1537: int num_ready;
! 1538: int cnum, ridx;
! 1539: connecttab* c;
! 1540: - httpd_conn* hc;
! 1541: httpd_sockaddr sa4;
! 1542: httpd_sockaddr sa6;
! 1543: int gotv4, gotv6;
! 1544: @@ -270,7 +291,9 @@
! 1545: no_log = 1;
! 1546: logfp = (FILE*) 0;
! 1547: }
! 1548: - else
! 1549: + else if (strcmp(logfile, "-") == 0) {
! 1550: + logfp = stdout;
! 1551: + } else
! 1552: {
! 1553: logfp = fopen( logfile, "a" );
! 1554: if ( logfp == (FILE*) 0 )
! 1555: @@ -420,7 +443,8 @@
! 1556: hostname,
! 1557: gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0,
! 1558: port, cgi_pattern, charset, cwd, no_log, logfp, no_symlink, do_vhost,
! 1559: - do_global_passwd, url_pattern, local_pattern, no_empty_referers );
! 1560: + do_global_passwd, url_pattern, local_pattern, no_empty_referers,
! 1561: + php_pattern, phps_pattern);
! 1562: if ( hs == (httpd_server*) 0 )
! 1563: exit( 1 );
! 1564:
! 1565: @@ -430,6 +454,12 @@
! 1566: syslog( LOG_CRIT, "tmr_create(occasional) failed" );
! 1567: exit( 1 );
! 1568: }
! 1569: +
! 1570: + if (tmr_create(0, timeout_conns, JunkClientData, 30 * 1000, 1) == 0) {
! 1571: + syslog(LOG_CRIT, "tmr_create(timeout_conns) failed");
! 1572: + exit(1);
! 1573: + }
! 1574: +
! 1575: if ( numthrottles > 0 )
! 1576: {
! 1577: /* Set up the throttles timer. */
! 1578: @@ -439,6 +469,12 @@
! 1579: exit( 1 );
! 1580: }
! 1581: }
! 1582: +
! 1583: + if (tmr_create(0, periodic_jobs, JunkClientData, 2000, 1) == 0) {
! 1584: + syslog(LOG_CRIT, "tmr_create failed");
! 1585: + exit(1);
! 1586: + }
! 1587: +
! 1588: #ifdef STATS_TIME
! 1589: /* Set up the stats timer. */
! 1590: if ( tmr_create( (struct timeval*) 0, show_stats, JunkClientData, STATS_TIME * 1000L, 1 ) == (Timer*) 0 )
! 1591: @@ -454,12 +490,14 @@
! 1592: /* If we're root, try to become someone else. */
! 1593: if ( getuid() == 0 )
! 1594: {
! 1595: +#ifndef __CYGWIN__
! 1596: /* Set aux groups to null. */
! 1597: if ( setgroups( 0, (const gid_t*) 0 ) < 0 )
! 1598: {
! 1599: syslog( LOG_CRIT, "setgroups - %m" );
! 1600: exit( 1 );
! 1601: }
! 1602: +#endif
! 1603: /* Set primary group. */
! 1604: if ( setgid( gid ) < 0 )
! 1605: {
! 1606: @@ -495,13 +533,17 @@
! 1607: }
! 1608: maxconnects -= SPARE_FDS;
! 1609: connects = NEW( connecttab, maxconnects );
! 1610: + free_connects = malloc(sizeof(connecttab *) * maxconnects);
! 1611: + next_free_connect = maxconnects;
! 1612: if ( connects == (connecttab*) 0 )
! 1613: {
! 1614: syslog( LOG_CRIT, "out of memory allocating a connecttab" );
! 1615: exit( 1 );
! 1616: }
! 1617: +
! 1618: for ( cnum = 0; cnum < maxconnects; ++cnum )
! 1619: {
! 1620: + free_connects[cnum] = &connects[maxconnects - cnum - 1];
! 1621: connects[cnum].conn_state = CNST_FREE;
! 1622: connects[cnum].hc = (httpd_conn*) 0;
! 1623: }
! 1624: @@ -518,6 +560,9 @@
! 1625:
! 1626: /* Main loop. */
! 1627: (void) gettimeofday( &tv, (struct timezone*) 0 );
! 1628: + httpd_time_now = tv.tv_sec;
! 1629: + periodic_jobs(JunkClientData, &tv);
! 1630: +
! 1631: while ( ( ! terminate ) || numconnects > 0 )
! 1632: {
! 1633: /* Do the fd watch. */
! 1634: @@ -530,6 +575,7 @@
! 1635: exit( 1 );
! 1636: }
! 1637: (void) gettimeofday( &tv, (struct timezone*) 0 );
! 1638: + httpd_time_now = tv.tv_sec;
! 1639: if ( num_ready == 0 )
! 1640: {
! 1641: /* No fd's are ready - run the timers. */
! 1642: @@ -565,16 +611,10 @@
! 1643: c = (connecttab*) fdwatch_get_client_data( ridx );
! 1644: if ( c == (connecttab*) 0 )
! 1645: continue;
! 1646: - hc = c->hc;
! 1647: - if ( c->conn_state == CNST_READING &&
! 1648: - fdwatch_check_fd( hc->conn_fd ) )
! 1649: - handle_read( c, &tv );
! 1650: - else if ( c->conn_state == CNST_SENDING &&
! 1651: - fdwatch_check_fd( hc->conn_fd ) )
! 1652: - handle_send( c, &tv );
! 1653: - else if ( c->conn_state == CNST_LINGERING &&
! 1654: - fdwatch_check_fd( hc->conn_fd ) )
! 1655: - handle_linger( c, &tv );
! 1656: +#if DO_UNNECESSARY_CHECK_FD
! 1657: + fdwatch_check_fd(c->hc->conn_fd);
! 1658: +#endif
! 1659: + RUN_HANDLER(c->conn_state, c);
! 1660: }
! 1661: tmr_run( &tv );
! 1662:
! 1663: @@ -627,6 +667,8 @@
! 1664: #else /* CGI_PATTERN */
! 1665: cgi_pattern = (char*) 0;
! 1666: #endif /* CGI_PATTERN */
! 1667: + php_pattern = "**.php";
! 1668: + phps_pattern = "**.phps";
! 1669: url_pattern = (char*) 0;
! 1670: no_empty_referers = 0;
! 1671: local_pattern = (char*) 0;
! 1672: @@ -833,6 +875,16 @@
! 1673: value_required( name, value );
! 1674: cgi_pattern = e_strdup( value );
! 1675: }
! 1676: + else if ( strcasecmp( name, "phppat" ) == 0 )
! 1677: + {
! 1678: + value_required( name, value );
! 1679: + php_pattern = e_strdup( value );
! 1680: + }
! 1681: + else if ( strcasecmp( name, "phpspat" ) == 0 )
! 1682: + {
! 1683: + value_required( name, value );
! 1684: + phps_pattern = e_strdup( value );
! 1685: + }
! 1686: else if ( strcasecmp( name, "urlpat" ) == 0 )
! 1687: {
! 1688: value_required( name, value );
! 1689: @@ -1196,8 +1248,10 @@
! 1690: logstats( &tv );
! 1691: for ( cnum = 0; cnum < maxconnects; ++cnum )
! 1692: {
! 1693: - if ( connects[cnum].conn_state != CNST_FREE )
! 1694: + if ( connects[cnum].conn_state != CNST_FREE ) {
! 1695: + httpd_complete_request( connects[cnum].hc, &tv );
! 1696: httpd_close_conn( connects[cnum].hc, &tv );
! 1697: + }
! 1698: if ( connects[cnum].hc != (httpd_conn*) 0 )
! 1699: {
! 1700: httpd_destroy_conn( connects[cnum].hc );
! 1701: @@ -1214,6 +1268,7 @@
! 1702: }
! 1703: mmc_destroy();
! 1704: tmr_destroy();
! 1705: + free( (void*) free_connects );
! 1706: free( (void*) connects );
! 1707: if ( throttles != (throttletab*) 0 )
! 1708: free( (void*) throttles );
! 1709: @@ -1234,7 +1289,7 @@
! 1710: for (;;)
! 1711: {
! 1712: /* Is there room in the connection table? */
! 1713: - if ( numconnects >= maxconnects )
! 1714: + if ( numconnects >= maxconnects || next_free_connect == 0 )
! 1715: {
! 1716: /* Out of connection slots. Run the timers, then the
! 1717: ** existing connections, and maybe we'll free up a slot
! 1718: @@ -1245,10 +1300,10 @@
! 1719: return 0;
! 1720: }
! 1721: /* Find a free connection entry. */
! 1722: - for ( cnum = 0; cnum < maxconnects; ++cnum )
! 1723: - if ( connects[cnum].conn_state == CNST_FREE )
! 1724: - break;
! 1725: - c = &connects[cnum];
! 1726: +
! 1727: + c = free_connects[--next_free_connect];
! 1728: + free_connects[next_free_connect] = NULL;
! 1729: +
! 1730: /* Make the httpd_conn if necessary. */
! 1731: if ( c->hc == (httpd_conn*) 0 )
! 1732: {
! 1733: @@ -1267,24 +1322,18 @@
! 1734: {
! 1735: case GC_FAIL:
! 1736: case GC_NO_MORE:
! 1737: + free_connects[next_free_connect++] = c;
! 1738: return 1;
! 1739: }
! 1740: c->conn_state = CNST_READING;
! 1741: ++numconnects;
! 1742: client_data.p = c;
! 1743: - c->idle_read_timer = tmr_create(
! 1744: - tvP, idle_read_connection, client_data, IDLE_READ_TIMELIMIT * 1000L,
! 1745: - 0 );
! 1746: - if ( c->idle_read_timer == (Timer*) 0 )
! 1747: - {
! 1748: - syslog( LOG_CRIT, "tmr_create(idle_read_connection) failed" );
! 1749: - exit( 1 );
! 1750: - }
! 1751: - c->idle_send_timer = (Timer*) 0;
! 1752: c->wakeup_timer = (Timer*) 0;
! 1753: c->linger_timer = (Timer*) 0;
! 1754: c->bytes_sent = 0;
! 1755: c->numtnums = 0;
! 1756: + c->keep_alive = 0;
! 1757: + c->last_io = httpd_time_now;
! 1758:
! 1759: /* Set the connection file descriptor to no-delay mode. */
! 1760: httpd_set_ndelay( c->hc->conn_fd );
! 1761: @@ -1298,11 +1347,100 @@
! 1762: }
! 1763:
! 1764:
! 1765: +#define FIXUP(x) if (hc->x >= oldptr && hc->x < pe) hc->x += d
! 1766: +
! 1767: +static void
! 1768: +realign_hc(httpd_conn *hc, char *oldptr)
! 1769: +{
! 1770: + int d = hc->read_buf - oldptr;
! 1771: + char *pe = oldptr + hc->checked_idx;
! 1772: +
! 1773: + FIXUP(encodedurl);
! 1774: + FIXUP(protocol);
! 1775: + FIXUP(referer);
! 1776: + FIXUP(useragent);
! 1777: + FIXUP(acceptl);
! 1778: + FIXUP(cookie);
! 1779: + FIXUP(contenttype);
! 1780: + FIXUP(hdrhost);
! 1781: + FIXUP(authorization);
! 1782: +}
! 1783: +
! 1784: +#undef FIXUP
! 1785: +
! 1786: +static void
! 1787: +setup_read_body(connecttab *c, struct timeval *tvP)
! 1788: +{
! 1789: + httpd_conn *hc = c->hc;
! 1790: + int already, missing;
! 1791: + char *oldptr = hc->read_buf;
! 1792: +
! 1793: + c->conn_state = CNST_READING_BODY;
! 1794: +
! 1795: + hc->read_body_into_mem = 0;
! 1796: +
! 1797: + already = hc->read_idx - hc->checked_idx;
! 1798: + missing = hc->contentlength - already;
! 1799: +
! 1800: + if (missing > 16384) {
! 1801: + char filename[] = "/tmp/thttpd.upload.XXXXXX";
! 1802: + int tmp = mkstemp(filename);
! 1803: +
! 1804: + if (tmp >= 0) {
! 1805: + void *p;
! 1806: + size_t sz = hc->contentlength + hc->checked_idx + 10;
! 1807: +
! 1808: + unlink(filename);
! 1809: +
! 1810: + ftruncate(tmp, sz);
! 1811: + p = mmap(NULL, sz,
! 1812: + PROT_READ|PROT_WRITE, MAP_PRIVATE, tmp, 0);
! 1813: +
! 1814: + if (p != MAP_FAILED) {
! 1815: + memcpy(p, hc->read_buf, hc->read_idx);
! 1816: + free(hc->read_buf);
! 1817: + hc->read_size = sz;
! 1818: + hc->read_buf = p;
! 1819: + hc->read_buf_is_mmap = 1;
! 1820: + }
! 1821: + close(tmp);
! 1822: + }
! 1823: +
! 1824: + if (!hc->read_buf_is_mmap) {
! 1825: + clear_connection( c, tvP, 0 );
! 1826: + return;
! 1827: + }
! 1828: + } else if (missing > 0) {
! 1829: + httpd_realloc_str(&hc->read_buf, &hc->read_size, hc->checked_idx + hc->contentlength + 10);
! 1830: + }
! 1831: + if (oldptr != hc->read_buf) realign_hc(hc, oldptr);
! 1832: +
! 1833: + fdwatch_del_fd( hc->conn_fd );
! 1834: + fdwatch_add_fd( hc->conn_fd, c, FDW_READ );
! 1835: +}
! 1836: +
! 1837: +static void
! 1838: +setup_sending(connecttab *c, int state, struct timeval *tvP)
! 1839: +{
! 1840: + httpd_conn *hc = c->hc;
! 1841: + ClientData client_data;
! 1842: +
! 1843: + c->conn_state = state;
! 1844: + c->started_at = tvP->tv_sec;
! 1845: + c->wouldblock_delay = 0;
! 1846: + client_data.p = c;
! 1847: +
! 1848: + fdwatch_del_fd( hc->conn_fd );
! 1849: + fdwatch_add_fd( hc->conn_fd, c, FDW_WRITE );
! 1850: +}
! 1851: +
! 1852: +static void handle_request( connecttab *c, struct timeval *tvP);
! 1853: +
! 1854: +
! 1855: static void
! 1856: handle_read( connecttab* c, struct timeval* tvP )
! 1857: {
! 1858: int sz;
! 1859: - ClientData client_data;
! 1860: httpd_conn* hc = c->hc;
! 1861:
! 1862: /* Is there room in our buffer to read more bytes? */
! 1863: @@ -1311,7 +1449,7 @@
! 1864: if ( hc->read_size > 5000 )
! 1865: {
! 1866: httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
! 1867: - clear_connection( c, tvP );
! 1868: + clear_connection( c, tvP, 0 );
! 1869: return;
! 1870: }
! 1871: httpd_realloc_str(
! 1872: @@ -1327,14 +1465,53 @@
! 1873: ** EWOULDBLOCK; however, this apparently can happen if a packet gets
! 1874: ** garbled.
! 1875: */
! 1876: - if ( sz == 0 || ( sz < 0 && ( errno != EWOULDBLOCK ) ) )
! 1877: - {
! 1878: - httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
! 1879: - clear_connection( c, tvP );
! 1880: + if ( sz == 0 ) {
! 1881: + if (! c->keep_alive) {
! 1882: + httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
! 1883: + }
! 1884: + clear_connection( c, tvP, 0 );
! 1885: + return;
! 1886: + } else if ( sz < 0 ) {
! 1887: + if (errno != EWOULDBLOCK) {
! 1888: + clear_connection( c, tvP, 0 );
! 1889: + }
! 1890: return;
! 1891: + }
! 1892: +
! 1893: + /* If this is a persistent PHP connection, we must not receive
! 1894: + ** any further requests on this connection. Some broken HTTP/1.1
! 1895: + ** implementations (e.g. Mozilla 1.0.1) are known to do
! 1896: + ** pipelining on a connection, although a prior response included
! 1897: + ** Connection: close
! 1898: + */
! 1899: + if (c->hc->file_address == (char *) 1) {
! 1900: + return;
! 1901: + }
! 1902: +
! 1903: + c->last_io = httpd_time_now;
! 1904: + if (sz > 0) hc->read_idx += sz;
! 1905: +
! 1906: + /*
! 1907: + ** if we start getting new data on this socket, "promote" it
! 1908: + ** to read timeout
! 1909: + */
! 1910: + if ( hc->keep_alive ) {
! 1911: + ClientData client_data;
! 1912: +
! 1913: +
! 1914: + client_data.p = c;
! 1915: +
! 1916: + hc->keep_alive = 0;
! 1917: + }
! 1918: + handle_request(c, tvP);
! 1919: }
! 1920: - hc->read_idx += sz;
! 1921:
! 1922: +
! 1923: +static void
! 1924: +handle_request( connecttab *c, struct timeval *tvP)
! 1925: +{
! 1926: + httpd_conn* hc = c->hc;
! 1927: +
! 1928: /* Do we have a complete request yet? */
! 1929: switch ( httpd_got_request( hc ) )
! 1930: {
! 1931: @@ -1342,14 +1519,14 @@
! 1932: return;
! 1933: case GR_BAD_REQUEST:
! 1934: httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
! 1935: - clear_connection( c, tvP );
! 1936: + clear_connection( c, tvP, 0 );
! 1937: return;
! 1938: }
! 1939:
! 1940: /* Yes. Try parsing and resolving it. */
! 1941: if ( httpd_parse_request( hc ) < 0 )
! 1942: {
! 1943: - clear_connection( c, tvP );
! 1944: + clear_connection( c, tvP, 0 );
! 1945: return;
! 1946: }
! 1947:
! 1948: @@ -1358,18 +1535,28 @@
! 1949: {
! 1950: httpd_send_err(
! 1951: hc, 503, httpd_err503title, "", httpd_err503form, hc->encodedurl );
! 1952: - clear_connection( c, tvP );
! 1953: + clear_connection( c, tvP, 0 );
! 1954: return;
! 1955: }
! 1956: + boot_request(c, tvP);
! 1957: +}
! 1958:
! 1959: +static void boot_request(connecttab *c, struct timeval *tvP)
! 1960: +{
! 1961: + httpd_conn *hc = c->hc;
! 1962: /* Start the connection going. */
! 1963: if ( httpd_start_request( hc, tvP ) < 0 )
! 1964: {
! 1965: /* Something went wrong. Close down the connection. */
! 1966: - clear_connection( c, tvP );
! 1967: + clear_connection( c, tvP, 0 );
! 1968: return;
! 1969: }
! 1970:
! 1971: + if ( hc->read_body_into_mem ) {
! 1972: + setup_read_body( c, tvP );
! 1973: + return;
! 1974: + }
! 1975: +
! 1976: /* Fill in bytes_to_send. */
! 1977: if ( hc->got_range )
! 1978: {
! 1979: @@ -1384,37 +1571,25 @@
! 1980: {
! 1981: /* No file address means someone else is handling it. */
! 1982: c->bytes_sent = hc->bytes_sent;
! 1983: - clear_connection( c, tvP );
! 1984: + clear_connection( c, tvP, 1 );
! 1985: return;
! 1986: }
! 1987: + if (hc->file_address == (char *) 1) {
! 1988: + c->last_io = (time_t) LONG_MAX;
! 1989: + c->wouldblock_delay = 0;
! 1990: + return;
! 1991: + }
! 1992: if ( c->bytes_sent >= c->bytes_to_send )
! 1993: {
! 1994: /* There's nothing to send. */
! 1995: - clear_connection( c, tvP );
! 1996: + clear_connection( c, tvP, 1 );
! 1997: return;
! 1998: }
! 1999:
! 2000: /* Cool, we have a valid connection and a file to send to it. */
! 2001: - c->conn_state = CNST_SENDING;
! 2002: - c->started_at = tvP->tv_sec;
! 2003: - c->wouldblock_delay = 0;
! 2004: - client_data.p = c;
! 2005: - tmr_cancel( c->idle_read_timer );
! 2006: - c->idle_read_timer = (Timer*) 0;
! 2007: - c->idle_send_timer = tmr_create(
! 2008: - tvP, idle_send_connection, client_data, IDLE_SEND_TIMELIMIT * 1000L,
! 2009: - 0 );
! 2010: - if ( c->idle_send_timer == (Timer*) 0 )
! 2011: - {
! 2012: - syslog( LOG_CRIT, "tmr_create(idle_send_connection) failed" );
! 2013: - exit( 1 );
! 2014: - }
! 2015: -
! 2016: - fdwatch_del_fd( hc->conn_fd );
! 2017: - fdwatch_add_fd( hc->conn_fd, c, FDW_WRITE );
! 2018: + setup_sending(c, CNST_SENDING, tvP);
! 2019: }
! 2020:
! 2021: -
! 2022: static void
! 2023: handle_send( connecttab* c, struct timeval* tvP )
! 2024: {
! 2025: @@ -1443,6 +1618,9 @@
! 2026: iv[1].iov_base = &(hc->file_address[c->bytes_sent]);
! 2027: iv[1].iov_len = MIN( c->bytes_to_send - c->bytes_sent, c->limit );
! 2028: sz = writev( hc->conn_fd, iv, 2 );
! 2029: +/*
! 2030: +printf("**RESPONSE2 [%d]** len = %d\n%*.*s\n", hc->conn_fd, hc->responselen, hc->responselen, hc->responselen, hc->response);
! 2031: +*/
! 2032: }
! 2033:
! 2034: if ( sz == 0 ||
! 2035: @@ -1486,12 +1664,12 @@
! 2036: */
! 2037: if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET )
! 2038: syslog( LOG_ERR, "write - %m sending %.80s", hc->encodedurl );
! 2039: - clear_connection( c, tvP );
! 2040: + clear_connection( c, tvP, 0 );
! 2041: return;
! 2042: }
! 2043:
! 2044: /* Ok, we wrote something. */
! 2045: - tmr_reset( tvP, c->idle_send_timer );
! 2046: + c->last_io = httpd_time_now;
! 2047: /* Was this a headers + file writev()? */
! 2048: if ( hc->responselen > 0 )
! 2049: {
! 2050: @@ -1500,7 +1678,7 @@
! 2051: {
! 2052: /* Yes; move the unwritten part to the front of the buffer. */
! 2053: int newlen = hc->responselen - sz;
! 2054: - (void) memcpy( hc->response, &(hc->response[sz]), newlen );
! 2055: + (void) memmove( hc->response, &(hc->response[sz]), newlen );
! 2056: hc->responselen = newlen;
! 2057: sz = 0;
! 2058: }
! 2059: @@ -1519,7 +1697,7 @@
! 2060: if ( c->bytes_sent >= c->bytes_to_send )
! 2061: {
! 2062: /* This conection is finished! */
! 2063: - clear_connection( c, tvP );
! 2064: + clear_connection( c, tvP, 1 );
! 2065: return;
! 2066: }
! 2067:
! 2068: @@ -1560,6 +1738,9 @@
! 2069: char buf[1024];
! 2070: int r;
! 2071:
! 2072: +/*
! 2073: +printf("*LINGER read\n");
! 2074: +*/
! 2075: /* In lingering-close mode we just read and ignore bytes. An error
! 2076: ** or EOF ends things, otherwise we go until a timeout.
! 2077: */
! 2078: @@ -1569,6 +1750,63 @@
! 2079: }
! 2080:
! 2081:
! 2082: +static void
! 2083: +handle_read_body(connecttab *c, struct timeval *tvP)
! 2084: +{
! 2085: + httpd_conn *hc = c->hc;
! 2086: + int n;
! 2087: +
! 2088: + n = read(hc->conn_fd, hc->read_buf + hc->read_idx,
! 2089: + hc->contentlength - (hc->read_idx - hc->checked_idx));
! 2090: +
! 2091: + if (n <= 0) {
! 2092: + if (errno == EAGAIN)
! 2093: + return;
! 2094: + clear_connection(c, tvP, 0);
! 2095: + return;
! 2096: + }
! 2097: +
! 2098: + c->last_io = httpd_time_now;
! 2099: +
! 2100: + hc->read_idx += n;
! 2101: +
! 2102: + if (hc->contentlength == hc->read_idx - hc->checked_idx) {
! 2103: + boot_request(c, tvP);
! 2104: + return;
! 2105: + }
! 2106: +}
! 2107: +
! 2108: +static void
! 2109: +handle_send_resp(connecttab *c, struct timeval *tvP)
! 2110: +{
! 2111: + httpd_conn* hc = c->hc;
! 2112: + int n = send(hc->conn_fd, hc->response, hc->responselen, 0);
! 2113: + int dokeep = 1;
! 2114: +
! 2115: + if (n < 0) {
! 2116: + if (errno == EAGAIN)
! 2117: + return;
! 2118: +
! 2119: + dokeep = 0;
! 2120: + goto clear;
! 2121: + }
! 2122: +
! 2123: + c->last_io = httpd_time_now;
! 2124: +
! 2125: + if (n == hc->responselen) {
! 2126: +clear:
! 2127: + hc->response = realloc(hc->response, hc->maxresponse + 1);
! 2128: + hc->responselen = 0;
! 2129: +
! 2130: + clear_connection(c, tvP, dokeep);
! 2131: + return;
! 2132: + }
! 2133: +
! 2134: + hc->responselen -= n;
! 2135: +
! 2136: + memmove(hc->response, hc->response + n, hc->responselen);
! 2137: +}
! 2138: +
! 2139: static int
! 2140: check_throttles( connecttab* c )
! 2141: {
! 2142: @@ -1635,23 +1873,18 @@
! 2143:
! 2144:
! 2145: static void
! 2146: -clear_connection( connecttab* c, struct timeval* tvP )
! 2147: +clear_connection( connecttab* c, struct timeval* tvP, int doKeep )
! 2148: {
! 2149: ClientData client_data;
! 2150: + int linger;
! 2151:
! 2152: /* If we haven't actually sent the buffered response yet, do so now. */
! 2153: - httpd_write_response( c->hc );
! 2154: + if (c->hc->responselen && c->conn_state != CNST_SENDING_RESP) {
! 2155: + setup_sending(c, CNST_SENDING_RESP, tvP);
! 2156:
! 2157: - if ( c->idle_read_timer != (Timer*) 0 )
! 2158: - {
! 2159: - tmr_cancel( c->idle_read_timer );
! 2160: - c->idle_read_timer = 0;
! 2161: - }
! 2162: - if ( c->idle_send_timer != (Timer*) 0 )
! 2163: - {
! 2164: - tmr_cancel( c->idle_send_timer );
! 2165: - c->idle_send_timer = 0;
! 2166: + return;
! 2167: }
! 2168: +
! 2169: if ( c->wakeup_timer != (Timer*) 0 )
! 2170: {
! 2171: tmr_cancel( c->wakeup_timer );
! 2172: @@ -1669,13 +1902,36 @@
! 2173: ** circumstances that make a lingering close necessary. If the flag
! 2174: ** isn't set we do the real close now.
! 2175: */
! 2176: - if ( c->hc->should_linger )
! 2177: +
! 2178: + if ( c->hc->do_keep_alive && doKeep)
! 2179: {
! 2180: - c->conn_state = CNST_LINGERING;
! 2181: + httpd_conn *hc = c->hc;
! 2182: + c->conn_state = CNST_READING;
! 2183: +
! 2184: + client_data.p = c;
! 2185: + c->bytes_sent = 0;
! 2186: + c->numtnums = 0;
! 2187: + c->keep_alive = 1;
! 2188: +
! 2189: + httpd_complete_request( c->hc, tvP );
! 2190: +
! 2191: fdwatch_del_fd( c->hc->conn_fd );
! 2192: fdwatch_add_fd( c->hc->conn_fd, c, FDW_READ );
! 2193: +
! 2194: + httpd_request_reset( c->hc, 1 );
! 2195: +
! 2196: + hc->read_idx -= hc->checked_idx;
! 2197: + memmove(hc->read_buf, hc->read_buf + hc->checked_idx, hc->read_idx);
! 2198: + hc->checked_idx = 0;
! 2199: +
! 2200: /* Make sure we are still in no-delay mode. */
! 2201: httpd_set_ndelay( c->hc->conn_fd );
! 2202: + handle_request(c, tvP);
! 2203: + }
! 2204: + else if ( c->hc->should_linger )
! 2205: + {
! 2206: + c->conn_state = CNST_LINGERING;
! 2207: +
! 2208: client_data.p = c;
! 2209: c->linger_timer = tmr_create(
! 2210: tvP, linger_clear_connection, client_data, LINGER_TIME * 1000L, 0 );
! 2211: @@ -1684,9 +1940,19 @@
! 2212: syslog( LOG_CRIT, "tmr_create(linger_clear_connection) failed" );
! 2213: exit( 1 );
! 2214: }
! 2215: +
! 2216: + httpd_complete_request( c->hc, tvP );
! 2217: +
! 2218: + fdwatch_del_fd( c->hc->conn_fd );
! 2219: + fdwatch_add_fd( c->hc->conn_fd, c, FDW_READ );
! 2220: + /* Make sure we are still in no-delay mode. */
! 2221: + httpd_set_ndelay( c->hc->conn_fd );
! 2222: }
! 2223: - else
! 2224: + else
! 2225: + {
! 2226: + httpd_complete_request( c->hc, tvP );
! 2227: really_clear_connection( c, tvP );
! 2228: + }
! 2229: }
! 2230:
! 2231:
! 2232: @@ -1702,45 +1968,12 @@
! 2233: tmr_cancel( c->linger_timer );
! 2234: c->linger_timer = 0;
! 2235: }
! 2236: + free_connects[next_free_connect++] = c;
! 2237: c->conn_state = CNST_FREE;
! 2238: --numconnects;
! 2239: }
! 2240:
! 2241:
! 2242: -static void
! 2243: -idle_read_connection( ClientData client_data, struct timeval* nowP )
! 2244: - {
! 2245: - connecttab* c;
! 2246: -
! 2247: - c = (connecttab*) client_data.p;
! 2248: - c->idle_read_timer = (Timer*) 0;
! 2249: - if ( c->conn_state != CNST_FREE )
! 2250: - {
! 2251: - syslog( LOG_INFO,
! 2252: - "%.80s connection timed out reading",
! 2253: - httpd_ntoa( &c->hc->client_addr ) );
! 2254: - httpd_send_err( c->hc, 408, httpd_err408title, "", httpd_err408form, "" );
! 2255: - clear_connection( c, nowP );
! 2256: - }
! 2257: - }
! 2258: -
! 2259: -
! 2260: -static void
! 2261: -idle_send_connection( ClientData client_data, struct timeval* nowP )
! 2262: - {
! 2263: - connecttab* c;
! 2264: -
! 2265: - c = (connecttab*) client_data.p;
! 2266: - c->idle_send_timer = (Timer*) 0;
! 2267: - if ( c->conn_state != CNST_FREE )
! 2268: - {
! 2269: - syslog( LOG_INFO,
! 2270: - "%.80s connection timed out sending",
! 2271: - httpd_ntoa( &c->hc->client_addr ) );
! 2272: - clear_connection( c, nowP );
! 2273: - }
! 2274: - }
! 2275: -
! 2276:
! 2277: static void
! 2278: wakeup_connection( ClientData client_data, struct timeval* nowP )
! 2279: @@ -1783,6 +2016,43 @@
! 2280: }
! 2281: #endif /* STATS_TIME */
! 2282:
! 2283: +char httpd_now_buf[100];
! 2284: +
! 2285: +
! 2286: +
! 2287: +static void
! 2288: +periodic_jobs( ClientData client_data, struct timeval* nowP )
! 2289: +{
! 2290: + const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
! 2291: + struct tm *t;
! 2292: + char date_nozone[100];
! 2293: + const char* cernfmt_nozone = "%d/%b/%Y:%H:%M:%S";
! 2294: + char data[100];
! 2295: + int zone;
! 2296: + char sign;
! 2297: +
! 2298: + strftime( httpd_now_buf, sizeof(httpd_now_buf), rfc1123fmt, gmtime( &nowP->tv_sec ) );
! 2299: +
! 2300: + t = localtime(&nowP->tv_sec);
! 2301: + strftime( date_nozone, sizeof(date_nozone), cernfmt_nozone, t );
! 2302: +#ifdef HAVE_TM_GMTOFF
! 2303: + zone = t->tm_gmtoff / 60L;
! 2304: +#else
! 2305: + zone = -timezone / 60L;
! 2306: + /* Probably have to add something about daylight time here. */
! 2307: +#endif
! 2308: + if ( zone >= 0 )
! 2309: + sign = '+';
! 2310: + else
! 2311: + {
! 2312: + sign = '-';
! 2313: + zone = -zone;
! 2314: + }
! 2315: + zone = ( zone / 60 ) * 100 + zone % 60;
! 2316: + hs->log_date_len = sprintf( hs->log_date, "%s %c%04d", date_nozone, sign,
! 2317: + zone );
! 2318: +}
! 2319: +
! 2320:
! 2321: /* Generate debugging statistics syslog messages for all packages. */
! 2322: static void
! 2323: @@ -1826,3 +2096,42 @@
! 2324: stats_connections = stats_bytes = 0L;
! 2325: stats_simultaneous = 0;
! 2326: }
! 2327: +
! 2328: +static void
! 2329: +timeout_conns(ClientData client_data, struct timeval *nowP)
! 2330: +{
! 2331: + connecttab *c = connects, *ce = c + maxconnects;
! 2332: + time_t now = nowP->tv_sec;
! 2333: + int r = 0, w = 0;
! 2334: + int checked = 0;
! 2335: +
! 2336: + while (c < ce) {
! 2337: + switch (c->conn_state) {
! 2338: + case CNST_SENDING:
! 2339: + case CNST_SENDING_RESP:
! 2340: + checked++;
! 2341: + if ((now - c->last_io) > IDLE_SEND_TIMELIMIT) {
! 2342: + clear_connection( c, nowP, 0 );
! 2343: + w++;
! 2344: + }
! 2345: + break;
! 2346: + case CNST_READING:
! 2347: + case CNST_READING_BODY:
! 2348: + checked++;
! 2349: + if ((now - c->last_io) > IDLE_READ_TIMELIMIT) {
! 2350: + clear_connection( c, nowP, 0 );
! 2351: + r++;
! 2352: + }
! 2353: + break;
! 2354: + case CNST_FREE: break;
! 2355: + default: checked++; break;
! 2356: + }
! 2357: + c++;
! 2358: + if (checked >= numconnects) break;
! 2359: + }
! 2360: +
! 2361: + if (r > 0 || w > 0) {
! 2362: + syslog(LOG_INFO, "Expired %d/%d connections in read/write state", r, w);
! 2363: + }
! 2364: +}
! 2365: +
! 2366: diff -ur thttpd-2.21b/version.h thttpd-2.21b-cool/version.h
! 2367: --- thttpd-2.21b/version.h Tue Apr 24 04:05:23 2001
! 2368: +++ thttpd-2.21b-cool/version.h Sat Sep 20 14:43:20 2003
! 2369: @@ -3,7 +3,7 @@
! 2370: #ifndef _VERSION_H_
! 2371: #define _VERSION_H_
! 2372:
! 2373: -#define SERVER_SOFTWARE "thttpd/2.21b 23apr2001"
! 2374: +#define SERVER_SOFTWARE "thttpd/2.21b PHP/20030920"
! 2375: #define SERVER_ADDRESS "http://www.acme.com/software/thttpd/"
! 2376:
! 2377: #endif /* _VERSION_H_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>