Mod_rewrite does not send Vary: accept-language when RewriteCond matches

I have a rewrite rule that redirects to / if the consent language is not present and someone is trying to visit ?lang=en. It works great except for heading returns. Vary: accept-languagemissing in response.

RewriteCond %{HTTP:Accept-Language} ^$  
RewriteCond %{QUERY_STRING}         ^lang=en  
RewriteRule ^$                      http://www.example.com/?     [R=301,L]

The Apache documentation indicates:

If the HTTP header is used in the condition, this header is added to the Vary response header if the condition is true for the request. It is not added if the condition evaluates to false for the request.

The conditions are definitely the same and redirected, so I don’t understand why Apache does not add the language. One can understand why this would be a real problem if the proxy had to cache it? Lang = en always redirects / regardless of the accepted accept-language header.

+5
source share
2 answers

After peering into the seedy underbelly of Apache's query processing system, it turns out that the documentation is somewhat misleading ... But before I get the explanation, from what I can say, you are at the mercy of Apache on this one.

Customer task

-, Vary, . , mod_rewrite .

, apr_table_get(), , :

const char *val = apr_table_get(ctx->r->headers_in, name);

name , NULL. , val:

if (val) {
   // Set the structure member ctx->vary_this
}

ctx->vary_this RewriteCond , Vary *. , , ( ) Vary. , , .

* , NV ( ) ctx->vary_this NULL, .

, Accept-Language, . , Vary mod_rewrite , . , , :

User-Agent: Fiddler
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: 
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Host: 129.168.0.123

, ? mod_rewrite , (ctx->vary ctx->vary_this ):

if (ctx->vary) {
    apr_table_merge(r->headers_out, "Vary", ctx->vary);
}

, r->headers_out - , . , - , , .

.htaccess

.htaccess <Directory>. , mod_rewrite Apache, , , . , , ( ).

, . , ap_internal_redirect(). , headers_out .

, mod_rewrite , , () , . , ( <VirtualHost>), ...

, , , mod_rewrite , , , , .

Apache, ap_process_request(). , , ap_process_request_internal(), ( mod_rewrite). , 301.

OK ( 0), ap_finalize_request_protocol(). , :

if (access_status == OK) {
    ap_finalize_request_protocol(r);
}
else {
    r->status = HTTP_OK;
    ap_die(access_status, r);
}

ap_die() (, 301), ap_send_error_response().

, , , . , , "", . :

if (!r->assbackwards) {
    apr_table_t *tmp = r->headers_out;

    /* For all HTTP/1.x responses for which we generate the message,
     * we need to avoid inheriting the "normal status" header fields
     * that may have been set by the request handler before the
     * error or redirect, except for Location on external redirects.
     */
    r->headers_out = r->err_headers_out;
    r->err_headers_out = tmp;
    apr_table_clear(r->err_headers_out);

    if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
        if ((location != NULL) && *location) {
            apr_table_setn(r->headers_out, "Location", location);
        }
        //...
    }
//...
}

, r->headers_out , . , , .

, . , . , , , .

Vary: Accept-Encoding, , , , . , Gumbo .

2.2.14 2.2 , Apache 2.2.15, -, .

+9

:

<LocationMatch "^.*lang\=">
    Header onsuccess merge Vary "Accept-Language"
</LocationMatch>
+1

All Articles