From 61c20333cd6e7c8284eb6dfc450f66bb86f37506 Mon Sep 17 00:00:00 2001 From: asrar Date: Fri, 6 Feb 2026 02:47:21 +0100 Subject: [PATCH 1/2] Add test case for httponly cookie parsing This test demonstrates the bug where cookies with the #HttpOnly_ prefix are incorrectly ignored. According to the Netscape cookie file format specification, lines starting with #HttpOnly_ should be parsed as cookies with the HttpOnly attribute set. See: https://curl.se/docs/http-cookies.html Currently fails: Expected 3 cookies (2 httponly + 1 regular) but only finds 1 (the regular cookie). --- .../Artax/NetscapeCookieFileJarTest.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/Integration/Adapter/Artax/NetscapeCookieFileJarTest.php b/tests/Integration/Adapter/Artax/NetscapeCookieFileJarTest.php index f6b3be3..67419d1 100644 --- a/tests/Integration/Adapter/Artax/NetscapeCookieFileJarTest.php +++ b/tests/Integration/Adapter/Artax/NetscapeCookieFileJarTest.php @@ -71,4 +71,41 @@ public function testLoadCookies() (yield $jar->get((new Request('http://127.0.0.1/'))->getUri()))[0]->getValue() ); } + + public function testLoadHttpOnlyCookies() + { + $expire = (new DateTimeImmutable())->modify('+1 day')->format('U'); + + $cookies = <<workspace()->path('httponly_cookies.txt'); + file_put_contents($path, $cookies); + + $jar = new NetscapeCookieFileJar($path); + + $allCookies = $jar->getAll(); + + // Should have 3 cookies total (2 httponly + 1 regular) + $this->assertCount(3, $allCookies); + + // Get cookies for example.com + $exampleCookies = yield $jar->get((new Request('https://example.com/'))->getUri()); + + // Should include the httponly cookie + $cookieNames = array_map(fn ($cookie) => $cookie->getName(), $exampleCookies); + $this->assertContains('session_id', $cookieNames); + $this->assertContains('regular_cookie', $cookieNames); + + // Verify httponly cookie value + $sessionCookie = array_filter($exampleCookies, fn ($cookie) => $cookie->getName() === 'session_id'); + $this->assertEquals('abc123', reset($sessionCookie)->getValue()); + } } From f6764eb348733c77b529d827f3fc002da6252963 Mon Sep 17 00:00:00 2001 From: asrar Date: Fri, 6 Feb 2026 02:52:31 +0100 Subject: [PATCH 2/2] Fix parsing of httponly cookies Parse cookies with #HttpOnly_ prefix according to the Netscape cookie file format specification. Previously, all lines starting with # were treated as comments, but lines starting with #HttpOnly_ indicate cookies with the HttpOnly attribute set. The fix: - Detects #HttpOnly_ prefix and strips it before parsing - Adds httponly attribute to the cookie string - Continues to treat regular # lines as comments See: https://curl.se/docs/http-cookies.html Fixes #133 --- lib/Adapter/Artax/NetscapeCookieFileJar.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/Adapter/Artax/NetscapeCookieFileJar.php b/lib/Adapter/Artax/NetscapeCookieFileJar.php index fce1a0b..be3d6d1 100644 --- a/lib/Adapter/Artax/NetscapeCookieFileJar.php +++ b/lib/Adapter/Artax/NetscapeCookieFileJar.php @@ -69,7 +69,14 @@ private function parse(string $line): ?ResponseCookie return null; } - if ($line[0] === '#') { + // Handle httponly cookies - lines starting with #HttpOnly_ should be parsed + // See: https://curl.se/docs/http-cookies.html + $isHttpOnly = false; + if (str_starts_with($line, '#HttpOnly_')) { + $line = substr($line, 10); // Remove the '#HttpOnly_' prefix + $isHttpOnly = true; + } elseif ($line[0] === '#') { + // Regular comment line, skip it return null; } @@ -104,6 +111,10 @@ private function parse(string $line): ?ResponseCookie $string .= '; secure'; } + if ($isHttpOnly) { + $string .= '; httponly'; + } + return ResponseCookie::fromHeader($string); } }