[BrowserKit] first attempt at fixing CookieJar (closes #2209)
This commit is contained in:
parent
b46114a0f6
commit
66a18f3239
@ -98,6 +98,10 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
|||||||
* added a timeline panel
|
* added a timeline panel
|
||||||
* The toolbar position can now be configured via the `position` option (can be `top` or `bottom`)
|
* The toolbar position can now be configured via the `position` option (can be `top` or `bottom`)
|
||||||
|
|
||||||
|
### BrowserKit
|
||||||
|
|
||||||
|
* [BC BREAK] The CookieJar internals have changed to allow cookies with the same name on different sub-domains/sub-paths
|
||||||
|
|
||||||
### Config
|
### Config
|
||||||
|
|
||||||
* added a way to add documentation on configuration
|
* added a way to add documentation on configuration
|
||||||
|
@ -31,35 +31,51 @@ class CookieJar
|
|||||||
*/
|
*/
|
||||||
public function set(Cookie $cookie)
|
public function set(Cookie $cookie)
|
||||||
{
|
{
|
||||||
$this->cookieJar[$cookie->getName()] = $cookie;
|
$this->cookieJar[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a cookie by name.
|
* Gets a cookie by name.
|
||||||
*
|
*
|
||||||
* @param string $name The cookie name
|
* @param string $name The cookie name
|
||||||
|
* @param string $path The cookie path
|
||||||
|
* @param string $domain The cookie domain
|
||||||
*
|
*
|
||||||
* @return Cookie|null A Cookie instance or null if the cookie does not exist
|
* @return Cookie|null A Cookie instance or null if the cookie does not exist
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function get($name)
|
public function get($name, $path = '/', $domain = null)
|
||||||
{
|
{
|
||||||
$this->flushExpiredCookies();
|
$this->flushExpiredCookies();
|
||||||
|
|
||||||
return isset($this->cookieJar[$name]) ? $this->cookieJar[$name] : null;
|
return isset($this->cookieJar[$domain][$path][$name]) ? $this->cookieJar[$domain][$path][$name] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a cookie by name.
|
* Removes a cookie by name.
|
||||||
*
|
*
|
||||||
* @param string $name The cookie name
|
* @param string $name The cookie name
|
||||||
|
* @param string $path The cookie path
|
||||||
|
* @param string $domain The cookie domain
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function expire($name)
|
public function expire($name, $path = '/', $domain = null)
|
||||||
{
|
{
|
||||||
unset($this->cookieJar[$name]);
|
if (null === $path) {
|
||||||
|
$path = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($this->cookieJar[$domain][$path][$name]);
|
||||||
|
|
||||||
|
if (empty($this->cookieJar[$domain][$path])) {
|
||||||
|
unset($this->cookieJar[$domain][$path]);
|
||||||
|
|
||||||
|
if (empty($this->cookieJar[$domain])) {
|
||||||
|
unset($this->cookieJar[$domain]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,7 +92,7 @@ class CookieJar
|
|||||||
* Updates the cookie jar from a Response object.
|
* Updates the cookie jar from a Response object.
|
||||||
*
|
*
|
||||||
* @param Response $response A Response object
|
* @param Response $response A Response object
|
||||||
* @param string $uri The base URL
|
* @param string $uri The base URL
|
||||||
*/
|
*/
|
||||||
public function updateFromResponse(Response $response, $uri = null)
|
public function updateFromResponse(Response $response, $uri = null)
|
||||||
{
|
{
|
||||||
@ -94,13 +110,22 @@ class CookieJar
|
|||||||
{
|
{
|
||||||
$this->flushExpiredCookies();
|
$this->flushExpiredCookies();
|
||||||
|
|
||||||
return $this->cookieJar;
|
$flattenedCookies = array();
|
||||||
|
foreach ($this->cookieJar as $path) {
|
||||||
|
foreach ($path as $cookies) {
|
||||||
|
foreach ($cookies as $cookie) {
|
||||||
|
$flattenedCookies[] = $cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $flattenedCookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns not yet expired cookie values for the given URI.
|
* Returns not yet expired cookie values for the given URI.
|
||||||
*
|
*
|
||||||
* @param string $uri A URI
|
* @param string $uri A URI
|
||||||
* @param Boolean $returnsRawValue Returns raw value or urldecoded value
|
* @param Boolean $returnsRawValue Returns raw value or urldecoded value
|
||||||
*
|
*
|
||||||
* @return array An array of cookie values
|
* @return array An array of cookie values
|
||||||
@ -110,25 +135,28 @@ class CookieJar
|
|||||||
$this->flushExpiredCookies();
|
$this->flushExpiredCookies();
|
||||||
|
|
||||||
$parts = array_replace(array('path' => '/'), parse_url($uri));
|
$parts = array_replace(array('path' => '/'), parse_url($uri));
|
||||||
|
|
||||||
$cookies = array();
|
$cookies = array();
|
||||||
foreach ($this->cookieJar as $cookie) {
|
foreach ($this->cookieJar as $domain => $pathCookies) {
|
||||||
if ($cookie->getDomain()) {
|
if ($domain) {
|
||||||
$domain = ltrim($cookie->getDomain(), '.');
|
$domain = ltrim($domain, '.');
|
||||||
if ($domain != substr($parts['host'], -strlen($domain))) {
|
if ($domain != substr($parts['host'], -strlen($domain))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cookie->getPath() != substr($parts['path'], 0, strlen($cookie->getPath()))) {
|
foreach ($pathCookies as $path => $namedCookies) {
|
||||||
continue;
|
if ($path != substr($parts['path'], 0, strlen($path))) {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ($cookie->isSecure() && 'https' != $parts['scheme']) {
|
foreach ($namedCookies as $name => $cookie) {
|
||||||
continue;
|
if ($cookie->isSecure() && 'https' != $parts['scheme']) {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue();
|
$cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cookies;
|
return $cookies;
|
||||||
@ -151,10 +179,13 @@ class CookieJar
|
|||||||
*/
|
*/
|
||||||
public function flushExpiredCookies()
|
public function flushExpiredCookies()
|
||||||
{
|
{
|
||||||
$cookies = $this->cookieJar;
|
foreach ($this->cookieJar as $domain => $pathCookies) {
|
||||||
foreach ($cookies as $name => $cookie) {
|
foreach ($pathCookies as $path => $namedCookies) {
|
||||||
if ($cookie->isExpired()) {
|
foreach ($namedCookies as $name => $cookie) {
|
||||||
unset($this->cookieJar[$name]);
|
if ($cookie->isExpired()) {
|
||||||
|
unset($this->cookieJar[$domain][$path][$name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
|
|||||||
$cookieJar->set($cookie1 = new Cookie('foo', 'bar'));
|
$cookieJar->set($cookie1 = new Cookie('foo', 'bar'));
|
||||||
$cookieJar->set($cookie2 = new Cookie('bar', 'foo'));
|
$cookieJar->set($cookie2 = new Cookie('bar', 'foo'));
|
||||||
|
|
||||||
$this->assertEquals(array('foo' => $cookie1, 'bar' => $cookie2), $cookieJar->all(), '->all() returns all cookies in the jar');
|
$this->assertEquals(array($cookie1, $cookie2), $cookieJar->all(), '->all() returns all cookies in the jar');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testClear()
|
public function testClear()
|
||||||
@ -93,7 +93,7 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('http://www.example.com/', array('foo_nothing', 'foo_domain')),
|
array('http://www.example.com/', array('foo_nothing', 'foo_domain')),
|
||||||
array('http://foo.example.com/', array('foo_nothing', 'foo_domain')),
|
array('http://foo.example.com/', array('foo_nothing', 'foo_domain')),
|
||||||
array('http://foo.example1.com/', array('foo_nothing')),
|
array('http://foo.example1.com/', array('foo_nothing')),
|
||||||
array('https://foo.example.com/', array('foo_nothing', 'foo_domain', 'foo_secure')),
|
array('https://foo.example.com/', array('foo_nothing', 'foo_secure', 'foo_domain')),
|
||||||
array('http://www.example.com/foo/bar', array('foo_nothing', 'foo_path', 'foo_domain')),
|
array('http://www.example.com/foo/bar', array('foo_nothing', 'foo_path', 'foo_domain')),
|
||||||
array('http://www4.example.com/', array('foo_nothing', 'foo_domain', 'foo_strict_domain')),
|
array('http://www4.example.com/', array('foo_nothing', 'foo_domain', 'foo_strict_domain')),
|
||||||
);
|
);
|
||||||
@ -107,4 +107,26 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(array('foo' => 'bar=baz'), $cookieJar->allValues('/'));
|
$this->assertEquals(array('foo' => 'bar=baz'), $cookieJar->allValues('/'));
|
||||||
$this->assertEquals(array('foo' => 'bar%3Dbaz'), $cookieJar->allRawValues('/'));
|
$this->assertEquals(array('foo' => 'bar%3Dbaz'), $cookieJar->allRawValues('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCookieWithSameNameButDifferentPaths()
|
||||||
|
{
|
||||||
|
$cookieJar = new CookieJar();
|
||||||
|
$cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/foo'));
|
||||||
|
$cookieJar->set($cookie2 = new Cookie('foo', 'bar2', null, '/bar'));
|
||||||
|
|
||||||
|
$this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/')));
|
||||||
|
$this->assertEquals(array('foo' => 'bar1'), $cookieJar->allValues('http://example.com/foo'));
|
||||||
|
$this->assertEquals(array('foo' => 'bar2'), $cookieJar->allValues('http://example.com/bar'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCookieWithSameNameButDifferentDomains()
|
||||||
|
{
|
||||||
|
$cookieJar = new CookieJar();
|
||||||
|
$cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/', 'foo.example.com'));
|
||||||
|
$cookieJar->set($cookie2 = new Cookie('foo', 'bar2', null, '/', 'bar.example.com'));
|
||||||
|
|
||||||
|
$this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/')));
|
||||||
|
$this->assertEquals(array('foo' => 'bar1'), $cookieJar->allValues('http://foo.example.com/'));
|
||||||
|
$this->assertEquals(array('foo' => 'bar2'), $cookieJar->allValues('http://bar.example.com/'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user