27

My iOS app is currently accessing domain A via http POST but I would like to forward all requests to domain B.

If I use the usual rewrite ^/(.*)$ http://mydomain/$1 permanent; the POST data seems to get lost.

How can I pass HTTP POST data to a different domain using NginX?

2 Answers 2

42

Try using the reverse proxy support instead. An example location section would be:

location / {
  proxy_pass      http://localhost:8080;
  proxy_redirect  http://localhost:8080/ /;
  proxy_read_timeout 60s;

  # May not need or want to set Host. Should default to the above hostname.
  proxy_set_header          Host            $host;
  proxy_set_header          X-Real-IP       $remote_addr;
  proxy_set_header          X-Forwarded-For $proxy_add_x_forwarded_for;
}

This example will pass through all requests to this server block to a second server running on localhost:8080. This preserves POST's and should also preserve other request types too if it ever becomes an issue.

The issue is that external redirects will never resend POST data. This is written into the HTTP spec (check the 3xx section). Any client that does do this is violating the spec.

If the 301/302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

I'm fairly sure that most browsers implement this by simply forcing the redirected request to be a GET request. Theoretically, the spec does allow for a browser that would ask the user whether to redirect the POST data, but I'm unaware of any that currently do.

5
  • a little bit confused from comment. Do I generally want to set the proxy_set_header values? Otherwise I guess that remote address becomes the remote address of the proxy server but what I usually want is the remote address of the client, correct? Mar 2, 2014 at 12:24
  • Thanks for the answer that saved me! Is there a way to set up nginx so that it passes post requests correctly back to uwsgi but with sockets instead of running uwsgi in http mode? Apr 9, 2015 at 1:11
  • @GregJennings A little late for a reply, but one would use the 'uwsgi_pass' directive instead of 'proxy_pass'. Just in case someone else wanders by looking...
    – Kamilion
    Apr 16, 2019 at 18:43
  • I'm curious about proxy_redirect http://localhost:8080/ / Why the second individual /? What impact does that have?
    – Will
    Aug 7, 2019 at 10:14
  • 1
    @Will proxy_redirect takes two arguments. See the docs: nginx.org/en/docs/http/… Aug 19, 2019 at 10:07
0

You can also achieve this in Nginx but using the mirror plugin not rewrite:

location "/post/uri/to/redirect/" {                                        
    mirror "/mirror";                                                       
    mirror_request_body on;                                                 
    return 200;                                                             
}                                                                           

location = "/mirror" {                                                      
    internal;                                                               
    proxy_pass "https://target_domain$request_uri";                   
    proxy_set_header Host "target_domain";                            
    proxy_set_header X-Original-URI $request_uri;                           
    proxy_set_header X-SERVER-PORT $server_port;                            
    proxy_set_header X-SERVER-ADDR $server_addr;                            
    proxy_set_header X-REAL-IP $remote_addr;                                
}                                                                           

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .