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;