Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add headers in nginx only sometimes

I have a nginx proxy to a API server. The API sometimes sets the cache control header. If the API hasnt set the cache control I want nginx to override it.

How do I do that?

I think I want to do something like this, but it doesnt work.

location /api {
  if ($sent_http_cache_control !~* "max-age=90") {
    add_header Cache-Control no-store;
    add_header Cache-Control no-cache;
    add_header Cache-Control private;
  }
  proxy_pass $apiPath;
}
like image 347
Stephen Avatar asked Jun 24 '15 04:06

Stephen


People also ask

Where do I put headers in nginx?

To enable the X-Frame-Options header in Nginx, add the following line in your Nginx web server default configuration file /etc/nginx/sites-enabled/example. conf: add_header X-Frame-Options "SAMEORIGIN"; Next, restart the Nginx service to apply the changes.

Does nginx pass headers?

Passing Request Headers By default, NGINX redefines two header fields in proxied requests, “Host” and “Connection”, and eliminates the header fields whose values are empty strings.

How do I add cache control headers in nginx?

If you want to enable Cache-Control for all files, add a add_header line without the enclosing location block, as what the location block does is specify specific filetypes you are targeting with your directives (ico,pdf,flv etc.).

What are Nginx headers?

The HTTP headers in NGINX are split in two parts: the input request headers (headers_in structure) and the output request headers (headers_out structure). There is no such an entity as a response, all the data is stored in the same single request structure.


2 Answers

You cannot use if here, because if, being a part of the rewrite module, is evaluated at a very early stage of the request processing, way before proxy_pass is called and the header is returned from the upstream server.

One way to solve your problem is to use map directive. Variables defined with map are evaluated only when they are used, which is exactly what you need here. Sketchily, your configuration in this case would look like this:

# When the $custom_cache_control variable is being addressed
# look up the value of the Cache-Control header held in
# the $upstream_http_cache_control variable
map $upstream_http_cache_control $custom_cache_control {

    # Set the $custom_cache_control variable with the original
    # response header from the upstream server if it consists
    # of at least one character (. is a regular expression)
    "~."          $upstream_http_cache_control;

    # Otherwise set it with this value
    default       "no-store, no-cache, private";
}

server {
    ...
    location /api {
        proxy_pass $apiPath;

        # Prevent sending the original response header to the client
        # in order to avoid unnecessary duplication
        proxy_hide_header Cache-Control;

        # Evaluate and send the right header
        add_header Cache-Control $custom_cache_control;
    }
    ...
}
like image 107
Ivan Tsirulev Avatar answered Oct 24 '22 02:10

Ivan Tsirulev


Awswer from Ivan Tsirulev is correct but you don't have to use regex.

Nginx uses the first parameter of map as default value automatically so you don't have to add that either.

# Get value from Http-Cache-Control header but override it when it's empty
map $upstream_http_cache_control $custom_cache_control {
    '' "no-store, no-cache, private";
}

server {
    ...
    location /api {
        # Use the value from map
        add_header Cache-Control $custom_cache_control;
    }
    ...
}
like image 26
onnimonni Avatar answered Oct 24 '22 01:10

onnimonni