301 status code must drop request method to GET.

[RFC 7231 §6.4.2](https://tools.ietf.org/html/rfc7231#section-6.4.2) states that 301 HTTP Code should forward POST requests to the Location URI.

But, it also states that:

> For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.

This is the behavior implemented in almost all user agents.
However the `BrowserKit` did forward the method to the subsequent request.
This commit is contained in:
Jules Lamur 2017-02-02 18:09:49 +01:00
parent e98c068745
commit abda966d75
4 changed files with 35 additions and 1 deletions

View File

@ -1,6 +1,12 @@
UPGRADE FROM 3.2 to 3.3
=======================
BrowserKit
----------
* The request method is dropped from POST to GET when the response
status code is 301.
ClassLoader
-----------

View File

@ -1,6 +1,12 @@
CHANGELOG
=========
3.3.0
-----
* [BC BREAK] The request method is dropped from POST to GET when the response
status code is 301.
3.2.0
-----

View File

@ -474,7 +474,7 @@ abstract class Client
$request = $this->internalRequest;
if (in_array($this->internalResponse->getStatus(), array(302, 303))) {
if (in_array($this->internalResponse->getStatus(), array(301, 302, 303))) {
$method = 'GET';
$files = array();
$content = null;

View File

@ -509,6 +509,28 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('POST', $client->getRequest()->getMethod(), '->followRedirect() keeps request method');
}
public function testFollowRedirectDropPostMethod()
{
$parameters = array('foo' => 'bar');
$files = array('myfile.foo' => 'baz');
$server = array('X_TEST_FOO' => 'bazbar');
$content = 'foobarbaz';
$client = new TestClient();
foreach (array(301, 302, 303) as $code) {
$client->setNextResponse(new Response('', $code, array('Location' => 'http://www.example.com/redirected')));
$client->request('POST', 'http://www.example.com/foo/foobar', $parameters, $files, $server, $content);
$this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() follows a redirect with POST method on response code: '.$code.'.');
$this->assertEmpty($client->getRequest()->getParameters(), '->followRedirect() drops parameters with POST method on response code: '.$code.'.');
$this->assertEmpty($client->getRequest()->getFiles(), '->followRedirect() drops files with POST method on response code: '.$code.'.');
$this->assertArrayHasKey('X_TEST_FOO', $client->getRequest()->getServer(), '->followRedirect() keeps $_SERVER with POST method on response code: '.$code.'.');
$this->assertEmpty($client->getRequest()->getContent(), '->followRedirect() drops content with POST method on response code: '.$code.'.');
$this->assertEquals('GET', $client->getRequest()->getMethod(), '->followRedirect() drops request method to GET on response code: '.$code.'.');
}
}
public function testBack()
{
$client = new TestClient();