replacing cache-control headers

Maxim Dounin mdounin at
Thu Mar 11 18:47:43 MSK 2010


On Thu, Mar 11, 2010 at 09:17:03AM -0600, Ryan Malayter wrote:

> I'm trying to add Cache-Control headers to an ill-behaved backend
> application (that I don't control). For many requests, the backend
> sets Cache-Control headers with an empty value (an RFC violation, I
> know, and a bug report has been filed, but resolution is likely going
> to take months from the vendor). Nginx 0.7.62 using default Ubuntu
> package from Karmic.
> I need to avoid using the "more Headers" module if at all possible for
> administrative reasons (standard packages are much easier to deal with
> administratively and make life much easier during audits).
> So, I am trying to use proxy_hide_header and variables to
> conditionally set the header. The problem is that using
> $upstream_http_cache_control in a "set" or "if" statement always seems
> to evaluate to the empty string. However, I can add a customer header
> which shows the value passed from the upstream correctly if is not
> empty.
> Here is the relevant portion of my config (I have tried many variants
> of positive and negative logic, without success):
>         location / {
>         proxy_pass http://backend;
>         proxy_set_header Host $host;
>         proxy_read_timeout 900;
>         proxy_redirect default;
>         proxy_hide_header Pragma;
>         proxy_hide_header Cache-Control;
>         set $mycc $upstream_http_cache_control;
>         if ($mycc = "") {
>                 set $mycc "no-cache";
>                 }

As rewrite module directives ("if", "set") are executed during 
rewrite phase of request processing it will always see empty value 
of $upstream_http_cache_control variable (it's not yet available 
as no headers got from upstream yet).

>         add_header "Cache-Control" $mycc;
>         add_header "X-Upstream-Cache-Control" $upstream_http_cache_control;
>         add_header "X-Upstream-Expires" $upstream_http_expires;
>         }
> With this configuration, I always get "Cache-Control: no-cache"
> headers, even when "X-Upstream-Cache-Control" shows that the upstream
> did pass a non-empty Cache-Control header. An Example response:

This is expected behaviour.


> Is there any way do do this using default nginx modules?

You may try to do this with embedded perl, specifically perl_set.  
Something like this should work:

    perl_set  $mycc  'sub {
        return shift->variable("upstream_http_cache_control") || "no-cache";

Maxim Dounin

More information about the nginx mailing list