I am trying to write a batch script which will alow users to easily fill in a police form about illegal fireworks. It takes some personal information about the user and uses this in combination with the current date and time to create a statement for the police. The personal information is also filled into the form so they can be contacted later.

When issuing a POST request, the server replies with a 302 status code. Therefore I used the -L flag in curl to make it follow the redirect.

The server, however, then responds with a 411 status code (length required) after this redirect.

For added context I am using curl version 8.0.1 (Windows) libcurl/8.0.1 Schannel WinIDN

Things I have already tried:

  1. Using GET instead of POST.
  2. Using the --post302 flag, an infinite loop results.
  3. Adding the "Content-Length: 0" header results in HTTP/1.1 403 Forbidden response.

My batch script is the following:

:: First we set some variables such as name, place, date, time, etc (omitted here)

...

:: We then use these variables to create the 'data' variable
set data="melding_bericht=%melding_bericht%&plaats_voorval=%plaats_voorval%&straat_voorval=%straat_voorval%&bestanden=&voornaam=%voornaam%&tussenvoegsel=%tussenvoegsel%&achternaam=%achternaam%&straatnaam=%straatnaam%&huisnummer=%huisnummer%&huisnummer-toevoeging=%huisnummer_toevoeging%&postcode=%postcode%&woonplaats=%woonplaats%&telefoonnummer=%telefoonnummer%&email=%email%&transmit=Versturen"

:: Now issue the request to the server
curl "https://www.politie.nl/aangifte-of-melding-doen/meldformulier-vuurwerkoverlast.html" ^
  -X POST ^
  -L ^
  -H "authority: www.politie.nl" ^
  --data %data% ^
  --verbose

Some logs from the curl process:

First the server responds with:

HTTP/1.1 302 Moved Temporarily

Then:

Issue another request to this URL: 'https://www.politie.nl/aangifte-of-melding-doen/meldformulier-vuurwerkoverlast.html? (the data in the form, omitted here)'

* Switch from POST to GET
* Found bundle for host: 0x21c63c12c50 \[serially\]
* Re-using existing connection #0 with host www.politie.nl

> POST /aangifte-of-melding-doen/meldformulier-vuurwerkoverlast.html?(the urlencoded data in the form, omitted here) HTTP/1.1

After this, the server response is:

HTTP/1.1 411 Length Required

Anyone know why

  1. curl seems to do another post request? Even though it says switch from POST to GET before

  2. If not, the server is expecting a content-lenght for a GET request?

1

There are 1 answers

8
phuzi On

Having a dig around the Internet uncovered this issue on GitHub: Invalid HTTP message when redirecting POST by 302. which lead me to the --post302 option.

Taking a look at the documentation for the `-L' option

When curl follows a redirect and if the request is a POST, it sends 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 resends the following request using the same unmodified method.

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

Which suggests that you should probably include the --post301, --post302 and --post303 options to enforce resending of the POST body.

Either way it does look like Curl seems to be getting a little confused by the redirect. As far as I can tell there's nothing in the [HTTP/1.1 spec, section 6.4.3](https://datatracker.ietf.org/doc/html/rfc7231#section-6.4.3 - 302 FOUND) that means the a redirect should be changed to a GET request:

Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.

Although it doesn't go in to what the "historical reasons" are!