Skip to content

Commit bc77813

Browse files
committed
Replaced URI parsing using Guzzle lib with local parsing.
1 parent 1444ccc commit bc77813

File tree

3 files changed

+133
-22
lines changed

3 files changed

+133
-22
lines changed

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"require": {
1616
"php": "^8.1",
1717
"ext-mbstring": "*",
18-
"guzzlehttp/psr7": "^2.0",
1918
"phpunit/phpunit": "^9.5 | ^10.0 | ^11.0 | ^12",
2019
"symfony/css-selector": ">=4.4.24 <8.0"
2120
},

src/Util/Uri.php

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ class Uri
2828
*/
2929
public static function mergeUrls(string $baseUri, string $uri): string
3030
{
31-
$base = new Psr7Uri($baseUri);
31+
$base = parse_url($baseUri);
3232
$parts = parse_url($uri);
3333

3434
//If the relative URL does not parse, attempt to parse the entire URL.
3535
//PHP Known bug ( https://bugs.php.net/bug.php?id=70942 )
3636
if ($parts === false) {
37-
$parts = parse_url($base . $uri);
37+
$parts = parse_url($baseUri . $uri);
3838
}
3939

4040
if ($parts === false) {
@@ -47,14 +47,14 @@ public static function mergeUrls(string $baseUri, string $uri): string
4747
}
4848

4949
if (isset($parts['host'])) {
50-
$base = $base->withHost($parts['host']);
51-
$base = $base->withPath('');
52-
$base = $base->withQuery('');
53-
$base = $base->withFragment('');
50+
$base['host'] = $parts['host'];
51+
$base['path'] = '';
52+
$base['query'] = '';
53+
$base['fragment'] = '';
5454
}
5555
if (isset($parts['path'])) {
5656
$path = $parts['path'];
57-
$basePath = $base->getPath();
57+
$basePath = $base['path'] ?? '';
5858
if ((!str_starts_with($path, '/')) && !empty($path)) {
5959
if ($basePath !== '') {
6060
// if it ends with a slash, relative paths are below it
@@ -69,31 +69,33 @@ public static function mergeUrls(string $baseUri, string $uri): string
6969
$path = '/' . ltrim($path, '/');
7070
}
7171
}
72-
$base = $base->withPath($path);
73-
$base = $base->withQuery('');
74-
$base = $base->withFragment('');
72+
$base['path'] = $path;
73+
$base['query'] = '';
74+
$base['fragment'] = '';
7575
}
7676
if (isset($parts['query'])) {
77-
$base = $base->withQuery($parts['query']);
78-
$base = $base->withFragment('');
77+
$base['query'] = $parts['query'];
78+
$base['fragment'] = '';
7979
}
8080
if (isset($parts['fragment'])) {
81-
$base = $base->withFragment($parts['fragment']);
81+
$base['fragment'] = $parts['fragment'];
8282
}
8383

84-
return (string)$base;
84+
return self::phpUrlPartsToString($base);
8585
}
8686

8787
/**
8888
* Retrieve /path?query#fragment part of URL
8989
*/
9090
public static function retrieveUri(string $url): string
9191
{
92-
$uri = new Psr7Uri($url);
93-
return (string)(new Psr7Uri())
94-
->withPath($uri->getPath())
95-
->withQuery($uri->getQuery())
96-
->withFragment($uri->getFragment());
92+
$urlParts = parse_url($url);
93+
94+
return self::phpUrlPartsToString([
95+
'path' => $urlParts['path'],
96+
'query' => $urlParts['query'] ?? '',
97+
'fragment' => $urlParts['fragment'] ?? '',
98+
]);
9799
}
98100

99101
public static function retrieveHost(string $url): string
@@ -111,13 +113,65 @@ public static function retrieveHost(string $url): string
111113

