Skip to content

Commit

Permalink
Fix ignoring invalid double Transfer-Encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
clue committed Feb 6, 2018
1 parent 924baa2 commit 53bec1a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
33 changes: 24 additions & 9 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,10 @@ public function __construct(ReadableStreamInterface $stream, $protocol, $version
$this->code = $code;
$this->reasonPhrase = $reasonPhrase;
$this->headers = $headers;
$normalizedHeaders = array_change_key_case($headers, CASE_LOWER);

if (isset($normalizedHeaders['transfer-encoding']) && strtolower($normalizedHeaders['transfer-encoding']) === 'chunked') {
if (strtolower($this->getHeaderLine('Transfer-Encoding')) === 'chunked') {
$this->stream = new ChunkedStreamDecoder($stream);

foreach ($this->headers as $key => $value) {
if (strcasecmp('transfer-encoding', $key) === 0) {
unset($this->headers[$key]);
break;
}
}
$this->removeHeader('Transfer-Encoding');
}

$this->stream->on('data', array($this, 'handleData'));
Expand Down Expand Up @@ -75,6 +68,28 @@ public function getHeaders()
return $this->headers;
}

private function removeHeader($name)
{
foreach ($this->headers as $key => $value) {
if (strcasecmp($name, $key) === 0) {
unset($this->headers[$key]);
break;
}
}
}

private function getHeader($name)
{
$normalized = array_change_key_case($this->headers, CASE_LOWER);

return isset($normalized[$name]) ? array($normalized[$name]) : array();
}

private function getHeaderLine($name)
{
return implode(', ' , $this->getHeader($name));
}

/** @internal */
public function handleData($data)
{
Expand Down
31 changes: 31 additions & 0 deletions tests/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,36 @@ public function chunkedEncodingResponse()
$response->getHeaders()
);
}

/** @test */
public function doubleChunkedEncodingResponseWillBePassedAsIs()
{
$stream = new ThroughStream();
$response = new Response(
$stream,
'http',
'1.0',
'200',
'ok',
array(
'content-type' => 'text/plain',
'transfer-encoding' => array(
'chunked',
'chunked'
)
)
);

$this->assertSame(
array(
'content-type' => 'text/plain',
'transfer-encoding' => array(
'chunked',
'chunked'
)
),
$response->getHeaders()
);
}
}

0 comments on commit 53bec1a

Please sign in to comment.