Commit 5b92eb42 authored by Yann Ylavic's avatar Yann Ylavic
Browse files

mod_proxy_http: forward 100-continue.

Handle end-to-end 100-continue, according to RFC 7231, such that the client
request body is not read/forwarded (according to its "Expect:" header) until
the backend wants to receive it (with interim 100 continue response), or never
forwarded if the backend provides a (non-interim) response and doesn't need
the client body at all.

This is achieved by filling the header_brigade in ap_proxy_http_prefetch()
and letting ap_proxy_http_request() determine whether it should forward that
brigade only (with the "Expect: 100-continue" specified by the client or added
according to "ping=" configuration), or forward the whole body for the usual
case (as before).

When 100-continue expectation is in place, the body is actually forwarded by
ap_proxy_http_process_response() when/if a "100 continue" response is sent by
the backend, otherwise the body is discarded; a future enhancement could make
so that in a balancer configuration, the body could be forwarded to another
balancer member depending on the status/error from the backend.

So stream_reqbody_cl() and stream_reqbody_chunked() functions are adapted to be
called by either ap_proxy_http_request() or ap_proxy_http_process_response(),
while spool_reqbody_cl() still spools the body in ap_proxy_http_prefetch() thus
before the backend is connected/reused to avoid inactivity on the connection
for the prefetch time (the prefetched body is also forwarded according to the
100-continue expectation, though).

Also, since the brigades and other runtime objects now need to be shared by the
ap_proxy_http_*() functions chain, a proxy_http_req_t struct/context is created
from the start and passed to them as (the single) argument. This is also a good
candidate for a future async baton, if we wanted to let the MPM event wait for
connection data for us at any stage and be called back ;)

Finally, ap_send_interim_response() is modified to correcly handle 100 continue
responses once, and take care of clearing r->expecting_100 only for them.

PR 60330.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1836588 13f79535-47bb-0310-9956-ffa450edef68
parent a45c7956
Loading
Loading
Loading
Loading
+3 −0
Changes for CHANGES: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.1

  *) mod_proxy_http: forward 100-continue, and minimize race conditions when
     reusing backend connections. PR 60330. [Yann Ylavic, Jean-Frederic Clere]

  *) mod_proxy: Remove load order and link dependency between mod_lbmethod_*
     modules and mod_proxy. PR 62557. [Ruediger Pluem, William Rowe]

+324 −259

File changed.

Preview size limit exceeded, changes collapsed.

+3 −1
Changes for server/protocol.c: 3 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -2283,7 +2283,8 @@ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers)
                      "Status is %d - not sending interim response", r->status);
        return;
    }
    if ((r->status == HTTP_CONTINUE) && !r->expecting_100) {
    if (r->status == HTTP_CONTINUE) {
        if (!r->expecting_100) {
            /*
             * Don't send 100-Continue when there was no Expect: 100-continue
             * in the request headers. For origin servers this is a SHOULD NOT
@@ -2299,6 +2300,7 @@ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers)
        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));