HTTP: POST request receives a 302, should the redirect-request be a GET?

25,961

Solution 1

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.

Solution 2

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;
}

Solution 3

Except for 303 and 307, either behaviour is acceptable as per the spec, mainly for historical reasons.

Share:
25,961
Albert
Author by

Albert

I am postgraduate of RWTH Aachen, Germany and received a M.S. Math and a M.S. CompSci. My main interests are Machine Learning, Neural Networks, Artificial Intelligence, Logic, Automata Theory and Programming Languages. And I'm an enthusiastic hobby programmer with a wide range of side projects, mostly in C++ and Python. Homepage GitHub SourceForge HackerNewsers profile page MetaOptimize Q+A

Updated on July 05, 2022

Comments

  • Albert
    Albert almost 2 years

    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?

  • Albert
    Albert over 12 years
    Well, maybe it is wiser to not follow the spec so strict if every browser seem to behave different and websites don't work that way?
  • Piotr Dobrogost
    Piotr Dobrogost over 12 years
    Well, maybe it is wiser to strictly follow the spec and make every browser's vendor respect the spec?
  • Simon Richter
    Simon Richter over 12 years
    The spec is rather lenient here.