merged branch fabpot/browserkit-redirections (PR #7840)

This PR was merged into the master branch.

Discussion
----------

Browserkit redirections

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #7811, #7731
| License       | MIT
| Doc PR        | n/a

Commits
-------

b60290a [BrowserKit] isolated the max redirect count to a given main request (refs #7811)
c8bc953 Add max redirections limit
This commit is contained in:
Fabien Potencier 2013-04-25 12:40:10 +02:00
commit 5f9a24d0fa
2 changed files with 58 additions and 1 deletions

View File

@ -42,6 +42,10 @@ abstract class Client
protected $redirect;
protected $followRedirects;
private $maxRedirects;
private $redirectCount;
private $isMainRequest;
/**
* Constructor.
*
@ -58,6 +62,9 @@ abstract class Client
$this->cookieJar = null === $cookieJar ? new CookieJar() : $cookieJar;
$this->insulated = false;
$this->followRedirects = true;
$this->maxRedirects = -1;
$this->redirectCount = 0;
$this->isMainRequest = true;
}
/**
@ -71,6 +78,17 @@ abstract class Client
{
$this->followRedirects = (Boolean) $followRedirect;
}
/**
* Sets the maximum number of requests that crawler can follow.
*
* @param integer $maxRedirects
*/
public function setMaxRedirects($maxRedirects)
{
$this->maxRedirects = $maxRedirects < 0 ? -1 : $maxRedirects;
$this->followRedirects = -1 != $this->maxRedirects;
}
/**
* Sets the insulated flag.
@ -277,6 +295,12 @@ abstract class Client
*/
public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true)
{
if ($this->isMainRequest) {
$this->redirectCount = 0;
} else {
++$this->redirectCount;
}
$uri = $this->getAbsoluteUri($uri);
$server = array_merge($this->server, $server);
@ -456,7 +480,19 @@ abstract class Client
throw new \LogicException('The request was not redirected.');
}
return $this->request('get', $this->redirect);
if (-1 !== $this->maxRedirects) {
if ($this->redirectCount > $this->maxRedirects) {
throw new \LogicException(sprintf('The maximum number (%d) of redirections was reached.', $this->maxRedirects));
}
}
$this->isMainRequest = false;
$response = $this->request('get', $this->redirect);
$this->isMainRequest = true;
return $response;
}
/**

View File

@ -349,6 +349,27 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() automatically follows redirects if followRedirects is true');
}
public function testFollowRedirectWithMaxRedirects()
{
$client = new TestClient();
$client->setMaxRedirects(1);
$client->setNextResponse(new Response('', 302, array('Location' => 'http://www.example.com/redirected')));
$client->request('GET', 'http://www.example.com/foo/foobar');
$this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() follows a redirect if any');
$client->setNextResponse(new Response('', 302, array('Location' => 'http://www.example.com/redirected2')));
try {
$client->followRedirect();
$this->fail('->followRedirect() throws a \LogicException if the request was redirected and limit of redirections was reached');
} catch (\Exception $e) {
$this->assertInstanceof('LogicException', $e, '->followRedirect() throws a \LogicException if the request was redirected and limit of redirections was reached');
}
$client->setNextResponse(new Response('', 302, array('Location' => 'http://www.example.com/redirected')));
$client->request('GET', 'http://www.example.com/foo/foobar');
$this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() follows a redirect if any');
}
public function testFollowRedirectWithCookies()
{