Skip to content

Instantly share code, notes, and snippets.

@dhotson
Created June 3, 2013 03:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhotson/5696044 to your computer and use it in GitHub Desktop.
Save dhotson/5696044 to your computer and use it in GitHub Desktop.
<?php
// Parse HTTP HOST header hostname and port according to http://tools.ietf.org/html/rfc3986.html
$h16 = '[[:xdigit:]]{1,4}';
$subDelims = "[!$&'()*+,;=]";
$pctEncoded = '%[[:xdigit]][[:xdigit]]';
$unreserved = '[-._~[:alpha:][:digit:]]';
$decOctet = <<<EOS
(?:
[0-9] # 0-9
| (?: [1-9][0-9] ) # 10-99
| (?: 1 [0-9][0-9] ) # 100-199
| (?: 2 [0-4][0-9] ) # 200-249
| (?: 25 [0-5] ) # 250-255
)
EOS;
$regName = <<<EOS
(?:
$unreserved
| $pctEncoded
| $subDelims
)*
EOS;
$ipv4Address = <<<EOS
(?:
$decOctet \. $decOctet \. $decOctet \. $decOctet
)
EOS;
$ls32 = <<<EOS
(?:
(?: $h16 : $h16) | $ipv4Address
)
EOS;
$h16c = "(?: $h16 : )";
$ipv6Address = <<<EOS
(?:
(?: $h16c{6} $ls32 )
| (?: :: $h16c{5} $ls32 )
| (?: (?: $h16 )? :: $h16c{4} $ls32 )
| (?: (?: $h16c{0,1} $h16 )? :: $h16c{3} $ls32 )
| (?: (?: $h16c{0,2} $h16 )? :: $h16c{2} $ls32 )
| (?: (?: $h16c{0,3} $h16 )? :: $h16c $ls32 )
| (?: (?: $h16c{0,4} $h16 )? :: $ls32 )
| (?: (?: $h16c{0,5} $h16 )? :: $h16 )
| (?: (?: $h16c{0,6} $h16 )? :: )
)
EOS;
$ipvFuture = <<<EOS
(?:
v [[:xdigit:]]+ \. (?: $unreserved | $subDelims | : )+
)
EOS;
$ipLiteral = <<<EOS
(?: \[ (?: $ipv6Address | $ipvFuture ) \] )
EOS;
$hostRule = <<<EOS
/
\A
(?P<host>
$ipLiteral
| $ipv4Address
| $regName
)
(?:
: (?P<port> [0-9]*)
)?
\Z
/x
EOS;
$testUrls = array(
'hello.com',
'hello.com:90',
'127.0.0.1',
'127.0.0.1:90',
'[::1]:90',
'[2607:f0d0:1002:0051:0000:0000:0000:0004]:90',
'[::ffff:192.0.2.128]:90',
'',
':90',
);
echo $host."\n\n";
foreach ($testUrls as $t) {
if (preg_match($hostRule, $t, $match)) {
$host = $match['host'];
$port = isset($match['port']) ? $match['port'] : '-';
echo $t . ' ==> ' . $host . ' : ' . $port . "\n";
} else {
echo '!! ' . $t . "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment