<div dir="ltr">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:<div><br></div><div># headers.conf:<br><div><br></div><div>add_header Cache-Control $cache_control;</div><div>add_header X-Robots-Tag $robots_tag always;</div><div>add_header X-Frame-Options $frame_options;<br></div><div><br></div><div><div>add_header X-XSS-Protection "1; mode=block";</div><div>add_header X-Content-Type-Options nosniff;</div></div><div># several more...</div><div><br></div><div>Many of the headers are the same for all requests, but the first three are tweaked for specific resources or target servers.</div><div><br></div><div>The first approach I took was to define two files:</div><div><br></div><div># header-vars.conf:</div></div><div><br></div><div><div># Values for the $cache_control header. By default, we use $one_day.</div><div>set $no_cache "max-age=0, no-store, no-cache, must-revalidate";</div><div>set $one_day  "public, max-age=86400";</div><div>set $one_year "public, max-age=31536000";</div><div>set $cache_control $one_day;</div></div><div><br></div><div># To allow robots, override this variable using `set $robots_tag all;`.</div><div>set $robots_tag "noindex, nofollow, nosnippet, noarchive";<br></div><div>set $frame_options "SAMEORIGIN";<br></div><div><br></div><div><br></div><div>...and the headers.conf above. Then, at appropriate contexts (either a server or location block), different servers would include the files as follows:</div><div><br></div><div>include header-vars.conf;</div><div>include headers.conf;</div><div><br></div><div>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:</div><div><br></div><div>include header-vars.conf;</div><div>set $cache_control $no_cache;</div><div>set $robots_tag all;</div><div>include headers.conf;</div><div><br></div><div><br></div><div>This was fine, but I recently came across <a href="https://serverfault.com/a/598106/405305">an interesting use of map</a> that I thought I could generalize to simplify this pattern. My idea was to do something like:</div><div><br></div><div># header-vars.conf:</div><div><br></div><div><div>map $robots $robots_tag {</div><div><br></div><div>    # Disallowed</div><div>    default "noindex, nofollow, nosnippet, noarchive";</div><div>    off     "noindex, nofollow, nosnippet, noarchive";</div><div><br></div><div>    # Allowed</div><div>    on      all;</div><div>}</div></div><div><br></div><div><div>map $frames $frame_options {</div><div><br></div><div>    # Allow in frames only on from the same origin (URL).</div><div>    default "SAMEORIGIN";</div><div><br></div><div>    # This isn't a real value, but it will cause the header to be ignored.</div><div>    allow   "ALLOW";</div><div>}</div></div><div><br></div><div><div>map $cache $cache_control {</div><div><br></div><div>    # no caching</div><div>    off     "max-age=0, no-store, no-cache, must-revalidate";</div><div><br></div><div>    # one day</div><div>    default "public, max-age=86400";</div><div>    1d      "public, max-age=86400";</div><div><br></div><div>    # one year</div><div>    1y      "public, max-age=31536000";</div><div>}</div></div><div><br></div><div><br></div><div>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:</div><div><br></div><div>set $cache off;</div><div>set $robots on;</div><div><br></div><div>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):</div><div><br></div><div>unknown "robots" variable<br></div><div><br></div><div>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).</div><div><br></div><div>Does anyone have any suggestions for how I can better solve this problem?</div><div><br></div><div>Thanks!</div></div>