diff --git a/spec/AuthenticationPluginSpec.php b/spec/AuthenticationPluginSpec.php index fe409f1..e028cad 100644 --- a/spec/AuthenticationPluginSpec.php +++ b/spec/AuthenticationPluginSpec.php @@ -4,22 +4,30 @@ use Http\Authentication\Authentication; use Http\Client\Promise; +use Psr\Http\Message\RequestInterface; use PhpSpec\ObjectBehavior; use Prophecy\Argument; -use Psr\Http\Message\RequestInterface; class AuthenticationPluginSpec extends ObjectBehavior { + function let(Authentication $authentication) + { + $this->beConstructedWith($authentication); + } + function it_is_initializable(Authentication $authentication) { - $this->beAnInstanceOf('Http\Client\Plugin\AuthenticationPlugin', [$authentication]); + $this->shouldHaveType('Http\Client\Plugin\AuthenticationPlugin'); + } + + function it_is_a_plugin() + { $this->shouldImplement('Http\Client\Plugin\Plugin'); } function it_sends_an_authenticated_request(Authentication $authentication, RequestInterface $notAuthedRequest, RequestInterface $authedRequest, Promise $promise) { - $this->beConstructedWith($authentication); - $authentication->authenticate($notAuthedRequest)->shouldBeCalled()->willReturn($authedRequest); + $authentication->authenticate($notAuthedRequest)->willReturn($authedRequest); $next = function (RequestInterface $request) use($authedRequest, $promise) { diff --git a/spec/CookiePluginSpec.php b/spec/CookiePluginSpec.php index 620862b..ac2448d 100644 --- a/spec/CookiePluginSpec.php +++ b/spec/CookiePluginSpec.php @@ -6,31 +6,39 @@ use Http\Client\Utils\Promise\FulfilledPromise; use Http\Cookie\Cookie; use Http\Cookie\CookieJar; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; class CookiePluginSpec extends ObjectBehavior { - function it_is_initializable(CookieJar $cookieJar) + function let(CookieJar $cookieJar) + { + $this->beConstructedWith($cookieJar); + } + + function it_is_initializable() + { + $this->shouldHaveType('Http\Client\Plugin\CookiePlugin'); + } + + function it_is_a_plugin() { - $this->beAnInstanceOf('Http\Client\Plugin\CookiePlugin', [$cookieJar]); $this->shouldImplement('Http\Client\Plugin\Plugin'); } function it_loads_cookie(CookieJar $cookieJar, RequestInterface $request, UriInterface $uri, Promise $promise) { $cookie = new Cookie('name', 'value', (new \DateTime())->modify('+1day'), 'test.com'); - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([$cookie]); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->getHost()->shouldBeCalled()->willReturn('test.com'); - $uri->getPath()->shouldBeCalled()->willReturn('/'); + $cookieJar->getCookies()->willReturn([$cookie]); + $request->getUri()->willReturn($uri); + $uri->getHost()->willReturn('test.com'); + $uri->getPath()->willReturn('/'); - $request->withAddedHeader('Cookie', 'name=value')->shouldBeCalled()->willReturn($request); + $request->withAddedHeader('Cookie', 'name=value')->willReturn($request); $this->handleRequest($request, function (RequestInterface $requestReceived) use ($request, $promise) { if (Argument::is($requestReceived)->scoreArgument($request->getWrappedObject())) { @@ -42,9 +50,8 @@ function it_loads_cookie(CookieJar $cookieJar, RequestInterface $request, UriInt function it_does_not_load_cookie_if_expired(CookieJar $cookieJar, RequestInterface $request, UriInterface $uri, Promise $promise) { $cookie = new Cookie('name', 'value', (new \DateTime())->modify('-1day'), 'test.com'); - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([$cookie]); + $cookieJar->getCookies()->willReturn([$cookie]); $request->withAddedHeader('Cookie', 'name=value')->shouldNotBeCalled(); $this->handleRequest($request, function (RequestInterface $requestReceived) use ($request, $promise) { @@ -57,11 +64,10 @@ function it_does_not_load_cookie_if_expired(CookieJar $cookieJar, RequestInterfa function it_does_not_load_cookie_if_domain_does_not_match(CookieJar $cookieJar, RequestInterface $request, UriInterface $uri, Promise $promise) { $cookie = new Cookie('name', 'value', (new \DateTime())->modify('+1day'), 'test2.com'); - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([$cookie]); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->getHost()->shouldBeCalled()->willReturn('test.com'); + $cookieJar->getCookies()->willReturn([$cookie]); + $request->getUri()->willReturn($uri); + $uri->getHost()->willReturn('test.com'); $request->withAddedHeader('Cookie', 'name=value')->shouldNotBeCalled(); @@ -75,12 +81,11 @@ function it_does_not_load_cookie_if_domain_does_not_match(CookieJar $cookieJar, function it_does_not_load_cookie_if_path_does_not_match(CookieJar $cookieJar, RequestInterface $request, UriInterface $uri, Promise $promise) { $cookie = new Cookie('name', 'value', (new \DateTime())->modify('+1day'), 'test.com', '/sub'); - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([$cookie]); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->getHost()->shouldBeCalled()->willReturn('test.com'); - $uri->getPath()->shouldBeCalled()->willReturn('/'); + $cookieJar->getCookies()->willReturn([$cookie]); + $request->getUri()->willReturn($uri); + $uri->getHost()->willReturn('test.com'); + $uri->getPath()->willReturn('/'); $request->withAddedHeader('Cookie', 'name=value')->shouldNotBeCalled(); @@ -94,13 +99,12 @@ function it_does_not_load_cookie_if_path_does_not_match(CookieJar $cookieJar, Re function it_does_not_load_cookie_when_cookie_is_secure(CookieJar $cookieJar, RequestInterface $request, UriInterface $uri, Promise $promise) { $cookie = new Cookie('name', 'value', (new \DateTime())->modify('+1day'), 'test.com', null, true); - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([$cookie]); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->getHost()->shouldBeCalled()->willReturn('test.com'); - $uri->getPath()->shouldBeCalled()->willReturn('/'); - $uri->getScheme()->shouldBeCalled()->willReturn('http'); + $cookieJar->getCookies()->willReturn([$cookie]); + $request->getUri()->willReturn($uri); + $uri->getHost()->willReturn('test.com'); + $uri->getPath()->willReturn('/'); + $uri->getScheme()->willReturn('http'); $request->withAddedHeader('Cookie', 'name=value')->shouldNotBeCalled(); @@ -114,15 +118,14 @@ function it_does_not_load_cookie_when_cookie_is_secure(CookieJar $cookieJar, Req function it_loads_cookie_when_cookie_is_secure(CookieJar $cookieJar, RequestInterface $request, UriInterface $uri, Promise $promise) { $cookie = new Cookie('name', 'value', (new \DateTime())->modify('+1day'), 'test.com', null, true); - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([$cookie]); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->getHost()->shouldBeCalled()->willReturn('test.com'); - $uri->getPath()->shouldBeCalled()->willReturn('/'); - $uri->getScheme()->shouldBeCalled()->willReturn('https'); + $cookieJar->getCookies()->willReturn([$cookie]); + $request->getUri()->willReturn($uri); + $uri->getHost()->willReturn('test.com'); + $uri->getPath()->willReturn('/'); + $uri->getScheme()->willReturn('https'); - $request->withAddedHeader('Cookie', 'name=value')->shouldBeCalled()->willReturn($request); + $request->withAddedHeader('Cookie', 'name=value')->willReturn($request); $this->handleRequest($request, function (RequestInterface $requestReceived) use ($request, $promise) { if (Argument::is($requestReceived)->scoreArgument($request->getWrappedObject())) { @@ -133,28 +136,26 @@ function it_loads_cookie_when_cookie_is_secure(CookieJar $cookieJar, RequestInte function it_saves_cookie(CookieJar $cookieJar, RequestInterface $request, ResponseInterface $response, UriInterface $uri) { - $this->beConstructedWith($cookieJar); - $cookieJar->getCookies()->shouldBeCalled()->willReturn([]); + $cookieJar->getCookies()->willReturn([]); $next = function () use ($response) { return new FulfilledPromise($response->getWrappedObject()); }; - $response->hasHeader('Set-Cookie')->shouldBeCalled()->willReturn(true); - $response->getHeader('Set-Cookie')->shouldBeCalled()->willReturn([ + $response->hasHeader('Set-Cookie')->willReturn(true); + $response->getHeader('Set-Cookie')->willReturn([ 'cookie=value', ]); $cookie = new Cookie('cookie', 'value', 0, 'test.com'); $cookieJar->addCookie($cookie)->shouldBeCalled(); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->getHost()->shouldBeCalled()->willReturn('test.com'); - $uri->getPath()->shouldBeCalled()->willReturn('/'); + $request->getUri()->willReturn($uri); + $uri->getHost()->willReturn('test.com'); + $uri->getPath()->willReturn('/'); $promise = $this->handleRequest($request, $next, function () {}); - $promise->shouldReturnAnInstanceOf('Http\Client\Promise'); - $response = $promise->getResponse(); - $response->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); + $promise->shouldHaveType('Http\Client\Promise'); + $promise->getResponse()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); } } diff --git a/spec/ErrorPluginSpec.php b/spec/ErrorPluginSpec.php index da23d33..2c24655 100644 --- a/spec/ErrorPluginSpec.php +++ b/spec/ErrorPluginSpec.php @@ -3,22 +3,26 @@ namespace spec\Http\Client\Plugin; use Http\Client\Utils\Promise\FulfilledPromise; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; class ErrorPluginSpec extends ObjectBehavior { function it_is_initializable() { $this->beAnInstanceOf('Http\Client\Plugin\ErrorPlugin'); + } + + function it_is_a_plugin() + { $this->shouldImplement('Http\Client\Plugin\Plugin'); } function it_throw_request_exception_on_500_error(RequestInterface $request, ResponseInterface $response) { - $response->getStatusCode()->shouldBeCalled()->willReturn('500'); + $response->getStatusCode()->willReturn('500'); $next = function (RequestInterface $receivedRequest) use($request, $response) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -31,7 +35,7 @@ function it_throw_request_exception_on_500_error(RequestInterface $request, Resp function it_returns_response(RequestInterface $request, ResponseInterface $response) { - $response->getStatusCode()->shouldBeCalled()->willReturn('200'); + $response->getStatusCode()->willReturn('200'); $next = function (RequestInterface $receivedRequest) use($request, $response) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -42,10 +46,11 @@ function it_returns_response(RequestInterface $request, ResponseInterface $respo $this->handleRequest($request, $next, function () {})->shouldReturnAnInstanceOf('Http\Client\Utils\Promise\FulfilledPromise'); } - function it_throw_request_exception_on_custom_regex(RequestInterface $request, ResponseInterface $response) + function it_throws_request_exception_on_custom_regex(RequestInterface $request, ResponseInterface $response) { $this->beConstructedWith('302'); - $response->getStatusCode()->shouldBeCalled()->willReturn('302'); + + $response->getStatusCode()->willReturn('302'); $next = function (RequestInterface $receivedRequest) use($request, $response) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { return new FulfilledPromise($response->getWrappedObject()); diff --git a/spec/PluginClientSpec.php b/spec/PluginClientSpec.php index 0c43f35..378f3a3 100644 --- a/spec/PluginClientSpec.php +++ b/spec/PluginClientSpec.php @@ -5,32 +5,44 @@ use Http\Client\HttpAsyncClient; use Http\Client\HttpClient; use Http\Client\Promise; -use PhpSpec\ObjectBehavior; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use PhpSpec\ObjectBehavior; class PluginClientSpec extends ObjectBehavior { - function it_is_initializable(HttpClient $client) + function let(HttpClient $client) + { + $this->beConstructedWith($client); + } + + function it_is_initializable() + { + $this->shouldHaveType('Http\Client\Plugin\PluginClient'); + } + + function it_is_an_http_client() { - $this->beAnInstanceOf('Http\Client\Plugin\PluginClient', [$client]); $this->shouldImplement('Http\Client\HttpClient'); + } + + function it_is_an_http_async_client() + { $this->shouldImplement('Http\Client\HttpAsyncClient'); } function it_sends_request_with_underlying_client(HttpClient $client, RequestInterface $request, ResponseInterface $response) { - $client->sendRequest($request)->shouldBeCalled()->willReturn($response); + $client->sendRequest($request)->willReturn($response); - $this->beConstructedWith($client); $this->sendRequest($request)->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); } - function it_sends_async_request_with_underlying_client(HttpAsyncClient $client, RequestInterface $request, Promise $promise) + function it_sends_async_request_with_underlying_client(HttpAsyncClient $asyncClient, RequestInterface $request, Promise $promise) { - $client->sendAsyncRequest($request)->shouldBeCalled()->willReturn($promise); + $asyncClient->sendAsyncRequest($request)->willReturn($promise); - $this->beConstructedWith($client); + $this->beConstructedWith($asyncClient); $this->sendAsyncRequest($request)->shouldReturn($promise); } } diff --git a/spec/RedirectPluginSpec.php b/spec/RedirectPluginSpec.php index 29eade6..af5ce44 100644 --- a/spec/RedirectPluginSpec.php +++ b/spec/RedirectPluginSpec.php @@ -5,21 +5,25 @@ use Http\Client\Utils\Promise\FulfilledPromise; use Http\Client\Plugin\RedirectPlugin; use Http\Client\Promise; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; class RedirectPluginSpec extends ObjectBehavior { function it_is_initializable() { - $this->beAnInstanceOf('Http\Client\Plugin\RedirectPlugin'); + $this->shouldHaveType('Http\Client\Plugin\RedirectPlugin'); + } + + function it_is_a_plugin() + { $this->shouldImplement('Http\Client\Plugin\Plugin'); } - function it_redirect_on_302( + function it_redirects_on_302( UriInterface $uri, UriInterface $uriRedirect, RequestInterface $request, @@ -28,22 +32,20 @@ function it_redirect_on_302( ResponseInterface $finalResponse, Promise $promise ) { - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('/redirect'); + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(true); + $responseRedirect->getHeaderLine('Location')->willReturn('/redirect'); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); + $request->getRequestTarget()->willReturn('/original'); + $request->getUri()->willReturn($uri); + $request->withUri($uriRedirect)->willReturn($modifiedRequest); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); - $uri->withPath('/redirect')->shouldBeCalled()->willReturn($uriRedirect); + $uri->withPath('/redirect')->willReturn($uriRedirect); + $uriRedirect->withFragment('')->willReturn($uriRedirect); + $uriRedirect->withQuery('')->willReturn($uriRedirect); - $uriRedirect->withFragment('')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withQuery('')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->__toString()->shouldBeCalled()->willReturn('/redirect'); - - $modifiedRequest->getUri()->willReturn($uriRedirect); - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('GET'); + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('GET'); $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -58,28 +60,28 @@ function it_redirect_on_302( }; $promise->wait()->shouldBeCalled(); - $promise->getState()->shouldBeCalled()->willReturn(Promise::FULFILLED); - $promise->getResponse()->shouldBeCalled()->willReturn($finalResponse); + $promise->getState()->willReturn(Promise::FULFILLED); + $promise->getResponse()->willReturn($finalResponse); $finalPromise = $this->handleRequest($request, $next, $first); $finalPromise->shouldReturnAnInstanceOf('Http\Client\Utils\Promise\FulfilledPromise'); $finalPromise->getResponse()->shouldReturn($finalResponse); } - function it_use_storage_on_301(UriInterface $uri, UriInterface $uriRedirect, RequestInterface $request, RequestInterface $modifiedRequest) + function it_use_storage_on_301(UriInterface $uriRedirect, RequestInterface $request, RequestInterface $modifiedRequest) { $this->beAnInstanceOf('spec\Http\Client\Plugin\RedirectPluginStub'); $this->beConstructedWith($uriRedirect, '/original', '301'); $next = function () { - throw new \Exception("Must not be called"); + throw new \Exception('Must not be called'); }; - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); + $request->getRequestTarget()->willReturn('/original'); + $request->withUri($uriRedirect)->willReturn($modifiedRequest); - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('GET'); + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('GET'); $this->handleRequest($request, $next, function () {}); } @@ -97,22 +99,21 @@ function it_stores_a_301( $this->beAnInstanceOf('spec\Http\Client\Plugin\RedirectPluginStub'); $this->beConstructedWith($uriRedirect, '', '301'); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/301-url'); + $request->getRequestTarget()->willReturn('/301-url'); + $request->getUri()->willReturn($uri); - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('301'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('/redirect'); + $responseRedirect->getStatusCode()->willReturn('301'); + $responseRedirect->hasHeader('Location')->willReturn(true); + $responseRedirect->getHeaderLine('Location')->willReturn('/redirect'); - $uri->withPath('/redirect')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withFragment('')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withQuery('')->shouldBeCalled()->willReturn($uriRedirect); + $uri->withPath('/redirect')->willReturn($uriRedirect); + $uriRedirect->withFragment('')->willReturn($uriRedirect); + $uriRedirect->withQuery('')->willReturn($uriRedirect); - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); - $modifiedRequest->getUri()->willReturn($uriRedirect); + $request->withUri($uriRedirect)->willReturn($modifiedRequest); - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('GET'); - $uriRedirect->__toString()->shouldBeCalled()->willReturn('/redirect'); + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('GET'); $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -127,8 +128,8 @@ function it_stores_a_301( }; $promise->wait()->shouldBeCalled(); - $promise->getState()->shouldBeCalled()->willReturn(Promise::FULFILLED); - $promise->getResponse()->shouldBeCalled()->willReturn($finalResponse); + $promise->getState()->willReturn(Promise::FULFILLED); + $promise->getResponse()->willReturn($finalResponse); $this->handleRequest($request, $next, $first); $this->hasStorage('/301-url')->shouldReturn(true); @@ -143,24 +144,24 @@ function it_replace_full_url( ResponseInterface $finalResponse, Promise $promise ) { - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); - - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('https://server.com:8000/redirect?query#fragment'); - - $uri->withScheme('https')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withHost('server.com')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withPort('8000')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withPath('/redirect')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withQuery('query')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withFragment('fragment')->shouldBeCalled()->willReturn($uriRedirect); - - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('GET'); - $modifiedRequest->getUri()->willReturn($uriRedirect); - $uriRedirect->__toString()->shouldBeCalled()->willReturn('/redirect'); + $request->getRequestTarget()->willReturn('/original'); + + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(true); + $responseRedirect->getHeaderLine('Location')->willReturn('https://server.com:8000/redirect?query#fragment'); + + $request->getUri()->willReturn($uri); + $uri->withScheme('https')->willReturn($uriRedirect); + $uriRedirect->withHost('server.com')->willReturn($uriRedirect); + $uriRedirect->withPort('8000')->willReturn($uriRedirect); + $uriRedirect->withPath('/redirect')->willReturn($uriRedirect); + $uriRedirect->withQuery('query')->willReturn($uriRedirect); + $uriRedirect->withFragment('fragment')->willReturn($uriRedirect); + + $request->withUri($uriRedirect)->willReturn($modifiedRequest); + + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('GET'); $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -175,13 +176,13 @@ function it_replace_full_url( }; $promise->wait()->shouldBeCalled(); - $promise->getState()->shouldBeCalled()->willReturn(Promise::FULFILLED); - $promise->getResponse()->shouldBeCalled()->willReturn($finalResponse); + $promise->getState()->willReturn(Promise::FULFILLED); + $promise->getResponse()->willReturn($finalResponse); $this->handleRequest($request, $next, $first); } - function it_throws_http_exception_on_no_location(UriInterface $uri, RequestInterface $request, ResponseInterface $responseRedirect) + function it_throws_http_exception_on_no_location(RequestInterface $request, ResponseInterface $responseRedirect) { $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -189,18 +190,16 @@ function it_throws_http_exception_on_no_location(UriInterface $uri, RequestInter } }; - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); - - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(false); + $request->getRequestTarget()->willReturn('/original'); + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(false); $promise = $this->handleRequest($request, $next, function () {}); $promise->shouldReturnAnInstanceOf('Http\Client\Utils\Promise\RejectedPromise'); $promise->getException()->shouldReturnAnInstanceOf('Http\Client\Exception\HttpException'); } - function it_throws_http_exception_on_invalid_location(UriInterface $uri, RequestInterface $request, ResponseInterface $responseRedirect) + function it_throws_http_exception_on_invalid_location(RequestInterface $request, ResponseInterface $responseRedirect) { $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -208,12 +207,11 @@ function it_throws_http_exception_on_invalid_location(UriInterface $uri, Request } }; - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('scheme:///invalid'); + $request->getRequestTarget()->willReturn('/original'); + $responseRedirect->getHeaderLine('Location')->willReturn('scheme:///invalid'); - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(true); $promise = $this->handleRequest($request, $next, function () {}); $promise->shouldReturnAnInstanceOf('Http\Client\Utils\Promise\RejectedPromise'); @@ -229,7 +227,7 @@ function it_throw_multi_redirect_exception_on_300(RequestInterface $request, Res }; $this->beConstructedWith(true, false); - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('300'); + $responseRedirect->getStatusCode()->willReturn('300'); $promise = $this->handleRequest($request, $next, function () {}); $promise->shouldReturnAnInstanceOf('Http\Client\Utils\Promise\RejectedPromise'); @@ -244,8 +242,8 @@ function it_throw_multi_redirect_exception_on_300_if_no_location(RequestInterfac } }; - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('300'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(false); + $responseRedirect->getStatusCode()->willReturn('300'); + $responseRedirect->hasHeader('Location')->willReturn(false); $promise = $this->handleRequest($request, $next, function () {}); $promise->shouldReturnAnInstanceOf('Http\Client\Utils\Promise\RejectedPromise'); @@ -261,24 +259,23 @@ function it_switch_method_for_302( ResponseInterface $finalResponse, Promise $promise ) { + $request->getRequestTarget()->willReturn('/original'); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(true); + $responseRedirect->getHeaderLine('Location')->willReturn('/redirect'); - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('/redirect'); + $request->getUri()->willReturn($uri); + $uri->withPath('/redirect')->willReturn($uriRedirect); + $uriRedirect->withFragment('')->willReturn($uriRedirect); + $uriRedirect->withQuery('')->willReturn($uriRedirect); - $uri->withPath('/redirect')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withFragment('')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withQuery('')->shouldBeCalled()->willReturn($uriRedirect); - - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); + $request->withUri($uriRedirect)->willReturn($modifiedRequest); $modifiedRequest->getUri()->willReturn($uriRedirect); - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('POST'); - $modifiedRequest->withMethod('GET')->shouldBeCalled()->willReturn($modifiedRequest); - $uriRedirect->__toString()->shouldBeCalled()->willReturn('/redirect'); + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('POST'); + $modifiedRequest->withMethod('GET')->willReturn($modifiedRequest); $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { @@ -293,8 +290,8 @@ function it_switch_method_for_302( }; $promise->wait()->shouldBeCalled(); - $promise->getState()->shouldBeCalled()->willReturn(Promise::FULFILLED); - $promise->getResponse()->shouldBeCalled()->willReturn($finalResponse); + $promise->getState()->willReturn(Promise::FULFILLED); + $promise->getResponse()->willReturn($finalResponse); $this->handleRequest($request, $next, $first); } @@ -310,23 +307,23 @@ function it_clears_headers( ) { $this->beConstructedWith(['Accept']); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); + $request->getRequestTarget()->willReturn('/original'); - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('/redirect'); + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(true); + $responseRedirect->getHeaderLine('Location')->willReturn('/redirect'); - $uri->withPath('/redirect')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withFragment('')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withQuery('')->shouldBeCalled()->willReturn($uriRedirect); + $request->getUri()->willReturn($uri); + $uri->withPath('/redirect')->willReturn($uriRedirect); + $uriRedirect->withFragment('')->willReturn($uriRedirect); + $uriRedirect->withQuery('')->willReturn($uriRedirect); - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); + $request->withUri($uriRedirect)->willReturn($modifiedRequest); - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('GET'); - $modifiedRequest->getHeaders()->shouldBeCalled()->willReturn(['Accept' => 'value', 'Cookie' => 'value']); - $modifiedRequest->withoutHeader('Cookie')->shouldBeCalled()->willReturn($modifiedRequest); - $uriRedirect->__toString()->shouldBeCalled()->willReturn('/redirect'); + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('GET'); + $modifiedRequest->getHeaders()->willReturn(['Accept' => 'value', 'Cookie' => 'value']); + $modifiedRequest->withoutHeader('Cookie')->willReturn($modifiedRequest); $modifiedRequest->getUri()->willReturn($uriRedirect); $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { @@ -342,8 +339,8 @@ function it_clears_headers( }; $promise->wait()->shouldBeCalled(); - $promise->getState()->shouldBeCalled()->willReturn(Promise::FULFILLED); - $promise->getResponse()->shouldBeCalled()->willReturn($finalResponse); + $promise->getState()->willReturn(Promise::FULFILLED); + $promise->getResponse()->willReturn($finalResponse); $this->handleRequest($request, $next, $first); } @@ -355,22 +352,21 @@ function it_throws_circular_redirection_exception(UriInterface $uri, UriInterfac $this->beAnInstanceOf('spec\Http\Client\Plugin\RedirectPluginStubCircular'); $this->beConstructedWith(spl_object_hash((object)$first)); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/original'); + $request->getRequestTarget()->willReturn('/original'); + $request->getUri()->willReturn($uri); - $responseRedirect->getStatusCode()->shouldBeCalled()->willReturn('302'); - $responseRedirect->hasHeader('Location')->shouldBeCalled()->willReturn(true); - $responseRedirect->getHeaderLine('Location')->shouldBeCalled()->willReturn('/redirect'); + $responseRedirect->getStatusCode()->willReturn('302'); + $responseRedirect->hasHeader('Location')->willReturn(true); + $responseRedirect->getHeaderLine('Location')->willReturn('/redirect'); - $uri->withPath('/redirect')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withFragment('')->shouldBeCalled()->willReturn($uriRedirect); - $uriRedirect->withQuery('')->shouldBeCalled()->willReturn($uriRedirect); + $uri->withPath('/redirect')->willReturn($uriRedirect); + $uriRedirect->withFragment('')->willReturn($uriRedirect); + $uriRedirect->withQuery('')->willReturn($uriRedirect); - $request->withUri($uriRedirect)->shouldBeCalled()->willReturn($modifiedRequest); + $request->withUri($uriRedirect)->willReturn($modifiedRequest); $modifiedRequest->getUri()->willReturn($uriRedirect); - - $modifiedRequest->getMethod()->shouldBeCalled()->willReturn('GET'); - $uriRedirect->__toString()->shouldBeCalled()->willReturn('/redirect'); + $modifiedRequest->getRequestTarget()->willReturn('/redirect'); + $modifiedRequest->getMethod()->willReturn('GET'); $next = function (RequestInterface $receivedRequest) use($request, $responseRedirect) { if (Argument::is($request->getWrappedObject())->scoreArgument($receivedRequest)) { diff --git a/spec/RetryPluginSpec.php b/spec/RetryPluginSpec.php index 130cdcf..3a25329 100644 --- a/spec/RetryPluginSpec.php +++ b/spec/RetryPluginSpec.php @@ -5,16 +5,20 @@ use Http\Client\Exception; use Http\Client\Utils\Promise\FulfilledPromise; use Http\Client\Utils\Promise\RejectedPromise; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; class RetryPluginSpec extends ObjectBehavior { function it_is_initializable() { - $this->beAnInstanceOf('Http\Client\Plugin\ErrorPlugin'); + $this->shouldHaveType('Http\Client\Plugin\RetryPlugin'); + } + + function it_is_a_plugin() + { $this->shouldImplement('Http\Client\Plugin\Plugin'); } @@ -31,8 +35,8 @@ function it_returns_response(RequestInterface $request, ResponseInterface $respo function it_throws_exception_on_multiple_exceptions(RequestInterface $request) { - $exception1 = new Exception\NetworkException("Exception 1", $request->getWrappedObject()); - $exception2 = new Exception\NetworkException("Exception 2", $request->getWrappedObject()); + $exception1 = new Exception\NetworkException('Exception 1', $request->getWrappedObject()); + $exception2 = new Exception\NetworkException('Exception 2', $request->getWrappedObject()); $count = 0; $next = function (RequestInterface $receivedRequest) use($request, $exception1, $exception2, &$count) { @@ -55,7 +59,7 @@ function it_throws_exception_on_multiple_exceptions(RequestInterface $request) function it_returns_response_on_second_try(RequestInterface $request, ResponseInterface $response) { - $exception = new Exception\NetworkException("Exception 1", $request->getWrappedObject()); + $exception = new Exception\NetworkException('Exception 1', $request->getWrappedObject()); $count = 0; $next = function (RequestInterface $receivedRequest) use($request, $exception, $response, &$count) { @@ -78,7 +82,7 @@ function it_returns_response_on_second_try(RequestInterface $request, ResponseIn function it_does_not_keep_history_of_old_failure(RequestInterface $request, ResponseInterface $response) { - $exception = new Exception\NetworkException("Exception 1", $request->getWrappedObject()); + $exception = new Exception\NetworkException('Exception 1', $request->getWrappedObject()); $count = 0; $next = function (RequestInterface $receivedRequest) use($request, $exception, $response, &$count) { diff --git a/spec/StopwatchPluginSpec.php b/spec/StopwatchPluginSpec.php index bd7112e..fa46132 100644 --- a/spec/StopwatchPluginSpec.php +++ b/spec/StopwatchPluginSpec.php @@ -5,27 +5,32 @@ use Http\Client\Exception\NetworkException; use Http\Client\Utils\Promise\FulfilledPromise; use Http\Client\Utils\Promise\RejectedPromise; -use PhpSpec\ObjectBehavior; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\UriInterface; use Symfony\Component\Stopwatch\Stopwatch; +use PhpSpec\ObjectBehavior; class StopwatchPluginSpec extends ObjectBehavior { + function let(Stopwatch $stopwatch) + { + $this->beConstructedWith($stopwatch); + } + function it_is_initializable(Stopwatch $stopwatch) { - $this->beAnInstanceOf('Http\Client\Plugin\StopwatchPlugin', [$stopwatch]); - $this->shouldImplement('Http\Client\Plugin\Plugin'); + $this->shouldHaveType('Http\Client\Plugin\StopwatchPlugin'); } - function it_records_event(Stopwatch $stopwatch, RequestInterface $request, UriInterface $uri, ResponseInterface $response) + function it_is_a_plugin() { - $this->beConstructedWith($stopwatch); + $this->shouldImplement('Http\Client\Plugin\Plugin'); + } - $request->getMethod()->shouldBeCalled()->willReturn('GET'); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/'); + function it_records_event(Stopwatch $stopwatch, RequestInterface $request, ResponseInterface $response) + { + $request->getMethod()->willReturn('GET'); + $request->getRequestTarget()->willReturn('/'); $stopwatch->start('GET /', 'php_http.request')->shouldBeCalled(); $stopwatch->stop('GET /', 'php_http.request')->shouldBeCalled(); @@ -37,13 +42,10 @@ function it_records_event(Stopwatch $stopwatch, RequestInterface $request, UriIn $this->handleRequest($request, $next, function () {}); } - function it_records_event_on_error(Stopwatch $stopwatch, RequestInterface $request, UriInterface $uri) + function it_records_event_on_error(Stopwatch $stopwatch, RequestInterface $request) { - $this->beConstructedWith($stopwatch); - - $request->getMethod()->shouldBeCalled()->willReturn('GET'); - $request->getUri()->shouldBeCalled()->willReturn($uri); - $uri->__toString()->shouldBeCalled()->willReturn('/'); + $request->getMethod()->willReturn('GET'); + $request->getRequestTarget()->willReturn('/'); $stopwatch->start('GET /', 'php_http.request')->shouldBeCalled(); $stopwatch->stop('GET /', 'php_http.request')->shouldBeCalled(); diff --git a/src/AuthenticationPlugin.php b/src/AuthenticationPlugin.php index f63b1f4..139958e 100644 --- a/src/AuthenticationPlugin.php +++ b/src/AuthenticationPlugin.php @@ -6,7 +6,7 @@ use Psr\Http\Message\RequestInterface; /** - * Send an authenticated request + * Send an authenticated request. * * @author Joel Wurtz */ @@ -17,13 +17,16 @@ class AuthenticationPlugin implements Plugin */ private $authentication; + /** + * @param Authentication $authentication + */ public function __construct(Authentication $authentication) { $this->authentication = $authentication; } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handleRequest(RequestInterface $request, callable $next, callable $first) { @@ -31,5 +34,4 @@ public function handleRequest(RequestInterface $request, callable $next, callabl return $next($request); } - } diff --git a/src/CookiePlugin.php b/src/CookiePlugin.php index e1afc8b..72a5f90 100644 --- a/src/CookiePlugin.php +++ b/src/CookiePlugin.php @@ -7,18 +7,30 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +/** + * Handle request cookies. + * + * @author Joel Wurtz + */ class CookiePlugin implements Plugin { - /** @var CookieJar Storage for cookies */ + /** + * Cookie storage + * + * @var CookieJar + */ private $cookieJar; + /** + * @param CookieJar $cookieJar + */ public function __construct(CookieJar $cookieJar) { $this->cookieJar = $cookieJar; } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handleRequest(RequestInterface $request, callable $next, callable $first) { @@ -68,7 +80,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl } /** - * Create a cookie from a string + * Creates a cookie from a string. * * @param RequestInterface $request * @param $setCookie @@ -126,7 +138,7 @@ private function createCookie(RequestInterface $request, $setCookie) } /** - * Separate key, value pair from cookie + * Separates key/value pair from cookie. * * @param $part * diff --git a/src/ErrorPlugin.php b/src/ErrorPlugin.php index 297cfee..776b678 100644 --- a/src/ErrorPlugin.php +++ b/src/ErrorPlugin.php @@ -8,22 +8,30 @@ /** * Throw exception when the response of a request is not acceptable. - * By default will throw error for all status code from 400 to 599 + * + * By default an exception will be thrown for all status codes from 400 to 599. * * @author Joel Wurtz */ class ErrorPlugin implements Plugin { - /** @var string Status code matcher to return an exception */ + /** + * Status code matcher to return an exception. + * + * @var string + */ private $statusCodeRegex; + /** + * @param string $statusCodeRegex + */ public function __construct($statusCodeRegex = '[45][0-9]{2}') { $this->statusCodeRegex = $statusCodeRegex; } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handleRequest(RequestInterface $request, callable $next, callable $first) { @@ -31,7 +39,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl return $promise->then(function (ResponseInterface $response) use($request) { if (preg_match('/'.$this->statusCodeRegex.'/', (string)$response->getStatusCode())) { - throw new HttpException('The server returns an error', $request, $response); + throw new HttpException('The server returned an error', $request, $response); } return $response; diff --git a/src/Exception/CircularRedirectionException.php b/src/Exception/CircularRedirectionException.php index 1e868bd..bf71b1a 100644 --- a/src/Exception/CircularRedirectionException.php +++ b/src/Exception/CircularRedirectionException.php @@ -4,7 +4,11 @@ use Http\Client\Exception\HttpException; +/** + * Thrown when circular redirection is detected. + * + * @author Joel Wurtz + */ class CircularRedirectionException extends HttpException { } - \ No newline at end of file diff --git a/src/Exception/MultipleRedirectionException.php b/src/Exception/MultipleRedirectionException.php index 7975091..b16c026 100644 --- a/src/Exception/MultipleRedirectionException.php +++ b/src/Exception/MultipleRedirectionException.php @@ -4,6 +4,11 @@ use Http\Client\Exception\HttpException; +/** + * Redirect location cannot be chosen. + * + * @author Joel Wurtz + */ class MultipleRedirectionException extends HttpException { } diff --git a/src/Plugin.php b/src/Plugin.php index 28ff4a2..0a38f15 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -6,19 +6,23 @@ use Psr\Http\Message\RequestInterface; /** - * A plugin is a middleware to transform the request and/or - * the response and use the next callable for + * A plugin is a middleware to transform the request and/or the response. + * + * The plugin can: + * - break the chain and return a response + * - dispatch the request to the next middleware + * - restart the request * * @author Joel Wurtz */ interface Plugin { /** - * handle the request and return the response coming from the next callable + * Handle the request and return the response coming from the next callable. * - * @param RequestInterface $request Request to use - * @param callable $next Callback to call to have the request, it muse have the request as it first argument - * @param callable $first First element in the plugin chain, used to to restart a request from the beginning + * @param RequestInterface $request + * @param callable $next Next middleware in the chain, the request is passed as the first argument + * @param callable $first First middleware in the chain, used to to restart a request * * @return Promise */ diff --git a/src/PluginClient.php b/src/PluginClient.php index 8f94296..366b9d0 100644 --- a/src/PluginClient.php +++ b/src/PluginClient.php @@ -9,39 +9,48 @@ use Http\Client\Utils\EmulateAsyncClient; use Psr\Http\Message\RequestInterface; +/** + * The client managing plugins and providing a decorator around HTTP Clients. + * + * @author Joel Wurtz + */ class PluginClient implements HttpClient, HttpAsyncClient { /** - * @var HttpAsyncClient A http async client + * An HTTP async client + * + * @var HttpAsyncClient */ protected $client; /** - * @var Plugin[] The plugin chain + * The plugin chain + * + * @var Plugin[] */ protected $plugins; /** - * @param HttpClient|HttpAsyncClient $client A http client (async or not) - * @param Plugin[] $plugins A list of plugins (middleware) to apply + * @param HttpClient|HttpAsyncClient $client + * @param Plugin[] $plugins * * @throws \RuntimeException if client is not an instance of HttpClient or HttpAsyncClient */ - public function __construct($client, array $plugins = array()) + public function __construct($client, array $plugins = []) { if ($client instanceof HttpAsyncClient) { $this->client = $client; } elseif ($client instanceof HttpClient) { $this->client = new EmulateAsyncClient($client); } else { - throw new \RuntimeException("Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient"); + throw new \RuntimeException('Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient'); } $this->plugins = $plugins; } /** - * {@inheritDoc} + * {@inheritdoc} */ public function sendRequest(RequestInterface $request) { @@ -56,7 +65,7 @@ public function sendRequest(RequestInterface $request) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function sendAsyncRequest(RequestInterface $request) { @@ -72,7 +81,7 @@ public function sendAsyncRequest(RequestInterface $request) */ private function createPluginChain($pluginList) { - $client = $this->client; + $client = $this->client; $lastCallable = function (RequestInterface $request) use($client) { return $client->sendAsyncRequest($request); }; diff --git a/src/RedirectPlugin.php b/src/RedirectPlugin.php index 27d33d4..d201f9e 100644 --- a/src/RedirectPlugin.php +++ b/src/RedirectPlugin.php @@ -5,16 +5,23 @@ use Http\Client\Exception\HttpException; use Http\Client\Plugin\Exception\CircularRedirectionException; use Http\Client\Plugin\Exception\MultipleRedirectionException; -use Http\Client\Plugin\Exception\RebootChainException; use Http\Client\Promise; +use Psr\Http\Message\MessageInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; +/** + * Follow redirections. + * + * @author Joel Wurtz + */ class RedirectPlugin implements Plugin { /** - * @var array Rule on how to redirect, change method for the new request + * Rule on how to redirect, change method for the new request. + * + * @var array */ protected $redirectCodes = [ 300 => [ @@ -62,7 +69,9 @@ class RedirectPlugin implements Plugin ]; /** - * @var boolean|array Determine how header should be preserved from old request + * Determine how header should be preserved from old request. + * + * @var bool|array * * true will keep all previous headers (default value) * false will ditch all previous headers @@ -71,35 +80,43 @@ class RedirectPlugin implements Plugin protected $preserveHeader; /** - * @var array Store all previous redirect from 301 / 308 status code + * Store all previous redirect from 301 / 308 status code. + * + * @var array */ - protected $redirectStorage = array(); + protected $redirectStorage = []; /** - * @var bool Whether the location header must be directly used for a multiple redirection status code (300) + * Whether the location header must be directly used for a multiple redirection status code (300). + * + * @var bool */ protected $useDefaultForMultiple; /** - * @var array Circular detection array + * @var array */ protected $circularDetection = []; + /** + * @param bool $preserveHeader + * @param bool $useDefaultForMultiple + */ public function __construct($preserveHeader = true, $useDefaultForMultiple = true) { $this->useDefaultForMultiple = $useDefaultForMultiple; - $this->preserveHeader = false === $preserveHeader ? array() : $preserveHeader; + $this->preserveHeader = false === $preserveHeader ? [] : $preserveHeader; } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handleRequest(RequestInterface $request, callable $next, callable $first) { // Check in storage - if (array_key_exists((string)$request->getUri(), $this->redirectStorage)) { - $uri = $this->redirectStorage[(string)$request->getUri()]['uri']; - $statusCode = $this->redirectStorage[(string)$request->getUri()]['status']; + if (array_key_exists($request->getRequestTarget(), $this->redirectStorage)) { + $uri = $this->redirectStorage[$request->getRequestTarget()]['uri']; + $statusCode = $this->redirectStorage[$request->getRequestTarget()]['status']; $redirectRequest = $this->buildRedirectRequest($request, $uri, $statusCode); return $first($redirectRequest); @@ -112,7 +129,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl return $response; } - $uri = $this->createUri($response, $request); + $uri = $this->createUri($response, $request); $redirectRequest = $this->buildRedirectRequest($request, $uri, $statusCode); $chainIdentifier = spl_object_hash((object)$first); @@ -120,16 +137,16 @@ public function handleRequest(RequestInterface $request, callable $next, callabl $this->circularDetection[$chainIdentifier] = []; } - $this->circularDetection[$chainIdentifier][] = (string)$request->getUri(); + $this->circularDetection[$chainIdentifier][] = $request->getRequestTarget(); - if (in_array((string)$redirectRequest->getUri(), $this->circularDetection[$chainIdentifier])) { + if (in_array($redirectRequest->getRequestTarget(), $this->circularDetection[$chainIdentifier])) { throw new CircularRedirectionException('Circular redirection detected', $request, $response); } if ($this->redirectCodes[$statusCode]['permanent']) { - $this->redirectStorage[(string)$request->getUri()] = [ + $this->redirectStorage[$request->getRequestTarget()] = [ 'uri' => $uri, - 'status' => $statusCode + 'status' => $statusCode, ]; } @@ -146,13 +163,13 @@ public function handleRequest(RequestInterface $request, callable $next, callabl } /** - * Build the redirect request + * Builds the redirect request. * * @param RequestInterface $request Original request * @param UriInterface $uri New uri * @param int $statusCode Status code from the redirect response * - * @return \Psr\Http\Message\MessageInterface|RequestInterface + * @return MessageInterface|RequestInterface */ protected function buildRedirectRequest(RequestInterface $request, UriInterface $uri, $statusCode) { @@ -176,13 +193,13 @@ protected function buildRedirectRequest(RequestInterface $request, UriInterface } /** - * Create a new Uri from the old request and the location header + * Creates a new Uri from the old request and the location header. * * @param ResponseInterface $response The redirect response * @param RequestInterface $request The original request * - * @throws \Http\Client\Exception\HttpException If location header is not usable (missing or incorrect) - * @throws MultipleRedirectionException If a 300 status code is received and default location cannot be resolved (doesn't use the location header or not present) + * @throws HttpException If location header is not usable (missing or incorrect) + * @throws MultipleRedirectionException If a 300 status code is received and default location cannot be resolved (doesn't use the location header or not present) * * @return UriInterface */ @@ -193,17 +210,18 @@ private function createUri(ResponseInterface $response, RequestInterface $reques } if (!$response->hasHeader('Location')) { - throw new HttpException("Redirect status code, but no location header present in the response", $request, $response); + throw new HttpException('Redirect status code, but no location header present in the response', $request, $response); } - $location = $response->getHeaderLine('Location'); + $location = $response->getHeaderLine('Location'); $parsedLocation = parse_url($location); - $uri = $request->getUri(); if (false === $parsedLocation) { - throw new HttpException(sprintf("Location %s could not be parsed", $location), $request, $response); + throw new HttpException(sprintf('Location %s could not be parsed', $location), $request, $response); } + $uri = $request->getUri(); + if (array_key_exists('scheme', $parsedLocation)) { $uri = $uri->withScheme($parsedLocation['scheme']); } diff --git a/src/RetryPlugin.php b/src/RetryPlugin.php index dcd6055..67eaeb5 100644 --- a/src/RetryPlugin.php +++ b/src/RetryPlugin.php @@ -9,30 +9,38 @@ use Psr\Http\Message\ResponseInterface; /** - * Retry the request if it has somehow failed - * By default will retry only one time + * Retry the request if it has somehow failed. + * + * By default will retry only one time. * * @author Joel Wurtz */ class RetryPlugin implements Plugin { - /** @var int Number of retry before sending an exception */ + /** + * Number of retry before sending an exception. + * + * @var int + */ private $retry; - /** @var array Store the retry counter for each request */ - private $retryStorage; + /** + * Store the retry counter for each request. + * + * @var array + */ + private $retryStorage = []; /** - * @param int $retry Number of retry before sending an exception + * @param int $retry Number of retry before sending an exception */ public function __construct($retry = 1) { - $this->retry = $retry; - $this->retryStorage = []; + $this->retry = $retry; } /** - * {@inheritDoc} + * {@inheritdoc} */ public function handleRequest(RequestInterface $request, callable $next, callable $first) { diff --git a/src/StopwatchPlugin.php b/src/StopwatchPlugin.php index a6d8c5b..1d2f2f0 100644 --- a/src/StopwatchPlugin.php +++ b/src/StopwatchPlugin.php @@ -8,7 +8,7 @@ use Symfony\Component\Stopwatch\Stopwatch; /** - * Know the duration of a request call with the stopwatch component + * Measure the duration of a request call with the stopwatch component. * * @author Joel Wurtz */ @@ -17,10 +17,13 @@ class StopwatchPlugin implements Plugin const CATEGORY = 'php_http.request'; /** - * @var \Symfony\Component\Stopwatch\Stopwatch + * @var Stopwatch */ private $stopwatch; + /** + * @param Stopwatch $stopwatch + */ public function __construct(Stopwatch $stopwatch) { $this->stopwatch = $stopwatch; @@ -46,7 +49,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl } /** - * Generate the event name + * Generates the event name. * * @param RequestInterface $request * @@ -54,6 +57,6 @@ public function handleRequest(RequestInterface $request, callable $next, callabl */ private function getStopwatchEventName(RequestInterface $request) { - return sprintf('%s %s', $request->getMethod(), $request->getUri()->__toString()); + return sprintf('%s %s', $request->getMethod(), $request->getRequestTarget()); } }