Skip to content

Commit b632753

Browse files
authored
Merge pull request php-curl-class#680 from zachborboa/master
Fix php-curl-class#679: Parsing schemeless urls
2 parents 45c0915 + 8bc9d6d commit b632753

File tree

2 files changed

+27
-69
lines changed

2 files changed

+27
-69
lines changed

src/Curl/Url.php

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@ public static function buildUrl($url, $mixed_data = '')
114114
*/
115115
private function absolutizeUrl()
116116
{
117-
$b = $this->parseUrl($this->baseUrl);
117+
$b = self::parseUrl($this->baseUrl);
118118
if (!isset($b['path'])) {
119119
$b['path'] = '/';
120120
}
121121
if ($this->relativeUrl === null) {
122122
return $this->unparseUrl($b);
123123
}
124-
$r = $this->parseUrl($this->relativeUrl);
124+
$r = self::parseUrl($this->relativeUrl);
125125
$r['authorized'] = isset($r['scheme']) || isset($r['host']) || isset($r['port'])
126126
|| isset($r['user']) || isset($r['pass']);
127127
$target = [];
@@ -178,58 +178,11 @@ private function absolutizeUrl()
178178
*
179179
* Parse url into components of a URI as specified by RFC 3986.
180180
*/
181-
private function parseUrl($url)
181+
public static function parseUrl($url)
182182
{
183-
// RFC 3986 - Parsing a URI Reference with a Regular Expression.
184-
// ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
185-
// 12 3 4 5 6 7 8 9
186-
//
187-
// "http://www.ics.uci.edu/pub/ietf/uri/#Related"
188-
// $1 = http: (scheme)
189-
// $2 = http (scheme)
190-
// $3 = //www.ics.uci.edu (ignore)
191-
// $4 = www.ics.uci.edu (authority)
192-
// $5 = /pub/ietf/uri/ (path)
193-
// $6 = <undefined> (ignore)
194-
// $7 = <undefined> (query)
195-
// $8 = #Related (ignore)
196-
// $9 = Related (fragment)
197-
preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/', (string) $url, $output_array);
198-
199-
$parts = [];
200-
if (isset($output_array['1']) && $output_array['1'] !== '') {
201-
$parts['scheme'] = $output_array['1'];
202-
}
203-
if (isset($output_array['2']) && $output_array['2'] !== '') {
204-
$parts['scheme'] = $output_array['2'];
205-
}
206-
if (isset($output_array['4']) && $output_array['4'] !== '') {
207-
// authority = [ userinfo "@" ] host [ ":" port ]
208-
$parts['host'] = $output_array['4'];
209-
if (strpos($parts['host'], ':') !== false) {
210-
$host_parts = explode(':', $output_array['4']);
211-
$parts['port'] = array_pop($host_parts);
212-
$parts['host'] = implode(':', $host_parts);
213-
if (strpos($parts['host'], '@') !== false) {
214-
$host_parts = explode('@', $parts['host']);
215-
$parts['host'] = array_pop($host_parts);
216-
$parts['user'] = implode('@', $host_parts);
217-
if (strpos($parts['user'], ':') !== false) {
218-
$user_parts = explode(':', $parts['user'], 2);
219-
$parts['user'] = array_shift($user_parts);
220-
$parts['pass'] = implode(':', $user_parts);
221-
}
222-
}
223-
}
224-
}
225-
if (isset($output_array['5']) && $output_array['5'] !== '') {
226-
$parts['path'] = $this->percentEncodeChars($output_array['5']);
227-
}
228-
if (isset($output_array['7']) && $output_array['7'] !== '') {
229-
$parts['query'] = $output_array['7'];
230-
}
231-
if (isset($output_array['9']) && $output_array['9'] !== '') {
232-
$parts['fragment'] = $output_array['9'];
183+
$parts = parse_url((string) $url);
184+
if (isset($parts['path'])) {
185+
$parts['path'] = self::percentEncodeChars($parts['path']);
233186
}
234187
return $parts;
235188
}
@@ -240,7 +193,7 @@ private function parseUrl($url)
240193
* Percent-encode characters to represent a data octet in a component when
241194
* that octet's corresponding character is outside the allowed set.
242195
*/
243-
private function percentEncodeChars($chars)
196+
private static function percentEncodeChars($chars)
244197
{
245198
// ALPHA = A-Z / a-z
246199
$alpha = 'A-Za-z';

tests/PHPCurlClass/UrlTest.php

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function testRemoveDotSegments()
6868
}
6969
}
7070

71-
public function testCyrillicChars()
71+
public function testUrlCyrillicChars()
7272
{
7373
$path_part = 'Банан-комнатный-саженцы-банана';
7474
$original_url = 'https://www.example.com/path/' . $path_part . '/page.html';
@@ -98,12 +98,7 @@ public function testParseUrlSyntaxComponents()
9898

9999
$this->assertEquals($expected_parts, parse_url($input_url));
100100

101-
$reflector = new \ReflectionClass('Curl\Url');
102-
$reflection_method = $reflector->getMethod('parseUrl');
103-
$reflection_method->setAccessible(true);
104-
105-
$url = new Url(null);
106-
$result = $reflection_method->invoke($url, $input_url);
101+
$result = Url::parseUrl($input_url);
107102
$this->assertEquals($expected_parts, $result);
108103
}
109104

@@ -123,26 +118,36 @@ public function testParseUrlExample()
123118

124119
$this->assertEquals($expected_parts, parse_url($input_url));
125120

126-
$reflector = new \ReflectionClass('Curl\Url');
127-
$reflection_method = $reflector->getMethod('parseUrl');
128-
$reflection_method->setAccessible(true);
129-
130-
$url = new Url(null);
131-
$result = $reflection_method->invoke($url, $input_url);
121+
$result = Url::parseUrl($input_url);
132122
$this->assertEquals($expected_parts, $result);
133123
}
134124

135-
public function testIpv6NoPort()
125+
public function testUrlIpv6NoPort()
136126
{
137127
$expected_url = 'http://[::1]/test';
138128
$actual_url = new Url($expected_url);
139129
$this->assertEquals($expected_url, $actual_url);
140130
}
141131

142-
public function testIpv6Port()
132+
public function testUrlIpv6Port()
143133
{
144134
$expected_url = 'http://[::1]:80/test';
145135
$actual_url = new Url($expected_url);
146136
$this->assertEquals($expected_url, $actual_url);
147137
}
138+
139+
public function testParseUrlSchemelessUrl()
140+
{
141+
$input_url = '10.1.2.43:8080/config/getconfig';
142+
$expected_parts = [
143+
'host' => '10.1.2.43',
144+
'port' => '8080',
145+
'path' => '/config/getconfig',
146+
];
147+
148+
$this->assertEquals($expected_parts, parse_url($input_url));
149+
150+
$result = Url::parseUrl($input_url);
151+
$this->assertEquals($expected_parts, $result);
152+
}
148153
}

0 commit comments

Comments
 (0)