Hacker News new | ask | show | jobs
by jmholla 247 days ago
Here's the article in question. [0] I think runxiyu is correct.

The author delves a bit more into the issue.

> One of most obvious problems is that if you also tell curl to follow HTTP redirects (using -L or --location), the -X option will also be used on the redirected-to requests which may not at all be what the server asks for and the user expected. Dropping the -X will make curl adhere to what the server asks for. And if you want to alter what method to use in a redirect, curl already have dedicated options for that named --post301, --post302 and --post303!

Per the man page (`man 1 curl`),

> 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 does not change request method according to the HTTP 30x response codes - and similar.

`-d` and `--data` will appropriately change the headers of their requests. Funnily, `--post301` and `--post302` which have a similar effect as `-X POST` are RFC 7231 compliant, browsers just don't do that. [2][3] This is so ubiquitous that the error codes 307 and 308 were added to support the original behavior of repeating the request verbatim at the target address. Compare the following:

    > nc -l -p 8080 -q 1 <<< $'HTTP/1.1 301 Moved Permanently\nLocation: http://localhost:8081\n\n' & nc -l -p 8081 -q 1 <<< $'HTTP/1.1 200 OK\nContent-Length: 0\n\n' & curl -L --data test localhost:8080; wait
    > nc -l -p 8080 -q 1 <<< $'HTTP/1.1 301 Moved Permanently\nLocation: http://localhost:8081\n\n' & nc -l -p 8081 -q 1 <<< $'HTTP/1.1 200 OK\nContent-Length: 0\n\n' & curl -X POST -L --data test localhost:8080; wait
    > nc -l -p 8080 -q 1 <<< $'HTTP/1.1 308 Permanent Redirect\nLocation: http://localhost:8081\n\n' & nc -l -p 8081 -q 1 <<< $'HTTP/1.1 200 OK\nContent-Length: 0\n\n' & curl -L --data test localhost:8080; wait
What happens here:

1. In the 301 case with just `--data`, the request turns into a GET request when sent to the redirect.

2. In the 301 case with `-X POST`, the request stays a `POST` request, but doesn't send any data to the redirect.

3. Finally, in the case where the server returns a 308, we see the POST request is kept and the data is resent.

To further expand slightly on a different thing that might surprise some people, the data options will automatically set the content type by adding the header, `Content-Type: application/x-www-form-urlencoded`, as if sending form data from a browser. This behvaior can be overridden with a manual `-H`, `--header` argument (e.g., `-H 'Content-Type: application/json`).

Edit: cube00 pointed out that newer versions of curl than mine have `--json` which will do that automatically. [4]

[0]: https://daniel.haxx.se/blog/2015/09/11/unnecessary-use-of-cu...

[1]: https://www.rfc-editor.org/rfc/rfc7231

[2]: https://evertpot.com/http/301-moved-permanently

[3]: https://evertpot.com/http/302-found

[4]: https://news.ycombinator.com/item?id=45655409