1<?php 2/** 3 * Unit tests for HTTP_Request2 package 4 * 5 * PHP version 5 6 * 7 * LICENSE 8 * 9 * This source file is subject to BSD 3-Clause License that is bundled 10 * with this package in the file LICENSE and available at the URL 11 * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE 12 * 13 * @category HTTP 14 * @package HTTP_Request2 15 * @author Alexey Borzov <avb@php.net> 16 * @copyright 2008-2021 Alexey Borzov <avb@php.net> 17 * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License 18 * @link http://pear.php.net/package/HTTP_Request2 19 */ 20 21/** Sets up includes */ 22require_once dirname(__DIR__) . '/TestHelper.php'; 23 24use Yoast\PHPUnitPolyfills\TestCases\TestCase; 25 26/** 27 * Unit test for HTTP_Request2_CookieJar class 28 */ 29class HTTP_Request2_CookieJarTest extends TestCase 30{ 31 /** 32 * Cookie jar instance being tested 33 * @var HTTP_Request2_CookieJar 34 */ 35 protected $jar; 36 37 protected function set_up() 38 { 39 $this->jar = new HTTP_Request2_CookieJar(); 40 } 41 42 /** 43 * Test that we can't store junk "cookies" in jar 44 * 45 * @dataProvider invalidCookieProvider 46 */ 47 public function testStoreInvalid($cookie) 48 { 49 $this->expectException(\HTTP_Request2_LogicException::class); 50 $this->jar->store($cookie); 51 } 52 53 /** 54 * Per feature requests, allow to ignore invalid cookies rather than throw exceptions 55 * 56 * @link http://pear.php.net/bugs/bug.php?id=19937 57 * @link http://pear.php.net/bugs/bug.php?id=20401 58 * @dataProvider invalidCookieProvider 59 */ 60 public function testCanIgnoreInvalidCookies($cookie) 61 { 62 $this->jar->ignoreInvalidCookies(true); 63 $this->assertFalse($this->jar->store($cookie)); 64 } 65 66 /** 67 * Ignore setting a cookie from "parallel" subdomain when relevant option is on 68 * 69 * @link http://pear.php.net/bugs/bug.php?id=20401 70 */ 71 public function testRequest20401() 72 { 73 $this->jar->ignoreInvalidCookies(true); 74 $response = HTTP_Request2_Adapter_Mock::createResponseFromFile( 75 fopen(dirname(__DIR__) . '/_files/response_cookies', 'rb') 76 ); 77 $setter = new Net_URL2('http://pecl.php.net/'); 78 79 $this->assertFalse($this->jar->addCookiesFromResponse($response, $setter)); 80 $this->assertCount(3, $this->jar->getAll()); 81 } 82 83 84 /** 85 * 86 * @dataProvider noPSLDomainsProvider 87 */ 88 public function testDomainMatchNoPSL($requestHost, $cookieDomain, $expected) 89 { 90 $this->jar->usePublicSuffixList(false); 91 $this->assertEquals($expected, $this->jar->domainMatch($requestHost, $cookieDomain)); 92 } 93 94 /** 95 * 96 * @dataProvider PSLDomainsProvider 97 */ 98 public function testDomainMatchPSL($requestHost, $cookieDomain, $expected) 99 { 100 $this->jar->usePublicSuffixList(true); 101 $this->assertEquals($expected, $this->jar->domainMatch($requestHost, $cookieDomain)); 102 } 103 104 public function testConvertExpiresToISO8601() 105 { 106 $dt = new DateTime(); 107 $dt->setTimezone(new DateTimeZone('UTC')); 108 $dt->modify('+1 day'); 109 110 $this->jar->store([ 111 'name' => 'foo', 112 'value' => 'bar', 113 'domain' => '.example.com', 114 'path' => '/', 115 'expires' => $dt->format(DateTime::COOKIE), 116 'secure' => false 117 ]); 118 $cookies = $this->jar->getAll(); 119 $this->assertEquals($cookies[0]['expires'], $dt->format(DateTime::ISO8601)); 120 } 121 122 public function testProblem2038() 123 { 124 $this->jar->store([ 125 'name' => 'foo', 126 'value' => 'bar', 127 'domain' => '.example.com', 128 'path' => '/', 129 'expires' => 'Sun, 01 Jan 2040 03:04:05 GMT', 130 'secure' => false 131 ]); 132 $cookies = $this->jar->getAll(); 133 $this->assertEquals([[ 134 'name' => 'foo', 135 'value' => 'bar', 136 'domain' => '.example.com', 137 'path' => '/', 138 'expires' => '2040-01-01T03:04:05+0000', 139 'secure' => false 140 ]], $cookies); 141 } 142 143 public function testStoreExpired() 144 { 145 $base = [ 146 'name' => 'foo', 147 'value' => 'bar', 148 'domain' => '.example.com', 149 'path' => '/', 150 'secure' => false 151 ]; 152 153 $dt = new DateTime(); 154 $dt->setTimezone(new DateTimeZone('UTC')); 155 $dt->modify('-1 day'); 156 $yesterday = $dt->format(DateTime::COOKIE); 157 158 $dt->modify('+2 days'); 159 $tomorrow = $dt->format(DateTime::COOKIE); 160 161 $this->jar->store($base + ['expires' => $yesterday]); 162 $this->assertEquals(0, count($this->jar->getAll())); 163 164 $this->jar->store($base + ['expires' => $tomorrow]); 165 $this->assertEquals(1, count($this->jar->getAll())); 166 $this->jar->store($base + ['expires' => $yesterday]); 167 $this->assertEquals(0, count($this->jar->getAll())); 168 } 169 170 /** 171 * 172 * @dataProvider cookieAndSetterProvider 173 */ 174 public function testGetDomainAndPathFromSetter($cookie, $setter, $expected) 175 { 176 $this->jar->store($cookie, $setter); 177 $expected = array_merge($cookie, $expected); 178 $cookies = $this->jar->getAll(); 179 $this->assertEquals($expected, $cookies[0]); 180 } 181 182 /** 183 * 184 * @dataProvider cookieMatchProvider 185 */ 186 public function testGetMatchingCookies($url, $expectedCount) 187 { 188 $cookies = [ 189 ['domain' => '.example.com', 'path' => '/', 'secure' => false], 190 ['domain' => '.example.com', 'path' => '/', 'secure' => true], 191 ['domain' => '.example.com', 'path' => '/path', 'secure' => false], 192 ['domain' => '.example.com', 'path' => '/other', 'secure' => false], 193 ['domain' => 'example.com', 'path' => '/', 'secure' => false], 194 ['domain' => 'www.example.com', 'path' => '/', 'secure' => false], 195 ['domain' => 'specific.example.com', 'path' => '/path', 'secure' => false], 196 ['domain' => 'nowww.example.com', 'path' => '/', 'secure' => false], 197 ]; 198 199 for ($i = 0; $i < count($cookies); $i++) { 200 $this->jar->store($cookies[$i] + ['expires' => null, 'name' => "cookie{$i}", 'value' => "cookie_{$i}_value"]); 201 } 202 203 $this->assertEquals($expectedCount, count($this->jar->getMatching(new Net_URL2($url)))); 204 } 205 206 public function testLongestPathFirst() 207 { 208 $cookie = [ 209 'name' => 'foo', 210 'domain' => '.example.com', 211 ]; 212 foreach (['/', '/specific/path/', '/specific/'] as $path) { 213 $this->jar->store($cookie + ['path' => $path, 'value' => str_replace('/', '_', $path)]); 214 } 215 $this->assertEquals( 216 'foo=_specific_path_; foo=_specific_; foo=_', 217 $this->jar->getMatching(new Net_URL2('http://example.com/specific/path/file.php'), true) 218 ); 219 } 220 221 public function testSerializable() 222 { 223 $dt = new DateTime(); 224 $dt->setTimezone(new DateTimeZone('UTC')); 225 $dt->modify('+1 day'); 226 $cookie = ['domain' => '.example.com', 'path' => '/', 'secure' => false, 'value' => 'foo']; 227 228 $this->jar->store($cookie + ['name' => 'session', 'expires' => null]); 229 $this->jar->store($cookie + ['name' => 'long', 'expires' => $dt->format(DateTime::COOKIE)]); 230 231 $newJar = unserialize(serialize($this->jar)); 232 $cookies = $newJar->getAll(); 233 $this->assertEquals(1, count($cookies)); 234 $this->assertEquals('long', $cookies[0]['name']); 235 236 $this->jar->serializeSessionCookies(true); 237 $newJar = unserialize(serialize($this->jar)); 238 $this->assertEquals($this->jar->getAll(), $newJar->getAll()); 239 } 240 241 public function testRemoveExpiredOnUnserialize() 242 { 243 $dt = new DateTime(); 244 $dt->setTimezone(new DateTimeZone('UTC')); 245 $dt->modify('+2 seconds'); 246 247 $this->jar->store([ 248 'name' => 'foo', 249 'value' => 'bar', 250 'domain' => '.example.com', 251 'path' => '/', 252 'expires' => $dt->format(DateTime::COOKIE), 253 ]); 254 255 $serialized = serialize($this->jar); 256 sleep(2); 257 $newJar = unserialize($serialized); 258 $this->assertEquals([], $newJar->getAll()); 259 } 260 261 public static function invalidCookieProvider() 262 { 263 return [ 264 [[]], 265 [['name' => 'foo']], 266 [[ 267 'name' => 'a name', 268 'value' => 'bar', 269 'domain' => '.example.com', 270 'path' => '/', 271 ]], 272 [[ 273 'name' => 'foo', 274 'value' => 'a value', 275 'domain' => '.example.com', 276 'path' => '/', 277 ]], 278 [[ 279 'name' => 'foo', 280 'value' => 'bar', 281 'domain' => '.example.com', 282 'path' => null, 283 ]], 284 [[ 285 'name' => 'foo', 286 'value' => 'bar', 287 'domain' => null, 288 'path' => '/', 289 ]], 290 [[ 291 'name' => 'foo', 292 'value' => 'bar', 293 'domain' => '.example.com', 294 'path' => '/', 295 'expires' => 'invalid date', 296 ]], 297 ]; 298 } 299 300 public static function noPSLdomainsProvider() 301 { 302 return [ 303 ['localhost', 'localhost', true], 304 ['www.example.com', 'www.example.com', true], 305 ['127.0.0.1', '127.0.0.1', true], 306 ['127.0.0.1', '.0.0.1', false], 307 ['www.example.com', '.example.com', true], 308 ['deep.within.example.com', '.example.com', true], 309 ['example.com', '.com', false], 310 ['anotherexample.com', 'example.com', false], 311 ['whatever.msk.ru', '.msk.ru', true], 312 ['whatever.co.uk', '.co.uk', true], 313 ['whatever.bd', '.whatever.bd', true], 314 ['whatever.tokyo.jp', '.whatever.tokyo.jp', true], 315 ['metro.tokyo.jp', '.metro.tokyo.jp', true], 316 ['foo.bar', '.foo.bar', true] 317 ]; 318 } 319 320 public static function PSLdomainsProvider() 321 { 322 return [ 323 ['localhost', 'localhost', true], 324 ['www.example.com', 'www.example.com', true], 325 ['127.0.0.1', '127.0.0.1', true], 326 ['127.0.0.1', '.0.0.1', false], 327 ['www.example.com', '.example.com', true], 328 ['deep.within.example.com', '.example.com', true], 329 ['example.com', '.com', false], 330 ['anotherexample.com', 'example.com', false], 331 ['whatever.msk.ru', '.msk.ru', false], 332 ['whatever.co.uk', '.co.uk', false], 333 ['whatever.bd', '.whatever.bd', false], 334 ['com.bn', '.com.bn', false], 335 ['nic.tr', '.nic.tr', true], 336 ['foo.bar', '.foo.bar', true] 337 ]; 338 } 339 340 public static function cookieAndSetterProvider() 341 { 342 return [ 343 [ 344 [ 345 'name' => 'foo', 346 'value' => 'bar', 347 'domain' => null, 348 'path' => null, 349 'expires' => null, 350 'secure' => false 351 ], 352 new Net_URL2('http://example.com/directory/file.php'), 353 [ 354 'domain' => 'example.com', 355 'path' => '/directory/' 356 ] 357 ], 358 [ 359 [ 360 'name' => 'foo', 361 'value' => 'bar', 362 'domain' => '.example.com', 363 'path' => null, 364 'expires' => null, 365 'secure' => false 366 ], 367 new Net_URL2('http://example.com/path/to/file.php'), 368 [ 369 'path' => '/path/to/' 370 ] 371 ], 372 [ 373 [ 374 'name' => 'foo', 375 'value' => 'bar', 376 'domain' => null, 377 'path' => '/', 378 'expires' => null, 379 'secure' => false 380 ], 381 new Net_URL2('http://example.com/another/file.php'), 382 [ 383 'domain' => 'example.com' 384 ] 385 ] 386 ]; 387 } 388 389 public static function cookieMatchProvider() 390 { 391 return [ 392 ['http://www.example.com/path/file.php', 4], 393 ['https://www.example.com/path/file.php', 5], 394 ['http://example.com/path/file.php', 3], 395 ['http://specific.example.com/path/file.php', 4], 396 ['http://specific.example.com/other/file.php', 3], 397 ['http://another.example.com/another', 2] 398 ]; 399 } 400} 401?>