Commit 83f3cd02 authored by Evgeny Kotkov's avatar Evgeny Kotkov
Browse files

mod_brotli, mod_deflate: Restore the separate handling of 304 Not Modified

responses allowing these modules to properly set or fix-up the response
headers such as Vary or ETag.

This change follows up on r1837056 that disabled that special handling and
thus resulted in a potential violation of RFC7232, 4.1:

   The server generating a 304 response MUST generate any of the following
   header fields that would have been sent in a 200 (OK) response to the
   same request: Cache-Control, Content-Location, Date, ETag, Expires,
   and Vary.)

References:
  https://lists.apache.org/thread.html/f5733ca6743757e8aa8b58a0cd9e27680971551c2a20f5606c66507e@%3Cdev.httpd.apache.org%3E
  https://tools.ietf.org/html/rfc7232#section-4.1

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1843242 13f79535-47bb-0310-9956-ffa450edef68
parent 71842c0b
Loading
Loading
Loading
Loading
+5 −3
Changes for modules/filters/mod_brotli.c: 5 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -346,12 +346,14 @@ static apr_status_t compress_filter(ap_filter_t *f, apr_bucket_brigade *bb)
        const char *accepts;

        /* Only work on main request, not subrequests, that are not
         * responses with no content (204/304), and are not tagged with the
         * a 204 response with no content, and are not tagged with the
         * no-brotli env variable, and are not a partial response to
         * a Range request.
         *
         * Note that responding to 304 is handled separately to set
         * the required headers (such as ETag) per RFC7232, 4.1.
         */
        if (r->main
            || AP_STATUS_IS_HEADER_ONLY(r->status)
        if (r->main || r->status == HTTP_NO_CONTENT
            || apr_table_get(r->subprocess_env, "no-brotli")
            || apr_table_get(r->headers_out, "Content-Range")) {
            ap_remove_output_filter(f);
+11 −7
Changes for modules/filters/mod_deflate.c: 11 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -642,19 +642,21 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,

        /*
         * Only work on main request, not subrequests,
         * that are not responses with no content (204/304),
         * that are not a 204 response with no content
         * and are not tagged with the no-gzip env variable
         * and not a partial response to a Range request.
         *
         * Note that responding to 304 is handled separately to
         * set the required headers (such as ETag) per RFC7232, 4.1.
         */
        if ((r->main != NULL) ||
            AP_STATUS_IS_HEADER_ONLY(r->status) ||
        if ((r->main != NULL) || (r->status == HTTP_NO_CONTENT) ||
            apr_table_get(r->subprocess_env, "no-gzip") ||
            apr_table_get(r->headers_out, "Content-Range")
           ) {
            if (APLOG_R_IS_LEVEL(r, APLOG_TRACE1)) {
                const char *reason =
                    (r->main != NULL)                           ? "subrequest" :
                    AP_STATUS_IS_HEADER_ONLY(r->status)         ? "no content" :
                    (r->status == HTTP_NO_CONTENT)              ? "no content" :
                    apr_table_get(r->subprocess_env, "no-gzip") ? "no-gzip" :
                    "content-range";
                ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
@@ -1531,12 +1533,14 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,

        /*
         * Only work on main request, not subrequests,
         * that are not responses with no content (204/304),
         * that are not a 204 response with no content
         * and not a partial response to a Range request,
         * and only when Content-Encoding ends in gzip.
         *
         * Note that responding to 304 is handled separately to
         * set the required headers (such as ETag) per RFC7232, 4.1.
         */
        if (!ap_is_initial_req(r) ||
            AP_STATUS_IS_HEADER_ONLY(r->status) ||
        if (!ap_is_initial_req(r) || (r->status == HTTP_NO_CONTENT) ||
            (apr_table_get(r->headers_out, "Content-Range") != NULL) ||
            (check_gzip(r, r->headers_out, r->err_headers_out) == 0)
           ) {