nginxnginx-reverse-proxynginx-confignginx-location

Nginx doesn't forward response headers


I have a .Net 6 application that for the following request returns a response as below. Please note there is a Access-Control-Allow-Origin present:

$ curl -i http://localhost:5081/Artworks/IMG_9346m.jpg -H "origin:https://m.beatajakimiak.art.pl" -H "referer:https://m.beatajakimiak.art.pl/" -o /dev/null -v
*   Trying 127.0.0.1:5081...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to localhost (127.0.0.1) port 5081 (#0)
> GET /Artworks/IMG_9346m.jpg HTTP/1.1
> Host: localhost:5081
> User-Agent: curl/7.81.0
> Accept: */*
> origin:https://m.beatajakimiak.art.pl
> referer:https://m.beatajakimiak.art.pl/
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 465767
< Content-Type: image/jpeg
< Date: Thu, 24 Aug 2023 20:23:16 GMT
< Server: Kestrel
< Accept-Ranges: bytes
< Access-Control-Allow-Origin: https://m.beatajakimiak.art.pl
< ETag: "1d837e79f7d7b67"
< Last-Modified: Mon, 14 Mar 2022 21:08:16 GMT
< Vary: Origin
<
{ [16384 bytes data]
100  454k  100  454k    0     0  39.8M      0 --:--:-- --:--:-- --:--:-- 40.3M
* Connection #0 to host localhost left intact

I even opened the 5081 port on the machine hosting nginx and this website for a while and called it directly. The Access-Control-Allow-Origin was there. CORS requests worked fine. I could see the header in chrome dev tools in response headers.

I have Nginx proxy configured for it as below:

server {
    server_name beatajakimiak.art.pl www.beatajakimiak.art.pl;

    include /etc/nginx/snippets/global.conf;
    include /etc/nginx/snippets/global_images_cache.conf;

    #access_log /var/log/nginx/beatajakimiak_art_pl/access.log;
    error_log  /var/log/nginx/beatajakimiak_art_pl/error.log;

    root /srv/www/beatajakimiakwebsite/wwwroot;

    location / {
        proxy_pass         http://localhost:5081;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    listen [::]:443 ssl http2; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ... SSL CONFIGURATION ...
}

global.conf looks like that:

location = /favicon.ico {
    log_not_found off;
    access_log off;
}

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

location ~ /\. {
    deny all;
}

location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

location ~ /\.ht {
    deny all;
}

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";

And global_images_cache.conf looks like that:

location ~* \.(?:jpg|jpeg|gif|png|ico|woff2)$ {
    expires 1M;
    add_header Cache-Control "public";
}

Now, with this config if I call my website with same curl I'm not getting the Access-Control-Allow-Origin header in my response. I tried with other custom headers and they are not forwarded to the response neither:

$ curl -i https://beatajakimiak.art.pl/Artworks/IMG_9346m.jpg -H "origin:https://m.beatajakimiak.art.pl" -H "referer:https://m.beatajakimiak.art.pl/" -o /dev/null -v
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 83.11.166.97:443...
[... TLS ...]
> GET /Artworks/IMG_9346m.jpg HTTP/2
> Host: beatajakimiak.art.pl
> user-agent: curl/7.81.0
> accept: */*
> origin:https://m.beatajakimiak.art.pl
> referer:https://m.beatajakimiak.art.pl/
>
[... TLS ...]
< HTTP/2 200
< server: nginx/1.18.0 (Ubuntu)
< date: Thu, 24 Aug 2023 20:24:08 GMT
< content-type: image/jpeg
< content-length: 465767
< last-modified: Mon, 14 Mar 2022 21:08:16 GMT
< etag: "622faec0-71b67"
< expires: Sat, 23 Sep 2023 20:24:08 GMT
< cache-control: max-age=2592000
< cache-control: public
< accept-ranges: bytes
<
[... TLS ...]
100  454k  100  454k    0     0  7416k      0 --:--:-- --:--:-- --:--:-- 7456k
* Connection #0 to host beatajakimiak.art.pl left intact

What's wrong with my config that it hides response headers?


Solution

  • I finally found it. The default nginx global_images_cache.conf snippet that I add to every single website I have was handling requests for static jpg files instead of the proxied website.

    Excluding global_images_cache.conf from website's nginx config fixed my issue.