Description
I doubted if I need to create a bug ticket, but then as I also will follow up with a solution that in backwards compatible, I would like to post the issue as a feature request
Currently statuses 300, 301, 302 are switching from methods that are not GET and HEAD to GET, even though specification states that it's not allowed, but at the same time, it is a common implementation by http clients and browsers
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, most
existing user agent implementations treat 302 as if it were a 303
response, performing a GET on the Location field-value regardless
of the original request method. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.
// Use a GET request if this is an entity enclosing request and we are
// not forcing RFC compliance, but rather emulating what all browsers
// would do.
$statusCode = $response->getStatusCode();
if ($statusCode == 303 ||
($statusCode <= 302 && !$options['allow_redirects']['strict'])
) {
$safeMethods = ['GET', 'HEAD', 'OPTIONS'];
$requestMethod = $request->getMethod();
$modify['method'] = in_array($requestMethod, $safeMethods) ? $requestMethod : 'GET';
$modify['body'] = '';
}
Even if the specification requires the method (and the body) not to be altered when the redirection is performed, not all user-agents align with it - you can still find this type of bugged software out there. It is therefore recommended to use the 301 code only as a response for GET or HEAD methods and to use the 308 Permanent Redirect for POST methods instead, as the method change is explicitly prohibited with this status.
Even if the specification requires the method (and the body) not to be altered when the redirection is performed, not all user-agents conform here - you can still find this type of bugged software out there. It is therefore recommended to set the 302 code only as a response for GET or HEAD methods and to use 307 Temporary Redirect instead, as the method change is explicitly prohibited in that case.
In the cases where you want the method used to be changed to GET, use 303 See Other instead. This is useful when you want to give a response to a PUT method that is not the uploaded resource but a confirmation message such as: 'you successfully uploaded XYZ'.
I could not find if method and body are not meant to be unmodified when 300, I propose implementing it the same way as guzzle has it - also strict
Description I doubted if I need to create a bug ticket, but then as I also will follow up with a solution that in backwards compatible, I would like to post the issue as a feature request
Currently statuses 300, 301, 302 are switching from methods that are not GET and HEAD to GET, even though specification states that it's not allowed, but at the same time, it is a common implementation by http clients and browsers
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3
So, according to specs that should happen
Request 1. POST http://example.com/api Response 1. 302 Location https://example.com/api Request 2. POST https://example.com/api
Currently that happens with client-common's RedirectPlugin
Request 1. POST http://example.com/api Response 1. 302 Location https://example.com/api Request 2. GET https://example.com/api
My suggestion would be to add
strict
option with default valuefalse
to RedirectPlugin a very similar way as guzzle's RedirectMiddleware does that:https://github.com/guzzle/guzzle/blob/de6f1e58e735754b888649495ed4cb9ae3b19589/src/RedirectMiddleware.php#L157-L169
Additional context