Jeff Trawick <[EMAIL PROTECTED]> writes:

> I'm following what happens when we get EOF on socket...
> 
> socket_read() returns APR_SUCCESS and immortal bucket with ""
> 
> core-input doesn't error out since it got APR_SUCCESS
> 
> core-input walks over the "" and deletes the immortal bucket
> 
> core-input sees empty brigade and returns APR_EOF
> 
> it gets returned up through net_time_filter to check_pipeline_flush
> 
> check_pipeline_flush knows ap_get_brigade() failed but it lost the
> retcode and has no way to return the error anyway
> 
> return to caller (ap_process_request)
> 
> do ap_run_log_transaction
> 
> back to ap_process_http_connection
> 
> ap_process_http_connection calls ap_read_request again and we segfault
> since core-input's brigade was empty
> 
> --/--
> 
> if check_pipeline_flush cleared c->keepalive we wouldn't have tried to
> read another request

The patch below gets rid of a segfault while processing every HTTP/1.1 
request (w/ ElectricFence and APR_POOL_DEBUG) but there is a much less
infrequent segfault remaining :(

Index: modules/http/http_request.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_request.c,v
retrieving revision 1.122
diff -u -r1.122 http_request.c
--- modules/http/http_request.c 14 Dec 2001 03:29:13 -0000      1.122
+++ modules/http/http_request.c 11 Jan 2002 18:26:04 -0000
@@ -240,6 +240,7 @@
        ### need to send a FLUSH. */
     apr_bucket_brigade *bb = apr_brigade_create(r->pool);
     apr_off_t zero = 0;
+    apr_status_t rv = APR_SUCCESS;
 
     /* Flush the filter contents if:
      *
@@ -249,7 +250,7 @@
     /* ### shouldn't this read from the connection input filters? */
     /* ### is zero correct? that means "read one line" */
     if (!r->connection->keepalive || 
-        ap_get_brigade(r->input_filters, bb, AP_MODE_PEEK, &zero) != APR_SUCCESS) {
+        (rv = ap_get_brigade(r->input_filters, bb, AP_MODE_PEEK, &zero)) != 
+APR_SUCCESS) {
         apr_bucket *e = apr_bucket_flush_create();
 
         /* We just send directly to the connection based filters.  At
@@ -260,6 +261,12 @@
          */
         APR_BRIGADE_INSERT_HEAD(bb, e);
         ap_pass_brigade(r->connection->output_filters, bb);
+        if (rv != APR_SUCCESS) {
+            /* We got an error earlier reading from the socket.  Make sure
+             * keepalive is off so that we don't try to read another request.
+             */
+            r->connection->keepalive = 0;
+        }
     }
 }
 


-- 
Jeff Trawick | [EMAIL PROTECTED] | PGP public key at web site:
       http://www.geocities.com/SiliconValley/Park/9289/
             Born in Roswell... married an alien...

Reply via email to