You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1997/07/29 09:10:07 UTC

[PATCH] 1.2.2: obscure chunking error

Ok I think these are obscure.  While chunking, it is possible to exit
bwrite() or bflush() without having started the next chunk.  It should
only happen when there's a write error ... but in some cases it would
return without setting the error flags.

This patch, already committed to 1.3 as part of my writev combining patch,
is for 1.2.2. 

Um I know that the number of people who grok buff.c well enough to figure
out if this is right are limited.  If someone could apply it to a server
and then try a bunch of CGI/SSI access from a 1.1 client (such as MSIE
4.0pr2, without java so that you don't have to downgrade-1.0
force-response-1.0 it) I'd appreciate it.  I slept on it a few days and it
still seems to be the right fix.  Or point a libwww-5.1 spider at it. 
Those are the only 1.1 clients I know of.

Dean

Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache/src/CHANGES,v
retrieving revision 1.286.2.31
diff -u -r1.286.2.31 CHANGES
--- CHANGES	1997/07/20 18:39:42	1.286.2.31
+++ CHANGES	1997/07/29 07:02:56
@@ -1,5 +1,8 @@
 Changes with Apache 1.2.2
-  
+
+  *) In some obscure cases involving partially failed writes while doing
+     HTTP/1.1 chunking apache would omit the chunk header.  [Dean Gaudet]
+
   *) The proxy didn't treat the "Host:" keyword of the host header as case-
      insensitive.  The proxy would corrupt the first line of a response from
      an HTTP/0.9 server.  [Kenichi Hori <ke...@d2.bs1.fc.nec.co.jp>] PR#813,814
Index: buff.c
===================================================================
RCS file: /export/home/cvs/apache/src/buff.c,v
retrieving revision 1.26
diff -u -r1.26 buff.c
--- buff.c	1997/05/29 05:21:15	1.26
+++ buff.c	1997/07/29 07:02:58
@@ -750,6 +750,9 @@
 	    return i;
     }
 
+    /* in case a chunk hasn't been started yet */
+    if( fb->flags & B_CHUNK ) start_chunk( fb );
+
 /*
  * Whilst there is data in the buffer, keep on adding to it and writing it
  * out
@@ -776,13 +779,17 @@
 	    /* it is just too painful to try to re-cram the buffer while
 	     * chunking
 	     */
-	    i = (write_it_all(fb, fb->outbase, fb->outcnt) == -1) ?
-	            -1 : fb->outcnt;
-	}
-	else {
-	    do i = write(fb->fd, fb->outbase, fb->outcnt);
-	    while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
+	    if (write_it_all(fb, fb->outbase, fb->outcnt) == -1) {
+		/* we cannot continue after a chunked error */
+		doerror (fb, B_WR);
+		return -1;
+	    }
+	    fb->outcnt = 0;
+	    break;
 	}
+	do {
+	    i = write(fb->fd, fb->outbase, fb->outcnt);
+	} while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
 	if (i <= 0) {
 	    if (i == 0) /* return of 0 means non-blocking */
 	        errno = EAGAIN;
@@ -861,7 +868,6 @@
 
     while (fb->outcnt > 0)
     {
-	/* the buffer must be full */
 	do i = write(fb->fd, fb->outbase, fb->outcnt);
 	while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
 	if (i == 0) {