I just discovered an interesting section in the book. According to page 378 section 302 ("Found")
:
This status code is the ultimate source of most redirection-related confusion. It’s supposed to be handled just like 307 (“Temporary Redirect”). In fact, in HTTP 1.0 its name
was “Moved Temporarily.” Unfortunately, in real life most clients handle 302 just like
303 (“See Other”). The difference hinges on what the client is supposed to do when it
gets a 302 in response to a PUT, POST, or DELETE request. See the entry for 307 below
if you’re interested in the details.
To resolve this ambiguity, in HTTP 1.1 this response code was renamed to “Found,”
and response code 307 was created.
In other words, HTTP 302 was split into HTTP 303 and 307.
Next, on page 380 section 307 ("Temporary Redirect")
:
For GET requests, where the only thing being requested is that the server send a representation, this status code is identical to 303 (“See Other”). A typical case where 307
is a good response to a GET is when the server wants to send a client to a mirror site.
But for POST, PUT, and DELETE requests, where the server is expected to take some
action in response to the request, this status code is significantly different from 303.
A 303 in response to a POST, PUT, or DELETE means that the operation has succeeded
but that the response entity-body is not being sent along with this request. If the client
wants the response entity-body, it needs to make a GET request to another URI.
A 307 in response to a POST, PUT, or DELETE means that the server has not even tried
to perform the operation. The client needs to resubmit the entire request to the URI in
the Location
header.
In other words, HTTP POST, PUT, DELETE are legal on HTTP 303, 307. The above paragraph explains the expected behavior.
That being said, I'm quoting the book here, not the HTTP specification (which is suspiciously silent on the expected behavior).