Skip to content

Commit 557f0f0

Browse files
authored
fix issue #184 (#185)
Fix UriString::resolve to correctly handle path and authority resolution.
1 parent c0855e4 commit 557f0f0

File tree

2 files changed

+27
-28
lines changed

2 files changed

+27
-28
lines changed

UriString.php

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ final class UriString
144144
*/
145145
public static function toIriString(BackedEnum|Stringable|string $uri): string
146146
{
147-
$components = UriString::parse($uri);
147+
$components = self::parse($uri);
148148
$port = null;
149149
if (isset($components['port'])) {
150150
$port = (int) $components['port'];
@@ -325,7 +325,7 @@ public static function normalizeAuthority(Stringable|string|null $authority): ?s
325325
return null;
326326
}
327327

328-
$components = UriString::parseAuthority($authority);
328+
$components = self::parseAuthority($authority);
329329
$components['host'] = self::normalizeHost($components['host'] ?? null);
330330
$components['user'] = Encoder::normalizeUser($components['user']);
331331
$components['pass'] = Encoder::normalizePassword($components['pass']);
@@ -358,50 +358,41 @@ public static function resolve(BackedEnum|Stringable|string $uri, BackedEnum|Str
358358

359359
$uri = (string) $uri;
360360
if ('' === $uri) {
361-
$uri = $baseUri ?? throw new SyntaxError('The uri can not be the empty string when there\'s no base URI.');
361+
$uri = $baseUri ?? throw new SyntaxError("The uri can not be the empty string when there's no base URI.");
362362
}
363363

364364
$uriComponents = self::parse($uri);
365365
$baseUriComponents = $uriComponents;
366-
if (null !== $baseUri && (string) $uri !== (string) $baseUri) {
366+
if (null !== $baseUri && $uri !== (string) $baseUri) {
367367
$baseUriComponents = self::parse($baseUri);
368368
}
369369

370-
$hasLeadingSlash = str_starts_with($baseUriComponents['path'], '/');
371370
if (null === $baseUriComponents['scheme']) {
372371
throw new SyntaxError('The base URI must be an absolute URI or null; If the base URI is null the URI must be an absolute URI.');
373372
}
374373

375-
if (null !== $uriComponents['scheme'] && '' !== $uriComponents['scheme']) {
376-
$uriComponents['path'] = self::removeDotSegments($uriComponents['path']);
377-
if ('' !== $uriComponents['path'] && '/' !== $uriComponents['path'][0] && $hasLeadingSlash) {
378-
$uriComponents['path'] = '/'.$uriComponents['path'];
379-
}
380-
381-
return UriString::build($uriComponents);
374+
$authority = self::buildAuthority($uriComponents);
375+
$path = self::removeDotSegments($uriComponents['path']);
376+
if (null !== $authority && '' !== $path && '/' !== $path[0]) {
377+
$path = '/'.$path;
382378
}
383379

384-
if (null !== self::buildAuthority($uriComponents)) {
385-
$uriComponents['scheme'] = $baseUriComponents['scheme'];
386-
$uriComponents['path'] = self::removeDotSegments($uriComponents['path']);
387-
if ('' !== $uriComponents['path'] && '/' !== $uriComponents['path'][0] && $hasLeadingSlash) {
388-
$uriComponents['path'] = '/'.$uriComponents['path'];
389-
}
380+
if (null !== $uriComponents['scheme'] && '' !== $uriComponents['scheme']) {
381+
return self::buildUri($uriComponents['scheme'], $authority, $path, $uriComponents['query'], $uriComponents['fragment']);
382+
}
390383

391-
return UriString::build($uriComponents);
384+
if (null !== $authority) {
385+
return self::buildUri($baseUriComponents['scheme'], $authority, $path, $uriComponents['query'], $uriComponents['fragment']);
392386
}
393387

394388
[$path, $query] = self::resolvePathAndQuery($uriComponents, $baseUriComponents);
395-
$path = UriString::removeDotSegments($path);
396-
if ('' !== $path && '/' !== $path[0] && $hasLeadingSlash) {
389+
$authority = self::buildAuthority($baseUriComponents);
390+
$path = self::removeDotSegments($path);
391+
if (null !== $authority && '' !== $path && '/' !== $path[0]) {
397392
$path = '/'.$path;
398393
}
399394

400-
$baseUriComponents['path'] = $path;
401-
$baseUriComponents['query'] = $query;
402-
$baseUriComponents['fragment'] = $uriComponents['fragment'];
403-
404-
return UriString::build($baseUriComponents);
395+
return self::buildUri($baseUriComponents['scheme'], $authority, $path, $query, $uriComponents['fragment']);
405396
}
406397

407398
/**

UriStringTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,13 +1101,21 @@ public static function normalizedUriProvider(): iterable
11011101
];
11021102
}
11031103

1104-
public function test_it_does_resolves_uri_against_authority_less_absolte_path(): void
1104+
public function test_it_does_resolves_uri_against_authority_less_absolute_path(): void
11051105
{
1106-
self::assertSame('foo:/c', UriString::resolve('../../c', 'foo:/a/b'));
1106+
self::assertSame('foo:c', UriString::resolve('../../c', 'foo:/a/b'));
11071107
}
11081108

11091109
public function test_it_can_resolve_uri_when_dot_segment_leave_the_path_relative(): void
11101110
{
11111111
self::assertSame('https://user:pass@host/toto', UriString::resolve('https://user:pass@host/./.././toto'));
11121112
}
1113+
1114+
public function test_it_resolve_correctly_uri_issue_184(): void
1115+
{
1116+
$baseUri = 'http://a/b/c/d;p?q';
1117+
1118+
self::assertSame('g:h', UriString::resolve('g:h', $baseUri));
1119+
self::assertSame('foo:g', UriString::resolve('foo:g', $baseUri));
1120+
}
11131121
}

0 commit comments

Comments
 (0)