Skip to content

Commit e0aa708

Browse files
committed
Fixes
1 parent ee1737b commit e0aa708

File tree

2 files changed

+22
-63
lines changed

2 files changed

+22
-63
lines changed

src/Plugin/AddPathPlugin.php

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,30 @@ public function __construct(UriInterface $uri)
3535
}
3636

3737
/**
38-
* Adds a prefix in the beginning of the URL's path. We will not add the prefix
39-
* if it already exists. This will of course not cover all the edge cases. For
40-
* example when you have a valid URL like `https://example.com/api/api/foo` and
41-
* you are using the prefix "/api".
38+
* Adds a prefix in the beginning of the URL's path.
4239
*
43-
* Some of the other edge cases are:
44-
* - request objects can be reused
45-
* - plugin chains could be restarted
46-
* - multiple AddPathPlugins may exist in one chain
40+
* The prefix is not added if that prefix is already on the URL's path. This will fail on the edge
41+
* case of the prefix being repeated, for example if `https://example.com/api/api/foo` is a valid
42+
* URL on the server and the configured prefix is `/api`.
4743
*
48-
* If one would like to cover all these scenarios one would have to add a custom
49-
* header to the request to indicate it has been rewritten by the plugin. This
50-
* implementation does not aim for pleasing all edge cases rather to be great
51-
* value for the 95% other use cases.
44+
* We looked at other solutions, but they are all much more complicated, while still having edge
45+
* cases:
46+
* - Doing an spl_object_hash on `$first` will lead to collisions over time because over time the
47+
* hash can collide.
48+
* - Have the PluginClient provide a magic header to identify the request chain and only apply
49+
* this plugin once.
50+
*
51+
* There are 2 reasons for the AddPathPlugin to be executed twice on the same request:
52+
* - A plugin can restart the chain by calling `$first`, e.g. redirect
53+
* - A plugin can call `$next` more than once, e.g. retry
54+
*
55+
* Depending on the scenario, the path should or should not be added. E.g. `$first` could
56+
* be called after a redirect response from the server. The server likely already has the
57+
* correct path.
58+
*
59+
* No solution fits all use cases. This implementation will work fine for the common use cases.
60+
* If you have a specific situation where this is not the right thing, you can build a custom plugin
61+
* that does exactly what you need.
5262
*
5363
* {@inheritdoc}
5464
*/

tests/Plugin/AddPathPluginTest.php

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,6 @@ public function testRewriteWithDifferentUrl()
7373
}, $this->first);
7474
}
7575

76-
public function testRewriteWithDifferentUrlWhenSecondUrlIncludesAddedPath()
77-
{
78-
$verify = function (RequestInterface $request) {
79-
$this->assertEquals('https://example.com/api/foo', $request->getUri()->__toString());
80-
};
81-
82-
$request = new Request('GET', 'https://example.com/foo');
83-
$this->plugin->handleRequest($request, $verify, $this->first);
84-
85-
$request = new Request('GET', 'https://example.com/api/foo');
86-
$this->plugin->handleRequest($request, $verify, $this->first);
87-
}
88-
8976
public function testRewriteWhenPathIsIncluded()
9077
{
9178
$verify = function (RequestInterface $request) {
@@ -95,42 +82,4 @@ public function testRewriteWhenPathIsIncluded()
9582
$request = new Request('GET', 'https://example.com/api/foo');
9683
$this->plugin->handleRequest($request, $verify, $this->first);
9784
}
98-
public function testRewriteOnRestart()
99-
{
100-
$secondPlugin = new class implements Plugin {
101-
private $firstRun = true;
102-
103-
public function handleRequest(RequestInterface $request, callable $next, callable $first)
104-
{
105-
if ($this->firstRun) {
106-
$this->firstRun = false;
107-
return $first($request)->wait();
108-
}
109-
return $next($request);
110-
}
111-
};
112-
113-
$verify = function (RequestInterface $request) {
114-
$this->assertEquals('https://example.com/api/foo', $request->getUri()->__toString());
115-
};
116-
117-
$client = new class($verify) implements HttpClient {
118-
private $callable;
119-
public function __construct(callable $callable)
120-
{
121-
$this->callable = $callable;
122-
}
123-
124-
public function sendRequest(RequestInterface $request)
125-
{
126-
$verify = $this->callable;
127-
$verify($request);
128-
return new Response();
129-
}
130-
};
131-
132-
$pluginClient = new PluginClient($client, [$this->plugin, $secondPlugin]);
133-
$request = new Request('GET', 'https://example.com/foo');
134-
$response = $pluginClient->sendAsyncRequest($request);
135-
}
13685
}

0 commit comments

Comments
 (0)