From: Nick Kew <niq@apache.org> Date: Tue, 8 Dec 2009 10:22:56 +0000 (+0000) Subject: Don't keepalive when we send a non-100 response while Client is expecting 100 X-Git-Tag: 2.3.5~96 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=33b33d1987b590f014ab1ba1b2f17d8f0381d46c;p=apache Don't keepalive when we send a non-100 response while Client is expecting 100 and may be feeding us continuation data. PR 47087 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@888310 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 9abae77f28..f25b7972ac 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,13 @@ Changes with Apache 2.3.5 + *) 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] + Changes with Apache 2.3.4 *) Replace AcceptMutex, LockFile, RewriteLock, SSLMutex, SSLStaplingMutex, diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index befb8c6052..354e1cafef 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -329,6 +329,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(HTTP_CONTINUE), CRLF CRLF, NULL); diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 7920507b66..fed255f7db 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -180,6 +180,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 @@ -201,6 +204,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 1697a7d9fd..11040f32a7 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -1682,6 +1682,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 */ @@ -1701,6 +1702,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));