Here is the patch again for flood_socket_keepalive relating to the
protocol, diff done correctly this time. The patches fix actual client
issues we have had with sites, and is explained in what I previously
wrote to the group, quoted below (note that it does not touch issues
related to chunking, which I also mentioned in that post, other than to
replace the assert() with something more user-friendly):

-Norman Tuttle, developer, OpenDemand Systems [EMAIL PROTECTED]

On Wed, 22 Oct 2003, Norman Tuttle wrote:

> The new diff available for Flood fixes protocol errors for keepalive (file
> flood_socket_keepalive.c, function keepalive_recv_resp()) mainly by
> assimilating the functionality of the wantresponse and !wantresponse modes
> within the readback operations, and maintaining whatever worked correctly.
> Also the algorithm for reading a decimal value within the above function
> was simplified (we found cases where what was replaced did not work), as
> was the routine for reading a hexadecimal value (this being in the
> function keepalive_read_chunk_size()), the same reason for its replacement
> applying.

In addition, I applied some fixes which would yield a more correct byte
count, and replaced the assert() with something more user-friendly.
Even after these changes, there are some gaping holes in the logic
connected with chunked transfer protocol. Besides not being applied in the
"wantresponse" case, it would clearly be unable to field a chunk size
which was greater than the MAX_DOC_LENGTH.
--- \flood-1.1\flood_socket_keepalive.c 2003-09-06 00:27:38.000000000 -0400
+++ flood_socket_keepalive.c    2003-10-30 13:57:15.000000000 -0500
@@ -161,25 +161,17 @@
                         write_socket(ksock->s, req);

 }

 

+/* This is really a hex evaluator function. */

 static long keepalive_read_chunk_size(char *begin_chunk)

 {

-    char chunk[17], *end_chunk;

-    long chunk_length;

-

-    /* FIXME: Handle chunk-extension */

-    end_chunk = strstr(begin_chunk, CRLF);

-

-    if (end_chunk && end_chunk - begin_chunk < 16)

+    long OutputHex=0;

+    unsigned char Addend;

+    while (isspace(*begin_chunk)) begin_chunk++;

+    while (isxdigit(Addend=(*(begin_chunk++))))

     {

-        strncpy(chunk, begin_chunk, end_chunk - begin_chunk);

-        chunk[end_chunk-begin_chunk] = '\0';

-        /* Chunks are base-16 */

-        chunk_length = strtol(chunk, &end_chunk, 16);

-        if (*end_chunk == '\0')

-            return chunk_length;

+      OutputHex=(OutputHex<<4)+((Addend & 0xF)+((Addend > '9')?9:0));

     }

-

-    return 0;

+    return OutputHex;

 }

 

 static apr_status_t keepalive_read_chunk(response_t *resp,

@@ -374,6 +366,7 @@
     keepalive_socket_t *ksock = (keepalive_socket_t *)sock;

     char *cl, *ecl, cls[17];

     char *current_line;

+    int keep_reading = 0;

     int i;

     response_t *new_resp;

     apr_status_t status;

@@ -433,11 +426,12 @@
         return APR_SUCCESS;

     }

 

+    new_resp->chunk = NULL;

+    new_resp->chunked = 0;

     header = apr_table_get(new_resp->headers, "Transfer-Encoding");

     if (header && !strcasecmp(header, "Chunked"))

     {

         new_resp->chunked = 1;

-        new_resp->chunk = NULL;

         /* Find where headers ended */

         cl = current_line;

 

@@ -474,7 +468,11 @@
                     chunk_length = keepalive_read_chunk_size(new_resp->chunk);

                     /* Search for the beginning of the chunk. */

                     foo = strstr(new_resp->chunk, CRLF);

-                    assert(foo);

+                    if (!foo)

+                    {

+                      return APR_EGENERAL;

+                      /* Serious error with violation of chunking protocol! */

+                    }

                     new_resp->chunk = foo + 2;

                     remaining = new_resp->rbufsize - 

                                     (int)(new_resp->chunk - 

@@ -497,19 +495,9 @@
         {

             new_resp->keepalive = 0; 

         }

-

-        if (header)

+        else

         {

-            cl = (char*)header;

-            ecl = cl + strlen(cl);

-            if (ecl && ecl - cl < 16)

-            {

-                strncpy(cls, cl, ecl - cl);

-                cls[ecl-cl] = '\0';

-                content_length = strtol(cls, &ecl, 10);

-                if (*ecl != '\0')

-                    new_resp->keepalive = 0; 

-            }

+          if ((content_length = atol(header))<=0) keep_reading = 1;

         }

 

         if (new_resp->keepalive)

@@ -530,7 +518,12 @@
     if (ksock->wantresponse)

     {

         if (new_resp->keepalive)

+        {

+          if ((keep_reading)||(content_length>0))

+          {

             status = keepalive_load_resp(new_resp, ksock, content_length, 
pool);

+          }

+        }

         else

             status = keepalive_load_resp(new_resp, ksock, 0, pool);

     }

@@ -544,9 +537,9 @@
         }

         else if (new_resp->keepalive)

         {

-            while (content_length && status != APR_EGENERAL &&

+            while ((keep_reading || content_length) && status != APR_EGENERAL 
&&

                    status != APR_EOF && status != APR_TIMEUP) {

-                if (content_length > MAX_DOC_LENGTH - 1)

+                if ((keep_reading)||(content_length > MAX_DOC_LENGTH - 1))

                     i = MAX_DOC_LENGTH - 1;

                 else

                     i = content_length;

@@ -554,6 +547,8 @@
                 status = ksock_read_socket(ksock, b, &i);

 

                 content_length -= i;

+                new_resp->rbufsize += i;

+                /* This makes sure the rbufsize maintains the real count*/

             }

         }

         else

@@ -562,6 +557,8 @@
                    status != APR_TIMEUP) {

                 i = MAX_DOC_LENGTH - 1;

                 status = ksock_read_socket(ksock, b, &i);

+                new_resp->rbufsize += i;

+                /* This makes sure the rbufsize maintains the real count*/

             }

         }

     }

Reply via email to