[SOLVED] grpc-web behind double nginx

Issue

This Content is from Stack Overflow. Question asked by Daniël van den Berg

I’ve got grpc-web running in react. This communicates through NGINX. This NGINX communicates with a different NGINX server, running in docker, which communicates with my rust tonic http1 server.

With one NGINX server the following config worked:

        location /my.EndPoint/ {
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,content-type,snet-current-block-number,snet-free-call-user-id,snet-payment-channel-signature-bin,snet-payment-type,x-grpc-web';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            proxy_pass http://hostname:50051/my.EndPoint/;
        }

When I put another NGINX in front with the following config:

  location / {
    proxy_pass http://192.168.0.xxx:81;
    client_max_body_size 5G;
  }

it stops working. I don’t get any data back. The server does receive the request, but after that the request does not come back to grpc-web.

How do I route grpc-web through two instances of NGINX?



Solution

It seems that NGINX uses the content-length header as returned.

What does seem to work is removing the content-length header where it originally was, and adding it only to the front-most server like such:

  location / {
    if ($content_type ~ 'application\/grpc(?!-web)(.*)'){
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,content-type,snet-current-block-number,snet-free-call-user-id,snet-payment-channel-signature-bin,snet-payment-type,x-grpc-web';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
    }
    proxy_pass http://192.168.0.xxx:81;
    client_max_body_size 5G;
  }


This Question was asked in StackOverflow by Daniël van den Berg and Answered by Daniël van den Berg It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?