]> granicus.if.org Git - apache/commitdiff
core, mod_rewrite: introduce the 'redirect-keeps-vary' note
authorLuca Toscano <elukey@apache.org>
Tue, 10 Oct 2017 17:41:37 +0000 (17:41 +0000)
committerLuca Toscano <elukey@apache.org>
Tue, 10 Oct 2017 17:41:37 +0000 (17:41 +0000)
                   to allow proper Vary header insertion when
                   dealing with a RewriteRule in a directory
                   context.

This change is an attempt to fix a long standing problem,
brought up while working on PR 58231. Our documentation clearly
states the following:

"If a HTTP header is used in a condition this header is added
to the Vary header of the response in case the condition
evaluates to true for the request."

This is currently not true for RewriteCond/Rules working in
a directory context, since when an internal redirect happens
all the outstanding response headers get dropped.

There might be a better solution so I am looking forward to
hear more opinions and comments. My goal for a delicate change
like this one would be to affect the least amount of configurations
possible, without triggering unwanted side effects.

If the solution is good for everybody tests will be written
in the suite asap.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1811744 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/http/http_request.c
modules/mappers/mod_rewrite.c

diff --git a/CHANGES b/CHANGES
index 4a81e947aaaa3a18ca554050c3615585b6497622..9e172201ffd4ff5fd49954c13b2872c1307cd5aa 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_rewrite, core: add the Vary header when a condition evaluates to true
+     and the related RewriteRule is used in a Directory context
+     (triggering an internal redirect). [Luca Toscano]
+
   *) ab: Make the TLS layer aware that the underlying socket is nonblocking,
      and use/handle POLLOUT where needed to avoid busy IOs and recover write
      errors when appropriate.  [Yann Ylavic]
index 2eff6f4e13521ad9aa273c360abd10ac14d9e076..85c65707a2016eac98d624ff74e9f794ab1d2982 100644 (file)
@@ -523,6 +523,7 @@ static request_rec *internal_internal_redirect(const char *new_uri,
                                                request_rec *r) {
     int access_status;
     request_rec *new;
+    const char *vary_header;
 
     if (ap_is_recursion_limit_exceeded(r)) {
         ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
@@ -586,6 +587,16 @@ static request_rec *internal_internal_redirect(const char *new_uri,
         if (location)
             apr_table_setn(new->headers_out, "Location", location);
     }
+
+    /* A module (like mod_rewrite) can force an internal redirect
+     * to carry over the Vary header (if present).
+     */
+    if (apr_table_get(r->notes, "redirect-keeps-vary")) {
+        if((vary_header = apr_table_get(r->headers_out, "Vary"))) {
+            apr_table_setn(new->headers_out, "Vary", vary_header);
+        }
+    }
+
     new->err_headers_out = r->err_headers_out;
     new->trailers_out    = apr_table_make(r->pool, 5);
     new->subprocess_env  = rename_original_env(r->pool, r->subprocess_env);
index bc8f52d6104b2cae67750b1db1a864bb444d9710..0b6c41ab27c7115d5a08e6f149f19ca0590c6a02 100644 (file)
@@ -5226,6 +5226,8 @@ static int hook_fixup(request_rec *r)
                 }
             }
 
+            apr_table_setn(r->notes, "redirect-keeps-vary", "");
+
             /* now initiate the internal redirect */
             rewritelog((r, 1, dconf->directory, "internal redirect with %s "
                         "[INTERNAL REDIRECT]", r->filename));