Skip to content

Commit f12663b

Browse files
authored
Merge pull request #76 from aaa2000/cookie-date-parsing
Implements a cookie-date parsing utility
2 parents d36c45f + caa5344 commit f12663b

File tree

5 files changed

+152
-0
lines changed

5 files changed

+152
-0
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
## Unreleased
55

6+
### Added
7+
8+
- CookieUtil::parseDate to create a date from cookie date string
9+
610
## 1.5.0 - 2017-02-14
711

812
### Added

spec/CookieUtilSpec.php

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace spec\Http\Message;
4+
5+
use Http\Message\Exception\UnexpectedValueException;
6+
use PhpSpec\ObjectBehavior;
7+
8+
class CookieUtilSpec extends ObjectBehavior
9+
{
10+
/**
11+
* @dataProvider getCookieStrings
12+
*/
13+
function it_parses_cookie_date_string($cookieDateString, $expectedString)
14+
{
15+
$this->beConstructedThrough('parseDate', [$cookieDateString]);
16+
$this->shouldHaveType('\DateTime');
17+
$this->format('l, d-M-Y H:i:s O')->shouldReturn($expectedString);
18+
}
19+
20+
/**
21+
* @dataProvider getInvalidCookieDateStrings
22+
*/
23+
function it_throws_an_exception_if_cookie_date_string_is_unparseable($cookieDateString)
24+
{
25+
$this->beConstructedThrough('parseDate', [$cookieDateString]);
26+
$this->shouldThrow('Http\Message\Exception\UnexpectedValueException');
27+
}
28+
29+
/**
30+
* Provides examples for valid cookie date string.
31+
*
32+
* @return array
33+
*/
34+
public function getCookieStrings()
35+
{
36+
return [
37+
['Friday, 31 Jul 20 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
38+
['Friday, 31-Jul-20 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
39+
['Fri, 31-Jul-2020 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
40+
['Fri, 31 Jul 2020 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
41+
['Fri, 31-07-2020 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
42+
['Fri, 31-07-20 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
43+
['Friday, 31-Jul-20 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
44+
['Fri Jul 31 08:49:37 2020', 'Friday, 31-Jul-2020 08:49:37 +0000'],
45+
['Friday July 31st 2020, 08:49:37 GMT', 'Friday, 31-Jul-2020 08:49:37 +0000'],
46+
// https://github.com/salesforce/tough-cookie/blob/master/test/date_test.js#L52
47+
['Wed, 09 Jun 2021 10:18:14 GMT', 'Wednesday, 09-Jun-2021 10:18:14 +0000'],
48+
['Wed, 09 Jun 2021 22:18:14 GMT', 'Wednesday, 09-Jun-2021 22:18:14 +0000'],
49+
['Tue, 18 Oct 2011 07:42:42.123 GMT', 'Tuesday, 18-Oct-2011 07:42:42 +0000'],
50+
['18 Oct 2011 07:42:42 GMT', 'Tuesday, 18-Oct-2011 07:42:42 +0000'],
51+
['8 Oct 2011 7:42:42 GMT', 'Saturday, 08-Oct-2011 07:42:42 +0000'],
52+
['8 Oct 2011 7:2:42 GMT', 'Saturday, 08-Oct-2011 07:02:42 +0000'],
53+
['Oct 18 2011 07:42:42 GMT', 'Tuesday, 18-Oct-2011 07:42:42 +0000'],
54+
['Tue Oct 18 2011 07:05:03 GMT+0000 (GMT)', 'Tuesday, 18-Oct-2011 07:05:03 +0000'],
55+
['09 Jun 2021 10:18:14 GMT', 'Wednesday, 09-Jun-2021 10:18:14 +0000'],
56+
['01 Jan 1970 00:00:00 GMT', 'Thursday, 01-Jan-1970 00:00:00 +0000'],
57+
['01 Jan 1601 00:00:00 GMT', 'Monday, 01-Jan-1601 00:00:00 +0000'],
58+
['10 Feb 81 13:00:00 GMT', 'Tuesday, 10-Feb-1981 13:00:00 +0000'], // implicit year
59+
['Thu, 17-Apr-2014 02:12:29 GMT', 'Thursday, 17-Apr-2014 02:12:29 +0000'], // dashes
60+
['Thu, 17-Apr-2014 02:12:29 UTC', 'Thursday, 17-Apr-2014 02:12:29 +0000'], // dashes and UTC
61+
];
62+
}
63+
64+
/**
65+
* Provides examples for invalid cookie date string.
66+
*
67+
* @return array
68+
*/
69+
public function getInvalidCookieDateStrings()
70+
{
71+
return [
72+
['Flursday July 31st 2020, 08:49:37 GMT'],
73+
['99 Jix 3038 48:86:72 ZMT'],
74+
];
75+
}
76+
}

src/CookieUtil.php

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Http\Message;
4+
5+
use Http\Message\Exception\UnexpectedValueException;
6+
7+
final class CookieUtil
8+
{
9+
/**
10+
* Handles dates as defined by RFC 2616 section 3.3.1, and also some other
11+
* non-standard, but common formats.
12+
*
13+
* @var array
14+
*/
15+
private static $dateFormats = [
16+
'D, d M y H:i:s T',
17+
'D, d M Y H:i:s T',
18+
'D, d-M-y H:i:s T',
19+
'D, d-M-Y H:i:s T',
20+
'D, d-m-y H:i:s T',
21+
'D, d-m-Y H:i:s T',
22+
'D M j G:i:s Y',
23+
'D M d H:i:s Y T',
24+
];
25+
26+
/**
27+
* @see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/BrowserKit/Cookie.php
28+
*
29+
* @param string $dateValue
30+
*
31+
* @return \DateTime
32+
*
33+
* @throws UnexpectedValueException if we cannot parse the cookie date string.
34+
*/
35+
public static function parseDate($dateValue)
36+
{
37+
foreach (self::$dateFormats as $dateFormat) {
38+
if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) {
39+
return $date;
40+
}
41+
}
42+
43+
// attempt a fallback for unusual formatting
44+
if (false !== $date = date_create($dateValue, new \DateTimeZone('GMT'))) {
45+
return $date;
46+
}
47+
48+
throw new UnexpectedValueException(sprintf(
49+
'Unparseable cookie date string "%s"',
50+
$dateValue
51+
));
52+
}
53+
}

src/Exception.php

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Http\Message;
4+
5+
/**
6+
* An interface implemented by all HTTP message related exceptions.
7+
*/
8+
interface Exception
9+
{
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Http\Message\Exception;
4+
5+
use Http\Message\Exception;
6+
7+
final class UnexpectedValueException extends \UnexpectedValueException implements Exception
8+
{
9+
}

0 commit comments

Comments
 (0)