112114
public static function appendPath(string $url, string $path): string
113115
{
114-
$uri = new Psr7Uri($url);
115-
$cutUrl = (string)$uri->withQuery('')->withFragment('');
116+
$cutUrl = parse_url($url);
117+
unset(
118+
$cutUrl['query'],
119+
$cutUrl['fragment'],
120+
);
121+
$cutUrl = self::phpUrlPartsToString($cutUrl);
116122

117123
if ($path === '' || $path[0] === '#') {
118124
return $cutUrl . $path;
119125
}
120126

121127
return rtrim($cutUrl, '/') . '/' . ltrim($path, '/');
122128
}
129+
130+
/**
131+
* @param array{
132+
* scheme: string,
133+
* host: string,
134+
* port: int,
135+
* user: string,
136+
* pass: string,
137+
* query: string,
138+
* path: string,
139+
* fragment: string,
140+
* } $urlParts
141+
*/
142+
public static function phpUrlPartsToString(array $urlParts): string
143+
{
144+
$uri = '';
145+
$scheme = $urlParts['scheme'] ?? '';
146+
$host = $urlParts['host'] ?? '';
147+
$path = $urlParts['path'] ?? '';
148+
149+
if (($scheme ?? '') !== '') {
150+
$uri .= $scheme . ':';
151+
}
152+
153+
if ($host !== '' || $scheme === 'file') {
154+
$uri .= '//' . $host;
155+
156+
if (($urlParts['port'] ?? '') !== '') {
157+
$uri .= ':' . $urlParts['port'];
158+
}
159+
}
160+
161+
if ($host !== '' && $path !== '' && $path[0] !== '/') {
162+
$path = '/' . $path;
163+
}
164+
165+
$uri .= $path;
166+
167+
if (($urlParts['query'] ?? '') !== '') {
168+
$uri .= '?' . $urlParts['query'];
169+
}
170+
171+
if (($urlParts['fragment'] ?? '') !== '') {
172+
$uri .= '#' . $urlParts['fragment'];
173+
}
174+
175+
return $uri;
176+
}
123177
}

tests/Util/UriTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tests\Codeception\Util;
66

77
use Codeception\Util\Uri;
8+
use PHPUnit\Framework\Attributes\DataProvider;
89
use PHPUnit\Framework\TestCase;
910

1011
class UriTest extends TestCase
@@ -125,4 +126,61 @@ public function testMergeUrlsWhenBaseUriEndsWithSlashButUriPathHasNoLeadingSlash
125126
Uri::mergeUrls('https://codeception.com/', 'test')
126127
);
127128
}
129+
130+
#[DataProvider('phpUrlPartsProvider')]
131+
public function testPhpUrlPartsToString(array $parts, string $expected): void
132+
{
133+
$this->assertSame($expected, Uri::phpUrlPartsToString($parts));
134+
}
135+
136+
public static function phpUrlPartsProvider(): iterable
137+
{
138+
yield [
139+
[
140+
'path' => '/test',
141+
],
142+
'/test'
143+
];
144+
145+
yield [
146+
[
147+
'query' => 'test=a',
148+
],
149+
'?test=a'
150+
];
151+
152+
yield [
153+
[
154+
'scheme' => 'https',
155+
'host' => 'codeception.com',
156+
'path' => '/test',
157+
],
158+
'https://codeception.com/test'
159+
];
160+
161+
yield [
162+
[
163+
'scheme' => 'https',
164+
'host' => 'codeception.com',
165+
],
166+
'https://codeception.com'
167+
];
168+
169+
yield [
170+
[
171+
'scheme' => 'https',
172+
'host' => 'codeception.com',
173+
],
174+
'https://codeception.com'
175+
];
176+
177+
yield [
178+
[
179+
'scheme' => 'https',
180+
'host' => 'codeception.com',
181+
'port' => 8080,
182+
],
183+
'https://codeception.com:8080'
184+
];
185+
}
128186
}

0 commit comments

Comments
 (0)