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

Reply via email to