From 0b3ff39704a6978b6183a24081ce2eb2854eb8bd Mon Sep 17 00:00:00 2001 From: Johannes Schmitt Date: Sun, 24 Jul 2011 21:13:25 +0200 Subject: [PATCH] fix supported cookie date formats --- src/Symfony/Component/BrowserKit/Cookie.php | 37 +++++++++++++++---- .../Tests/Component/BrowserKit/CookieTest.php | 19 +++++++++- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php index 4c87825539..5f9a213016 100644 --- a/src/Symfony/Component/BrowserKit/Cookie.php +++ b/src/Symfony/Component/BrowserKit/Cookie.php @@ -20,7 +20,18 @@ namespace Symfony\Component\BrowserKit; */ 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; @@ -74,7 +85,7 @@ class Cookie $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) { @@ -159,11 +170,7 @@ class Cookie 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]; @@ -182,6 +189,22 @@ class Cookie ); } + 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. * diff --git a/tests/Symfony/Tests/Component/BrowserKit/CookieTest.php b/tests/Symfony/Tests/Component/BrowserKit/CookieTest.php index cec759ccf4..e309b6ccdd 100644 --- a/tests/Symfony/Tests/Component/BrowserKit/CookieTest.php +++ b/tests/Symfony/Tests/Component/BrowserKit/CookieTest.php @@ -27,7 +27,6 @@ class CookieTest extends \PHPUnit_Framework_TestCase { 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/'), @@ -44,6 +43,24 @@ class CookieTest extends \PHPUnit_Framework_TestCase $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/'));