JoshuaJ
JoshuaJ

Reputation: 979

Nginx proxy_pass missing error body

Below is a pretty standard nginx proxy_pass setup:

server {
  listen 80;
  server_name ireport.jungdigital.com;
  access_log /var/log/nginx/ireport.access.log;
  root /var/www/ireport.jungdigital.com/dist;
  index index.html index.htm;
  location / {       
  }
  location /api/ {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
     }
     if ($request_method = 'PUT') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Reques
     }
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header X-NginX-proxy true;
     proxy_set_header Host ireport.somehost.org;
     proxy_pass http://ireport_dyndns/api/;
     proxy_ssl_session_reuse off;
     proxy_redirect off;
  }
}

The API that I'm proxying returns response body's that contain error information for 400, 404, and 500 error codes. For example, on a 404, my response body might look like:

{
  "errorCode": "TOKEN_NOT_FOUND",
  "errorMessages": [
    "Could not find a matching authorization token."
  ]
}

If I perform the request without the proxy, I get the response bodies for the errors.

If I use the nginx proxy, for some reason the response bodies are swallowed by nginx and I can't even see a response at all in my web browser Network tab.

Is there a way to tell Nginx to return response bodies for error codes in a proxy_pass?

Upvotes: 5

Views: 6716

Answers (3)

NorthWind
NorthWind

Reputation: 66

I run into same question recently.

And the last anwser is that: add proxy header Upgrade

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';

My full config as following:

upstream cloud-api {
        server 127.0.0.1:8089;
}

client_max_body_size 20M;
client_header_buffer_size 8k;
large_client_header_buffers 4 16k;

server {
        listen 8001;
        access_log  /data/senseid-cloud-log/senseid-cloud-api-access.log;
        error_log  /data/senseid-cloud-log/senseid-cloud-api-error.log warn;

        location / {
                proxy_http_version 1.1;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';

                proxy_read_timeout 300s;
                proxy_pass http://cloud-api;
        }
}

And you could catch 500/401 .etc error body

Details : http://nginx.org/en/docs/http/websocket.html

Hope to give you some help.

Upvotes: 5

David Tobiano
David Tobiano

Reputation: 1258

See How to add a response header on nginx when using proxy_pass?

  1. Per Alexey's comment - "browsers need headers to allow access to response body. I guess, you need always flag for add_header"
  2. Since nginx 1.7.5 you can use the keyword always to include headers even in error responses - so you can setup your nginx.conf as follow:

-

server {
    server_name  .myserver.com
    location / {
        proxy_pass  http://mybackend;
        add_header X-Upstream $upstream_addr always;
    }
}

Upvotes: 1

xCiCi
xCiCi

Reputation: 177

Today I move Laravel 5.2 from IIS 8.5 to Ubuntu 16.04 (Nginx 1.10.0 - PHP-FPM 7.0.10), I have same problem. The body response from server are always empty when request from Angular2. But the postman still get body on response. So that must be problem with request headers.

This config help me solved problem above:

    add_header 'Access-Control-Allow-Origin' '*' 'always';
    add_header 'Access-Control-Allow-Credentials' 'true' 'always';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, HEAD' 'always';
    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' 'always';

Third parameters for add_header only available in recent nginx version.

Upvotes: 0

Related Questions