Skip to content

Commit 1b90bf7

Browse files
committed
[BrowserKit] Adds support for meta refresh
1 parent e6f99da commit 1b90bf7

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

src/Symfony/Component/BrowserKit/Client.php

+26-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,15 @@ public function request(string $method, string $uri, array $parameters = array()
367367
return $this->crawler = $this->followRedirect();
368368
}
369369

370-
return $this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
370+
$this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
371+
372+
// Check for meta refresh redirect.
373+
if ($this->followRedirects && null !== $redirect = $this->getMetaRefreshUrl()) {
374+
$this->redirect = $redirect;
375+
$this->crawler = $this->followRedirect();
376+
}
377+
378+
return $this->crawler;
371379
}
372380

373381
/**
@@ -563,6 +571,23 @@ public function followRedirect()
563571
return $response;
564572
}
565573

574+
/**
575+
* Get the meta refresh URL if the response has one.
576+
*
577+
* @see https://dev.w3.org/html5/spec-preview/the-meta-element.html#attr-meta-http-equiv-refresh
578+
*/
579+
private function getMetaRefreshUrl(): ?string
580+
{
581+
$metaRefresh = $this->getCrawler()->filter('head meta[http-equiv="refresh"]');
582+
foreach ($metaRefresh->extract(array('content')) as $content) {
583+
if (preg_match('/^\s*0\s*;\s*URL\s*=\s*(?|\'([^\']++)|"([^"]++)|([^\'"].*))/i', $content, $m)) {
584+
return str_replace("\t\r\n", '', rtrim($m[1]));
585+
}
586+
}
587+
588+
return null;
589+
}
590+
566591
/**
567592
* Restarts the client.
568593
*

src/Symfony/Component/BrowserKit/Tests/ClientTest.php

+30
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,36 @@ public function testFollowRedirectDropPostMethod()
594594
}
595595
}
596596

597+
/**
598+
* @dataProvider getTestsForMetaRefresh
599+
*/
600+
public function testFollowMetaRefresh(string $content, string $expectedEndingUrl)
601+
{
602+
$client = new TestClient();
603+
$client->setNextResponse(new Response($content));
604+
$client->request('GET', 'http://www.example.com/foo/foobar');
605+
$this->assertEquals($expectedEndingUrl, $client->getRequest()->getUri());
606+
}
607+
608+
public function getTestsForMetaRefresh()
609+
{
610+
return array(
611+
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'),
612+
array('<html><head><meta http-equiv="refresh" content="0;URL=http://www.example.com/redirected"/></head></html>', 'http://www.example.com/redirected'),
613+
array('<html><head><meta http-equiv="refresh" content="0;URL=\'http://www.example.com/redirected\'"/></head></html>', 'http://www.example.com/redirected'),
614+
array('<html><head><meta http-equiv="refresh" content=\'0;URL="http://www.example.com/redirected"\'/></head></html>', 'http://www.example.com/redirected'),
615+
array('<html><head><meta http-equiv="refresh" content="0; URL = http://www.example.com/redirected"/></head></html>', 'http://www.example.com/redirected'),
616+
array('<html><head><meta http-equiv="refresh" content="0;URL= http://www.example.com/redirected "/></head></html>', 'http://www.example.com/redirected'),
617+
array('<html><head><meta http-equiv="refresh" content="0;url=http://www.example.com/redirected "/></head></html>', 'http://www.example.com/redirected'),
618+
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'),
619+
// Non-zero timeout should not result in a redirect.
620+
array('<html><head><meta http-equiv="refresh" content="4; URL=http://www.example.com/redirected"/></head></html>', 'http://www.example.com/foo/foobar'),
621+
array('<html><body></body></html>', 'http://www.example.com/foo/foobar'),
622+
// Invalid meta tag placement should not result in a redirect.
623+
array('<html><body><meta http-equiv="refresh" content="0;url=http://www.example.com/redirected"/></body></html>', 'http://www.example.com/foo/foobar'),
624+
);
625+
}
626+
597627
public function testBack()
598628
{
599629
$client = new TestClient();

0 commit comments

Comments
 (0)