[BrowserKit] Adds support for meta refresh
This commit is contained in:
parent
7a8b706084
commit
1c64c8267d
@ -40,6 +40,7 @@ abstract class Client
|
||||
protected $insulated = false;
|
||||
protected $redirect;
|
||||
protected $followRedirects = true;
|
||||
protected $followMetaRefresh = false;
|
||||
|
||||
private $maxRedirects = -1;
|
||||
private $redirectCount = 0;
|
||||
@ -68,6 +69,14 @@ abstract class Client
|
||||
$this->followRedirects = (bool) $followRedirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to automatically follow meta refresh redirects or not.
|
||||
*/
|
||||
public function followMetaRefresh(bool $followMetaRefresh = true)
|
||||
{
|
||||
$this->followMetaRefresh = $followMetaRefresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether client automatically follows redirects or not.
|
||||
*
|
||||
@ -367,7 +376,16 @@ abstract class Client
|
||||
return $this->crawler = $this->followRedirect();
|
||||
}
|
||||
|
||||
return $this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
|
||||
$this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
|
||||
|
||||
// Check for meta refresh redirect
|
||||
if ($this->followMetaRefresh && null !== $redirect = $this->getMetaRefreshUrl()) {
|
||||
$this->redirect = $redirect;
|
||||
$this->redirects[serialize($this->history->current())] = true;
|
||||
$this->crawler = $this->followRedirect();
|
||||
}
|
||||
|
||||
return $this->crawler;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -563,6 +581,21 @@ abstract class Client
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://dev.w3.org/html5/spec-preview/the-meta-element.html#attr-meta-http-equiv-refresh
|
||||
*/
|
||||
private function getMetaRefreshUrl(): ?string
|
||||
{
|
||||
$metaRefresh = $this->getCrawler()->filter('head meta[http-equiv="refresh"]');
|
||||
foreach ($metaRefresh->extract(array('content')) as $content) {
|
||||
if (preg_match('/^\s*0\s*;\s*URL\s*=\s*(?|\'([^\']++)|"([^"]++)|([^\'"].*))/i', $content, $m)) {
|
||||
return str_replace("\t\r\n", '', rtrim($m[1]));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restarts the client.
|
||||
*
|
||||
|
@ -594,6 +594,39 @@ class ClientTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTestsForMetaRefresh
|
||||
*/
|
||||
public function testFollowMetaRefresh(string $content, string $expectedEndingUrl, bool $followMetaRefresh = true)
|
||||
{
|
||||
$client = new TestClient();
|
||||
$client->followMetaRefresh($followMetaRefresh);
|
||||
$client->setNextResponse(new Response($content));
|
||||
$client->request('GET', 'http://www.example.com/foo/foobar');
|
||||
$this->assertEquals($expectedEndingUrl, $client->getRequest()->getUri());
|
||||
}
|
||||
|
||||
public function getTestsForMetaRefresh()
|
||||
{
|
||||
return array(
|
||||
array('<html><head><meta http-equiv="Refresh" content="4" /><meta http-equiv="refresh" content="0; URL=http://www.example.com/redirected"/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><meta http-equiv="refresh" content="0;URL=http://www.example.com/redirected"/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><meta http-equiv="refresh" content="0;URL=\'http://www.example.com/redirected\'"/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><meta http-equiv="refresh" content=\'0;URL="http://www.example.com/redirected"\'/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><meta http-equiv="refresh" content="0; URL = http://www.example.com/redirected"/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><meta http-equiv="refresh" content="0;URL= http://www.example.com/redirected "/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><meta http-equiv="refresh" content="0;url=http://www.example.com/redirected "/></head></html>', 'http://www.example.com/redirected'),
|
||||
array('<html><head><noscript><meta http-equiv="refresh" content="0;URL=http://www.example.com/redirected"/></noscript></head></head></html>', 'http://www.example.com/redirected'),
|
||||
// Non-zero timeout should not result in a redirect.
|
||||
array('<html><head><meta http-equiv="refresh" content="4; URL=http://www.example.com/redirected"/></head></html>', 'http://www.example.com/foo/foobar'),
|
||||
array('<html><body></body></html>', 'http://www.example.com/foo/foobar'),
|
||||
// Invalid meta tag placement should not result in a redirect.
|
||||
array('<html><body><meta http-equiv="refresh" content="0;url=http://www.example.com/redirected"/></body></html>', 'http://www.example.com/foo/foobar'),
|
||||
// Valid meta refresh should not be followed if disabled.
|
||||
array('<html><head><meta http-equiv="refresh" content="0;URL=http://www.example.com/redirected"/></head></html>', 'http://www.example.com/foo/foobar', false),
|
||||
);
|
||||
}
|
||||
|
||||
public function testBack()
|
||||
{
|
||||
$client = new TestClient();
|
||||
|
Reference in New Issue
Block a user