Skip to content

Commit

Permalink
fix supported cookie date formats
Browse files Browse the repository at this point in the history
  • Loading branch information
schmittjoh committed Jul 24, 2011
1 parent 858cce8 commit 0b3ff39
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
37 changes: 30 additions & 7 deletions src/Symfony/Component/BrowserKit/Cookie.php
Expand Up @@ -20,7 +20,18 @@
*/
class Cookie
{
const DATE_FORMAT = 'D, d-M-Y H:i:s T';
/**
* Handles dates as defined by RFC 2616 section 3.3.1, and also some other
* non-standard, but common formats.
*
* @var array
*/
private static $dateFormats = array(
'D, d M Y H:i:s T',
'D, d-M-y H:i:s T',
'D, d-M-Y H:i:s T',
'D M j G:i:s Y',
);

protected $name;
protected $value;
Expand Down Expand Up @@ -74,7 +85,7 @@ public function __toString()
$cookie = sprintf('%s=%s', $this->name, $this->rawValue);

if (null !== $this->expires) {
$cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('UTC'))->format(static::DATE_FORMAT), 0, -5);
$cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'))->format(self::$dateFormats[0]), 0, -5);
}

if ('' !== $this->domain) {
Expand Down Expand Up @@ -159,11 +170,7 @@ static public function fromString($cookie, $url = null)

if (2 === count($elements = explode('=', $part, 2))) {
if ('expires' === $elements[0]) {
if (false === $date = \DateTime::createFromFormat(static::DATE_FORMAT, $elements[1], new \DateTimeZone('UTC'))) {
throw new \InvalidArgumentException(sprintf('The expires part of cookie is not valid (%s).', $elements[1]));
}

$elements[1] = $date->getTimestamp();
$elements[1] = self::parseDate($elements[1]);
}

$values[strtolower($elements[0])] = $elements[1];
Expand All @@ -182,6 +189,22 @@ static public function fromString($cookie, $url = null)
);
}

private static function parseDate($dateValue)
{
// trim single quotes around date if present
if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length-1]) {
$dateValue = substr($dateValue, 1, -1);
}

foreach (self::$dateFormats as $dateFormat) {
if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) {
return $date->getTimestamp();
}
}

throw new \InvalidArgumentException(sprintf('Could not parse date "%s".', $dateValue));
}

/**
* Gets the name of the cookie.
*
Expand Down
19 changes: 18 additions & 1 deletion tests/Symfony/Tests/Component/BrowserKit/CookieTest.php
Expand Up @@ -27,7 +27,6 @@ public function getTestsForToFromString()
{
return array(
array('foo=bar'),
array('foo=bar; expires=Fri, 31-Dec-2010 23:59:59 GMT'),
array('foo=bar; path=/foo'),
array('foo=bar; domain=google.com'),
array('foo=bar; domain=example.com; secure', 'https://example.com/'),
Expand All @@ -44,6 +43,24 @@ public function testFromStringIgnoreSecureFlag()
$this->assertFalse(Cookie::fromString('foo=bar; secure', 'http://example.com/')->isSecure());
}

/**
* @dataProvider getExpireCookieStrings
*/
public function testFromStringAcceptsSeveralExpiresDateFormats($cookie)
{
$this->assertEquals(1596185377, Cookie::fromString($cookie)->getExpiresTime());
}

public function getExpireCookieStrings()
{
return array(
array('foo=bar; expires=Fri, 31-Jul-2020 08:49:37 GMT'),
array('foo=bar; expires=Fri, 31 Jul 2020 08:49:37 GMT'),
array('foo=bar; expires=Friday, 31-Jul-20 08:49:37 GMT'),
array('foo=bar; expires=Fri Jul 31 08:49:37 2020'),
);
}

public function testFromStringWithUrl()
{
$this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar', 'http://www.example.com/'));
Expand Down

0 comments on commit 0b3ff39

Please sign in to comment.