httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Justin Erenkrantz <jerenkra...@apache.org>
Subject Re: Reverse proxy dead in current HEAD
Date Sun, 02 Jun 2002 22:44:02 GMT
On Sun, Jun 02, 2002 at 02:50:13PM -0700, Ian Holsman wrote:
> it looks like something broke recently..
> the proxy appears to be waiting for the timeout to occur before 
> delivering the final bucket.
> this is most noticable when you have a page including multiple 
> subrequests, all of which are reverse proxied
> 
> to recreate
> 
> <location /foo>
> 	Proxypass http://yourhost
> </location>
> 
> and have /foo/bar.html include /foo/1.html & /foo/2.html
> 
> This is working in 2.0.36 and is a show stopper for me

This is related to my post earlier today entitled: "Subrequests
reading bodies?"

If the answer is that they can't, this patch fixes it by wrapping
the input calls with if (!r->main)...)  If they can, we need
to rethink some things.  -- justin

Index: modules/proxy/proxy_http.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/proxy/proxy_http.c,v
retrieving revision 1.152
diff -u -r1.152 proxy_http.c
--- modules/proxy/proxy_http.c	31 May 2002 21:21:10 -0000	1.152
+++ modules/proxy/proxy_http.c	2 Jun 2002 22:36:52 -0000
@@ -627,41 +627,43 @@
     }
 
     /* send the request data, if any. */
-    seen_eos = 0;
-    do {
-        status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
-                                APR_BLOCK_READ, HUGE_STRING_LEN);
+    if (!r->main) {
+        seen_eos = 0;
+        do {
+            status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+                                    APR_BLOCK_READ, HUGE_STRING_LEN);
 
-        if (status != APR_SUCCESS) {
-            return status;
-        }
-
-        /* If this brigade contain EOS, either stop or remove it. */
-        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
-            /* As a shortcut, if this brigade is simply an EOS bucket,
-             * don't send anything down the filter chain.
-             */
-            if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
-                break;
+            if (status != APR_SUCCESS) {
+                return status;
             }
 
-            /* We can't pass this EOS to the output_filters. */
-            APR_BUCKET_REMOVE(APR_BRIGADE_LAST(bb));
-            seen_eos = 1;
-        }
+            /* If this brigade contain EOS, either stop or remove it. */
+            if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
+                /* As a shortcut, if this brigade is simply an EOS bucket,
+                 * don't send anything down the filter chain.
+                 */
+                if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
+                    break;
+                }
+
+                /* We can't pass this EOS to the output_filters. */
+                APR_BUCKET_REMOVE(APR_BRIGADE_LAST(bb));
+                seen_eos = 1;
+            }
 
-        e = apr_bucket_flush_create(c->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(bb, e);
+            e = apr_bucket_flush_create(c->bucket_alloc);
+            APR_BRIGADE_INSERT_TAIL(bb, e);
 
-        status = ap_pass_brigade(origin->output_filters, bb);
-        if (status != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
-                         "proxy: pass request data failed to %pI (%s)",
-                         p_conn->addr, p_conn->name);
-            return status;
-        }
-        apr_brigade_cleanup(bb);
-    } while (!seen_eos);
+            status = ap_pass_brigade(origin->output_filters, bb);
+            if (status != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
+                             "proxy: pass request data failed to %pI (%s)",
+                             p_conn->addr, p_conn->name);
+                return status;
+            }
+            apr_brigade_cleanup(bb);
+        } while (!seen_eos);
+    }
 
     return APR_SUCCESS;
 }
Index: modules/generators/mod_cgi.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/generators/mod_cgi.c,v
retrieving revision 1.139
diff -u -r1.139 mod_cgi.c
--- modules/generators/mod_cgi.c	30 May 2002 00:36:58 -0000	1.139
+++ modules/generators/mod_cgi.c	2 Jun 2002 22:36:53 -0000
@@ -692,75 +692,79 @@
 
     /* Transfer any put/post args, CERN style...
      * Note that we already ignore SIGPIPE in the core server.
+     *
+     * Note that only non-subrequests may have an entity body.
      */
     bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
