Response Header IF statement problem

Francis Daly francis at
Fri Feb 16 12:35:30 UTC 2018

On Thu, Feb 15, 2018 at 01:22:04PM +0000, Friscia, Michael wrote:

Hi there,

> To add one more thing. I mentioned that my testing failed. Exactly what was failing is that the map{} block that worked and then stopped working was the problem, the $nocache variable would always return the default value no matter what I did.

there is a lot of information here, and your design seems quite complex.

I think that you are close to having an nginx config that does what
you want; but I suspect that it will help you to have a clear picture
of how things are intended to work within nginx, so that you understand
the building blocks available to you, so that you can put them together
in the way that you want.

Very briefly and hand-wavily (and check the proper documentation to fill
in all the pieces I am leaving out):

In your common case, a request comes to nginx; it is handled in one
server{} in one location{}, which does proxy_pass to an upstream http

nginx checks the proxy_cache_key corresponding to the request, and if
that key is in the proxy_cache, then the content is returned from there
directly. If that key is not in the proxy_cache, then the request is
made to upstream, the response is written to the proxy_cache, and the
response is also returned to the client.

Not everything is cached from upstream. There are http rules for when
things can and cannot be cached, and for how long they can be cached,
and nginx (in general) obeys them. So: the simplest thing on the nginx
side is for your upstream http server to use http rules to say "this
response is not cacheable", and nginx will deal with it without extra
config on your part.

If you want nginx not to look in the proxy_cache for the proxy_cache_key
for this request, you can use proxy_cache_bypass.

If you want nginx not to write the response from upstream into the
proxy_cache, you can use proxy_no_cache.

"map" is defined outside all server{}s, and takes the form "map
current$thing $new_variable {}". $new_variable gets a value the first
time it is used in this request -- if $new_variable is not used, the map
is never consulted; so having multiple "map"s that are not used by this
request has zero overhead for this request.

And: unless you understand it, don't use "if", especially not inside
a location{}.

If you want to, for example, add a debug-response-header with a certain
value, do exactly that. Do not try to do "if the value is non-zero,
add the header; else don't add the header". Just add the header with
the value, or with a concatenated set of values, and let the reading
side decide how to interpret it.

So: putting all that back in to what you seem to want to do...

* do use a map to read $upstream_http_x_secured_page and to set
$your_variable to non-blank and non-zero only when the $upstream_
variable is true

* do use a proxy_no_cache which includes $your_variable

* do not read $your_variable anywhere early -- such as in a
proxy_cache_bypass directive, or anywhere within an if() block --
because it is unnecessary, and it will break things

* do make sure your proxy_cache is empty of things that you now newly
want to "proxy_no_cache", before you start

And if you have any behaviour you do not want or do not understand, it is
very helpful if you can show the exact config that shows that behaviour,
so that someone else can reproduce it without having to guess what you
might have meant. Ideally, a test config will have a few tens of lines,
with most of the unnecessary parts removed and with all of the private
details replaced with information that was tested and works on something
like "localhost".

copy-paste is better than re-type.

Good luck with it,

Francis Daly        francis at

More information about the nginx mailing list