httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Roy T. Fielding" <field...@kiwi.ICS.UCI.EDU>
Subject Re: [PATCH] PR#232: work around netscape header problem
Date Fri, 18 Apr 1997 14:02:04 GMT
After thinking about this a while, I've changed my mind and now believe
that we need to fix Netscape's bug for them.  The reasons are that the
bug is non-intuitive to non-programmers, we'll end up getting blamed
for it anyway, I have a feeling that Netscape won't get around to
fixing it in 4.0, and my fix has no impact unless the headers are
exactly 256 or 257 bytes long (the bug manifests in both cases).

I took Dean's patch and removed the BrowserMatch (it would match almost
all browsers anyway) and made it apply to all places where we terminate
headers.  I also verified that it prevents the bug on Netscape 3.01.

....Roy   [+1 for 1.2]


Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.113
diff -c -r1.113 http_protocol.c
*** http_protocol.c	1997/04/12 04:24:57	1.113
--- http_protocol.c	1997/04/18 13:43:36
***************
*** 1053,1058 ****
--- 1053,1086 ----
      table_unset(r->headers_out, "Server");
  }
  
+ /* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
+  * have a header parsing bug.  If the terminating \r\n occur starting
+  * at the 256th or 257th byte of output then it will not properly parse
+  * the headers.  Curiously it doesn't exhibit this problem at 512, 513.
+  * We are guessing that this is because their initial read of a new request
+  * uses a 256 byte buffer, and subsequent reads use a larger buffer.
+  * So the problem might exist at different offsets as well.
+  *
+  * This should also work on keepalive connections assuming they use the
+  * same small buffer for the first read of each new request.
+  *
+  * At any rate, we check the bytes written so far and, if we are about to
+  * tickle the bug, we instead insert a bogus padding header.  Since the bug
+  * manifests as a broken image in Navigator, users blame the server.  :(
+  * It is more expensive to check the User-Agent than it is to just add the
+  * bytes, so we haven't used the BrowserMatch feature here.
+  */
+ static void terminate_header (BUFF *client)
+ {
+     long int bs;
+ 
+     bgetopt(client, BO_BYTECT, &bs);
+     if (bs == 256 || bs == 257)
+         bputs("X-Pad: avoid browser bug\015\012", client);
+ 
+     bputs("\015\012", client);    /* Send the terminating empty line */
+ }
+ 
  static char *make_allow(request_rec *r)
  {
      int allowed = r->allowed;
***************
*** 1114,1120 ****
  
      table_do((int (*)(void *, const char *, const char *))send_header_field,
               (void *)r, r->headers_out, NULL);
!     bputs("\015\012", r->connection->client);
  
      kill_timeout(r);
      bsetopt(r->connection->client, BO_BYTECT, &zero);
--- 1142,1149 ----
  
      table_do((int (*)(void *, const char *, const char *))send_header_field,
               (void *)r, r->headers_out, NULL);
! 
!     terminate_header(r->connection->client);
  
      kill_timeout(r);
      bsetopt(r->connection->client, BO_BYTECT, &zero);
***************
*** 1207,1213 ****
  
      table_do((int (*)(void *, const char *, const char *))send_header_field,
               (void *)r, r->headers_out, NULL);
!     bputs("\015\012", r->connection->client);
  
      kill_timeout(r);
  
--- 1236,1243 ----
  
      table_do((int (*)(void *, const char *, const char *))send_header_field,
               (void *)r, r->headers_out, NULL);
! 
!     terminate_header(r->connection->client);
  
      kill_timeout(r);
  
***************
*** 1630,1636 ****
  	             "Warning",
  	             "WWW-Authenticate",
  	             NULL);
! 	    bputs("\015\012", fd);
  
  	    kill_timeout(r);
  	    return;
--- 1660,1667 ----
  	             "Warning",
  	             "WWW-Authenticate",
  	             NULL);
! 
! 	    terminate_header(r->connection->client);
  
  	    kill_timeout(r);
  	    return;

Mime
View raw message