From 7d0a84d196d2a00c00804158bd3366a1b946dc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 27 Jan 2018 13:27:54 +0100 Subject: [PATCH] Fix ignoring invalid double Transfer-Encoding --- src/Response.php | 34 +++++++++++++++++++++++++--------- tests/ResponseTest.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Response.php b/src/Response.php index 6aa1f12..88605dd 100644 --- a/src/Response.php +++ b/src/Response.php @@ -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')); @@ -75,6 +68,29 @@ 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) + { + $name = strtolower($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) { diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 2bea171..d7ad6b8 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -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() + ); + } }