-
Notifications
You must be signed in to change notification settings - Fork 132
/
Copy pathUrlFormatter.php
107 lines (89 loc) · 3.3 KB
/
UrlFormatter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\FunctionalTestingFramework\Util\Path;
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
class UrlFormatter implements FormatterInterface
{
/**
* Return formatted url path from input string
*
* @param string $url
* @param boolean $withTrailingSeparator
* @return string
* @throws TestFrameworkException
*/
public static function format($url, $withTrailingSeparator = true)
{
$sanitizedUrl = rtrim($url, '/');
// Remove all characters except letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=
$sanitizedUrl = filter_var($sanitizedUrl, FILTER_SANITIZE_URL);
if (false === $sanitizedUrl) {
throw new TestFrameworkException("Invalid url: $url\n");
}
// Validate URL according to http://www.faqs.org/rfcs/rfc2396
$validUrl = filter_var($sanitizedUrl, FILTER_VALIDATE_URL);
if (false !== $validUrl) {
return $withTrailingSeparator ? $validUrl . '/' : $validUrl;
}
// Validation might be failed due to missing URL scheme or host, attempt to build them and re-validate
$validUrl = filter_var(self::buildUrl($sanitizedUrl), FILTER_VALIDATE_URL);
if (false !== $validUrl) {
return $withTrailingSeparator ? $validUrl . '/' : $validUrl;
}
throw new TestFrameworkException("Invalid url: $url\n");
}
/**
* Try to build missing url scheme and host
*
* @param string $url
* @return string
*/
private static function buildUrl($url)
{
$urlParts = parse_url($url);
if (!isset($urlParts['scheme'])) {
$urlParts['scheme'] = 'http';
}
if (!isset($urlParts['host'])) {
$urlParts['host'] = rtrim($urlParts['path'], '/');
$urlParts['host'] = str_replace("//", '/', $urlParts['host']);
unset($urlParts['path']);
}
if (isset($urlParts['path'])) {
$urlParts['path'] = rtrim($urlParts['path'], '/');
}
return str_replace("///", "//", self::merge($urlParts));
}
/**
* Returns url from $parts given, used with parse_url output for convenience.
* This only exists because of deprecation of http_build_url, which does the exact same thing as the code below.
* @param array $parts
* @return string
*/
private static function merge(array $parts)
{
$get = function ($key) use ($parts) {
return isset($parts[$key]) ? $parts[$key] : null;
};
$pass = $get('pass');
$user = $get('user');
$userinfo = $pass !== null ? "$user:$pass" : $user;
$port = $get('port');
$scheme = $get('scheme');
$query = $get('query');
$fragment = $get('fragment');
$authority =
($userinfo !== null ? "$userinfo@" : '') .
$get('host') .
($port ? ":$port" : '');
return
(strlen($scheme) ? "$scheme:" : '') .
(strlen($authority) ? "//$authority" : '') .
$get('path') .
(strlen($query) ? "?$query" : '') .
(strlen($fragment) ? "#$fragment" : '');
}
}