Posting POST, getting GET



Recently I once again stumbled upon a detail of the HTTP specification involving the POST verb and "enforced" https. I'll document it here in an attempt to save other people the time (hopefully also future-me). <span id="more-4486"></span> I put "enforced" in quotation marks because it just means to also listen on port `80` - apart from listing on port `443` for the encrypted traffic - and issue a redirect (`301`) to the same URL but with `https` instead of `http` as protocol. The thing is that different clients handle that redirect differently and especially the Python `requests` library may confuse you - at least it did confuse me: Say you send a `POST` request to a `http` URL and the server issues a HTTP response code of `301`. According to Wikipedia, the client should confirm with the user before redirecting ((https://en.wikipedia.org/wiki/HTTP_301)). But on the command line or - even worse - in case of libraries used for programming, this is not (easily) possible. The situation is even more involved if one uses the HTTP status code `302` (which one should *not* do for enforcing https btw): In these cases some - but not all - clients translate a `POST` request to a `GET` request and use that verb against the redirection target ((https://en.wikipedia.org/wiki/HTTP_301)). The two HTTP status codes `303` and `307` have been introduces to deconflict this but all participants need to be backwards-compatible of course. Anyhow, let's use your favorite CL tool ```bash curl -v -L -X POST 'http://example.com' > /dev/null wget -O- --method=POST 'http://example.com' > /dev/null ``` or the Python `requests` library to perform a `POST` request: ```python import requests requests.post('http://example.com') ``` All three tools don't interact with the user in any way. They especially re-perform a `POST` in case of `301` without asking first which seems to me like a straight violation of the specification. I cut `requests` some slack of course: As a library it should not wait for user-input during execution. Tool | 301 redirect | 302 redirect -----------|--------------|---------------- `curl` | keep `POST` | keep `POST` `wget` | keep `POST` | switch to `GET` `requests` | keep `POST` | switch to `GET`

Leave a Reply

Your email address will not be published. Required fields are marked *