Skip to content

Commit c735789

Browse files
committed
Added BaseHostPlugin
1 parent 3d77e7d commit c735789

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

spec/BaseUriPluginSpec.php

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
namespace spec\Http\Client\Plugin;
4+
5+
use Http\Message\StreamFactory;
6+
use Http\Message\UriFactory;
7+
use Http\Promise\FulfilledPromise;
8+
use PhpSpec\ObjectBehavior;
9+
use Prophecy\Argument;
10+
use Psr\Cache\CacheItemInterface;
11+
use Psr\Cache\CacheItemPoolInterface;
12+
use Psr\Http\Message\RequestInterface;
13+
use Psr\Http\Message\ResponseInterface;
14+
use Psr\Http\Message\StreamInterface;
15+
use Psr\Http\Message\UriInterface;
16+
17+
class BaseUriPluginSpec extends ObjectBehavior
18+
{
19+
function let(UriInterface $uri)
20+
{
21+
$this->beConstructedWith($uri);
22+
}
23+
24+
function it_is_initializable()
25+
{
26+
$this->shouldHaveType('Http\Client\Plugin\BaseUriPlugin');
27+
}
28+
29+
function it_is_a_plugin()
30+
{
31+
$this->shouldImplement('Http\Client\Plugin\Plugin');
32+
}
33+
34+
function it_appends_base_uri(
35+
ResponseInterface $response,
36+
RequestInterface $request,
37+
RequestInterface $modifiedRequest,
38+
UriInterface $baseUri,
39+
UriInterface $inputUri,
40+
UriInterface $modifiedUri
41+
) {
42+
$inputUri->__toString()->shouldBeCalled()->willReturn('biz');
43+
$baseUri->__toString()->willReturn('http://httplug.io/bar/');
44+
$baseUri->getPath()->shouldBeCalled()->willReturn('/bar/');
45+
$baseUri->getQuery()->shouldBeCalled()->willReturn('');
46+
47+
$baseUri->withPath('/bar/biz')->shouldBeCalled()->willReturn($modifiedUri);
48+
49+
$this->beConstructedWith($baseUri);
50+
$this->valdateReturnValue($request, $modifiedRequest, $inputUri, $modifiedUri, $response);
51+
}
52+
53+
function it_appends_base_uri_with_query(
54+
ResponseInterface $response,
55+
RequestInterface $request,
56+
RequestInterface $modifiedRequest,
57+
UriInterface $baseUri,
58+
UriInterface $inputUri,
59+
UriInterface $modifiedUri
60+
) {
61+
$inputUri->__toString()->shouldBeCalled()->willReturn('&a=b&c=d');
62+
$baseUri->__toString()->willReturn('http://httplug.io/bar/');
63+
$baseUri->getPath()->willReturn('/bar/');
64+
$baseUri->getQuery()->willReturn('foo=bar');
65+
66+
$baseUri->withQuery('foo=bar&a=b&c=d')->shouldBeCalled()->willReturn($modifiedUri);
67+
68+
$this->beConstructedWith($baseUri);
69+
$this->valdateReturnValue($request, $modifiedRequest, $inputUri, $modifiedUri, $response);
70+
}
71+
72+
function it_replaces_path_on_base_uri(
73+
ResponseInterface $response,
74+
RequestInterface $request,
75+
RequestInterface $modifiedRequest,
76+
UriInterface $baseUri,
77+
UriInterface $inputUri,
78+
UriInterface $modifiedUri
79+
) {
80+
$inputUri->__toString()->shouldBeCalled()->willReturn('/foo');
81+
$inputUri->getPath()->shouldBeCalled()->willReturn('/foo');
82+
$inputUri->getQuery()->shouldBeCalled()->willReturn('');
83+
$baseUri->__toString()->willReturn('http://httplug.io/bar/');
84+
85+
$baseUri->withPath('/foo')->shouldBeCalled()->willReturn($modifiedUri);
86+
$modifiedUri->withQuery('')->shouldBeCalled()->willReturn($modifiedUri);
87+
88+
$this->beConstructedWith($baseUri);
89+
$this->valdateReturnValue($request, $modifiedRequest, $inputUri, $modifiedUri, $response);
90+
}
91+
92+
function it_ignores_absolute_url(RequestInterface $request, UriInterface $uri)
93+
{
94+
$request->getUri()->shouldBeCalled()->willReturn($uri);
95+
$uri->__toString()->shouldBeCalled()->willReturn('http://foo.io/bar');
96+
97+
$this->handleRequest($request, function () {}, function () {});
98+
}
99+
100+
/**
101+
* Make sure the handleRequest function returns what we expect. We expect that if we input a request
102+
* the output request will have an instance of output uri.
103+
*
104+
* @param RequestInterface $inputRequest
105+
* @param ResponseInterface $dummyResponse
106+
* @param UriInterface $outputUri
107+
*/
108+
private function valdateReturnValue(
109+
RequestInterface $inputRequest,
110+
RequestInterface $outputRequest,
111+
UriInterface $inputUri,
112+
UriInterface $outputUri,
113+
ResponseInterface $dummyResponse
114+
) {
115+
$inputRequest->getUri()->willReturn($inputUri);
116+
$inputRequest->withUri($outputUri)->willReturn($outputRequest);
117+
$outputRequest->getUri()->willReturn($outputUri);
118+
119+
$next = function (RequestInterface $receivedRequest) use ($outputUri, $dummyResponse) {
120+
if (Argument::is($outputUri->getWrappedObject())->scoreArgument($receivedRequest->getUri())) {
121+
return new FulfilledPromise($dummyResponse->getWrappedObject());
122+
}
123+
};
124+
125+
$finalPromise = $this->handleRequest($inputRequest, $next, function () {});
126+
$finalPromise->shouldReturnAnInstanceOf('Http\Promise\FulfilledPromise');
127+
}
128+
129+
}

src/BaseHostPlugin.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Http\Client\Plugin;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
use Psr\Http\Message\UriInterface;
7+
use Symfony\Component\OptionsResolver\OptionsResolver;
8+
9+
/**
10+
* Allow to modify the the schema and the host of an existing request.
11+
*
12+
* @author Tobias Nyholm <[email protected]>
13+
*/
14+
class BaseHostPlugin implements Plugin
15+
{
16+
/**
17+
* @var UriInterface
18+
*/
19+
private $baseUri;
20+
21+
/**
22+
* @var bool
23+
*/
24+
private $replace;
25+
26+
/**
27+
* Available options for $config are:
28+
* - replace: bool True will replace all hosts, false will only add host when none is specified.
29+
*
30+
* @param UriInterface $baseUri
31+
* @param array $config
32+
*/
33+
public function __construct(UriInterface $baseUri, array $config = [])
34+
{
35+
$this->baseUri = $baseUri;
36+
37+
$resolver = new OptionsResolver();
38+
$this->configureOptions($resolver);
39+
$options = $resolver->resolve($config);
40+
41+
$this->replace = $options['replace'];
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function handleRequest(RequestInterface $request, callable $next, callable $first)
48+
{
49+
if ($this->replace || $request->getUri()->getHost() === '') {
50+
$uri = $request->getUri()->withHost($this->baseUri->getHost());
51+
$uri = $uri->withScheme($this->baseUri->getScheme());
52+
53+
$request = $request->withUri($uri);
54+
}
55+
56+
return $next($request);
57+
}
58+
59+
/**
60+
* @param OptionsResolver $resolver
61+
*/
62+
private function configureOptions(OptionsResolver $resolver)
63+
{
64+
$resolver->setDefaults([
65+
'replace' => false,
66+
]);
67+
$resolver->setAllowedTypes('replace', 'bool');
68+
}
69+
}

0 commit comments

Comments
 (0)