diff --git a/src/Response.php b/src/Response.php index bab5fc0f..968894ab 100644 --- a/src/Response.php +++ b/src/Response.php @@ -96,15 +96,19 @@ public function write($data) throw new \Exception('Response head has not yet been written.'); } + // prefix with chunk length for chunked transfer encoding if ($this->chunkedEncoding) { $len = strlen($data); - $chunk = dechex($len)."\r\n".$data."\r\n"; - $flushed = $this->conn->write($chunk); - } else { - $flushed = $this->conn->write($data); + + // skip empty chunks + if ($len === 0) { + return true; + } + + $data = dechex($len) . "\r\n" . $data . "\r\n"; } - return $flushed; + return $this->conn->write($data); } public function end($data = null) diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 11407f28..db47d835 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -77,6 +77,33 @@ public function testResponseBodyShouldBeChunkedCorrectly() $response->end(); } + public function testResponseBodyShouldSkipEmptyChunks() + { + $conn = $this + ->getMockBuilder('React\Socket\ConnectionInterface') + ->getMock(); + $conn + ->expects($this->at(4)) + ->method('write') + ->with("5\r\nHello\r\n"); + $conn + ->expects($this->at(5)) + ->method('write') + ->with("5\r\nWorld\r\n"); + $conn + ->expects($this->at(6)) + ->method('write') + ->with("0\r\n\r\n"); + + $response = new Response($conn); + $response->writeHead(); + + $response->write('Hello'); + $response->write(''); + $response->write('World'); + $response->end(); + } + public function testResponseShouldEmitEndOnStreamEnd() { $ended = false;