I was reading this but I didn't really got from there what request-type the redirect-request should have in what case, i.e. the function (initial request-type, response-type) -> redirect-request-type.
In my particular case, I had:
- initial request-type: POST
- response-type: 302
Google Chrome used a GET for the redirected request.
In the Python library requests, there is the following code (here):
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
if r.status_code is codes.see_other:
method = 'GET'
else:
method = self.method
I.e., the redirect-request-type is GET in case of 303 (codes.see_other
), in all other cases it is the initial request-type. I.e., for my particular case above, it would be POST, in contrast to Chrome.
This is probably wrong because I have one website where this actually doesn't seem to work correct (i.e. the website doesn't behave well this way).
What would be the correct way/function?
Per RFC 2616, the answer is "the original method". HTTPbis will revise this, as it doesn't reflect what browsers do (sadly).
See http://trac.tools.ietf.org/wg/httpbis/trac/ticket/160 for the history.
I just searched for the relevant code in Chrome, and here it is:
std::string ComputeMethodForRedirect(const std::string& method,
int http_status_code) {
// For 303 redirects, all request methods except HEAD are converted to GET,
// as per the latest httpbis draft. The draft also allows POST requests to
// be converted to GETs when following 301/302 redirects, for historical
// reasons. Most major browsers do this and so shall we. Both RFC 2616 and
// the httpbis draft say to prompt the user to confirm the generation of new
// requests, other than GET and HEAD requests, but IE omits these prompts and
// so shall we.
// See:
// https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3
if ((http_status_code == 303 && method != "HEAD") ||
((http_status_code == 301 || http_status_code == 302) &&
method == "POST")) {
return "GET";
}
return method;
}
Except for 303 and 307, either behaviour is acceptable as per the spec, mainly for historical reasons.
I thought about what the answer to this question was after experiencing it with Chrome and node-requests, and initially assuming that it was totally normal. Then I thought that while it may be "historical", it wasn't probably "correct". So I found this page, and it sounds like being "correct" is less important than being compatible with "historical" implementations...which sounded disappointing for a minute. Then I remembered that every "traditional", non-Ajax/API, form based "POST" I have ever seen responds with a redirect that assumes a GET.
It is what it is and that's probably not changing ever. Thanks to all the previous responders for providing all the relevant info.