How Curl Handles POST to GET Redirects
When using the curl command-line tool to send an HTTP
POST request, encountering a redirect (3xx status code) can alter how
the subsequent request is made. This article explains how
curl handles the conversion of a POST request to a GET
request during a redirect, how different HTTP status codes influence
this behavior, and how you can control these transitions using specific
command-line flags.
Default Redirection Behavior in Curl
By default, curl does not follow redirects unless you
explicitly instruct it to do so using the -L or
--location flag. When this flag is active,
curl’s reaction to a redirect depends entirely on the
specific HTTP status code returned by the server.
Here is how curl handles method conversion for each
major redirect status code:
303 See Other
The 303 status code is explicitly designed to direct the client to a
new URI using a GET request, regardless of the original request method.
When curl receives a 303 redirect after a POST, it
always converts the request method to GET for the
subsequent request.
301 Moved Permanently & 302 Found
According to the strict HTTP specifications, 301 and 302 redirects
should not result in a method change. However, historical web browser
behavior routinely converted these POST requests to GET requests. To
align with standard web browser behavior, curl
defaults to converting POST requests to GET requests when
following 301 and 302 redirects.
307 Temporary Redirect & 308 Permanent Redirect
These status codes were introduced to eliminate ambiguity. They
explicitly forbid the client from changing the request method. When
encountering a 307 or 308 redirect, curl preserves
the POST method and resends the original payload to the new
location.
Overriding the Default Behavior
If you need curl to deviate from its default behavior
and maintain the POST method during 301, 302, or 303 redirects, you can
use specialized command-line flags.
--post301: Tellscurlto respect the HTTP spec and not convert POST to GET after receiving a 301 redirect.--post302: Tellscurlto respect the HTTP spec and not convert POST to GET after receiving a 302 redirect.--post303: Forcescurlto keep the POST method even after receiving a 303 redirect.
Example Commands
To send a POST request, follow redirects, and allow curl
to convert the request to GET (default behavior for 301/302/303):
curl -L -X POST -d "param1=value1" https://example.com/submitTo send a POST request and force curl to preserve the
POST method through 301 and 302 redirects:
curl -L --post301 --post302 -X POST -d "param1=value1" https://example.com/submit