Skip to content
Permalink
Browse files

Add cookie parsing to convert from psr7 to cakephp.

Re-purpose the cookie parsing code that lives in the 2.x HttpSocket
here. I figured that was a good place to draw an implementation from as
its fairly battle tested and works well.
  • Loading branch information...
markstory committed Jun 22, 2016
1 parent b2f1c72 commit 6a72463c72844943638354d86330a2c55e79f982
Showing with 86 additions and 0 deletions.
  1. +50 −0 src/Http/ResponseTransformer.php
  2. +36 −0 tests/TestCase/Http/ResponseTransformerTest.php
@@ -43,6 +43,9 @@ public static function toCake(PsrResponse $response)
'body' => static::getBody($response),
];
$cake = new CakeResponse($data);
foreach (static::parseCookies($response->getHeader('Set-Cookie')) as $cookie) {
$cake->cookie($cookie);
}
$cake->header(static::collapseHeaders($response));
return $cake;
}
@@ -63,6 +66,53 @@ protected static function getBody(PsrResponse $response)
return $stream->getContents();
}
/**
* Parse the Set-Cookie headers in a PSR7 response
* into the format CakePHP expects.
*
* @param array $cookieHeader A list of Set-Cookie headers.
* @return array Parsed cookie data.
*/
protected static function parseCookies(array $cookieHeader)
{
$cookies = [];
foreach ($cookieHeader as $cookie) {
if (strpos($cookie, '";"') !== false) {
$cookie = str_replace('";"', "{__cookie_replace__}", $cookie);
$parts = preg_split('/\;[ \t]*/', $cookie);
$parts = str_replace("{__cookie_replace__}", '";"', $parts);
} else {
$parts = preg_split('/\;[ \t]*/', $cookie);
}
list($name, $value) = explode('=', array_shift($parts), 2);
$parsed = compact('name', 'value');
foreach ($parts as $part) {
if (strpos($part, '=') !== false) {
list($key, $value) = explode('=', $part);
} else {
$key = $part;
$value = true;
}
$key = strtolower($key);
if ($key === 'httponly') {
$key = 'httpOnly';
}
if ($key === 'expires') {
$key = 'expire';
$value = strtotime($value);
}
if (!isset($parsed[$key])) {
$parsed[$key] = $value;
}
}
$cookies[] = $parsed;
}
return $cookies;
}
/**
* Convert a PSR7 Response headers into a flat array
*
@@ -118,6 +118,42 @@ public function testToCakeBody()
$this->assertSame('A message for you', $result->body());
}
/**
* Test conversion getting cookies.
*
* @return void
*/
public function testToCakeCookies()
{
$cookies = [
'remember me=1";"1',
'forever=yes; Expires=Wed, 13 Jan 2021 12:30:40 GMT; Path=/some/path; Domain=example.com; HttpOnly; Secure'
];
$psr = new PsrResponse('php://memory', 200, ['Set-Cookie' => $cookies]);
$result = ResponseTransformer::toCake($psr);
$expected = [
'name' => 'remember me',
'value' => '1";"1',
'path' => '/',
'domain' => '',
'expire' => 0,
'secure' => false,
'httpOnly' => false,
];
$this->assertEquals($expected, $result->cookie('remember me'));
$expected = [
'name' => 'forever',
'value' => 'yes',
'path' => '/some/path',
'domain' => 'example.com',
'expire' => 1610541040,
'secure' => true,
'httpOnly' => true,
];
$this->assertEquals($expected, $result->cookie('forever'));
}
/**
* Test conversion setting the status code.
*

0 comments on commit 6a72463

Please sign in to comment.
You can’t perform that action at this time.