Welcome! Log In Create A New Profile

Advanced

Overridable header values (with map?)

Brandon Mintern
November 30, 2017 12:30AM
We're using nginx for several different types of servers, but we're trying
to unify the configuration to minimize shared code. One stumbling block is
headers. For most requests, we want to add a set of standard headers:

# headers.conf:

add_header Cache-Control $cache_control;
add_header X-Robots-Tag $robots_tag always;
add_header X-Frame-Options $frame_options;

add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
# several more...

Many of the headers are the same for all requests, but the first three are
tweaked for specific resources or target servers.

The first approach I took was to define two files:

# header-vars.conf:

# Values for the $cache_control header. By default, we use $one_day.
set $no_cache "max-age=0, no-store, no-cache, must-revalidate";
set $one_day "public, max-age=86400";
set $one_year "public, max-age=31536000";
set $cache_control $one_day;

# To allow robots, override this variable using `set $robots_tag all;`.
set $robots_tag "noindex, nofollow, nosnippet, noarchive";
set $frame_options "SAMEORIGIN";


....and the headers.conf above. Then, at appropriate contexts (either a
server or location block), different servers would include the files as
follows:

include header-vars.conf;
include headers.conf;

That would give them all of our defaults. If the specific application or
context needs to tweak the caching and robots, it might do something like
this:

include header-vars.conf;
set $cache_control $no_cache;
set $robots_tag all;
include headers.conf;


This was fine, but I recently came across an interesting use of map
https://serverfault.com/a/598106/405305 that I thought I could generalize
to simplify this pattern. My idea was to do something like:

# header-vars.conf:

map $robots $robots_tag {

# Disallowed
default "noindex, nofollow, nosnippet, noarchive";
off "noindex, nofollow, nosnippet, noarchive";

# Allowed
on all;
}

map $frames $frame_options {

# Allow in frames only on from the same origin (URL).
default "SAMEORIGIN";

# This isn't a real value, but it will cause the header to be ignored.
allow "ALLOW";
}

map $cache $cache_control {

# no caching
off "max-age=0, no-store, no-cache, must-revalidate";

# one day
default "public, max-age=86400";
1d "public, max-age=86400";

# one year
1y "public, max-age=31536000";
}


I thought this would allow me to include both header-vars.conf and
headers.conf in the http block. Then, within the server or location blocks,
I wouldn't have to do anything to get the defaults. Or, to tweak robots and
caching:

set $cache off;
set $robots on;

Since the variables wouldn't be evaluated till the headers were actually
added, I thought this would work well and simplify things a lot.
Unfortunately, I was mistaken that I would be able to use an undefined
variable in the first position of a map directive (I thought it would just
be empty):

unknown "robots" variable

Of course, I can't set a default value for that variable since I'm
including header-vars.conf at the http level. I'd rather not need to
include defaults in every server (there are many).

Does anyone have any suggestions for how I can better solve this problem?

Thanks!
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Subject Author Posted

Overridable header values (with map?)

Brandon Mintern November 30, 2017 12:30AM

Re: Overridable header values (with map?)

Maxim Dounin November 30, 2017 09:46AM

Re: Overridable header values (with map?)

Brandon Mintern November 30, 2017 01:16PM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 239
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready