Browse Source

Fix authority parsing (mostly)

master
J. King 4 years ago
parent
commit
ff782a132e
  1. 45
      lib/Url.php

45
lib/Url.php

@ -46,23 +46,8 @@ class Url implements UriInterface {
(\#.*)? # fragment part
$>six
PCRE;
protected const AUTHORITY_PATTERN = <<<'PCRE'
<^
//
(?:
([^@:]*) # username part
(?::([^@]*))? # password part
@
)?
(
\[[a-f0-9:]*\] | # IPv6 address
[^:]* # domain or IPv4 address
)
(?:
:([^/]*) # port part
)?
$>six
PCRE;
protected const HOST_PATTERN = '/^(\[[a-f0-9:]*\]|[^:]*)(?::([^\/]*))?$/si';
protected const USER_PATTERN = '/^([^:]*)(?::(.*))?$/s';
protected const SCHEME_PATTERN = '/^(?:[a-z][a-z0-9\.\-\+]*|)$/i';
protected const IPV6_PATTERN = '/^\[[a-f0-9:]+\]$/i';
protected const PORT_PATTERN = '/^\d*$/';
@ -70,7 +55,7 @@ PCRE;
protected const WHITESPACE_CHARS = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20";
protected const ESCAPE_CHARS = [
'user' => [":", "@", "/", "?", "#"],
'pass' => ["@", "/", "?", "#"],
'pass' => [":", "@", "/", "?", "#"],
'path' => ["?", "#"],
'query' => ["#"],
];
@ -117,14 +102,21 @@ PCRE;
}
}
if (strlen($authority)) {
if (preg_match(self::AUTHORITY_PATTERN, $authority, $match)) {
[$authority, $user, $pass, $host, $port] = array_pad($match, 5, "");
foreach (["user", "pass", "host", "port"] as $part) {
$this->set($part, $$part);
$authority = substr($authority, 2);
if (($cleft = strrpos($authority, "@")) !== false) {
if (preg_match(self::USER_PATTERN, substr($authority, 0, $cleft), $match)) {
$this->set("user", $match[1]);
$this->set("pass", $match[2] ?? "");
}
} else {
assert(false, "Authority did not match pattern");
if (preg_match(self::HOST_PATTERN, substr($authority, $cleft + 1), $match)) {
$this->set("host", $match[1]);
$this->set("port", $match[2] ?? "");
}
} elseif (preg_match(self::HOST_PATTERN, $authority, $match)) {
$this->set("host", $match[1]);
$this->set("port", $match[2] ?? "");
}
}
if ((!$this->scheme || ($this->host === null && array_key_exists($this->scheme, self::SPECIAL_SCHEMES))) && strlen($baseUrl ?? "")) {
$this->resolve(new static($baseUrl));
@ -233,12 +225,15 @@ PCRE;
}
public function __toString() {
$auth = $this->getAuthority();
$out = "";
$out .= strlen($this->scheme) ? $this->scheme.":" : "";
if (is_null($this->host)) {
$out .= $this->path;
} else {
$auth = $this->host;
$auth .= (strlen($auth) && !is_null($this->port)) ? ":".$this->port : "";
$user = $this->user.(strlen($this->pass) ? ":".$this->pass : "");
$auth = (strlen($auth) && strlen($user)) ? "$user@$auth" : $auth;
$out .= "//";
$out .= $auth;
$out .= ($this->path[0] ?? "") !== "/" && strlen($auth) ? "/" : "";

Loading…
Cancel
Save