Skip to content

Support PSR-17 #52

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 4 commits into from
Jan 24, 2019
Merged
Show file tree
Hide file tree
Changes from 2 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
18 changes: 10 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
{
"name": "php-http/curl-client",
"description": "cURL client for PHP-HTTP",
"description": "PSR-18 cURL client",
"license": "MIT",
"keywords": ["http", "curl"],
"keywords": [
"curl",
"http",
"psr-18"
],
"homepage": "http://php-http.org",
"authors": [
{
Expand All @@ -12,23 +16,21 @@
],
"prefer-stable": true,
"minimum-stability": "dev",
"config": {
"bin-dir": "vendor/bin"
},
"require": {
"php": "^7.1",
"ext-curl": "*",
"php-http/discovery": "^1.0",
"php-http/httplug": "^2.0",
"php-http/message-factory": "^1.0.2",
"php-http/message": "^1.2",
"php-http/discovery": "^1.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"symfony/options-resolver": "^3.4 || ^4.0"
},
"require-dev": {
"guzzlehttp/psr7": "^1.0",
"php-http/client-integration-tests": "dev-master",
"phpunit/phpunit": "^7.5",
"zendframework/zend-diactoros": "^1.0"
"zendframework/zend-diactoros": "^2.0"
},
"autoload": {
"psr-4": {
Expand Down
39 changes: 32 additions & 7 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" bootstrap="tests/bootstrap.php">

<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/7.0/phpunit.xsd"
bootstrap="tests/bootstrap.php"
colors="true"
>
<php>
<server name="TEST_SERVER" value="http://127.0.0.1:10000/server.php"/>
</php>

<testsuites>
<testsuite name="Curl Client Test Suite">
<directory>tests/</directory>

<testsuite name="All">
<directory>tests</directory>
<!-- Exclude till https://github.com/php-http/message/issues/105 resolved. -->
<exclude>tests/Functional/HttpAsyncClientGuzzleTest.php</exclude>
<exclude>tests/Functional/HttpClientGuzzleTest.php</exclude>
</testsuite>

<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>

<testsuite name="Functional">
<directory>tests/Functional</directory>
<!-- Exclude till https://github.com/php-http/message/issues/105 resolved. -->
<exclude>tests/Functional/HttpAsyncClientGuzzleTest.php</exclude>
<exclude>tests/Functional/HttpClientGuzzleTest.php</exclude>
</testsuite>

</testsuites>
<php>
<server name="TEST_SERVER" value="http://127.0.0.1:10000/server.php" />
</php>

<filter>
<whitelist>
<directory suffix=".php">src/</directory>
<directory>src</directory>
</whitelist>
</filter>

</phpunit>
65 changes: 35 additions & 30 deletions src/Client.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<?php

declare(strict_types=1);

namespace Http\Client\Curl;

use Http\Client\Exception;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Discovery\StreamFactoryDiscovery;
use Http\Message\MessageFactory;
use Http\Message\StreamFactory;
use Http\Promise\Promise;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
Expand All @@ -35,16 +37,16 @@ class Client implements HttpClient, HttpAsyncClient
private $options;

/**
* PSR-7 message factory.
* PSR-17 response factory.
*
* @var MessageFactory
* @var ResponseFactoryInterface
*/
private $messageFactory;
private $responseFactory;

/**
* PSR-7 stream factory.
* PSR-17 stream factory.
*
* @var StreamFactory
* @var StreamFactoryInterface
*/
private $streamFactory;

Expand All @@ -53,37 +55,43 @@ class Client implements HttpClient, HttpAsyncClient
*
* @var resource|null
*/
private $handle = null;
private $handle;

/**
* Simultaneous requests runner.
*
* @var MultiRunner|null
*/
private $multiRunner = null;
private $multiRunner;

/**
* @param MessageFactory|null $messageFactory HTTP Message factory
* @param StreamFactory|null $streamFactory HTTP Stream factory
* @param array $options cURL options {@link http://php.net/curl_setopt}
* Construct client.
*
* @param ResponseFactoryInterface|null $responseFactory PSR-17 HTTP response factory.
* @param StreamFactoryInterface|null $streamFactory PSR-17 HTTP stream factory.
* @param array $options cURL options {@link http://php.net/curl_setopt}
*
* @throws \Http\Discovery\Exception\NotFoundException If factory discovery failed
*
* @since x.x $messageFactory changed to PSR-17 ResponseFactoryInterface $responseFactory.
* @since x.x $streamFactory type changed to PSR-17 StreamFactoryInterface.
* @since 1.0
*/
public function __construct(
MessageFactory $messageFactory = null,
StreamFactory $streamFactory = null,
ResponseFactoryInterface $responseFactory = null,
StreamFactoryInterface $streamFactory = null,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe make these required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm for that.

Copy link
Contributor

Choose a reason for hiding this comment

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

we can now use the psr17 factory for these. lets keep using that for ease of use?

array $options = []
) {
$this->messageFactory = $messageFactory ?: MessageFactoryDiscovery::find();
$this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find();
$this->responseFactory = $responseFactory; // FIXME ?: MessageFactoryDiscovery::find();
$this->streamFactory = $streamFactory; // FIXME ?: StreamFactoryDiscovery::find();
$resolver = new OptionsResolver();
$resolver->setDefaults([
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_FOLLOWLOCATION => false,
]);
$resolver->setDefaults(
[
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_FOLLOWLOCATION => false,
]
);
$resolver->setAllowedValues(CURLOPT_HEADER, [false]); // our parsing will fail if this is set to true
$resolver->setAllowedValues(CURLOPT_RETURNTRANSFER, [false]); // our parsing will fail if this is set to true

Expand All @@ -105,7 +113,7 @@ public function __destruct()
}

/**
* Sends a PSR-7 request.
* Sends a PSR-7 request and returns a PSR-7 response.
*
* @param RequestInterface $request
*
Expand Down Expand Up @@ -363,17 +371,14 @@ private function createHeaders(RequestInterface $request, array $options): array
* Create new ResponseBuilder instance.
*
* @return ResponseBuilder
*
* @throws \RuntimeException If creating the stream from $body fails
*/
private function createResponseBuilder(): ResponseBuilder
{
try {
$body = $this->streamFactory->createStream(fopen('php://temp', 'w+b'));
} catch (\InvalidArgumentException $e) {
throw new \RuntimeException('Can not create "php://temp" stream.');
}
$response = $this->messageFactory->createResponse(200, null, [], $body);
$body = $this->streamFactory->createStreamFromFile('php://temp', 'w+b');

$response = $this->responseFactory
->createResponse(200)
->withBody($body);

return new ResponseBuilder($response);
}
Expand Down
10 changes: 5 additions & 5 deletions src/MultiRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class MultiRunner
*
* @var resource|null
*/
private $multiHandle = null;
private $multiHandle;

/**
* Awaiting cores.
Expand All @@ -43,7 +43,7 @@ public function __destruct()
*
* @param PromiseCore $core
*/
public function add(PromiseCore $core)
public function add(PromiseCore $core): void
{
foreach ($this->cores as $existed) {
if ($existed === $core) {
Expand All @@ -64,7 +64,7 @@ public function add(PromiseCore $core)
*
* @param PromiseCore $core
*/
public function remove(PromiseCore $core)
public function remove(PromiseCore $core): void
{
foreach ($this->cores as $index => $existed) {
if ($existed === $core) {
Expand All @@ -81,7 +81,7 @@ public function remove(PromiseCore $core)
*
* @param PromiseCore|null $targetCore
*/
public function wait(PromiseCore $targetCore = null)
public function wait(PromiseCore $targetCore = null): void
{
do {
$status = curl_multi_exec($this->multiHandle, $active);
Expand Down Expand Up @@ -118,7 +118,7 @@ public function wait(PromiseCore $targetCore = null)
*
* @return PromiseCore|null
*/
private function findCoreByHandle($handle)
private function findCoreByHandle($handle): ?PromiseCore
{
foreach ($this->cores as $core) {
if ($core->getHandle() === $handle) {
Expand Down
20 changes: 10 additions & 10 deletions src/PromiseCore.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function __construct(
*
* @param callable $callback
*/
public function addOnFulfilled(callable $callback)
public function addOnFulfilled(callable $callback): void
{
if ($this->getState() === Promise::PENDING) {
$this->onFulfilled[] = $callback;
Expand All @@ -126,7 +126,7 @@ public function addOnFulfilled(callable $callback)
*
* @param callable $callback
*/
public function addOnRejected(callable $callback)
public function addOnRejected(callable $callback): void
{
if ($this->getState() === Promise::PENDING) {
$this->onRejected[] = $callback;
Expand All @@ -150,7 +150,7 @@ public function getHandle()
*
* @return string
*/
public function getState()
public function getState(): string
{
return $this->state;
}
Expand All @@ -160,17 +160,17 @@ public function getState()
*
* @return RequestInterface
*/
public function getRequest()
public function getRequest(): RequestInterface
{
return $this->request;
}

/**
* Return the value of the promise (fulfilled).
*
* @return ResponseInterface Response Object only when the Promise is fulfilled
* @return ResponseInterface Response object only when the Promise is fulfilled
*/
public function getResponse()
public function getResponse(): ResponseInterface
{
return $this->responseBuilder->getResponse();
}
Expand All @@ -181,11 +181,11 @@ public function getResponse()
* If the exception is an instance of Http\Client\Exception\HttpException it will contain
* the response object with the status code and the http reason.
*
* @return Exception Exception Object only when the Promise is rejected
* @return \Throwable Exception Object only when the Promise is rejected
*
* @throws \LogicException When the promise is not rejected
*/
public function getException()
public function getException(): \Throwable
{
if (null === $this->exception) {
throw new \LogicException('Promise is not rejected');
Expand All @@ -197,7 +197,7 @@ public function getException()
/**
* Fulfill promise.
*/
public function fulfill()
public function fulfill(): void
{
$this->state = Promise::FULFILLED;
$response = $this->responseBuilder->getResponse();
Expand Down Expand Up @@ -225,7 +225,7 @@ public function fulfill()
*
* @param Exception $exception Reject reason
*/
public function reject(Exception $exception)
public function reject(Exception $exception): void
{
$this->exception = $exception;
$this->state = Promise::REJECTED;
Expand Down
2 changes: 1 addition & 1 deletion src/ResponseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ResponseBuilder extends OriginalResponseBuilder
*
* @param ResponseInterface $response
*/
public function setResponse(ResponseInterface $response)
public function setResponse(ResponseInterface $response): void
{
$this->response = $response;
}
Expand Down
Loading