Skip to content
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

Use Guzzle to resolve the URL against the base URL #51799

Closed
wants to merge 1 commit into from

Conversation

joke2k
Copy link
Contributor

@joke2k joke2k commented Jun 13, 2024

Hello Reviewers 👋

This work extends the support for RFC3986 from Guzzle Client to the Http Client.

Previously @JaZo tried to implement this but it was partially addressed by #41307 in version 9 and not merged for version 10 #41289.

The RFC3986 that Guzzle implements allows us to do something that currently isn't possible because this code:

public function send(string $method, string $url, array $options = [])
{
if (! Str::startsWith($url, ['http://', 'https://'])) {
$url = ltrim(rtrim($this->baseUrl, '/').'/'.ltrim($url, '/'), '/');
}

🔴 First: overriding the base path (initial slash of URI)

Http::baseUrl('http://foo.com/foo')->get('/bar')
// should call -> http://foo.com/bar
// but now     -> http://foo.com/foo/bar
// same as Http::baseUrl('http://foo.com/foo')->get('bar')

this is really helpful when you have special routes (baseUri: http://foo.com/api/v1 but you would like to call http://foo.com/health-check)

🔴 Second: overriding the last part of the path (no trailing slash in baseURI)

Http::baseUrl('http://foo.com/foo/bar')->get('baz')
// should call -> http://foo.com/foo/baz
// but now     -> http://foo.com/foo/bar/baz
// same as Http::baseUrl('http://foo.com/foo/bar')->get('/baz')

💡 Solution

If it is set, pass the PendingRequest:baseUrl into the options for the Guzzle client and delegate to it the resolution of the final URI . If the base_uri is explicitly set in the $options for a request, this takes precedence over the PendingRequest:baseUrl. By doing this, we also have support for idn_conversion and the addition of the schema if it's missing thanks to Guzzle's Client::buildUrl(...)

This is the table taken from Guzzle doc :

baseUri URI Expected by RFC Current result Compliant
http://foo.com /bar http://foo.com/bar http://foo.com/bar ✔️
http://foo.com/foo /bar http://foo.com/bar http://foo.com/foo/bar
http://foo.com/foo bar http://foo.com/bar http://foo.com/foo/bar
http://foo.com/foo/ bar http://foo.com/foo/bar http://foo.com/foo/bar ✔️
http://foo.com/ http://baz.com/ http://baz.com/ http://baz.com/ ✔️
http://foo.com/?bar bar http://foo.com/bar http://foo.com/?bar/bar

🟢 Adopting an RFC and having consistency with the underlying Guzzle client, I think, will help future developers.

‼️ This introduces breaking changes potentially affecting all those who have incorrectly used the baseUri/URI combination.
For this reason, I have targeted the PR to master and not to 11.x or 10.x, but if it can considered a bugfix I'm happy to cherry-pick this commit.

tests/Http/HttpClientTest.php Outdated Show resolved Hide resolved
@taylorotwell
Copy link
Member

No plans to change this behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants