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.