Skip to content

Commit cb9ced0

Browse files
authored
Merge pull request #381 from clue-labs/chunked-decoder
Expose `Transfer-Encoding: chunked` response header and fix chunked responses for `HEAD` requests
2 parents f674d1b + bbe6cd5 commit cb9ced0

File tree

8 files changed

+75
-529
lines changed

8 files changed

+75
-529
lines changed

src/Client/ChunkedStreamDecoder.php

Lines changed: 0 additions & 207 deletions
This file was deleted.

src/Client/Response.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ public function __construct(ReadableStreamInterface $stream, $protocol, $version
3232
$this->reasonPhrase = $reasonPhrase;
3333
$this->headers = $headers;
3434

35-
if (strtolower($this->getHeaderLine('Transfer-Encoding')) === 'chunked') {
36-
$this->stream = new ChunkedStreamDecoder($stream);
37-
$this->removeHeader('Transfer-Encoding');
38-
}
39-
4035
$this->stream->on('data', array($this, 'handleData'));
4136
$this->stream->on('error', array($this, 'handleError'));
4237
$this->stream->on('end', array($this, 'handleEnd'));
@@ -68,16 +63,6 @@ public function getHeaders()
6863
return $this->headers;
6964
}
7065

71-
private function removeHeader($name)
72-
{
73-
foreach ($this->headers as $key => $value) {
74-
if (strcasecmp($name, $key) === 0) {
75-
unset($this->headers[$key]);
76-
break;
77-
}
78-
}
79-
}
80-
8166
private function getHeader($name)
8267
{
8368
$name = strtolower($name);

src/Io/ChunkedDecoder.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public function handleData($data)
116116
}
117117

118118
if ($hexValue !== '') {
119-
$hexValue = \ltrim($hexValue, "0");
119+
$hexValue = \ltrim(\trim($hexValue), "0");
120120
if ($hexValue === '') {
121121
$hexValue = "0";
122122
}
@@ -155,16 +155,19 @@ public function handleData($data)
155155
$this->headerCompleted = false;
156156
$this->transferredSize = 0;
157157
$this->buffer = (string)\substr($this->buffer, 2);
158+
} elseif ($this->chunkSize === 0) {
159+
// end chunk received, skip all trailer data
160+
$this->buffer = (string)\substr($this->buffer, $positionCrlf);
158161
}
159162

160-
if ($positionCrlf !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) > 2) {
161-
// the first 2 characters are not CLRF, send error event
162-
$this->handleError(new Exception('Chunk does not end with a CLRF'));
163+
if ($positionCrlf !== 0 && $this->chunkSize !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) > 2) {
164+
// the first 2 characters are not CRLF, send error event
165+
$this->handleError(new Exception('Chunk does not end with a CRLF'));
163166
return;
164167
}
165168

166169
if ($positionCrlf !== 0 && \strlen($this->buffer) < 2) {
167-
// No CLRF found, wait for additional data which could be a CLRF
170+
// No CRLF found, wait for additional data which could be a CRLF
168171
return;
169172
}
170173
}

src/Io/Sender.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,12 @@ public function send(RequestInterface $request)
110110

111111
$requestStream->on('response', function (ResponseStream $responseStream) use ($deferred, $request) {
112112
$length = null;
113+
$body = $responseStream;
113114
$code = $responseStream->getCode();
114115
if ($request->getMethod() === 'HEAD' || ($code >= 100 && $code < 200) || $code == 204 || $code == 304) {
115116
$length = 0;
117+
} elseif (\strtolower($responseStream->getHeaderLine('Transfer-Encoding')) === 'chunked') {
118+
$body = new ChunkedDecoder($body);
116119
} elseif ($responseStream->hasHeader('Content-Length')) {
117120
$length = (int) $responseStream->getHeaderLine('Content-Length');
118121
}
@@ -121,7 +124,7 @@ public function send(RequestInterface $request)
121124
$deferred->resolve(new Response(
122125
$responseStream->getCode(),
123126
$responseStream->getHeaders(),
124-
new ReadableBodyStream($responseStream, $length),
127+
new ReadableBodyStream($body, $length),
125128
$responseStream->getVersion(),
126129
$responseStream->getReasonPhrase()
127130
));

0 commit comments

Comments
 (0)