Commit 122d7c1a authored by Yann Ylavic's avatar Yann Ylavic
Browse files

http: Fix possible empty response with mod_ratelimit for HEAD requests.

Don't eat the EOS in ap_http_header_filter() if it comes in single brigade
with a full response to a HEAD request, otherwise mod_ratelimit will never
flush its pending data.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1854004 13f79535-47bb-0310-9956-ffa450edef68
parent 04e06abc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.1

  *) http: Fix possible empty response with mod_ratelimit for HEAD requests.
     PR 63192. [Yann Ylavic]

  *) mod_cache_socache: Avoid reallocations and be safe with outgoing data
     lifetime. [Yann Ylavic]

+14 −6
Original line number Diff line number Diff line
@@ -1234,6 +1234,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
{
    request_rec *r = f->r;
    conn_rec *c = r->connection;
    int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status));
    const char *protocol = NULL;
    apr_bucket *e;
    apr_bucket_brigade *b2;
@@ -1251,7 +1252,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
    }
    else if (ctx->headers_sent) {
        /* Eat body if response must not have one. */
        if (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status)) {
        if (header_only) {
            /* Still next filters may be waiting for EOS, so pass it (alone)
             * when encountered and be done with this filter.
             */
@@ -1448,14 +1449,21 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,

    terminate_header(b2);

    rv = ap_pass_brigade(f->next, b2);
    if (rv != APR_SUCCESS) {
        goto out;
    if (header_only) {
        e = APR_BRIGADE_LAST(b);
        if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(b2, e);
            ap_remove_output_filter(f);
        }
        apr_brigade_cleanup(b);
    }

    rv = ap_pass_brigade(f->next, b2);
    apr_brigade_cleanup(b2);
    ctx->headers_sent = 1;

    if (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status)) {
        apr_brigade_cleanup(b);
    if (rv != APR_SUCCESS || header_only) {
        goto out;
    }