Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

curl uses POST for all requests after redirect

According to the documentation and some similar questions on SO curl should follow a redirect using GET method, unless --post30x is specified as a parameter. However that's the result of my testing

curl -kvv -b /tmp/tmp.BEo6w3GKDq -c /tmp/tmp.BEo6w3GKDq -X POST -H "Accept: application/json" -L https://localhost/api/v1/resource

> POST /api/v1/resource HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Cookie: JSESSIONIDSSO=AB59F2FD09D38EDBAACB726CF212EA2E; JSESSIONID=743FD68B520840094B6D283A81CF3CFA
> Accept: application/json
> 
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1    
< Strict-Transport-Security: max-age=15768000; includeSubDomains
< Cache-control: no-cache, no-store
< Pragma: no-cache
< Location: https://testserver.int/api/v1/resource
< Content-Length: 0
< Date: Fri, 27 Jan 2017 08:41:05 GMT
<
> POST /api/v1/resource HTTP/1.1
> User-Agent: curl/7.29.0
> Host: testserver.int
> Cookie: JSESSIONID=1tcxpkul4qyqh1hycpf9insei9
> Accept: application/json

I would expect the second request to actually be using GET instead of POST.

curl's man page says:

When curl follows a redirect and the request is not a plain GET (for example POST or PUT), it will do the following request with a GET if the HTTP response was 301, 302, or 303. If the response code was any other 3xx code, curl will re-send the following request using the same unmodified method.

You can tell curl to not change the non-GET request method to GET after a 30x response by using the dedicated options for that: --post301, --post302 and --post303.

Unfortunatelly that's not what I'm seeing and there is no option for --get30x.

So my question is - how to make curl follow a redirect response (301/302/303) with a GET request to the Location as it is written in the documentation?

I've tested it with curl/7.29.0 as well as curl/7.50.3.

like image 392
Makpoc Avatar asked Jan 27 '17 09:01

Makpoc


People also ask

Does curl automatically follow redirects?

By default, Curl does not follow redirects and displays the content of the 300x page (if any). To follow redirects with Curl, you need to use the -L or --location command-line option.

Do not follow redirects curl?

In curl's tradition of only doing the basics unless you tell it differently, it does not follow HTTP redirects by default. Use the -L, --location option to tell it to do that. When following redirects is enabled, curl will follow up to 50 redirects by default.

Can POST requests redirect?

in response to a POST request. Rather, the RFC simply states that the browser should alert the user and present an option to proceed or to cancel without reposting data to the new location. Unless you write complex server code, you can't force POST redirection and preserve posted data.

What is curl request D?

The -d or --data option makes the curl command send data in POST request to the server. This option makes the curl command pass data to the server using content-type (JSON in your case) just as the browser does when a user submits a form.


1 Answers

Problem: You are telling curl to do that with your use of -X POST. As the man page section for -X explains this:

The method string you set with -X, --request will be used for all requests, which
if you for example use -L, --location may cause unintended side-effects when curl
doesn't change request method according to the HTTP 30x response codes - and
similar.

Fix: Remove the -X POST from your command line. Use -d "" instead to send an empty post that will adjust accordingly to the proper method after redirect.

More: Explanation and rant in my blog post unnecessary use of curl -X.

like image 139
Daniel Stenberg Avatar answered Oct 23 '22 13:10

Daniel Stenberg