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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With