Jorge Henriquez
Jorge Henriquez

Reputation: 13

Browser gives me http status code 200, whereas curl gives me status code 301

When I fill out the form on a site and examine it using the Chrome Dev Tools I get the following information:

Response Headers:
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Status: 200 OK

Request Headers:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 53
Content-Type: application/x-www-form-urlencoded
DNT: 1
Host: www.32x8.com
Origin: http://www.32x8.com

Form Data:
in0: 0
calctype: pos
in1: 1
in2: 1
in3: 0
drawtype: htmlcss

This works perfectly fine in the browser but when I issue the following curl request:

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "in0=1&calctype=pos&in1=1&in2=1&in3=0&drawtype=htmlcss" -v http://www.32x8.com/circuits2

I get this output:

...
* Connected to www.32x8.com (2605:de00:1:1:4a:3c:0:42) port 80 (#0)
> POST /circuits2 HTTP/1.1
> Host: www.32x8.com

< Server: nginx
< Status: 301 Moved Permanently
< Location: http://www.32x8.com/var2.html
...

I get a 301 response. So I tried adding the -L flag to the command to follow any redirects

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "in0=1&calctype=pos&in1=1&in2=1&in3=0&drawtype=htmlcss" -L -v http://www.32x8.com/circuits2

But that just gets me this output

...
> POST /circuits2 HTTP/1.1
> Host: www.32x8.com
> User-Agent: curl/7.52.1
> Accept: */*
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 53
>
* upload completely sent off: 53 out of 53 bytes
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Wed, 01 May 2019 19:54:49 GMT
< Content-Type: text/html;charset=utf-8
< Content-Length: 0
< Connection: keep-alive
< Status: 301 Moved Permanently
...
* Switch from POST to GET
...
> POST /var2.html HTTP/1.1
> Host: www.32x8.com
> User-Agent: curl/7.52.1
> Accept: */*
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 405 Not Allowed
< Server: nginx
< Date: Wed, 01 May 2019 19:54:49 GMT
< Content-Type: text/html
< Content-Length: 173
< Connection: keep-alive
...

I get a 405. What am I doing wrong?

Upvotes: 1

Views: 1648

Answers (2)

Dan Rosenstark
Dan Rosenstark

Reputation: 69787

This is totally random, but the same thing happened to me today and the response was to switch Cloudflare's SSL from Flexible to Full. This was after quite some DNS and SSL changing. But yeah, same thing: curl failed with a 301 and browser gets 200s. Weird DNS trickery!

Upvotes: 0

user9613905
user9613905

Reputation:

You're not really doing anything wrong, as such, but you're experiencing a quirk of HTTP that dates from years ago and is maintained by cURL for compatibiity reasons.

You're making a POST request to your server, to which the server is responding with a 301 redirect message. When you ask cURL to follow the redirection it does so, but changes the POST to a GET. This is behaviour inherited from generations of browsers past (I don't understand the logic here). Your server then rejects the GET request as Not Allowed.

You have two possible solutions: a 301 message indicates a permanent redirect, so just use the new address (you should probably do this anyway)

Or, in your own code detect the 301 message and follow the redirection yourself so that you can issue the proper POST command. This might mean you need a shell script rather than just cURL.

Upvotes: 2

Related Questions