# Nginx https rewrite turns POST to GET

**URL:** <https://www.ruby-forum.com/t/nginx-https-rewrite-turns-post-to-get/223402>\
**Category:** NGINX\
**Created:** [October 2, 2012, 10:44pm UTC](https://www.ruby-forum.com/t/nginx-https-rewrite-turns-post-to-get/223402 "2012-10-02T22:44:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [October 2, 2012, 10:44pm UTC](https://www.ruby-forum.com/t/nginx-https-rewrite-turns-post-to-get/223402/1 "2012-10-02T22:44:28Z")

</div>

My proxy server runs on ip A and this is how people access my web  
service.  
The nginx configuration will redirect to a virtual machine on ip B.

For the proxy server on IP A, I have this in my sites-available

server {  
listen 443;  
ssl on;  
ssl\_certificate nginx.pem;  
ssl\_certificate\_key nginx.key;

```
    client_max_body_size 200M;
    server_name localhost 127.0.0.1;
    server_name_in_redirect off;

    location / {
            proxy_pass http://10.10.0.59:80;
            proxy_redirect http://10.10.0.59:80/ /;

            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;  
}

}

server {  
listen 80;  
rewrite ^(.\*) https://$http\_host$1 permanent;  
server\_name localhost 127.0.0.1;  
server\_name\_in\_redirect off;  
location / {  
proxy\_pass [http://10.10.0.59:80](http://10.10.0.59:80);  
proxy\_redirect [http://10.10.0.59:80/](http://10.10.0.59:80/) /;  
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;  
}  
}

The proxy\_redirect was taken from how do I get nginx to forward HTTP  
POST  
requests via rewrite?

Everything that hits the public IP will hit 443 because of the rewrite.  
Internally, we are forwarding to 80 on the virtual machine.

But when I run a python script such as the one below to test our  
configuration

import requests

data = {‘username’: ‘…’, ‘password’: ‘…’}  
url = ‘http://IP\_A/api/service/signup’

res = requests.post(url, data=data, verify=False)  
print res  
print res.json  
print res.status\_code  
print res.headers

I am getting a 405 Method Not Allowed. In nginx we found that when it  
hit  
the internal server, the internal nginx was getting a GET request, even  
though in the original header we did a POST (this was shown in the  
Python  
script).

So it seems like rewrite has problem. Any idea how to fix this? When I  
commented out the rewrite, it hits 80 for sure, and it went through.  
Since  
rewrite was able to talk to our internal server, so rewrite itself has  
no  
issue. It’s just the rewrite dropped POST to GET.

Thank you!Nginx rewrittes to https makes POST becomes GET

Posted at Nginx Forum:

> **[Nginx https rewrite turns POST to GET](https://forum.nginx.org/read.php?2,231339,231339#msg-231339)**
>
> My proxy server runs on ip A and this is how people access my web service. The nginx configuration will redirect to a virtual machine on ip B. For the proxy server on IP A, I have this in my sites-available server { listen 443; ssl on;

---

<div class="post-metadata">

**Author:** ![jwxie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ac91a4/32.png) [@jwxie](https://www.ruby-forum.com/u/jwxie)\
**Post date:** [October 2, 2012, 11:10pm UTC](https://www.ruby-forum.com/t/nginx-https-rewrite-turns-post-to-get/223402/2 "2012-10-02T23:10:12Z")

</div>

On Oct 2, 2012 9:44 PM, “jwxie” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> ssl_certificate_key nginx.key;
> proxy_set_header X-Real-IP $remote_addr;
> server_name_in_redirect off;
> 
> ```
> 
> The proxy\_redirect was taken from how do I get nginx to forward HTTP POST  
> data = {‘username’: ‘…’, ‘password’: ‘…’}  
> though in the original header we did a POST (this was shown in the Python  
> script).
> 
> So it seems like rewrite has problem.

Rewrite has no problem. It doesn’t dictate a verb that the client should  
use. The user-agent you’re using is choosing to do this, possibly  
correctly, upon receipt of the 301 response.

Have a read of the 301, 302, 303, 307 and 308 sections here for more  
information:

> **[List of HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection)**
>
> This article lists standard and notable non-standard HTTP response status codes. Standardized codes are defined by IETF as documented in Request for Comments (RFC) publications and maintained by the IANA. Other, non-standard values are used by various servers. The descriptive text after the numeric code – the reason phrase – is shown here with typical value, but in practice, can be different or omitted. Status codes defined by IETF are listed below. Emphasized terms must, must not and should ...

Your options appear to be to use an experimental response code, or to  
enforce that clients POST to the correct port. I’d choose the latter if  
at  
all possible.

Jonathan

---

<div class="post-metadata">

**Author:** ![jwxie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ac91a4/32.png) [@jwxie](https://www.ruby-forum.com/u/jwxie)\
**Post date:** [October 2, 2012, 11:14pm UTC](https://www.ruby-forum.com/t/nginx-https-rewrite-turns-post-to-get/223402/3 "2012-10-02T23:14:17Z")

</div>

Hi Jonathan  
Thanks for helping! It’s a critical blocker.

I understand the HTTP spec there. To make it short, how do I enforce  
that  
client to POST (an eventually PUT, DELETE, GET, ) correctly?

I mean this is not a custom situation. Pretty sure many production  
servers  
are running in a similar config (user hits a public ip on 443 and then  
redirects to an internal server).

If you are interested, without the first layer (the public proxy), and  
use  
the same configuration directly inside the internal server, and running  
the  
communication directly to that server will be fine. In other words, make  
that server public will be fine even with rewrite rule.

Posted at Nginx Forum:

> **[Re: Nginx https rewrite turns POST to GET](https://forum.nginx.org/read.php?2,231339,231341#msg-231341)**
>
> My proxy server runs on ip A and this is how people access my web service. The nginx configuration will redirect to a virtual machine on ip B. For the proxy server on IP A, I have this in my sites-available server { listen 443; ssl on;

---

<div class="post-metadata">

**Author:** ![jwxie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ac91a4/32.png) [@jwxie](https://www.ruby-forum.com/u/jwxie)\
**Post date:** [October 3, 2012, 12:08am UTC](https://www.ruby-forum.com/t/nginx-https-rewrite-turns-post-to-get/223402/4 "2012-10-03T00:08:02Z")

</div>

I figured I was very wrong from the beginning. If a user hits http it  
would  
be a GET by nature and hence forced to redirect to a viewable page that  
runs  
on HTTPS. You are right.  
My script would work in the test machine only because I did something  
special.

Ah. Thanks Forget about this 😛

Posted at Nginx Forum:

> **[Re: Nginx https rewrite turns POST to GET](https://forum.nginx.org/read.php?2,231339,231342#msg-231342)**
>
> My proxy server runs on ip A and this is how people access my web service. The nginx configuration will redirect to a virtual machine on ip B. For the proxy server on IP A, I have this in my sites-available server { listen 443; ssl on;
