sas Sun Nov 10 10:21:13 2002 EDT Modified files: /php4/sapi/thttpd thttpd_patch Log: Defend against pipelined requests on persistent connections as used by IRCG. These could cause thttpd to start a second request in the same connection context, and thereby causing real damage. Mozilla 1.0.1 is buggy in that context: When HTTP/1.1 pipelining is enabled (defaults to off), it will send any number of requests over a persistent connection (which is fine), even after it has received a "Connection: close" header field in a subsequent response header. This blatantly violates RFC 2616, section 8.1.2. Because it cannot receive any response on the dead connection, the download manager pops up and tries to download a file (which never arrives). Also, we don't try to send a 400 message anymore, if the connection dies.
Index: php4/sapi/thttpd/thttpd_patch diff -u php4/sapi/thttpd/thttpd_patch:1.30 php4/sapi/thttpd/thttpd_patch:1.31 --- php4/sapi/thttpd/thttpd_patch:1.30 Wed Nov 6 12:31:03 2002 +++ php4/sapi/thttpd/thttpd_patch Sun Nov 10 10:21:13 2002 @@ -1,6 +1,6 @@ diff -ur thttpd-2.21b/Makefile.in thttpd-2.21b-cool/Makefile.in --- thttpd-2.21b/Makefile.in Thu Mar 29 20:36:21 2001 -+++ thttpd-2.21b-cool/Makefile.in Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/Makefile.in Fri Nov 8 14:27:14 2002 @@ -46,13 +46,15 @@ # You shouldn't need to edit anything below here. @@ -49,7 +49,7 @@ @name=`sed -n -e '/SERVER_SOFTWARE/!d' -e 's,.*thttpd/,thttpd-,' -e 's, .*,,p' version.h` ; \ diff -ur thttpd-2.21b/config.h thttpd-2.21b-cool/config.h --- thttpd-2.21b/config.h Mon Apr 9 23:57:36 2001 -+++ thttpd-2.21b-cool/config.h Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/config.h Fri Nov 8 14:27:14 2002 @@ -82,6 +82,11 @@ */ #define IDLE_READ_TIMELIMIT 60 @@ -73,7 +73,7 @@ ** index pages for directories that don't have an explicit index file. diff -ur thttpd-2.21b/configure thttpd-2.21b-cool/configure --- thttpd-2.21b/configure Sat Apr 21 02:07:14 2001 -+++ thttpd-2.21b-cool/configure Wed Nov 6 18:28:05 2002 ++++ thttpd-2.21b-cool/configure Fri Nov 8 14:27:14 2002 @@ -1021,7 +1021,7 @@ fi echo "$ac_t""$CPP" 1>&6 @@ -85,7 +85,7 @@ echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 diff -ur thttpd-2.21b/configure.in thttpd-2.21b-cool/configure.in --- thttpd-2.21b/configure.in Sat Apr 21 02:06:23 2001 -+++ thttpd-2.21b-cool/configure.in Wed Nov 6 18:25:00 2002 ++++ thttpd-2.21b-cool/configure.in Fri Nov 8 14:27:14 2002 @@ -64,7 +64,7 @@ AC_MSG_RESULT(no) fi @@ -97,7 +97,7 @@ diff -ur thttpd-2.21b/fdwatch.c thttpd-2.21b-cool/fdwatch.c --- thttpd-2.21b/fdwatch.c Fri Apr 13 07:36:08 2001 -+++ thttpd-2.21b-cool/fdwatch.c Wed Nov 6 18:20:53 2002 ++++ thttpd-2.21b-cool/fdwatch.c Sun Nov 10 16:08:16 2002 @@ -460,7 +460,7 @@ ridx = 0; @@ -120,7 +120,7 @@ } diff -ur thttpd-2.21b/libhttpd.c thttpd-2.21b-cool/libhttpd.c --- thttpd-2.21b/libhttpd.c Tue Apr 24 00:42:40 2001 -+++ thttpd-2.21b-cool/libhttpd.c Wed Nov 6 18:29:07 2002 ++++ thttpd-2.21b-cool/libhttpd.c Fri Nov 8 14:27:14 2002 @@ -56,6 +56,10 @@ #include <unistd.h> #include <stdarg.h> @@ -578,7 +578,7 @@ diff -ur thttpd-2.21b/libhttpd.h thttpd-2.21b-cool/libhttpd.h --- thttpd-2.21b/libhttpd.h Tue Apr 24 00:36:50 2001 -+++ thttpd-2.21b-cool/libhttpd.h Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/libhttpd.h Fri Nov 8 14:27:14 2002 @@ -69,6 +69,8 @@ char* server_hostname; int port; @@ -624,7 +624,7 @@ ** mallocced strings. diff -ur thttpd-2.21b/mime_encodings.txt thttpd-2.21b-cool/mime_encodings.txt --- thttpd-2.21b/mime_encodings.txt Wed May 10 03:22:28 2000 -+++ thttpd-2.21b-cool/mime_encodings.txt Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/mime_encodings.txt Fri Nov 8 14:27:14 2002 @@ -3,6 +3,6 @@ # A list of file extensions followed by the corresponding MIME encoding. # Extensions not found in the table proceed to the mime_types table. @@ -636,7 +636,7 @@ uu x-uuencode diff -ur thttpd-2.21b/mime_types.txt thttpd-2.21b-cool/mime_types.txt --- thttpd-2.21b/mime_types.txt Sat Apr 14 04:53:30 2001 -+++ thttpd-2.21b-cool/mime_types.txt Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/mime_types.txt Fri Nov 8 14:27:14 2002 @@ -1,135 +1,138 @@ -# mime_types.txt -# @@ -887,7 +887,7 @@ +ice x-conference/x-cooltalk diff -ur thttpd-2.21b/mmc.c thttpd-2.21b-cool/mmc.c --- thttpd-2.21b/mmc.c Fri Apr 13 23:02:15 2001 -+++ thttpd-2.21b-cool/mmc.c Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/mmc.c Fri Nov 8 14:27:14 2002 @@ -70,6 +70,7 @@ unsigned int hash; int hash_idx; @@ -959,7 +959,7 @@ else diff -ur thttpd-2.21b/mmc.h thttpd-2.21b-cool/mmc.h --- thttpd-2.21b/mmc.h Fri Apr 13 07:36:54 2001 -+++ thttpd-2.21b-cool/mmc.h Fri Nov 1 13:15:14 2002 ++++ thttpd-2.21b-cool/mmc.h Fri Nov 8 14:27:14 2002 @@ -31,8 +31,9 @@ /* Returns an mmap()ed area for the given file, or (void*) 0 on errors. ** If you have a stat buffer on the file, pass it in, otherwise pass 0. @@ -973,7 +973,7 @@ ** If you have a stat buffer on the file, pass it in, otherwise pass 0. diff -ur thttpd-2.21b/thttpd.c thttpd-2.21b-cool/thttpd.c --- thttpd-2.21b/thttpd.c Tue Apr 24 00:41:57 2001 -+++ thttpd-2.21b-cool/thttpd.c Wed Nov 6 18:20:53 2002 ++++ thttpd-2.21b-cool/thttpd.c Sun Nov 10 16:10:52 2002 @@ -66,6 +66,8 @@ static char* dir; static int do_chroot, no_log, no_symlink, do_vhost, do_global_passwd; @@ -1321,7 +1321,7 @@ return; } httpd_realloc_str( -@@ -1327,14 +1398,43 @@ +@@ -1327,14 +1398,53 @@ ** EWOULDBLOCK; however, this apparently can happen if a packet gets ** garbled. */ @@ -1337,11 +1337,21 @@ + return; + } else if ( sz < 0 ) { + if (errno != EWOULDBLOCK) { -+ httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" ); + clear_connection( c, tvP, 0 ); + } return; + } ++ ++ /* If this is a persistent PHP connection, we must not receive ++ ** any further requests on this connection. Some broken HTTP/1.1 ++ ** implementations (e.g. Mozilla 1.0.1) are known to do ++ ** pipelining on a connection, although a prior response included ++ ** Connection: close ++ */ ++ if (c->hc->file_address == (char *) 1) { ++ return; ++ } ++ + c->last_io = httpd_time_now; + if (sz > 0) hc->read_idx += sz; + @@ -1370,7 +1380,7 @@ /* Do we have a complete request yet? */ switch ( httpd_got_request( hc ) ) { -@@ -1342,14 +1442,14 @@ +@@ -1342,14 +1452,14 @@ return; case GR_BAD_REQUEST: httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" ); @@ -1387,7 +1397,7 @@ return; } -@@ -1358,18 +1458,28 @@ +@@ -1358,18 +1468,28 @@ { httpd_send_err( hc, 503, httpd_err503title, "", httpd_err503form, hc->encodedurl ); @@ -1418,7 +1428,7 @@ /* Fill in bytes_to_send. */ if ( hc->got_range ) { -@@ -1384,37 +1494,25 @@ +@@ -1384,37 +1504,25 @@ { /* No file address means someone else is handling it. */ c->bytes_sent = hc->bytes_sent; @@ -1464,7 +1474,7 @@ static void handle_send( connecttab* c, struct timeval* tvP ) { -@@ -1443,6 +1541,9 @@ +@@ -1443,6 +1551,9 @@ iv[1].iov_base = &(hc->file_address[c->bytes_sent]); iv[1].iov_len = MIN( c->bytes_to_send - c->bytes_sent, c->limit ); sz = writev( hc->conn_fd, iv, 2 ); @@ -1474,7 +1484,7 @@ } if ( sz == 0 || -@@ -1486,12 +1587,12 @@ +@@ -1486,12 +1597,12 @@ */ if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET ) syslog( LOG_ERR, "write - %m sending %.80s", hc->encodedurl ); @@ -1489,7 +1499,7 @@ /* Was this a headers + file writev()? */ if ( hc->responselen > 0 ) { -@@ -1500,7 +1601,7 @@ +@@ -1500,7 +1611,7 @@ { /* Yes; move the unwritten part to the front of the buffer. */ int newlen = hc->responselen - sz; @@ -1498,7 +1508,7 @@ hc->responselen = newlen; sz = 0; } -@@ -1519,7 +1620,7 @@ +@@ -1519,7 +1630,7 @@ if ( c->bytes_sent >= c->bytes_to_send ) { /* This conection is finished! */ @@ -1507,7 +1517,7 @@ return; } -@@ -1560,6 +1661,9 @@ +@@ -1560,6 +1671,9 @@ char buf[1024]; int r; @@ -1517,7 +1527,7 @@ /* In lingering-close mode we just read and ignore bytes. An error ** or EOF ends things, otherwise we go until a timeout. */ -@@ -1569,6 +1673,61 @@ +@@ -1569,6 +1683,61 @@ } @@ -1579,7 +1589,7 @@ static int check_throttles( connecttab* c ) { -@@ -1635,23 +1794,18 @@ +@@ -1635,23 +1804,18 @@ static void @@ -1609,7 +1619,7 @@ if ( c->wakeup_timer != (Timer*) 0 ) { tmr_cancel( c->wakeup_timer ); -@@ -1669,13 +1823,36 @@ +@@ -1669,13 +1833,36 @@ ** circumstances that make a lingering close necessary. If the flag ** isn't set we do the real close now. */ @@ -1648,7 +1658,7 @@ client_data.p = c; c->linger_timer = tmr_create( tvP, linger_clear_connection, client_data, LINGER_TIME * 1000L, 0 ); -@@ -1684,9 +1861,19 @@ +@@ -1684,9 +1871,19 @@ syslog( LOG_CRIT, "tmr_create(linger_clear_connection) failed" ); exit( 1 ); } @@ -1669,7 +1679,7 @@ } -@@ -1702,45 +1889,12 @@ +@@ -1702,45 +1899,12 @@ tmr_cancel( c->linger_timer ); c->linger_timer = 0; } @@ -1716,7 +1726,7 @@ static void wakeup_connection( ClientData client_data, struct timeval* nowP ) -@@ -1826,3 +1980,41 @@ +@@ -1826,3 +1990,41 @@ stats_connections = stats_bytes = 0L; stats_simultaneous = 0; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php