]> granicus.if.org Git - apache/commitdiff
Don't keepalive when we send a non-100 response while Client is expecting 100
authorNick Kew <niq@apache.org>
Tue, 8 Dec 2009 10:22:56 +0000 (10:22 +0000)
committerNick Kew <niq@apache.org>
Tue, 8 Dec 2009 10:22:56 +0000 (10:22 +0000)
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

CHANGES
modules/http/http_filters.c
modules/http/http_protocol.c
server/protocol.c

diff --git a/CHANGES b/CHANGES
index 9abae77f28effe120ca30216dc700f664433a85c..f25b7972ac9a87ca0dcb8c6687c934214a12c992 100644 (file)
--- 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,
index befb8c6052b2f2a9c4528fa64efc781dcc5d4c68..354e1cafefa452b21463a9e024849f337774a5c7 100644 (file)
@@ -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);
index 7920507b664952db48e8912a4948f69a01660b9f..fed255f7dba4e0daf2f1a6ff63f73c14809890d9 100644 (file)
@@ -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
index 1697a7d9fddda9138138175abceef2fb64278e9c..11040f32a7646ef0fac539478d202a67e12e8f70 100644 (file)
@@ -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));