@@ -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 }
0 commit comments