1

Context

I use Docker to deploy my Rails application with an nginx container as my front HTTP server.

I configured rack-cors in Rails to send CORS headers for some URLs.

My application is available using 2 different domains using HTTPS, configured in nginx as 2 different server configurations. This first one configured as the default_server.

Internal communications between nginx and Rails are using HTTP. HTTPS is only configured in nginx.

To be clear, what I mean by CORS headers are:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Expose-Headers
  • Access-Control-Max-Age

I am using rack-cors 1.0.2 and nginx 1.16.0.

I created a Gist with my nginx configuration.

Problem

When using the 2nd domain using HTTPS, my CORS headers set by rack-cors are removed by nginx.

I know they are removed because I monitored multiple things:

  • I put rack-cors in debug mode and it correctly outputs the CORS headers in Rails logs.
  • I performed the query directly to Rails from within the nginx container and the response contained the CORS headers.
  • I monitored the query/response made by nginx to Rails using tcpdump and the response contained the CORS headers.

But the response made by nginx to the end user does not contain the CORS headers.

All this time, responses sent for the first domain are OK and contain the CORS headers.

Questions

  • Why is nginx removing those headers from the upstream response?
  • How can I monitor this behavior in nginx?
  • How can I prevent nginx from rewriting these response?

Thanks

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Vincent Robert
  • 35,564
  • 14
  • 82
  • 119
  • What is the nginx configs? – Pavel Mikhailyuk Jul 17 '19 at 12:45
  • @PavelMikhailyuk Here is a gist with my config files: https://gist.github.com/genezys/5c2ae32bfe6e454dc380c196fb543951 – Vincent Robert Jul 17 '19 at 13:40
  • 1
    Is it only specifically those Access-Control-\* headers that are getting dropped? Or are other headers that are being set on the Rails upstream side also getting dropped? – sideshowbarker Jul 17 '19 at 14:40
  • 1
    It appears that all headers are dropped. Further investigations show that it has something to do with `X-Accel-Redirect`. When I trigger an `internal` location, the headers are dropped and nginx seems to be using its own set of headers based on the file sent. – Vincent Robert Jul 17 '19 at 17:34
  • 3
    The answer at https://stackoverflow.com/a/24509358/441757 seems possibly relevant: *Since `X-Accel-Redirect` causes internal redirect nginx will not send returned headers, but it will keep them in [`$upstream_http_...`](http://nginx.org/r/$upstream_http_) variables.* Or maybe the answer at https://serverfault.com/a/957377/306824: *You should make sure you pass the request headers from the browser onward to S3 with `proxy_pass_request_headers on;` in the `location`. Further, you probably should not have `internal` defined for that `location`.* – sideshowbarker Jul 18 '19 at 05:39

1 Answers1

0

My site.conf

server {
  listen 80;
  server_name localhost;
  sendfile on;

  access_log /var/log/nginx/site.log;

  location /folderWithFiles/ {
        internal;
    set $access_control_expose_headers $upstream_http_access_control_expose_headers;
    set $access_control_allow_origin $upstream_http_access_control_allow_origin;
    set $access_control_allow_credentials $upstream_http_access_control_allow_credentials;
    set $access_control_allow_methods $upstream_http_access_control_allow_methods;
    set $access_control_allow_headers $upstream_http_access_control_allow_headers;

    add_header Access-Control-Expose-Headers $access_control_expose_headers;
    add_header Access-Control-Allow-Origin $access_control_allow_origin;
    add_header Access-Control-Allow-Credentials $access_control_allow_credentials;
    add_header Access-Control-Allow-Methods $access_control_allow_methods;
    add_header Access-Control-Allow-Headers $access_control_allow_headers;

    root /home/ilya/Projects/site/uploads/; 
    #result path /home/ilya/Projects/site/uploads/folderWithFiles/
  }

  location / {
    proxy_pass http://localhost:5252/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}