diff --git a/src/Cookie/ResponseCookie.php b/src/Cookie/ResponseCookie.php index 006b19f..3d2c08a 100644 --- a/src/Cookie/ResponseCookie.php +++ b/src/Cookie/ResponseCookie.php @@ -22,6 +22,9 @@ final class ResponseCookie 'D M d H:i:s Y T', ]; + /** @var string[] */ + private $unknownAttributes = []; + /** * Parses a cookie from a 'set-cookie' header. * @@ -49,6 +52,7 @@ public static function fromHeader(string $string) // httpOnly must default to false for parsing $meta = CookieAttributes::empty(); + $unknownAttributes = []; foreach ($parts as $part) { $pieces = \array_map('trim', \explode('=', $part, 2)); @@ -63,6 +67,10 @@ public static function fromHeader(string $string) case 'httponly': $meta = $meta->withHttpOnly(); break; + + default: + $unknownAttributes[] = $part; + break; } } else { switch ($key) { @@ -94,12 +102,19 @@ public static function fromHeader(string $string) case 'domain': $meta = $meta->withDomain($pieces[1]); break; + + default: + $unknownAttributes[] = $part; + break; } } } try { - return new self($name, $value, $meta); + $cookie = new self($name, $value, $meta); + $cookie->unknownAttributes = $unknownAttributes; + + return $cookie; } catch (InvalidCookieException $e) { return null; } @@ -327,6 +342,11 @@ public function __toString(): string $line = $this->name . '=' . $this->value; $line .= $this->attributes; + $unknownAttributes = \implode('; ', $this->unknownAttributes); + if ($unknownAttributes !== '') { + $line .= '; ' . $unknownAttributes; + } + return $line; } } diff --git a/test/Cookie/ResponseCookieTest.php b/test/Cookie/ResponseCookieTest.php index 7250a71..a02bd08 100644 --- a/test/Cookie/ResponseCookieTest.php +++ b/test/Cookie/ResponseCookieTest.php @@ -248,4 +248,14 @@ public function testInvalidCookieValueModify() $cookie->withValue('what is this'); } + + public function testPreservesUnknownAttributes() + { + $cookie = ResponseCookie::fromHeader('key=value; HttpOnly; SameSite=strict;Foobar'); + $this->assertNotNull($cookie); + $this->assertSame('key', $cookie->getName()); + $this->assertSame('value', $cookie->getValue()); + $this->assertTrue($cookie->isHttpOnly()); + $this->assertSame('key=value; HttpOnly; SameSite=strict; Foobar', (string) $cookie); + } }