Skip to content

Upgrade to react/http instead of react/http-client which is deprecated. #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 17, 2020
Merged
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: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/phpspec.yml
/phpunit.xml
/vendor/
.phpunit.result.cache
3 changes: 0 additions & 3 deletions .styleci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,5 @@ finder:
- "src"
- "tests"

enabled:
- short_array_syntax

disabled:
- phpdoc_annotation_without_dot # This is still buggy: https://github.com/symfony/symfony/pull/19198
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Work with HTTPlug 2, drop HTTPlug 1 support
- Move to `react/http` library instead of `react/http-client`

## [2.3.0] - 2019-07-30

Expand Down
13 changes: 5 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,20 @@
"authors": [
{
"name": "Stéphane HULARD",
"email": "s.hulard@gmail.com"
"email": "s.hulard@chstudio.fr"
}
],
"require": {
"php": "^7.1",
"php-http/httplug": "^2.0",
"react/http-client": "~0.5.9",
"react/dns": "^1.0|^0.4.15",
"react/socket": "^1.0",
"react/stream": "^1.0",
"react/http": "^1.0",
"react/event-loop": "^1.0",
"php-http/discovery": "^1.0"
},
"require-dev": {
"php-http/client-integration-tests": "^2.0",
"php-http/client-integration-tests": "^3.0",
"php-http/message": "^1.0",
"phpunit/phpunit": "^4.8.36 || ^5.4"
"nyholm/psr7": "^1.3"
},
"provide": {
"php-http/client-implementation": "1.0",
Expand All @@ -45,7 +42,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
"dev-master": "3.x-dev"
}
}
}
135 changes: 15 additions & 120 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,22 @@

use Http\Client\HttpClient;
use Http\Client\HttpAsyncClient;
use Http\Client\Exception\HttpException;
use Http\Client\Exception\RequestException;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Discovery\StreamFactoryDiscovery;
use Http\Message\ResponseFactory;
use Http\Message\StreamFactory;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use React\EventLoop\LoopInterface;
use React\HttpClient\Client as ReactClient;
use React\HttpClient\Request as ReactRequest;
use React\HttpClient\Response as ReactResponse;
use React\Http\Browser as ReactBrowser;

/**
* Client for the React promise implementation.
*
* @author Stéphane Hulard <stephane@hlrd.me>
* @author Stéphane Hulard <s.hulard@chstudio.fr>
*/
class Client implements HttpClient, HttpAsyncClient
{
/**
* React HTTP client.
*
* @var Client
* @var ReactBrowser
*/
private $client;

Expand All @@ -39,41 +30,19 @@ class Client implements HttpClient, HttpAsyncClient
*/
private $loop;

/**
* @var ResponseFactory
*/
private $responseFactory;

/**
* @var StreamFactory
*/
private $streamFactory;

/**
* Initialize the React client.
*
* @param ResponseFactory|null $responseFactory
* @param LoopInterface|null $loop
* @param ReactClient|null $client
* @param StreamFactory|null $streamFactory
*/
public function __construct(
ResponseFactory $responseFactory = null,
LoopInterface $loop = null,
ReactClient $client = null,
StreamFactory $streamFactory = null
ReactBrowser $client = null
) {
if (null !== $client && null === $loop) {
throw new \RuntimeException(
'You must give a LoopInterface instance with the Client'
);
throw new \RuntimeException('You must give a LoopInterface instance with the Client');
}

$this->loop = $loop ?: ReactFactory::buildEventLoop();
$this->client = $client ?: ReactFactory::buildHttpClient($this->loop);

$this->responseFactory = $responseFactory ?: MessageFactoryDiscovery::find();
$this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find();
}

/**
Expand All @@ -91,91 +60,17 @@ public function sendRequest(RequestInterface $request): ResponseInterface
*/
public function sendAsyncRequest(RequestInterface $request)
{
$reactRequest = $this->buildReactRequest($request);
$promise = new Promise($this->loop);

$reactRequest->on('error', function (\Exception $error) use ($promise, $request) {
$promise->reject(new RequestException(
$error->getMessage(),
$request,
$error
));
});

$reactRequest->on('response', function (ReactResponse $reactResponse = null) use ($promise, $request) {
$bodyStream = $this->streamFactory->createStream();
$reactResponse->on('data', function ($data) use (&$bodyStream) {
$bodyStream->write((string) $data);
});

$reactResponse->on('end', function (\Exception $error = null) use ($promise, $request, $reactResponse, &$bodyStream) {
$response = $this->buildResponse(
$reactResponse,
$bodyStream
);
if (null !== $error) {
$promise->reject(new HttpException(
$error->getMessage(),
$request,
$response,
$error
));
} else {
$promise->resolve($response);
}
});
});

$reactRequest->end((string) $request->getBody());

return $promise;
}

/**
* Build a React request from the PSR7 RequestInterface.
*
* @param RequestInterface $request
*
* @return ReactRequest
*/
private function buildReactRequest(RequestInterface $request)
{
$headers = [];

foreach ($request->getHeaders() as $name => $value) {
$headers[$name] = (is_array($value) ? $value[0] : $value);
}

$reactRequest = $this->client->request(
$request->getMethod(),
(string) $request->getUri(),
$headers,
$request->getProtocolVersion()
$promise = new Promise(
$this->client->request(
$request->getMethod(),
$request->getUri(),
$request->getHeaders(),
$request->getBody()
),
$this->loop,
$request
);

return $reactRequest;
}

/**
* Transform a React Response to a valid PSR7 ResponseInterface instance.
*
* @param ReactResponse $response
* @param StreamInterface $body
*
* @return ResponseInterface
*/
private function buildResponse(
ReactResponse $response,
StreamInterface $body
) {
$body->rewind();

return $this->responseFactory->createResponse(
$response->getCode(),
$response->getReasonPhrase(),
$response->getHeaders(),
$body,
$response->getVersion()
);
return $promise;
}
}
Loading