You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2007/11/02 17:45:49 UTC
svn commit: r591393 - /httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
Author: jorton
Date: Fri Nov 2 09:45:46 2007
New Revision: 591393
URL: http://svn.apache.org/viewvc?rev=591393&view=rev
Log:
Fix handling of buffered request body for per-location SSL
renegotiation when an internal redirect occurs:
* modules/ssl/ssl_engine_io.c (ssl_io_buffer_fill): Remove
protocol-level filters before inserting the buffering filter.
(ssl_io_filter_buffer): Return an EOS if invoked with an empty
brigade; do not remove the filter after exhausting the buffer.
(ssl_io_filter_buffer): Increase the type of the buffer filter to be
AP_FTYPE_PROTOCOL.
PR: 43738
Modified:
httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_io.c?rev=591393&r1=591392&r2=591393&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_io.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_io.c Fri Nov 2 09:45:46 2007
@@ -1539,14 +1539,25 @@
apr_brigade_destroy(tempb);
- /* Insert the filter which will supply the buffered data. */
+ /* After consuming all protocol-level input, remove all protocol-level
+ * filters. It should strictly only be necessary to remove filters
+ * at exactly ftype == AP_FTYPE_PROTOCOL, since this filter will
+ * precede all > AP_FTYPE_PROTOCOL anyway. */
+ while (r->proto_input_filters->frec->ftype < AP_FTYPE_CONNECTION) {
+ ap_remove_input_filter(r->proto_input_filters);
+ }
+
+ /* Insert the filter which will supply the buffered content. */
ap_add_input_filter(ssl_io_buffer, ctx, r, c);
return 0;
}
/* This input filter supplies the buffered request body to the caller
- * from the brigade stored in f->ctx. */
+ * from the brigade stored in f->ctx. Note that the placement of this
+ * filter in the filter stack is important; it must be the first
+ * r->proto_input_filter; lower-typed filters will not be preserved
+ * across internal redirects (see PR 43738). */
static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
@@ -1565,6 +1576,19 @@
return APR_ENOTIMPL;
}
+ if (APR_BRIGADE_EMPTY(ctx->bb)) {
+ /* Suprisingly (and perhaps, wrongly), the request body can be
+ * pulled from the input filter stack more than once; a
+ * handler may read it, and ap_discard_request_body() will
+ * attempt to do so again after *every* request. So input
+ * filters must be prepared to give up an EOS if invoked after
+ * initially reading the request. The HTTP_IN filter does this
+ * with its ->eos_sent flag. */
+
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_eos_create(f->c->bucket_alloc));
+ return APR_SUCCESS;
+ }
+
if (mode == AP_MODE_READBYTES) {
apr_bucket *e;
@@ -1619,8 +1643,9 @@
}
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c,
- "buffered SSL brigade now exhausted; removing filter");
- ap_remove_input_filter(f);
+ "buffered SSL brigade exhausted");
+ /* Note that the filter must *not* be removed here; it may be
+ * invoked again, see comment above. */
}
return APR_SUCCESS;
@@ -1695,7 +1720,7 @@
ap_register_input_filter (ssl_io_filter, ssl_io_filter_input, NULL, AP_FTYPE_CONNECTION + 5);
ap_register_output_filter (ssl_io_filter, ssl_io_filter_output, NULL, AP_FTYPE_CONNECTION + 5);
- ap_register_input_filter (ssl_io_buffer, ssl_io_filter_buffer, NULL, AP_FTYPE_PROTOCOL - 1);
+ ap_register_input_filter (ssl_io_buffer, ssl_io_filter_buffer, NULL, AP_FTYPE_PROTOCOL);
return;
}