This patch combined with the last few patches I've posted today allow
chunked trailer support again and now passes all httpd-test cases.
What we try to do is to ensure that ap_discard_request_body() is not
called before the handler "accepts" the request and begins generating
the output. It is still possible for a bad module to call discard
more than once or improperly.
This effectively reverts Ryan's patch to http_protocol.c, so
I'd appreciate it gets some review (preferably from Ryan
himself!). -- justin
Index: modules/dav/main/mod_dav.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.c,v
retrieving revision 1.79
diff -u -r1.79 mod_dav.c
--- modules/dav/main/mod_dav.c 17 May 2002 11:33:08 -0000 1.79
+++ modules/dav/main/mod_dav.c 2 Jun 2002 22:50:08 -0000
@@ -1084,11 +1097,6 @@
int result;
int depth;
- /* We don't use the request body right now, so torch it. */
- if ((result = ap_discard_request_body(r)) != OK) {
- return result;
- }
-
/* Ask repository module to resolve the resource */
err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
&resource);
@@ -2680,11 +2646,6 @@
"and Overwrite has been specified.");
}
- /* ### for now, we don't need anything in the body */
- if ((result = ap_discard_request_body(r)) != OK) {
- return result;
- }
-
if ((err = dav_open_lockdb(r, 0, &lockdb)) != NULL) {
/* ### add a higher-level description? */
return dav_handle_err(r, err, NULL);
@@ -3461,10 +3422,6 @@
if (vsn_hooks == NULL)
return DECLINED;
- if ((result = ap_discard_request_body(r)) != OK) {
- return result;
- }
-
/* Ask repository module to resolve the resource */
err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
&resource);
@@ -3506,6 +3463,11 @@
return dav_handle_err(r, err, NULL);
}
+ /* Discard the body now. */
+ if ((result = ap_discard_request_body(r)) != OK) {
+ return result;
+ }
+
/* no body */
ap_set_content_length(r, 0);
@@ -4056,11 +4018,6 @@
&resource);
if (err != NULL)
return dav_handle_err(r, err, NULL);
-
- /* MKACTIVITY does not have a defined request body. */
- if ((result = ap_discard_request_body(r)) != OK) {
- return result;
- }
/* Check request preconditions */
Index: modules/http/http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.432
diff -u -r1.432 http_protocol.c
--- modules/http/http_protocol.c 31 May 2002 20:41:06 -0000 1.432
+++ modules/http/http_protocol.c 2 Jun 2002 22:50:14 -0000
@@ -903,11 +903,6 @@
if (!ctx->remaining) {
switch (ctx->state) {
case BODY_NONE:
- if (f->r->proxyreq != PROXYREQ_RESPONSE) {
- e = apr_bucket_eos_create(f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- return APR_SUCCESS;
- }
break;
case BODY_LENGTH:
e = apr_bucket_eos_create(f->c->bucket_alloc);
@@ -2285,14 +2280,8 @@
const char *title = status_lines[idx];
const char *h1;
- /* XXX This is a major hack that should be fixed cleanly. The
- * problem is that we have the information we need in a previous
- * request, but the text of the page must be sent down the last
- * request_rec's filter stack. rbb
- */
- request_rec *rlast = r;
- while (rlast->next) {
- rlast = rlast->next;
+ if (ap_discard_request_body(r) == AP_FILTER_ERROR) {
+ return;
}
/* Accept a status_line set by a module, but only if it begins
@@ -2315,24 +2304,24 @@
* so do ebcdic->ascii translation explicitly (if needed)
*/
- ap_rvputs_proto_in_ascii(rlast,
+ ap_rvputs_proto_in_ascii(r,
DOCTYPE_HTML_2_0
"<html><head>\n<title>", title,
"</title>\n</head><body>\n<h1>", h1, "</h1>\n",
NULL);
- ap_rvputs_proto_in_ascii(rlast,
+ ap_rvputs_proto_in_ascii(r,
get_canned_error_string(status, r, location),
NULL);
if (recursive_error) {
- ap_rvputs_proto_in_ascii(rlast, "<p>Additionally, a ",
+ ap_rvputs_proto_in_ascii(r, "<p>Additionally, a ",
status_lines[ap_index_of_response(recursive_error)],
"\nerror was encountered while trying to use an "
"ErrorDocument to handle the request.</p>\n", NULL);
}
- ap_rvputs_proto_in_ascii(rlast, ap_psignature("<hr />\n", r), NULL);
- ap_rvputs_proto_in_ascii(rlast, "</body></html>\n", NULL);
+ ap_rvputs_proto_in_ascii(r, ap_psignature("<hr />\n", r), NULL);
+ ap_rvputs_proto_in_ascii(r, "</body></html>\n", NULL);
}
ap_finalize_request_protocol(r);
}
Index: modules/http/http_request.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_request.c,v
retrieving revision 1.145
diff -u -r1.145 http_request.c
--- modules/http/http_request.c 31 May 2002 07:37:19 -0000 1.145
+++ modules/http/http_request.c 2 Jun 2002 22:50:15 -0000
@@ -145,17 +145,6 @@
if (ap_status_drops_connection(r->status)) {
r->connection->keepalive = 0;
}
- else if ((r->status != HTTP_NOT_MODIFIED) &&
- (r->status != HTTP_NO_CONTENT) &&
- r->connection && (r->connection->keepalive != -1)) {
- /* If the discard returns AP_FILTER_ERROR, it means that we went
- * recursive on ourselves and we should abort.
- */
- int errstatus = ap_discard_request_body(r);
- if (errstatus == AP_FILTER_ERROR) {
- return;
- }
- }
/*
* Two types of custom redirects --- plain text, and URLs. Plain text has
Index: modules/mappers/mod_negotiation.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/mappers/mod_negotiation.c,v
retrieving revision 1.102
diff -u -r1.102 mod_negotiation.c
--- modules/mappers/mod_negotiation.c 17 May 2002 11:24:16 -0000 1.102
+++ modules/mappers/mod_negotiation.c 2 Jun 2002 22:50:18 -0000
@@ -2818,9 +2818,6 @@
apr_bucket *e;
ap_allow_standard_methods(r, REPLACE_ALLOW, M_GET, M_OPTIONS, M_POST, -1);
- if ((res = ap_discard_request_body(r)) != OK) {
- return res;
- }
/*if (r->method_number == M_OPTIONS) {
* return ap_send_http_options(r);
*}
@@ -2841,6 +2838,9 @@
return res;
}
+ if ((res = ap_discard_request_body(r)) != OK) {
+ return res;
+ }
bb = apr_brigade_create(r->pool, c->bucket_alloc);
e = apr_bucket_file_create(map, best->body,
(apr_size_t)best->bytes, r->pool,
Index: server/core.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/core.c,v
retrieving revision 1.182
diff -u -r1.182 core.c
--- server/core.c 31 May 2002 20:52:28 -0000 1.182
+++ server/core.c 2 Jun 2002 22:50:23 -0000
@@ -3196,15 +3196,6 @@
ap_allow_standard_methods(r, MERGE_ALLOW, M_GET, M_OPTIONS, M_POST, -1);
- /* If filters intend to consume the request body, they must
- * register an InputFilter to slurp the contents of the POST
- * data from the POST input stream. It no longer exists when
- * the output filters are invoked by the default handler.
- */
- if ((errstatus = ap_discard_request_body(r)) != OK) {
- return errstatus;
- }
-
if (r->method_number == M_GET || r->method_number == M_POST) {
if (r->finfo.filetype == 0) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
@@ -3242,6 +3233,11 @@
if (bld_content_md5) {
apr_table_setn(r->headers_out, "Content-MD5",
ap_md5digest(r->pool, fd));
+ }
+
+ /* We know we are okay to respond to this, so discard the body. */
+ if ((errstatus = ap_discard_request_body(r)) != OK) {
+ return errstatus;
}
bb = apr_brigade_create(r->pool, c->bucket_alloc);
Index: server/protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/protocol.c,v
retrieving revision 1.104
diff -u -r1.104 protocol.c
--- server/protocol.c 17 May 2002 11:11:37 -0000 1.104
+++ server/protocol.c 2 Jun 2002 22:50:25 -0000
@@ -968,8 +968,9 @@
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
"client sent an unrecognized expectation value of "
"Expect: %s", expect);
- ap_send_error_response(r, 0);
- (void) ap_discard_request_body(r);
+ if (ap_discard_request_body(r) != AP_FILTER_ERROR) {
+ ap_send_error_response(r, 0);
+ }
ap_run_log_transaction(r);
return r;
}