-    seen_eos = 0;
-    child_stopped_reading = 0;
-    if (conf->logname) {
-        dbuf = apr_palloc(r->pool, conf->bufbytes + 1);
-        dbpos = 0;
-    }
-    do {
-        apr_bucket *bucket;
-
-        rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
-                            APR_BLOCK_READ, HUGE_STRING_LEN);
-       
-        if (rv != APR_SUCCESS) {
-            return rv;
+    if (!r->main) {
+        seen_eos = 0;
+        child_stopped_reading = 0;
+        if (conf->logname) {
+            dbuf = apr_palloc(r->pool, conf->bufbytes + 1);
+            dbpos = 0;
         }
+        do {
+            apr_bucket *bucket;
 
-        APR_BRIGADE_FOREACH(bucket, bb) {
-            const char *data;
-            apr_size_t len;
-
-            if (APR_BUCKET_IS_EOS(bucket)) {
-                seen_eos = 1;
-                break;
+            rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+                                APR_BLOCK_READ, HUGE_STRING_LEN);
+       
+            if (rv != APR_SUCCESS) {
+                return rv;
             }
 
-            /* We can't do much with this. */
-            if (APR_BUCKET_IS_FLUSH(bucket)) {
-                continue;
-            }
+            APR_BRIGADE_FOREACH(bucket, bb) {
+                const char *data;
+                apr_size_t len;
+
+                if (APR_BUCKET_IS_EOS(bucket)) {
+                    seen_eos = 1;
+                    break;
+                }
 
-            /* If the child stopped, we still must read to EOS. */
-            if (child_stopped_reading) {
-                continue;
-            } 
+                /* We can't do much with this. */
+                if (APR_BUCKET_IS_FLUSH(bucket)) {
+                    continue;
+                }
 
-            /* read */
-            apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+                /* If the child stopped, we still must read to EOS. */
+                if (child_stopped_reading) {
+                    continue;
+                }
+
+                /* read */
+                apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
             
-            if (conf->logname && dbpos < conf->bufbytes) {
-                int cursize;
+                if (conf->logname && dbpos < conf->bufbytes) {
+                    int cursize;
 
-                if ((dbpos + len) > conf->bufbytes) {
-                    cursize = conf->bufbytes - dbpos;
-                }
-                else {
-                    cursize = len;
+                    if ((dbpos + len) > conf->bufbytes) {
+                        cursize = conf->bufbytes - dbpos;
+                    }
+                    else {
+                        cursize = len;
+                    }
+                    memcpy(dbuf + dbpos, data, cursize);
+                    dbpos += cursize;
                 }
-                memcpy(dbuf + dbpos, data, cursize);
-                dbpos += cursize;
-            }
-
-            /* Keep writing data to the child until done or too much time
-             * elapses with no progress or an error occurs.
-             */
-            rv = apr_file_write_full(script_out, data, len, NULL);
 
-            if (rv != APR_SUCCESS) {
-                /* silly script stopped reading, soak up remaining message */
-                child_stopped_reading = 1;
+                /* Keep writing data to the child until done or too much time
+                 * elapses with no progress or an error occurs.
+                 */
+                rv = apr_file_write_full(script_out, data, len, NULL);
+
+                if (rv != APR_SUCCESS) {
+                    /* silly script stopped reading, still soak up body */
+                    child_stopped_reading = 1;
+                }
             }
+            apr_brigade_cleanup(bb);
         }
-        apr_brigade_cleanup(bb);
-    }
-    while (!seen_eos);
+        while (!seen_eos);
 
-    if (conf->logname) {
-        dbuf[dbpos] = '\0';
+        if (conf->logname) {
+            dbuf[dbpos] = '\0';
+        }
     }
     /* Is this flush really needed? */
     apr_file_flush(script_out);
Index: modules/generators/mod_cgid.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/generators/mod_cgid.c,v
retrieving revision 1.134
diff -u -r1.134 mod_cgid.c
--- modules/generators/mod_cgid.c	30 May 2002 05:42:46 -0000	1.134
+++ modules/generators/mod_cgid.c	2 Jun 2002 22:36:55 -0000
@@ -1111,74 +1111,76 @@
      * Note that we already ignore SIGPIPE in the core server. 
      */ 
     bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
-    seen_eos = 0;
-    child_stopped_reading = 0;
-    if (conf->logname) {
-        dbuf = apr_palloc(r->pool, conf->bufbytes + 1);
-        dbpos = 0;
-    }
-    do {
-        apr_bucket *bucket;
-        apr_status_t rv;
+    if (!r->main) {
+        seen_eos = 0;
+        child_stopped_reading = 0;
+        if (conf->logname) {
+            dbuf = apr_palloc(r->pool, conf->bufbytes + 1);
+            dbpos = 0;
+        }
+        do {
+            apr_bucket *bucket;
+            apr_status_t rv;
 
-        rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
-                            APR_BLOCK_READ, HUGE_STRING_LEN);
+            rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+                                APR_BLOCK_READ, HUGE_STRING_LEN);
        
-        if (rv != APR_SUCCESS) {
-            return rv;
-        }
- 
-        APR_BRIGADE_FOREACH(bucket, bb) {
-            const char *data;
-            apr_size_t len;
-
-            if (APR_BUCKET_IS_EOS(bucket)) {
-                seen_eos = 1;
-                break;
+            if (rv != APR_SUCCESS) {
+                return rv;
             }
+ 
+            APR_BRIGADE_FOREACH(bucket, bb) {
+                const char *data;
+                apr_size_t len;
+
+                if (APR_BUCKET_IS_EOS(bucket)) {
+                    seen_eos = 1;
+                    break;
+                }
 
-            /* We can't do much with this. */
-            if (APR_BUCKET_IS_FLUSH(bucket)) {
-                continue;
-            }
+                /* We can't do much with this. */
+                if (APR_BUCKET_IS_FLUSH(bucket)) {
+                    continue;
+                }
 
-            /* If the child stopped, we still must read to EOS. */
-            if (child_stopped_reading) {
-                continue;
-            } 
+                /* If the child stopped, we still must read to EOS. */
+                if (child_stopped_reading) {
+                    continue;
+                } 
 
-            /* read */
-            apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+                /* read */
+                apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
             
-            if (conf->logname && dbpos < conf->bufbytes) {
-                int cursize;
+                if (conf->logname && dbpos < conf->bufbytes) {
+                    int cursize;
 
-                if ((dbpos + len) > conf->bufbytes) {
-                    cursize = conf->bufbytes - dbpos;
-                }
-                else {
-                    cursize = len;
+                    if ((dbpos + len) > conf->bufbytes) {
+                        cursize = conf->bufbytes - dbpos;
+                    }
+                    else {
+                        cursize = len;
+                    }
+                    memcpy(dbuf + dbpos, data, cursize);
+                    dbpos += cursize;
                 }
-                memcpy(dbuf + dbpos, data, cursize);
-                dbpos += cursize;
-            }
-
-            /* Keep writing data to the child until done or too much time
-             * elapses with no progress or an error occurs.
-             */
-            rv = apr_file_write_full(tempsock, data, len, NULL);
 
-            if (rv != APR_SUCCESS) {
-                /* silly script stopped reading, soak up remaining message */
-                child_stopped_reading = 1;
+                /* Keep writing data to the child until done or too much time
+                 * elapses with no progress or an error occurs.
+                 */
+                rv = apr_file_write_full(tempsock, data, len, NULL);
+
+                if (rv != APR_SUCCESS) {
+                    /* silly script stopped reading, soak up rest of body */
+                    child_stopped_reading = 1;
+                }
             }
+            apr_brigade_cleanup(bb);
         }
-        apr_brigade_cleanup(bb);
-    }
-    while (!seen_eos);
+        while (!seen_eos);
  
-    if (conf->logname) {
-        dbuf[dbpos] = '\0';
+        if (conf->logname) {
+            dbuf[dbpos] = '\0';
+        }
     }
 
     /* we're done writing, or maybe we didn't write at all;

Mime
View raw message