From: Jeff Trawick Date: Sat, 30 Apr 2011 12:10:23 +0000 (+0000) Subject: Grab trunk r888310: X-Git-Tag: 2.2.18~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee0a5957811b972fbe023c217079ff27d1bf2473;p=thirdparty%2Fapache%2Fhttpd.git Grab trunk r888310: Core HTTP: disable keepalive when the Client has sent Expect: 100-continue but we respond directly with a non-100 response. Keepalive here led to data from clients continuing being treated as a new request. PR: 47087 Submitted by: niq Reviewed by: wrowe, sf, trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1098104 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 78c2c0fa4be..9cc3ee34172 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,12 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.18 + *) Core HTTP: disable keepalive when the Client has sent + Expect: 100-continue + but we respond directly with a non-100 response. Keepalive here led + to data from clients continuing being treated as a new request. + PR 47087. [Nick Kew] + *) htpasswd: Change the default algorithm for htpasswd to MD5 on all platforms. Crypt with its 8 character limit is not useful anymore; improve out of disk space handling (PR 30877); print a warning if diff --git a/STATUS b/STATUS index 0947952fc89..3281b755923 100644 --- a/STATUS +++ b/STATUS @@ -91,11 +91,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * HTTP Protocol: Fix handling of extra request data sent with Expect: 100 - PR 47087 - Trunk patch: http://svn.apache.org/viewvc?view=revision&revision=888310 - 2.2.x: Trunk works with offset - +1: niq, wrowe, sf PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 7fbc3692ac0..b42998959e0 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -331,6 +331,10 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, char *tmp; int len; + /* if we send an interim response, we're no longer + * in a state of expecting one. + */ + f->r->expecting_100 = 0; tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ", ap_get_status_line(100), CRLF CRLF, NULL); len = strlen(tmp); diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index fdd7d7578ac..be864e8256e 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -174,6 +174,9 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r) * body should use the HTTP/1.1 chunked transfer-coding. In English, * * IF we have not marked this connection as errored; + * and the client isn't expecting 100-continue (PR47087 - more + * input here could be the client continuing when we're + * closing the request). * and the response body has a defined length due to the status code * being 304 or 204, the request method being HEAD, already * having defined Content-Length or Transfer-Encoding: chunked, or @@ -195,6 +198,7 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r) * Note that the condition evaluation order is extremely important. */ if ((r->connection->keepalive != AP_CONN_CLOSE) + && !r->expecting_100 && ((r->status == HTTP_NOT_MODIFIED) || (r->status == HTTP_NO_CONTENT) || r->header_only diff --git a/server/protocol.c b/server/protocol.c index 570ec2e0329..98513601b8f 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -1641,6 +1641,7 @@ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers) { hdr_ptr x; char *status_line = NULL; + request_rec *rr; if (r->proto_num < 1001) { /* don't send interim response to HTTP/1.0 Client */ @@ -1652,6 +1653,14 @@ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers) return; } + /* if we send an interim response, we're no longer in a state of + * expecting one. Also, this could feasibly be in a subrequest, + * so we need to propagate the fact that we responded. + */ + for (rr = r; rr != NULL; rr = rr->main) { + rr->expecting_100 = 0; + } + status_line = apr_pstrcat(r->pool, AP_SERVER_PROTOCOL, " ", r->status_line, CRLF, NULL); ap_xlate_proto_to_ascii(status_line, strlen(status_line));