Fix parsing schemeless url

This commit is contained in:
Zach Borboa
2021-08-07 17:48:47 -04:00
parent 25e9126f77
commit eadd466f66
2 changed files with 19 additions and 55 deletions
+1 -52
View File
@@ -180,58 +180,7 @@ class Url
*/
public static function parseUrl($url)
{
// RFC 3986 - Parsing a URI Reference with a Regular Expression.
// ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
// 12 3 4 5 6 7 8 9
//
// "http://www.ics.uci.edu/pub/ietf/uri/#Related"
// $1 = http: (scheme)
// $2 = http (scheme)
// $3 = //www.ics.uci.edu (ignore)
// $4 = www.ics.uci.edu (authority)
// $5 = /pub/ietf/uri/ (path)
// $6 = <undefined> (ignore)
// $7 = <undefined> (query)
// $8 = #Related (ignore)
// $9 = Related (fragment)
preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/', (string) $url, $output_array);
$parts = [];
if (isset($output_array['1']) && $output_array['1'] !== '') {
$parts['scheme'] = $output_array['1'];
}
if (isset($output_array['2']) && $output_array['2'] !== '') {
$parts['scheme'] = $output_array['2'];
}
if (isset($output_array['4']) && $output_array['4'] !== '') {
// authority = [ userinfo "@" ] host [ ":" port ]
$parts['host'] = $output_array['4'];
if (strpos($parts['host'], ':') !== false) {
$host_parts = explode(':', $output_array['4']);
$parts['port'] = array_pop($host_parts);
$parts['host'] = implode(':', $host_parts);
if (strpos($parts['host'], '@') !== false) {
$host_parts = explode('@', $parts['host']);
$parts['host'] = array_pop($host_parts);
$parts['user'] = implode('@', $host_parts);
if (strpos($parts['user'], ':') !== false) {
$user_parts = explode(':', $parts['user'], 2);
$parts['user'] = array_shift($user_parts);
$parts['pass'] = implode(':', $user_parts);
}
}
}
}
if (isset($output_array['5']) && $output_array['5'] !== '') {
$parts['path'] = self::percentEncodeChars($output_array['5']);
}
if (isset($output_array['7']) && $output_array['7'] !== '') {
$parts['query'] = $output_array['7'];
}
if (isset($output_array['9']) && $output_array['9'] !== '') {
$parts['fragment'] = $output_array['9'];
}
return $parts;
return parse_url((string) $url);
}
/**
+18 -3
View File
@@ -68,7 +68,7 @@ class UrlTest extends \PHPUnit\Framework\TestCase
}
}
public function testCyrillicChars()
public function testUrlCyrillicChars()
{
$path_part = 'Банан-комнатный-саженцы-банана';
$original_url = 'https://www.example.com/path/' . $path_part . '/page.html';
@@ -122,17 +122,32 @@ class UrlTest extends \PHPUnit\Framework\TestCase
$this->assertEquals($expected_parts, $result);
}
public function testIpv6NoPort()
public function testUrlIpv6NoPort()
{
$expected_url = 'http://[::1]/test';
$actual_url = new Url($expected_url);
$this->assertEquals($expected_url, $actual_url);
}
public function testIpv6Port()
public function testUrlIpv6Port()
{
$expected_url = 'http://[::1]:80/test';
$actual_url = new Url($expected_url);
$this->assertEquals($expected_url, $actual_url);
}
public function testParseUrlSchemelessUrl()
{
$input_url = '10.1.2.43:8080/config/getconfig';
$expected_parts = [
'host' => '10.1.2.43',
'port' => '8080',
'path' => '/config/getconfig',
];
$this->assertEquals($expected_parts, parse_url($input_url));
$result = Url::parseUrl($input_url);
$this->assertEquals($expected_parts, $result);
}
}