Commit 2e68cdae authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Merge r1666998 from trunk:

core: Cleanup the request soon/even if some output filter fails to
handle the EOR bucket.

Submitted by: ylavic
Reviewed/backported by: jim


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1681113 13f79535-47bb-0310-9956-ffa450edef68
parent 1bb552ce
Loading
Loading
Loading
Loading
+3 −0
Changes for CHANGES: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ Changes with Apache 2.4.13
     or framework is unable to return Location in the internal-redirect
     form.  [Jeff Trawick]

  *) core: Cleanup the request soon/even if some output filter fails to
     handle the EOR bucket.  [Yann Ylavic]

  *) mpm_event: Allow for timer events duplicates. [Jim Jagielski, Yann Ylavic]

  *) mod_proxy, mod_ssl, mod_cache_socache, mod_socache_*: Support machine
+0 −7
Changes for STATUS: 0 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -112,13 +112,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
     2.4.x patch: trunk works (modulo CHANGES)
     +1: ylavic, minfrin, jim

  *) core: Cleanup the request soon/even if some output filter fails to
     handle the EOR bucket.
     trunk patch: http://svn.apache.org/r1666998
     2.4.x patch: trunk works (modulo CHANGES)
     +1: ylavic, minfrin, jim



PATCHES PROPOSED TO BACKPORT FROM TRUNK:
  [ New proposals should be added at the end of the list ]
+18 −9
Changes for modules/http/http_request.c: 18 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -216,12 +216,12 @@ AP_DECLARE(void) ap_die(int type, request_rec *r)
    ap_send_error_response(r_1st_err, recursive_error);
}

static void check_pipeline(conn_rec *c)
static void check_pipeline(conn_rec *c, apr_bucket_brigade *bb)
{
    if (c->keepalive != AP_CONN_CLOSE) {
    if (c->keepalive != AP_CONN_CLOSE && !c->aborted) {
        apr_status_t rv;
        apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc);

        AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(bb));
        rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE,
                            APR_NONBLOCK_READ, 1);
        if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
@@ -234,7 +234,6 @@ static void check_pipeline(conn_rec *c)
        else {
            c->data_in_input_filters = 1;
        }
        apr_brigade_destroy(bb);
    }
}

@@ -249,20 +248,30 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
     * this bucket is destroyed, the request will be logged and
     * its pool will be freed
     */
    bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
    b = ap_bucket_eor_create(r->connection->bucket_alloc, r);
    bb = apr_brigade_create(c->pool, c->bucket_alloc);
    b = ap_bucket_eor_create(c->bucket_alloc, r);
    APR_BRIGADE_INSERT_HEAD(bb, b);

    ap_pass_brigade(r->connection->output_filters, bb);
    ap_pass_brigade(c->output_filters, bb);
    
    /* The EOR bucket has either been handled by an output filter (eg.
     * deleted or moved to a buffered_bb => no more in bb), or an error
     * occured before that (eg. c->aborted => still in bb) and we ought
     * to destroy it now. So cleanup any remaining bucket along with
     * the orphan request (if any).
     */
    apr_brigade_cleanup(bb);

    /* From here onward, it is no longer safe to reference r
     * or r->pool, because r->pool may have been destroyed
     * already by the EOR bucket's cleanup function.
     */

    check_pipeline(c, bb);
    apr_brigade_destroy(bb);
    if (c->cs)
        c->cs->state = CONN_STATE_WRITE_COMPLETION;
    check_pipeline(c);
        c->cs->state = (c->aborted) ? CONN_STATE_LINGER
                                    : CONN_STATE_WRITE_COMPLETION;
    AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
    if (ap_extended_status) {
        ap_time_process_request(c->sbh, STOP_PREQUEST);
+6 −5
Changes for server/core_filters.c: 6 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -468,17 +468,16 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
    if (new_bb == NULL) {
        rv = send_brigade_nonblocking(net->client_socket, bb,
                                      &(ctx->bytes_written), c);
        if (APR_STATUS_IS_EAGAIN(rv)) {
            rv = APR_SUCCESS;
        }
        else if (rv != APR_SUCCESS) {
        if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
            /* The client has aborted the connection */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
                          "core_output_filter: writing data to the network");
            apr_brigade_cleanup(bb);
            c->aborted = 1;
            return rv;
        }
        setaside_remaining_output(f, ctx, bb, c);
        return rv;
        return APR_SUCCESS;
    }

    bytes_in_brigade = 0;
@@ -547,6 +546,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
            /* The client has aborted the connection */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
                          "core_output_filter: writing data to the network");
            apr_brigade_cleanup(bb);
            c->aborted = 1;
            return rv;
        }
@@ -560,6 +560,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
            /* The client has aborted the connection */
            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
                          "core_output_filter: writing data to the network");
            apr_brigade_cleanup(bb);
            c->aborted = 1;
            return rv;
        }