Using 2 intersection of conditions for proxy_cache_bypass (avoiding logical if/and)

I use nginx to cache both GET and POST requests. I want to use
proxy_cache_bypass to allow users to bypass the cache, but ONLY for
GET requests. POST requests should always be cached. I tried this:

map $request_method $is_get {
default: “”;
GET “true”;
}
proxy_cache_methods POST;
proxy_cache_bypass $http_cache_control $is_get;

However, this bypasses the cache when either $http_cache_control OR
$is_get is set. How can I achieve to set proxy_cache_bypass when both
http_cache_control AND $is_get are set?

Hello,

On Fri, Jan 24, 2014 at 9:45 PM, Jeroen O.
[email protected]wrote:

However, this bypasses the cache when either $http_cache_control OR
$is_get is set. How can I achieve to set proxy_cache_bypass when both
http_cache_control AND $is_get are set?

​The logic you wish imply using a single variable in proxy_cache_bypass
which is set if and only if both $http_cache_control and $_is_get are
set.

Does the following ​work?

map $request_method $is_get {
default: “”;
GET “true”;
}

set $bypass “true”; # Defaults to true

Each map then deactivates the $bypass variable if one

of the variables linked with the AND logic is empty

map $http_cache_control $bypass {
default: “”;
“”: $bypass;
}

map $is_get $bypass {
default: “”;
“”: $bypass;
}

proxy_cache_methods POST;
​​​​​proxy_cache_bypass $bypass;

B. R.

On Fri, Jan 24, 2014 at 1:04 PM, B.R. [email protected] wrote:

Does the following work?

This looks like a fragile solution. You’re basically simulating an
“if”, but I don’t think we should assume that nginx will resolve all
maps in the defined order, as would be using “if”.

The nginx documentation for HttpMapModule says: “The map directive
creates the variable, but only performs the mapping operation when
(and if) the variable is accessed.” In your solution, $bypass is
already set to “true” a-priori, and also defined in two maps. I doubt
nginx will resolve those maps, in the right order, to arrive at the
desired value of $bypass.

Maybe someone from the nginx team can comment if this is a viable
solution?

map $http_cache_control$request_method $no_cache {
default 0;
~^.+GET$ 1;
}

proxy_cache_methods POST;
proxy_cache_bypass $no_cache;
proxy_no_cache $no_cache;

----appa

---------- Forwarded message ----------
From: Jeroen O. [email protected]
Date: Fri, Jan 24, 2014 at 9:45 PM
Subject: Using 2 intersection of conditions for proxy_cache_bypass
(avoiding logical if/and)
To: [email protected]

I use nginx to cache both GET and POST requests. I want to use
proxy_cache_bypass to allow users to bypass the cache, but ONLY for
GET requests. POST requests should always be cached. I tried this:

map $request_method $is_get {
default: “”;
GET “true”;
}
proxy_cache_methods POST;
proxy_cache_bypass $http_cache_control $is_get;

However, this bypasses the cache when either $http_cache_control OR
$is_get is set. How can I achieve to set proxy_cache_bypass when both
http_cache_control AND $is_get are set?

Hello,

On Sat, Jan 25, 2014 at 3:40 AM, Jeroen O.
[email protected]wrote:

This looks like a fragile solution. You’re basically simulating an
“if”, but I don’t think we should assume that nginx will resolve all
maps in the defined order, as would be using “if”.

snip

Maybe someone from the nginx team can comment if this is a viable solution?

​You explicited clearly you wanted to avoid if/and logic in your message
subject (one could wonder why since there appears to be no other trivial
solution)…
In the end, since proxy_cache_bypass doc clearly state that it works
based
on an OR logic, what you wish won’t happen magically.

With those ​conditions set, I hardly see something that won’t look
edgy…

​Maybe someone else could help you better.​
Good luck,

B. R.

You can chain two maps to get a logical and:

map $request_method $is_get {
default 0;
GET 1;
}

map $http_cache_bypass $bypass_cache {
default $is_get;
“” 0;
}

proxy_cache_methods POST;
proxy_cache_bypass $bypass_cache;

note the lack of : after default in the maps, it’s incorrect to have

it
there like your original map did

On Sat, Jan 25, 2014 at 5:24 AM, Jonathan K. [email protected]
wrote:

You can chain two maps to get a logical and:

Thank you, this is precisely what I needed.

note the lack of : after default in the maps, it’s incorrect to have it

there like your original map did

Good catch, thanks. Appreciate it.