add header to response in nginx location directive

teddy picture teddy · May 15, 2017 · Viewed 10.3k times · Source

I try to add a response header to only one location path served and have an nginx config looks like

server {
    ...
    add_header x-test test;
    location /my.img {
        rewrite ^/my.img$ /119.img;
        add_header x-amz-meta-sig 1234567890abcdef;
    }
}

But only the top-level header (x-test) is effective, the one within the location directive does not show up as shown in

$ curl -v -o /tmp/test.img 'https://www.example.com/my.img'
< HTTP/1.1 200 OK
< Server: nginx/1.9.3 (Ubuntu)
< Date: Sun, 14 May 2017 23:58:08 GMT
< Content-Type: application/octet-stream
< Content-Length: 251656
< Last-Modified: Fri, 03 Mar 2017 04:57:47 GMT
< Connection: keep-alive
< ETag: "58b8f7cb-3d708"
< x-test: test
< Accept-Ranges: bytes
< 
{ [16104 bytes data]

How to send back a custom headrr only for the specific file served.

Answer

Richard Smith picture Richard Smith · May 15, 2017

The rewrite statement is an implicit rewrite...last, which means that the final URI /119.img is not processed by this location block. By the time the response headers are being calculated, nginx is in a different location block.

You could try processing the final URI from within the same location block, by using a rewrite...break statement. See this document for details.

location = /my.img {
    root /path/to/file;
    rewrite ^ /119.img break;
    add_header x-amz-meta-sig 1234567890abcdef;
}

If the location is intended to match only one URI, use the = format. See this document for details.

Note also that the presence of an add_header statement in this location block, will mean that the outer statement will no longer be inherited. See this document for details. :