Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ $loop->run();

## TODO

* gzip content encoding
* chunked transfer encoding
* keep-alive connections
* following redirections
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"react/event-loop": "0.4.*",
"react/stream": "0.4.*",
"react/promise": "~2.2",
"evenement/evenement": "~2.0"
"evenement/evenement": "~2.0",
"clue/zlib-react": "^0.1.0"
},
"autoload": {
"psr-4": {
Expand Down
8 changes: 6 additions & 2 deletions src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public function handleData($data)

$this->emit('response', array($response, $this));

$response->emit('data', array($bodyChunk, $response));
$this->stream->emit('data', array($bodyChunk));
}
}

Expand Down Expand Up @@ -238,11 +238,15 @@ public function setResponseFactory($factory)
$this->responseFactory = $factory;
}

public function getResponseFactory()
public function getResponseFactory($psrResponse = null)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very fond of solving it this way, any suggestions to do it better then this are very welcome

{
if (null === $factory = $this->responseFactory) {
$stream = $this->stream;

if ($psrResponse != null) {
$stream = StreamDecoder::detect($stream, $psrResponse);
}

$factory = function ($protocol, $version, $code, $reasonPhrase, $headers) use ($stream) {
return new Response(
$stream,
Expand Down
5 changes: 3 additions & 2 deletions src/RequestData.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ private function mergeDefaultheaders(array $headers)

return array_merge(
array(
'Host' => $this->getHost().$port,
'User-Agent' => 'React/alpha',
'Host' => $this->getHost().$port,
'User-Agent' => 'React/alpha',
'Accept-Encoding' => 'gzip',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be gzip and deflate

),
$connectionHeaders,
$authHeaders,
Expand Down
32 changes: 32 additions & 0 deletions src/StreamDecoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace React\HttpClient;

use Clue\React\Zlib\ZlibFilterStream;
use GuzzleHttp\Psr7\Response as psr7Response;
use React\Stream\DuplexStreamInterface;

class StreamDecoder
{
public static function detect(DuplexStreamInterface $stream, psr7Response $response)
{
if ($response->hasHeader('content-encoding')) {
$stream = static::contentEncoding($stream, $response->getHeaderLine('content-encoding'));
}

return $stream;
}

protected static function contentEncoding($stream, $encoding)
{
if ($encoding == 'gzip') {
return $stream->pipe(ZlibFilterStream::createGzipDecompressor());
}

if ($encoding == 'deflate') {
return $stream->pipe(ZlibFilterStream::createDeflateDecompressor());
}

return $stream;
}
}
4 changes: 4 additions & 0 deletions tests/RequestDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public function toStringReturnsHTTPRequestMessage()
$expected = "GET / HTTP/1.0\r\n" .
"Host: www.example.com\r\n" .
"User-Agent: React/alpha\r\n" .
"Accept-Encoding: gzip\r\n" .
"\r\n";

$this->assertSame($expected, $requestData->__toString());
Expand All @@ -28,6 +29,7 @@ public function toStringReturnsHTTPRequestMessageWithProtocolVersion()
$expected = "GET / HTTP/1.1\r\n" .
"Host: www.example.com\r\n" .
"User-Agent: React/alpha\r\n" .
"Accept-Encoding: gzip\r\n" .
"Connection: close\r\n" .
"\r\n";

Expand All @@ -42,6 +44,7 @@ public function toStringReturnsHTTPRequestMessageWithProtocolVersionThroughConst
$expected = "GET / HTTP/1.1\r\n" .
"Host: www.example.com\r\n" .
"User-Agent: React/alpha\r\n" .
"Accept-Encoding: gzip\r\n" .
"Connection: close\r\n" .
"\r\n";

Expand All @@ -56,6 +59,7 @@ public function toStringUsesUserPassFromURL()
$expected = "GET / HTTP/1.0\r\n" .
"Host: www.example.com\r\n" .
"User-Agent: React/alpha\r\n" .
"Accept-Encoding: gzip\r\n" .
"Authorization: Basic am9objpkdW1teQ==\r\n" .
"\r\n";

Expand Down
16 changes: 8 additions & 8 deletions tests/RequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ public function requestShouldBindToStreamEventsAndUseconnector()
->expects($this->at(8))
->method('removeListener')
->with('error', $this->identicalTo(array($request, 'handleError')));
$this->stream
->expects($this->at(9))
->method('emit')
->with('data', array('body'));

$response = $this->response;

$response->expects($this->once())
->method('emit')
->with('data', array('body', $response));

$response->expects($this->at(0))
->method('on')
->with('end', $this->anything())
Expand Down Expand Up @@ -249,7 +249,7 @@ public function postRequestShouldSendAPostRequest()
$this->stream
->expects($this->at(4))
->method('write')
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\n\r\n$#"));
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\nAccept-Encoding: gzip\r\n\r\n$#"));
$this->stream
->expects($this->at(5))
->method('write')
Expand Down Expand Up @@ -279,7 +279,7 @@ public function writeWithAPostRequestShouldSendToTheStream()
$this->stream
->expects($this->at(4))
->method('write')
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\n\r\n$#"));
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\nAccept-Encoding: gzip\r\n\r\n$#"));
$this->stream
->expects($this->at(5))
->method('write')
Expand Down Expand Up @@ -320,7 +320,7 @@ public function writeWithAPostRequestShouldSendBodyAfterHeadersAndEmitDrainEvent
$this->stream
->expects($this->at(4))
->method('write')
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\n\r\n$#"));
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\nAccept-Encoding: gzip\r\n\r\n$#"));
$this->stream
->expects($this->at(5))
->method('write')
Expand Down Expand Up @@ -367,7 +367,7 @@ public function pipeShouldPipeDataIntoTheRequestBody()
$this->stream
->expects($this->at(4))
->method('write')
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\n\r\n$#"));
->with($this->matchesRegularExpression("#^POST / HTTP/1\.0\r\nHost: www.example.com\r\nUser-Agent:.*\r\nAccept-Encoding: gzip\r\n\r\n$#"));
$this->stream
->expects($this->at(5))
->method('write')
Expand Down
53 changes: 53 additions & 0 deletions tests/StreamDecoderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace React\Tests\HttpClient;

use GuzzleHttp\Psr7\Response as psr7Response;
use React\HttpClient\StreamDecoder;
use React\Stream\ThroughStream;

class StreamDecoderTest extends TestCase
{
public function providerDetect()
{
return [
[
new psr7Response(200),
'React\Stream\ThroughStream',
],
[
new psr7Response(200, [
'Content-Encoding' => [
'gzip'
],
]),
'Clue\React\Zlib\ZlibFilterStream',
],
[
new psr7Response(200, [
'Content-Encoding' => [
'deflate'
],
]),
'Clue\React\Zlib\ZlibFilterStream',
],
[
new psr7Response(200, [
'Content-Encoding' => [
'foobar'
],
]),
'React\Stream\ThroughStream',
],
];
}

/**
* @dataProvider providerDetect
*/
public function testDetect($response, $instanceOf)
{
$stream = StreamDecoder::detect(new ThroughStream(), $response);
$this->assertInstanceOf($instanceOf, $stream);
}
}