Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit fcb2117

Browse files
committed
#127 Set-Cookie: added ability to set value without URL encoding
1 parent bdfe6ca commit fcb2117

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

src/Header/Cookie.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,20 @@ public function __construct(array $array = [])
7575
parent::__construct($array, ArrayObject::ARRAY_AS_PROPS);
7676
}
7777

78+
/**
79+
* @param bool $encodeValue
80+
*
81+
* @return $this
82+
*/
7883
public function setEncodeValue($encodeValue)
7984
{
8085
$this->encodeValue = (bool) $encodeValue;
8186
return $this;
8287
}
8388

89+
/**
90+
* @return bool
91+
*/
8492
public function getEncodeValue()
8593
{
8694
return $this->encodeValue;

src/Header/SetCookie.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ class SetCookie implements MultipleHeaderInterface
8585
*/
8686
protected $httponly;
8787

88+
/**
89+
* @var bool
90+
*/
91+
protected $encodeValue = true;
92+
8893
/**
8994
* @static
9095
* @throws Exception\InvalidArgumentException
@@ -99,6 +104,7 @@ public static function fromString($headerLine, $bypassHeaderFieldName = false)
99104
if ($setCookieProcessor === null) {
100105
$setCookieClass = get_called_class();
101106
$setCookieProcessor = function ($headerLine) use ($setCookieClass) {
107+
/** @var SetCookie $header */
102108
$header = new $setCookieClass();
103109
$keyValuePairs = preg_split('#;\s*#', $headerLine);
104110

@@ -115,6 +121,11 @@ public static function fromString($headerLine, $bypassHeaderFieldName = false)
115121
if ($header->getName() === null) {
116122
$header->setName($headerKey);
117123
$header->setValue(urldecode($headerValue));
124+
125+
// set no encode value if raw and encoded values are the same
126+
if (urldecode($headerValue) === $headerValue) {
127+
$header->setEncodeValue(false);
128+
}
118129
continue;
119130
}
120131

@@ -213,6 +224,22 @@ public function __construct(
213224
->setHttpOnly($httponly);
214225
}
215226

227+
/**
228+
* @return bool
229+
*/
230+
public function getEncodeValue()
231+
{
232+
return $this->encodeValue;
233+
}
234+
235+
/**
236+
* @param bool $encodeValue
237+
*/
238+
public function setEncodeValue($encodeValue)
239+
{
240+
$this->encodeValue = (bool) $encodeValue;
241+
}
242+
216243
/**
217244
* @return string 'Set-Cookie'
218245
*/
@@ -231,7 +258,7 @@ public function getFieldValue()
231258
return '';
232259
}
233260

234-
$value = urlencode($this->getValue());
261+
$value = $this->encodeValue ? urlencode($this->getValue()) : $this->getValue();
235262
if ($this->hasQuoteFieldValue()) {
236263
$value = '"' . $value . '"';
237264
}

test/Header/SetCookieTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public function testSetCookieFromStringWithQuotedValue()
5050
$this->assertEquals('myname=quotedValue', $setCookieHeader->getFieldValue());
5151
}
5252

53+
public function testSetCookieFromStringWithNotEncodedValue()
54+
{
55+
$setCookieHeader = SetCookie::fromString('Set-Cookie: foo=a:b; Path=/');
56+
$this->assertFalse($setCookieHeader->getEncodeValue());
57+
$this->assertEquals('a:b', $setCookieHeader->getValue());
58+
$this->assertEquals('foo=a:b; Path=/', $setCookieHeader->getFieldValue());
59+
}
60+
5361
public function testSetCookieFromStringCreatesValidSetCookieHeader()
5462
{
5563
$setCookieHeader = SetCookie::fromString('Set-Cookie: xxx');
@@ -457,6 +465,25 @@ public function testPreventsCRLFAttackViaSetValue()
457465
$this->assertEquals('Set-Cookie: leo_auth_token=example%0D%0A%0D%0AevilContent', $header->toString());
458466
}
459467

468+
public function testSetCookieWithEncodeValue()
469+
{
470+
$header = new SetCookie('test');
471+
$header->setValue('a:b');
472+
473+
$this->assertSame('a:b', $header->getValue());
474+
$this->assertSame('test=a%3Ab', $header->getFieldValue());
475+
}
476+
477+
public function testSetCookieWithNoEncodeValue()
478+
{
479+
$header = new SetCookie('test');
480+
$header->setValue('a:b');
481+
$header->setEncodeValue(false);
482+
483+
$this->assertSame('a:b', $header->getValue());
484+
$this->assertSame('test=a:b', $header->getFieldValue());
485+
}
486+
460487
public function setterInjections()
461488
{
462489
return [

0 commit comments

Comments
 (0)