1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-02-23 11:28:33 +01:00
php-phpbb/vendor/goutte.phar

413 lines
261 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
$web = '_web_stub.php';
if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
Phar::interceptFileFuncs();
set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
Phar::webPhar(null, $web);
include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
return;
}
if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
Extract_Phar::go(true);
$mimes = array(
'phps' => 2,
'c' => 'text/plain',
'cc' => 'text/plain',
'cpp' => 'text/plain',
'c++' => 'text/plain',
'dtd' => 'text/plain',
'h' => 'text/plain',
'log' => 'text/plain',
'rng' => 'text/plain',
'txt' => 'text/plain',
'xsd' => 'text/plain',
'php' => 1,
'inc' => 1,
'avi' => 'video/avi',
'bmp' => 'image/bmp',
'css' => 'text/css',
'gif' => 'image/gif',
'htm' => 'text/html',
'html' => 'text/html',
'htmls' => 'text/html',
'ico' => 'image/x-ico',
'jpe' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'js' => 'application/x-javascript',
'midi' => 'audio/midi',
'mid' => 'audio/midi',
'mod' => 'audio/mod',
'mov' => 'movie/quicktime',
'mp3' => 'audio/mp3',
'mpg' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'pdf' => 'application/pdf',
'png' => 'image/png',
'swf' => 'application/shockwave-flash',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'wav' => 'audio/wav',
'xbm' => 'image/xbm',
'xml' => 'text/xml',
);
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
$basename = basename(__FILE__);
if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
chdir(Extract_Phar::$temp);
include $web;
return;
}
$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
if (!$pt || $pt == '/') {
$pt = $web;
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
exit;
}
$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
header('HTTP/1.0 404 Not Found');
echo "<html>\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File ", $pt, " Not Found</h1>\n </body>\n</html>";
exit;
}
$b = pathinfo($a);
if (!isset($b['extension'])) {
header('Content-Type: text/plain');
header('Content-Length: ' . filesize($a));
readfile($a);
exit;
}
if (isset($mimes[$b['extension']])) {
if ($mimes[$b['extension']] === 1) {
include $a;
exit;
}
if ($mimes[$b['extension']] === 2) {
highlight_file($a);
exit;
}
header('Content-Type: ' .$mimes[$b['extension']]);
header('Content-Length: ' . filesize($a));
readfile($a);
exit;
}
}
class Extract_Phar
{
static $temp;
static $origdir;
const GZ = 0x1000;
const BZ2 = 0x2000;
const MASK = 0x3000;
const START = '_cli_stub.php';
const LEN = 6693;
static function go($return = false)
{
$fp = fopen(__FILE__, 'rb');
fseek($fp, self::LEN);
$L = unpack('V', $a = (binary)fread($fp, 4));
$m = (binary)'';
do {
$read = 8192;
if ($L[1] - strlen($m) < 8192) {
$read = $L[1] - strlen($m);
}
$last = (binary)fread($fp, $read);
$m .= $last;
} while (strlen($last) && strlen($m) < $L[1]);
if (strlen($m) < $L[1]) {
die('ERROR: manifest length read was "' .
strlen($m) .'" should be "' .
$L[1] . '"');
}
$info = self::_unpack($m);
$f = $info['c'];
if ($f & self::GZ) {
if (!function_exists('gzinflate')) {
die('Error: zlib extension is not enabled -' .
' gzinflate() function needed for zlib-compressed .phars');
}
}
if ($f & self::BZ2) {
if (!function_exists('bzdecompress')) {
die('Error: bzip2 extension is not enabled -' .
' bzdecompress() function needed for bz2-compressed .phars');
}
}
$temp = self::tmpdir();
if (!$temp || !is_writable($temp)) {
$sessionpath = session_save_path();
if (strpos ($sessionpath, ";") !== false)
$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
die('Could not locate temporary directory to extract phar');
}
$temp = $sessionpath;
}
$temp .= '/pharextract/'.basename(__FILE__, '.phar');
self::$temp = $temp;
self::$origdir = getcwd();
@mkdir($temp, 0777, true);
$temp = realpath($temp);
if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
self::_removeTmpFiles($temp, getcwd());
@mkdir($temp, 0777, true);
@file_put_contents($temp . '/' . md5_file(__FILE__), '');
foreach ($info['m'] as $path => $file) {
$a = !file_exists(dirname($temp . '/' . $path));
@mkdir(dirname($temp . '/' . $path), 0777, true);
clearstatcache();
if ($path[strlen($path) - 1] == '/') {
@mkdir($temp . '/' . $path, 0777);
} else {
file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
@chmod($temp . '/' . $path, 0666);
}
}
}
chdir($temp);
if (!$return) {
include self::START;
}
}
static function tmpdir()
{
if (strpos(PHP_OS, 'WIN') !== false) {
if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
return $var;
}
if (is_dir('/temp') || mkdir('/temp')) {
return realpath('/temp');
}
return false;
}
if ($var = getenv('TMPDIR')) {
return $var;
}
return realpath('/tmp');
}
static function _unpack($m)
{
$info = unpack('V', substr($m, 0, 4));
$l = unpack('V', substr($m, 10, 4));
$m = substr($m, 14 + $l[1]);
$s = unpack('V', substr($m, 0, 4));
$o = 0;
$start = 4 + $s[1];
$ret['c'] = 0;
for ($i = 0; $i < $info[1]; $i++) {
$len = unpack('V', substr($m, $start, 4));
$start += 4;
$savepath = substr($m, $start, $len[1]);
$start += $len[1];
$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
& 0xffffffff);
$ret['m'][$savepath][7] = $o;
$o += $ret['m'][$savepath][2];
$start += 24 + $ret['m'][$savepath][5];
$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
}
return $ret;
}
static function extractFile($path, $entry, $fp)
{
$data = '';
$c = $entry[2];
while ($c) {
if ($c < 8192) {
$data .= @fread($fp, $c);
$c = 0;
} else {
$c -= 8192;
$data .= @fread($fp, 8192);
}
}
if ($entry[4] & self::GZ) {
$data = gzinflate($data);
} elseif ($entry[4] & self::BZ2) {
$data = bzdecompress($data);
}
if (strlen($data) != $entry[0]) {
die("Invalid internal .phar file (size error " . strlen($data) . " != " .
$stat[7] . ")");
}
if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
die("Invalid internal .phar file (checksum error)");
}
return $data;
}
static function _removeTmpFiles($temp, $origdir)
{
chdir($temp);
foreach (glob('*') as $f) {
if (file_exists($f)) {
is_dir($f) ? @rmdir($f) : @unlink($f);
if (file_exists($f) && is_dir($f)) {
self::_removeTmpFiles($f, getcwd());
}
}
}
@rmdir($temp);
clearstatcache();
chdir($origdir);
}
}
Extract_Phar::go();
__HALT_COMPILER(); ?>
ZRGoutteLICENSE)Ɓ2N)<00><1C><><EFBFBD> autoload.php^Ɓ2N^<00><>}7<>=vendor/Symfony/Component/ClassLoader/UniversalClassLoader.php<68> Ɓ2N<32> <00><41>5vendor/zend/library/Zend/Tool/Framework/Exception.php>Ɓ2N> <0B>E<>%vendor/zend/library/Zend/Registry.php<68>Ɓ2N<32>=9H<39><48>$vendor/zend/library/Zend/Uri/Uri.phpA8Ɓ2NA8<00><0F><><EFBFBD>0vendor/zend/library/Zend/Validator/Validator.phpyƁ2Ny<00>\<5C>ݶ8vendor/zend/library/Zend/Validator/AbstractValidator.php;Ɓ2N;<00><>H<EFBFBD><48>/vendor/zend/library/Zend/Validator/Hostname.phpQƁ2NQ<0F><><EFBFBD><EFBFBD>)vendor/zend/library/Zend/Validator/Ip.phpi
Ɓ2Ni
<00><><EFBFBD>Z<EFBFBD>3vendor/zend/library/Zend/Validator/Hostname/Com.phpG0Ɓ2NG0K<><4B>D<EFBFBD>2vendor/zend/library/Zend/Validator/Hostname/Jp.php/<2F>Ɓ2N/<2F>RƏS<C68F>src/Goutte/Client.php<68> Ɓ2N<32> ܧ<>Ķsrc/Goutte/Compiler.php<68>Ɓ2N<32>Y<>VA<56>.vendor/Symfony/Component/BrowserKit/Client.phpƁ2NMt<4D><74><EFBFBD>.vendor/Symfony/Component/BrowserKit/Cookie.php?Ɓ2N?2<>w
<EFBFBD>1vendor/Symfony/Component/BrowserKit/CookieJar.phpAƁ2NA<00><>`<60><>/vendor/Symfony/Component/BrowserKit/History.php<68>Ɓ2N<32><1D>/vendor/Symfony/Component/BrowserKit/Request.php<68>Ɓ2N<32><00><>Q<EFBFBD><51>0vendor/Symfony/Component/BrowserKit/Response.php<68>Ɓ2N<32>p<14><><EFBFBD>/vendor/Symfony/Component/DomCrawler/Crawler.php4Ɓ2N4<00><>f<EFBFBD><66>=vendor/Symfony/Component/DomCrawler/Field/ChoiceFormField.php<68>Ɓ2N<32>W<>|V<>;vendor/Symfony/Component/DomCrawler/Field/FileFormField.php<68>Ɓ2N<32><00><>p<>7vendor/Symfony/Component/DomCrawler/Field/FormField.phpDƁ2NDk<><6B><EFBFBD><vendor/Symfony/Component/DomCrawler/Field/InputFormField.phprƁ2Nr<00>#<23>c<EFBFBD>?vendor/Symfony/Component/DomCrawler/Field/TextareaFormField.php<68>Ɓ2N<32><00><>$@<40>,vendor/Symfony/Component/DomCrawler/Form.phpFƁ2NF<00>#<23>,vendor/Symfony/Component/DomCrawler/Link.php<68>Ɓ2N<32><05>4vendor/Symfony/Component/CssSelector/CssSelector.php&Ɓ2N&H<48>Avendor/Symfony/Component/CssSelector/Exception/ParseException.phpfƁ2Nf<00><>)<29>8vendor/Symfony/Component/CssSelector/Node/AttribNode.php
Ɓ2N
<00><>7vendor/Symfony/Component/CssSelector/Node/ClassNode.php<68>Ɓ2N<32><00>g<EFBFBD>ǶBvendor/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php2Ɓ2N2<00>Z<EFBFBD><5A><EFBFBD>9vendor/Symfony/Component/CssSelector/Node/ElementNode.php<68>Ɓ2N<32>~2]<5D><>:vendor/Symfony/Component/CssSelector/Node/FunctionNode.php<68>
Ɓ2N<32>
k<>x<EFBFBD><78>6vendor/Symfony/Component/CssSelector/Node/HashNode.phpƁ2NL;vendor/Symfony/Component/CssSelector/Node/NodeInterface.php|Ɓ2N|ڰK<DAB0><4B>4vendor/Symfony/Component/CssSelector/Node/OrNode.php<68>Ɓ2N<32><00>b<EFBFBD>u<EFBFBD>8vendor/Symfony/Component/CssSelector/Node/PseudoNode.php\
Ɓ2N\
<00><>d<EFBFBD><64>.vendor/Symfony/Component/CssSelector/Token.php<68>Ɓ2N<32>GQ<47><51>2vendor/Symfony/Component/CssSelector/Tokenizer.phpo Ɓ2No <00><>4vendor/Symfony/Component/CssSelector/TokenStream.php*Ɓ2N*<06>z<EFBFBD>2vendor/Symfony/Component/CssSelector/XPathExpr.php<68> Ɓ2N<32> <00><>2<1B>4vendor/Symfony/Component/CssSelector/XPathExprOr.phpoƁ2NoB<><08><>5vendor/Symfony/Component/Process/ExecutableFinder.phpƁ2N<12><16><>8vendor/Symfony/Component/Process/PhpExecutableFinder.php<68>Ɓ2N<32> h<>v<EFBFBD>/vendor/Symfony/Component/Process/PhpProcess.php<68>Ɓ2N<32><><7F>><3E>,vendor/Symfony/Component/Process/Process.phpƁ2N<00>߀?<3F>Cvendor/zend/library/Zend/Uri/Exception/InvalidArgumentException.php<68>Ɓ2N<32>̀<><01>>vendor/zend/library/Zend/Uri/Exception/InvalidUriException.php<68>Ɓ2N<32>-<2D>$<24>Bvendor/zend/library/Zend/Uri/Exception/InvalidUriPartException.php<68>Ɓ2N<32><00><><17><>Bvendor/zend/library/Zend/Uri/Exception/InvalidUriTypeException.php<68>Ɓ2N<32>+G<>ݶ*vendor/zend/library/Zend/Uri/Exception.php2Ɓ2N2<00>u4Ӷ%vendor/zend/library/Zend/Uri/File.php<68>Ɓ2N<32>XQ<58>*<2A>%vendor/zend/library/Zend/Uri/Http.php<68>Ɓ2N<32>ă<>Ƕ'vendor/zend/library/Zend/Uri/Mailto.php[Ɓ2N[ِ<>h<EFBFBD>+vendor/zend/library/Zend/Uri/UriFactory.php:Ɓ2N:&j<><6A><EFBFBD>5vendor/zend/library/Zend/Http/Client/Adapter/Curl.php<68>Ɓ2N<32>N<><4E>v<EFBFBD>Rvendor/zend/library/Zend/Http/Client/Adapter/Exception/InitializationException.php<68>Ɓ2N<32>^<5E><>ȶSvendor/zend/library/Zend/Http/Client/Adapter/Exception/InvalidArgumentException.php<68>Ɓ2N<32><00><>܇<EFBFBD>Nvendor/zend/library/Zend/Http/Client/Adapter/Exception/OutOfRangeException.php<68>Ɓ2N<32>B rG<72>Kvendor/zend/library/Zend/Http/Client/Adapter/Exception/RuntimeException.php<68>Ɓ2N<32>bc<62>S<EFBFBD>Kvendor/zend/library/Zend/Http/Client/Adapter/Exception/TimeoutException.php<68>Ɓ2N<32><00><><EFBFBD>+<2B>:vendor/zend/library/Zend/Http/Client/Adapter/Exception.phpfƁ2Nf*<2A><><EFBFBD>6vendor/zend/library/Zend/Http/Client/Adapter/Proxy.php<68>Ɓ2N<32><00>9<EFBFBD>4<EFBFBD>7vendor/zend/library/Zend/Http/Client/Adapter/Socket.php<68>Ɓ2N<32><><EEA4BF>7vendor/zend/library/Zend/Http/Client/Adapter/Stream.phpcƁ2Nc<00><><EFBFBD>v<EFBFBD>5vendor/zend/library/Zend/Http/Client/Adapter/Test.php" Ɓ2N" <00><>n <0B>0vendor/zend/library/Zend/Http/Client/Adapter.php.Ɓ2N.<00>_L3<4C>Kvendor/zend/library/Zend/Http/Client/Exception/InvalidArgumentException.php<68>Ɓ2N<32><00>O<EFBFBD><4F><EFBFBD>Cvendor/zend/library/Zend/Http/Client/Exception/RuntimeException.php<68>Ɓ2N<32><00>2vendor/zend/library/Zend/Http/Client/Exception.phpWƁ2NW<00>i<EFBFBD><69><EFBFBD>(vendor/zend/library/Zend/Http/Client.php<68>GƁ2N<32>Gǒ<><C792><EFBFBD>(vendor/zend/library/Zend/Http/Cookie.php?Ɓ2N?MuP<75><50>+vendor/zend/library/Zend/Http/CookieJar.php%Ɓ2N%<00>&<26><><EFBFBD>Dvendor/zend/library/Zend/Http/Exception/InvalidArgumentException.php<68>Ɓ2N<32><00><><EFBFBD>t<EFBFBD><vendor/zend/library/Zend/Http/Exception/RuntimeException.phpzƁ2Nz<00>51<>+vendor/zend/library/Zend/Http/Exception.php3Ɓ2N3Y<><1C><>1vendor/zend/library/Zend/Http/Response/Stream.phpƁ2N<00><04><><EFBFBD>*vendor/zend/library/Zend/Http/Response.php<68>Ɓ2N<32>H<>˶
_cli_stub.php5Ɓ2N5*.<2E>:<3A>
_web_stub.phpdƁ2Nd<00><00>U<EFBFBD>Copyright (c) 2010,2011 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php
require_once __DIR__.'/vendor/Symfony/Component/ClassLoader/UniversalClassLoader.php'; use Symfony\Component\ClassLoader\UniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( 'Symfony' => __DIR__.'/vendor', 'Zend' => __DIR__.'/vendor/zend/library', 'Goutte' => __DIR__.'/src', )); $loader->register(); <?php
namespace Symfony\Component\ClassLoader; class UniversalClassLoader { private $namespaces = array(); private $prefixes = array(); private $namespaceFallbacks = array(); private $prefixFallbacks = array(); public function getNamespaces() { return $this->namespaces; } public function getPrefixes() { return $this->prefixes; } public function getNamespaceFallbacks() { return $this->namespaceFallbacks; } public function getPrefixFallbacks() { return $this->prefixFallbacks; } public function registerNamespaceFallbacks(array $dirs) { $this->namespaceFallbacks = $dirs; } public function registerPrefixFallbacks(array $dirs) { $this->prefixFallbacks = $dirs; } public function registerNamespaces(array $namespaces) { foreach ($namespaces as $namespace => $locations) { $this->namespaces[$namespace] = (array) $locations; } } public function registerNamespace($namespace, $paths) { $this->namespaces[$namespace] = (array) $paths; } public function registerPrefixes(array $classes) { foreach ($classes as $prefix => $locations) { $this->prefixes[$prefix] = (array) $locations; } } public function registerPrefix($prefix, $paths) { $this->prefixes[$prefix] = (array) $paths; } public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } public function loadClass($class) { if ($file = $this->findFile($class)) { require $file; } } public function findFile($class) { if ('\\' == $class[0]) { $class = substr($class, 1); } if (false !== $pos = strrpos($class, '\\')) { $namespace = substr($class, 0, $pos); foreach ($this->namespaces as $ns => $dirs) { foreach ($dirs as $dir) { if (0 === strpos($namespace, $ns)) { $className = substr($class, $pos + 1); $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; if (file_exists($file)) { return $file; } } } } foreach ($this->namespaceFallbacks as $dir) { $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; if (file_exists($file)) { return $file; } } } else { foreach ($this->prefixes as $prefix => $dirs) { foreach ($dirs as $dir) { if (0 === strpos($class, $prefix)) { $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; if (file_exists($file)) { return $file; } } } } foreach ($this->prefixFallbacks as $dir) { $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; if (file_exists($file)) { return $file; } } } } } <?php
namespace Zend\Tool\Framework; interface Exception { } <?php
namespace Zend; class Registry extends \ArrayObject { private static $_registryClassName = '\\Zend\\Registry'; private static $_registry = null; public static function getInstance() { if (self::$_registry === null) { self::init(); } return self::$_registry; } public static function setInstance(Registry $registry) { if (self::$_registry !== null) { throw new \RuntimeException('Registry is already initialized'); } self::setClassName(get_class($registry)); self::$_registry = $registry; } protected static function init() { self::setInstance(new self::$_registryClassName()); } public static function setClassName($registryClassName = '\\Zend\\Registry') { if (self::$_registry !== null) { throw new \RuntimeException('Registry is already initialized'); } if (!is_string($registryClassName)) { throw new \RuntimeException("Argument is not a class name"); } if (!class_exists($registryClassName)) { Loader::loadClass($registryClassName); } self::$_registryClassName = $registryClassName; } public static function _unsetInstance() { self::$_registry = null; } public static function get($index) { $instance = self::getInstance(); if (!$instance->offsetExists($index)) { throw new \RuntimeException("No entry is registered for key '$index'"); } return $instance->offsetGet($index); } public static function set($index, $value) { $instance = self::getInstance(); $instance->offsetSet($index, $value); } public static function isRegistered($index) { if (self::$_registry === null) { return false; } return self::$_registry->offsetExists($index); } public function __construct($array = array(), $flags = parent::ARRAY_AS_PROPS) { parent::__construct($array, $flags); } public function offsetExists($index) { return array_key_exists($index, $this); } } <?php
namespace Zend\Uri; use Zend\Validator; class Uri { const CHAR_UNRESERVED = '\w\-\.~'; const CHAR_GEN_DELIMS = ':\/\?#\[\]@'; const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;='; const CHAR_RESERVED = ':\/\?#\[\]@!\$&\'\(\)\*\+,;='; const HOST_IPV4 = 1; const HOST_IPV6 = 2; const HOST_IPVF = 4; const HOST_IPVANY = 7; const HOST_DNSNAME = 8; const HOST_DNSORIPV4 = 9; const HOST_REGNAME = 16; const HOST_ALL = 31; protected $scheme; protected $userInfo; protected $host; protected $port; protected $path; protected $query; protected $fragment; protected $validHostTypes = self::HOST_ALL; protected static $validSchemes = array(); protected static $defaultPorts = array(); public function __construct($uri = null) { if (is_string($uri)) { $this->parse($uri); } elseif ($uri instanceof Uri) { $this->setScheme($uri->getScheme()); $this->setUserInfo($uri->getUserInfo()); $this->setHost($uri->getHost()); $this->setPort($uri->getPort()); $this->setPath($uri->getPath()); $this->setQuery($uri->getQuery()); $this->setFragment($uri->getFragment()); } elseif ($uri !== null) { throw new Exception\InvalidArgumentException(sprintf( 'Expecting a string or a URI object, received "%s"', (is_object($uri) ? get_class($uri) : gettype($uri)) )); } } public function isValid() { if ($this->host) { if (strlen($this->path) > 0 && substr($this->path, 0, 1) != '/') { return false; } return true; } if ($this->userInfo || $this->port) { return false; } if ($this->path) { if (substr($this->path, 0, 2) == '//') { return false; } return true; } if (! ($this->query || $this->fragment)) { return false; } return true; } public function isAbsolute() { return ($this->scheme !== null); } public function parse($uri) { if (($scheme = self::parseScheme($uri)) !== null) { $this->setScheme($scheme); $uri = substr($uri, strlen($scheme) + 1); } if (preg_match('|^//([^/\?#]*)|', $uri, $match)) { $authority = $match[1]; $uri = substr($uri, strlen($match[0])); if (strpos($authority, '@') !== false) { $segments = explode('@', $authority); $authority = array_pop($segments); $userInfo = implode('@', $segments); unset($segments); $this->setUserInfo($userInfo); } $colonPos = strrpos($authority, ':'); if ($colonPos !== false) { $port = substr($authority, $colonPos + 1); if ($port) { $this->setPort((int) $port); } $authority = substr($authority, 0, $colonPos); } $this->setHost($authority); } if (!$uri) { return $this; } if (preg_match('|^[^\?#]*|', $uri, $match)) { $this->setPath($match[0]); $uri = substr($uri, strlen($match[0])); } if (!$uri) { return $this; } if (preg_match('|^\?([^#]*)|', $uri, $match)) { $this->setQuery($match[1]); $uri = substr($uri, strlen($match[0])); } if (!$uri) { return $this; } if ($uri && substr($uri, 0, 1) == '#') { $this->setFragment(substr($uri, 1)); } return $this; } public function toString() { if (!$this->isValid()) { throw new Exception\InvalidUriException('URI is not valid and cannot be converted into a string'); } $uri = ''; if ($this->scheme) { $uri .= $this->scheme . ':'; } if ($this->host !== null) { $uri .= '//'; if ($this->userInfo) { $uri .= $this->userInfo . '@'; } $uri .= $this->host; if ($this->port) { $uri .= ':' . $this->port; } } if ($this->path) { $uri .= self::encodePath($this->path); } elseif ($this->host && ($this->query || $this->fragment)) { $uri .= '/'; } if ($this->query) { $uri .= "?" . self::encodeQueryFragment($this->query); } if ($this->fragment) { $uri .= "#" . self::encodeQueryFragment($this->fragment); } return $uri; } public function normalize() { if ($this->scheme) { $this->scheme = static::normalizeScheme($this->scheme); } if ($this->host) { $this->host = static::normalizeHost($this->host); } if ($this->port) { $this->port = static::normalizePort($this->port, $this->scheme); } if ($this->path) { $this->path = static::normalizePath($this->path); } if ($this->query) { $this->query = static::normalizeQuery($this->query); } if ($this->fragment) { $this->fragment = static::normalizeFragment($this->fragment); } if ($this->host && empty($this->path)) { $this->path = '/'; } return $this; } public function resolve($baseUri) { if ($this->isAbsolute()) { return $this; } if (is_string($baseUri)) { $baseUri = new static($baseUri); } if (!$baseUri instanceof static) { throw new Exception\InvalidUriTypeException(sprintf( 'Provided base URL is not an instance of "%s"', get_class($this) )); } if ($this->getHost()) { $this->setPath(static::removePathDotSegments($this->getPath())); } else { $basePath = $baseUri->getPath(); $relPath = $this->getPath(); if (!$relPath) { $this->setPath($basePath); if (!$this->getQuery()) { $this->setQuery($baseUri->getQuery()); } } else { if (substr($relPath, 0, 1) == '/') { $this->setPath(static::removePathDotSegments($relPath)); } else { if ($baseUri->getHost() && !$basePath) { $mergedPath = '/'; } else { $mergedPath = substr($basePath, 0, strrpos($basePath, '/') + 1); } $this->setPath(static::removePathDotSegments($mergedPath . $relPath)); } } $this->setUserInfo($baseUri->getUserInfo()); $this->setHost($baseUri->getHost()); $this->setPort($baseUri->getPort()); } $this->setScheme($baseUri->getScheme()); return $this; } public function makeRelative($baseUri) { $baseUri = new static($baseUri); $this->normalize(); $baseUri->normalize(); $host = $this->getHost(); $baseHost = $baseUri->getHost(); if ($host && $baseHost && ($host != $baseHost)) { return $this; } $port = $this->getPort(); $basePort = $baseUri->getPort(); if ($port && $basePort && ($port != $basePort)) { return $this; } $scheme = $this->getScheme(); $baseScheme = $baseUri->getScheme(); if ($scheme && $baseScheme && ($scheme != $baseScheme)) { return $this; } $this->setHost(null) ->setPort(null) ->setScheme(null); if ($this->getPath() == $baseUri->getPath()) { $this->setPath(''); return $this; } $pathParts = preg_split('|(/)|', $this->getPath(), null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $baseParts = preg_split('|(/)|', $baseUri->getPath(), null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $matchingParts = array_intersect_assoc($pathParts, $baseParts); foreach ($matchingParts as $index => $segment) { if ($index && !isset($matchingParts[$index - 1])) { array_unshift($pathParts, '../'); continue; } unset($pathParts[$index]); } $this->setPath(implode($pathParts)); return $this; } public function getScheme() { return $this->scheme; } public function getUserInfo() { return $this->userInfo; } public function getHost() { return $this->host; } public function getPort() { return $this->port; } public function getPath() { return $this->path; } public function getQuery() { return $this->query; } public function getQueryAsArray() { $query = array(); if ($this->query) { parse_str($this->query, $query); } return $query; } public function getFragment() { return $this->fragment; } public function setScheme($scheme) { if (($scheme !== null) && (!self::validateScheme($scheme))) { throw new Exception\InvalidUriPartException(sprintf( 'Scheme "%s" is not valid or is not accepted by %s', $scheme, get_class($this) ), Exception\InvalidUriPartException::INVALID_SCHEME); } $this->scheme = $scheme; return $this; } public function setUserInfo($userInfo) { $this->userInfo = $userInfo; return $this; } public function setHost($host) { if (($host !== '') && ($host !== null) && !self::validateHost($host, $this->validHostTypes) ) { throw new Exception\InvalidUriPartException(sprintf( 'Host "%s" is not valid or is not accepted by %s', $host, get_class($this) ), Exception\InvalidUriPartException::INVALID_HOSTNAME); } $this->host = $host; return $this; } public function setPort($port) { $this->port = $port; return $this; } public function setPath($path) { $this->path = $path; return $this; } public function setQuery($query) { if (is_array($query)) { $query = str_replace('+', '%20', http_build_query($query)); } $this->query = $query; return $this; } public function setFragment($fragment) { $this->fragment = $fragment; return $this; } public function __toString() { try { return $this->toString(); } catch (\Exception $e) { return ''; } } public static function validateScheme($scheme) { if (!empty(static::$validSchemes) && !in_array(strtolower($scheme), static::$validSchemes) ) { return false; } return (bool) preg_match('/^[A-Za-z][A-Za-z0-9\-\.+]*$/', $scheme); } public static function validateUserInfo($userInfo) { $regex = '/^(?:[' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ':]+|%[A-Fa-f0-9]{2})*$/'; return (boolean) preg_match($regex, $userInfo); } public static function validateHost($host, $allowed = self::HOST_ALL) { if ($allowed & self::HOST_REGNAME) { if (static::isValidRegName($host)) { return true; } } if ($allowed & self::HOST_DNSNAME) { if (static::isValidDnsHostname($host)) { return true; } } if ($allowed & self::HOST_IPVANY) { if (static::isValidIpAddress($host, $allowed)) { return true; } } return false; } public static function validatePort($port) { if ($port === 0) { return false; } if ($port) { $port = (int) $port; if ($port < 1 || $port > 0xffff) { return false; } } return true; } public static function validatePath($path) { $pchar = '(?:[' . self::CHAR_UNRESERVED . ':@&=\+\$,]+|%[A-Fa-f0-9]{2})*'; $segment = $pchar . "(?:;{$pchar})*"; $regex = "/^{$segment}(?:\/{$segment})*$/"; return (boolean) preg_match($regex, $path); } public static function validateQueryFragment($input) { $regex = '/^(?:[' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ':@\/\?]+|%[A-Fa-f0-9]{2})*$/'; return (boolean) preg_match($regex, $input); } public static function encodeUserInfo($userInfo) { if (!is_string($userInfo)) { throw new Exception\InvalidArgumentException(sprintf( 'Expecting a string, got %s', (is_object($userInfo) ? get_class($userInfo) : gettype($userInfo)) )); } $regex = '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:]|%(?![A-Fa-f0-9]{2}))/'; $replace = function($match) { return rawurlencode($match[0]); }; return preg_replace_callback($regex, $replace, $userInfo); } public static function encodePath($path) { if (!is_string($path)) { throw new Exception\InvalidArgumentException(sprintf( 'Expecting a string, got %s', (is_object($path) ? get_class($path) : gettype($path)) )); } $regex = '/(?:[^' . self::CHAR_UNRESERVED . ':@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/'; $replace = function($match) { return rawurlencode($match[0]); }; return preg_replace_callback($regex, $replace, $path); } public static function encodeQueryFragment($input) { if (!is_string($input)) { throw new Exception\InvalidArgumentException(sprintf( 'Expecting a string, got %s', (is_object($input) ? get_class($input) : gettype($input)) )); } $regex = '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/'; $replace = function($match) { return rawurlencode($match[0]); }; return preg_replace_callback($regex, $replace, $input); } public static function parseScheme($uriString) { if (! is_string($uriString)) { throw new Exception\InvalidArgumentException(sprintf( 'Expecting a string, got %s', (is_object($uriString) ? get_class($uriString) : gettype($uriString)) )); } if (preg_match('/^([A-Za-z][A-Za-z0-9\.\+\-]*):/', $uriString, $match)) { return $match[1]; } return null; } public static function removePathDotSegments($path) { $output = ''; while ($path) { if ($path == '..' || $path == '.') { break; } switch (true) { case ($path == '/.'): $path = '/'; break; case ($path == '/..'): $path = '/'; $output = substr($output, 0, strrpos($output, '/', -1)); break; case (substr($path, 0, 4) == '/../'): $path = '/' . substr($path, 4); $output = substr($output, 0, strrpos($output, '/', -1)); break; case (substr($path, 0, 3) == '/./'): $path = substr($path, 2); break; case (substr($path, 0, 2) == './'): $path = substr($path, 2); break; case (substr($path, 0, 3) == '../'): $path = substr($path, 3); break; default: $slash = strpos($path, '/', 1); if ($slash === false) { $seg = $path; } else { $seg = substr($path, 0, $slash); } $output .= $seg; $path = substr($path, strlen($seg)); break; } } return $output; } public static function merge($baseUri, $relativeUri) { $uri = new self($relativeUri); return $uri->resolve($baseUri); } protected static function isValidIpAddress($host, $allowed) { $validatorParams = array( 'allowipv4' => (bool) ($allowed & self::HOST_IPV4), 'allowipv6' => (bool) ($allowed & self::HOST_IPV6), ); if ($allowed & (self::HOST_IPV6 | self::HOST_IPVF)) { if (preg_match('/^\[(.+)\]$/', $host, $match)) { $host = $match[1]; $validatorParams['allowipv4'] = false; } } if ($allowed & (self::HOST_IPV4 | self::HOST_IPV6)) { $validator = new Validator\Ip($validatorParams); if ($validator->isValid($host)) { return true; } } if ($allowed & self::HOST_IPVF) { $regex = '/^v\.[[:xdigit:]]+[' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ':]+$/'; return (bool) preg_match($regex, $host); } return false; } protected static function isValidDnsHostname($host) { $validator = new Validator\Hostname(array( 'allow' => Validator\Hostname::ALLOW_DNS | Validator\Hostname::ALLOW_LOCAL, )); return $validator->isValid($host); } protected static function isValidRegName($host) { $regex = '/^(?:[' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ':@\/\?]+|%[A-Fa-f0-9]{2})+$/'; return (bool) preg_match($regex, $host); } protected static function normalizeScheme($scheme) { return strtolower($scheme); } protected static function normalizeHost($host) { return strtolower($host); } protected static function normalizePort($port, $scheme = null) { if ($scheme && isset(static::$defaultPorts[$scheme]) && ($port == static::$defaultPorts[$scheme]) ) { return null; } return $port; } protected static function normalizePath($path) { $path = self::encodePath( self::decodeUrlEncodedChars( self::removePathDotSegments($path), '/[' . self::CHAR_UNRESERVED . ':@&=\+\$,\/;%]/' ) ); return $path; } protected static function normalizeQuery($query) { $query = self::encodeQueryFragment( self::decodeUrlEncodedChars( $query, '/[' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]/' ) ); return $query; } protected static function normalizeFragment($fragment) { return static::normalizeQuery($fragment); } protected static function decodeUrlEncodedChars($input, $allowed = '') { $decodeCb = function($match) use ($allowed) { $char = rawurldecode($match[0]); if (preg_match($allowed, $char)) { return $char; } return $match[0]; }; return preg_replace_callback('/%[A-Fa-f0-9]{2}/', $decodeCb, $input); } } <?php
namespace Zend\Validator; interface Validator { public function isValid($value); public function getMessages(); } <?php
namespace Zend\Validator; use Zend\Translator; abstract class AbstractValidator implements Validator { protected $_value; protected $_messageVariables = array(); protected $_messageTemplates = array(); protected $_messages = array(); protected $_obscureValue = false; protected $_errors = array(); protected $_translator; protected static $_defaultTranslator; protected $_translatorDisabled = false; protected static $_messageLength = -1; public function getMessages() { return $this->_messages; } public function __invoke($value) { return $this->isValid($value); } public function getMessageVariables() { return array_keys($this->_messageVariables); } public function getMessageTemplates() { return $this->_messageTemplates; } public function setMessage($messageString, $messageKey = null) { if ($messageKey === null) { $keys = array_keys($this->_messageTemplates); foreach($keys as $key) { $this->setMessage($messageString, $key); } return $this; } if (!isset($this->_messageTemplates[$messageKey])) { throw new Exception\InvalidArgumentException("No message template exists for key '$messageKey'"); } $this->_messageTemplates[$messageKey] = $messageString; return $this; } public function setMessages(array $messages) { foreach ($messages as $key => $message) { $this->setMessage($message, $key); } return $this; } public function __get($property) { if ($property == 'value') { return $this->_value; } if (array_key_exists($property, $this->_messageVariables)) { return $this->{$this->_messageVariables[$property]}; } throw new Exception\InvalidArgumentException("No property exists by the name '$property'"); } protected function _createMessage($messageKey, $value) { if (!isset($this->_messageTemplates[$messageKey])) { return null; } $message = $this->_messageTemplates[$messageKey]; if (null !== ($translator = $this->getTranslator())) { if ($translator->isTranslated($messageKey)) { $message = $translator->translate($messageKey); } else { $message = $translator->translate($message); } } if (is_object($value)) { if (!in_array('__toString', get_class_methods($value))) { $value = get_class($value) . ' object'; } else { $value = $value->__toString(); } } else { $value = (string)$value; } if ($this->getObscureValue()) { $value = str_repeat('*', strlen($value)); } $message = str_replace('%value%', (string) $value, $message); foreach ($this->_messageVariables as $ident => $property) { $message = str_replace("%$ident%", (string) $this->$property, $message); } $length = self::getMessageLength(); if (($length > -1) && (strlen($message) > $length)) { $message = substr($message, 0, (self::getMessageLength() - 3)) . '...'; } return $message; } protected function _error($messageKey, $value = null) { if ($messageKey === null) { $keys = array_keys($this->_messageTemplates); $messageKey = current($keys); } if ($value === null) { $value = $this->_value; } $this->_errors[] = $messageKey; $this->_messages[$messageKey] = $this->_createMessage($messageKey, $value); } protected function _setValue($value) { $this->_value = $value; $this->_messages = array(); $this->_errors = array(); } public function getErrors() { return $this->_errors; } public function setObscureValue($flag) { $this->_obscureValue = (bool) $flag; return $this; } public function getObscureValue() { return $this->_obscureValue; } public function setTranslator($translator = null) { if ((null === $translator) || ($translator instanceof Translator\Adapter)) { $this->_translator = $translator; } elseif ($translator instanceof Translator\Translator) { $this->_translator = $translator->getAdapter(); } else { throw new Exception\InvalidArgumentException('Invalid translator specified'); } return $this; } public function getTranslator() { if ($this->translatorIsDisabled()) { return null; } if (null === $this->_translator) { return self::getDefaultTranslator(); } return $this->_translator; } public function hasTranslator() { return (bool)$this->_translator; } public static function setDefaultTranslator($translator = null) { if ((null === $translator) || ($translator instanceof Translator\Adapter)) { self::$_defaultTranslator = $translator; } elseif ($translator instanceof Translator\Translator) { self::$_defaultTranslator = $translator->getAdapter(); } else { throw new Exception\InvalidArgumentException('Invalid translator specified'); } } public static function getDefaultTranslator() { if (null === self::$_defaultTranslator) { if (\Zend\Registry::isRegistered('Zend_Translate')) { $translator = \Zend\Registry::get('Zend_Translate'); if ($translator instanceof Translator\Adapter) { return $translator; } elseif ($translator instanceof Translator\Translator) { return $translator->getAdapter(); } } } return self::$_defaultTranslator; } public static function hasDefaultTranslator() { return (bool)self::$_defaultTranslator; } public function setDisableTranslator($flag) { $this->_translatorDisabled = (bool) $flag; return $this; } public function translatorIsDisabled() { return $this->_translatorDisabled; } public static function getMessageLength() { return self::$_messageLength; } public static function setMessageLength($length = -1) { self::$_messageLength = $length; } } <?php
namespace Zend\Validator; class Hostname extends AbstractValidator { const CANNOT_DECODE_PUNYCODE = 'hostnameCannotDecodePunycode'; const INVALID = 'hostnameInvalid'; const INVALID_DASH = 'hostnameDashCharacter'; const INVALID_HOSTNAME = 'hostnameInvalidHostname'; const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema'; const INVALID_LOCAL_NAME = 'hostnameInvalidLocalName'; const INVALID_URI = 'hostnameInvalidUri'; const IP_ADDRESS_NOT_ALLOWED = 'hostnameIpAddressNotAllowed'; const LOCAL_NAME_NOT_ALLOWED = 'hostnameLocalNameNotAllowed'; const UNDECIPHERABLE_TLD = 'hostnameUndecipherableTld'; const UNKNOWN_TLD = 'hostnameUnknownTld'; protected $_messageTemplates = array( self::CANNOT_DECODE_PUNYCODE => "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded", self::INVALID => "Invalid type given. String expected", self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash in an invalid position", self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname", self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name", self::INVALID_URI => "'%value%' does not appear to be a valid URI hostname", self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed", self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed", self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part", self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list", ); protected $_messageVariables = array( 'tld' => '_tld' ); const ALLOW_DNS = 1; const ALLOW_IP = 2; const ALLOW_LOCAL = 4; const ALLOW_URI = 8; const ALLOW_ALL = 15; protected $_validTlds = array( 'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'arpa', 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'biz', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', 'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'edu', 'ee', 'eg', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'info', 'int', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', 'mn', 'mo', 'mobi', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 'ne', 'net', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', 'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm', 'zw' ); protected $_tld; protected $_validIdns = array( 'AC' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), 'AR' => array(1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'), 'AS' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'), 'AT' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'), 'BIZ' => 'Hostname/Biz.php', 'BR' => array(1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'), 'BV' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 'CAT' => array(1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'), 'CH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), 'CL' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), 'CN' => 'Hostname/Cn.php', 'COM' => 'Hostname/Com.php', 'DE' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 'DK' => array(1 => '/^[\x{002d}0-9a-zäéöü]{1,63}$/iu'), 'ES' => array(1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'), 'EU' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'), 'FI' => array(1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'), 'GR' => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'), 'HK' => 'Hostname/Cn.php', 'HU' => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'), 'INFO'=> array(1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'), 'IO' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 'IS' => array(1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'), 'JP' => 'Hostname/Jp.php', 'KR' => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'), 'LI' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'), 'LT' => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'), 'MD' => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'), 'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'), 'NET' => 'Hostname/Com.php', 'NO' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 'NU' => 'Hostname/Com.php', 'ORG' => array(1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'), 'PE' => array(1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'), 'PL' => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', 10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', 11=> '/^[\x{002d}0-9a-zçë]{1,63}$/iu', 12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', 13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', 14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', 15=> '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', 16=> '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', 17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', 18=> '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', 19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', 20=> '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', 21=> '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', 22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', 23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', 24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', 25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', 26=> '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', 27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', 28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', 29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', 30=> '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', 31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', 32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', 33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'), 'PR' => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'), 'PT' => array(1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'), 'RU' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), 'SA' => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'), 'SE' => array(1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'), 'SH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'), 'SJ' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'), 'TH' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), 'TM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'), 'TW' => 'Hostname/Cn.php', 'TR' => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'), 'VE' => array(1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'), 'VN' => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'), '中国' => 'Hostname/Cn.php', '中國' => 'Hostname/Cn.php', 'ලංකා' => array(1 => '/^[\x{0d80}-\x{0dff}]{1,63}$/iu'), '香港' => 'Hostname/Cn.php', '台湾' => 'Hostname/Cn.php', '台灣' => 'Hostname/Cn.php', 'امارات' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), 'الاردن' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), 'السعودية' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), 'ไทย' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'), 'рф' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'), 'تونس' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), 'مصر' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), 'இலங்கை' => array(1 => '/^[\x{0b80}-\x{0bff}]{1,63}$/iu'), 'فلسطين' => array(1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'), ); protected $_idnLength = array( 'BIZ' => array(5 => 17, 11 => 15, 12 => 20), 'CN' => array(1 => 20), 'COM' => array(3 => 17, 5 => 20), 'HK' => array(1 => 15), 'INFO'=> array(4 => 17), 'KR' => array(1 => 17), 'NET' => array(3 => 17, 5 => 20), 'ORG' => array(6 => 17), 'TW' => array(1 => 20), 'امارات' => array(1 => 30), 'الاردن' => array(1 => 30), 'السعودية' => array(1 => 30), 'تونس' => array(1 => 30), 'مصر' => array(1 => 30), 'فلسطين' => array(1 => 30), '中国' => array(1 => 20), '中國' => array(1 => 20), '香港' => array(1 => 20), '台湾' => array(1 => 20), '台灣' => array(1 => 20), ); protected $_options = array( 'allow' => self::ALLOW_DNS, 'idn' => true, 'tld' => true, 'ip' => null ); public function __construct($options = array()) { if ($options instanceof \Zend\Config\Config) { $options = $options->toArray(); } else if (!is_array($options)) { $options = func_get_args(); $temp['allow'] = array_shift($options); if (!empty($options)) { $temp['idn'] = array_shift($options); } if (!empty($options)) { $temp['tld'] = array_shift($options); } if (!empty($options)) { $temp['ip'] = array_shift($options); } $options = $temp; } $options += $this->_options; $this->setOptions($options); } public function getOptions() { return $this->_options; } public function setOptions($options) { if (array_key_exists('allow', $options)) { $this->setAllow($options['allow']); } if (array_key_exists('idn', $options)) { $this->setValidateIdn($options['idn']); } if (array_key_exists('tld', $options)) { $this->setValidateTld($options['tld']); } if (array_key_exists('ip', $options)) { $this->setIpValidator($options['ip']); } return $this; } public function getIpValidator() { return $this->_options['ip']; } public function setIpValidator(Ip $ipValidator = null) { if ($ipValidator === null) { $ipValidator = new Ip(); } $this->_options['ip'] = $ipValidator; return $this; } public function getAllow() { return $this->_options['allow']; } public function setAllow($allow) { $this->_options['allow'] = $allow; return $this; } public function getValidateIdn() { return $this->_options['idn']; } public function setValidateIdn ($allowed) { $this->_options['idn'] = (bool) $allowed; return $this; } public function getValidateTld() { return $this->_options['tld']; } public function setValidateTld ($allowed) { $this->_options['tld'] = (bool) $allowed; return $this; } public function isValid($value) { if (!is_string($value)) { $this->_error(self::INVALID); return false; } $this->_setValue($value); if (preg_match('/^[0-9.a-e:.]*$/i', $value) && $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { if (!($this->_options['allow'] & self::ALLOW_IP)) { $this->_error(self::IP_ADDRESS_NOT_ALLOWED); return false; } else { return true; } } if ($this->_options['allow'] & self::ALLOW_LOCAL) { if (substr($value, -1) === '.') { $value = substr($value, 0, -1); if (substr($value, -1) === '.') { $this->_error(self::INVALID_LOCAL_NAME); return false; } } } $domainParts = explode('.', $value); if ((count($domainParts) == 4) && preg_match('/^[0-9.a-e:.]*$/i', $value) && $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) { $this->_error(self::INVALID_LOCAL_NAME); } if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) { $status = false; $origenc = iconv_get_encoding('internal_encoding'); iconv_set_encoding('internal_encoding', 'UTF-8'); do { $matches = array(); if (preg_match('/([^.]{2,10})$/i', end($domainParts), $matches) || (array_key_exists(end($domainParts), $this->_validIdns))) { reset($domainParts); $this->_tld = strtolower($matches[1]); if ($this->_options['tld']) { if (!in_array($this->_tld, $this->_validTlds)) { $this->_error(self::UNKNOWN_TLD); $status = false; break; } } $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i'); if ($this->_options['idn'] && isset($this->_validIdns[strtoupper($this->_tld)])) { if (is_string($this->_validIdns[strtoupper($this->_tld)])) { $regexChars += include($this->_validIdns[strtoupper($this->_tld)]); } else { $regexChars += $this->_validIdns[strtoupper($this->_tld)]; } } $check = 0; foreach ($domainParts as $domainPart) { if (strpos($domainPart, 'xn--') === 0) { $domainPart = $this->decodePunycode(substr($domainPart, 4)); if ($domainPart === false) { return false; } } if ((strpos($domainPart, '-') === 0) || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3)) || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) { $this->_error(self::INVALID_DASH); $status = false; break 2; } $checked = false; foreach($regexChars as $regexKey => $regexChar) { $status = @preg_match($regexChar, $domainPart); if ($status > 0) { $length = 63; if (array_key_exists(strtoupper($this->_tld), $this->_idnLength) && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) { $length = $this->_idnLength[strtoupper($this->_tld)]; } if (iconv_strlen($domainPart, 'UTF-8') > $length) { $this->_error(self::INVALID_HOSTNAME); } else { $checked = true; break; } } } if ($checked) { ++$check; } } if ($check !== count($domainParts)) { $this->_error(self::INVALID_HOSTNAME_SCHEMA); $status = false; } } else { $this->_error(self::UNDECIPHERABLE_TLD); $status = false; } } while (false); iconv_set_encoding('internal_encoding', $origenc); if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) { return true; } } else if ($this->_options['allow'] & self::ALLOW_DNS) { $this->_error(self::INVALID_HOSTNAME); } if ($this->_options['allow'] & self::ALLOW_URI) { if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { return true; } else { $this->_error(self::INVALID_URI); } } $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; $status = @preg_match($regexLocal, $value); $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL; if ($status && $allowLocal) { return true; } if (!$status) { $this->_error(self::INVALID_LOCAL_NAME); } if ($status && !$allowLocal) { $this->_error(self::LOCAL_NAME_NOT_ALLOWED); } return false; } protected function decodePunycode($encoded) { $found = preg_match('/([^a-z0-9\x2d]{1,10})$/i', $encoded); if (empty($encoded) || ($found > 0)) { $this->_error(self::CANNOT_DECODE_PUNYCODE); return false; } $separator = strrpos($encoded, '-'); if ($separator > 0) { for ($x = 0; $x < $separator; ++$x) { $decoded[] = ord($encoded[$x]); } } else { $this->_error(self::CANNOT_DECODE_PUNYCODE); return false; } $lengthd = count($decoded); $lengthe = strlen($encoded); $init = true; $base = 72; $index = 0; $char = 0x80; for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) { for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) { $hex = ord($encoded[$indexe++]); $digit = ($hex - 48 < 10) ? $hex - 22 : (($hex - 65 < 26) ? $hex - 65 : (($hex - 97 < 26) ? $hex - 97 : 36)); $index += $digit * $pos; $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base)); if ($digit < $tag) { break; } $pos = (int) ($pos * (36 - $tag)); } $delta = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2)); $delta += intval($delta / ($lengthd + 1)); for ($key = 0; $delta > 910 / 2; $key += 36) { $delta = intval($delta / 35); } $base = intval($key + 36 * $delta / ($delta + 38)); $init = false; $char += (int) ($index / ($lengthd + 1)); $index %= ($lengthd + 1); if ($lengthd > 0) { for ($i = $lengthd; $i > $index; $i--) { $decoded[$i] = $decoded[($i - 1)]; } } $decoded[$index++] = $char; } foreach ($decoded as $key => $value) { if ($value < 128) { $decoded[$key] = chr($value); } elseif ($value < (1 << 11)) { $decoded[$key] = chr(192 + ($value >> 6)); $decoded[$key] .= chr(128 + ($value & 63)); } elseif ($value < (1 << 16)) { $decoded[$key] = chr(224 + ($value >> 12)); $decoded[$key] .= chr(128 + (($value >> 6) & 63)); $decoded[$key] .= chr(128 + ($value & 63)); } elseif ($value < (1 << 21)) { $decoded[$key] = chr(240 + ($value >> 18)); $decoded[$key] .= chr(128 + (($value >> 12) & 63)); $decoded[$key] .= chr(128 + (($value >> 6) & 63)); $decoded[$key] .= chr(128 + ($value & 63)); } else { $this->_error(self::CANNOT_DECODE_PUNYCODE); return false; } } return implode($decoded); } } <?php
namespace Zend\Validator; class Ip extends AbstractValidator { const INVALID = 'ipInvalid'; const NOT_IP_ADDRESS = 'notIpAddress'; protected $_messageTemplates = array( self::INVALID => "Invalid type given. String expected", self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address", ); protected $_options = array( 'allowipv6' => true, 'allowipv4' => true ); public function __construct($options = array()) { if ($options instanceof \Zend\Config\Config) { $options = $options->toArray(); } else if (!is_array($options)) { $options = func_get_args(); $temp['allowipv6'] = array_shift($options); if (!empty($options)) { $temp['allowipv4'] = array_shift($options); } $options = $temp; } $options += $this->_options; $this->setOptions($options); } public function getOptions() { return $this->_options; } public function setOptions($options) { if (array_key_exists('allowipv6', $options)) { $this->_options['allowipv6'] = (boolean) $options['allowipv6']; } if (array_key_exists('allowipv4', $options)) { $this->_options['allowipv4'] = (boolean) $options['allowipv4']; } if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) { throw new Exception\InvalidArgumentException('Nothing to validate. Check your options'); } return $this; } public function isValid($value) { if (!is_string($value)) { $this->_error(self::INVALID); return false; } $this->_setValue($value); if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) || (!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) || ($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) { $this->_error(self::NOT_IP_ADDRESS); return false; } return true; } protected function _validateIPv4($value) { $ip2long = ip2long($value); if($ip2long === false) { return false; } return $value == long2ip($ip2long); } protected function _validateIPv6($value) { if (strlen($value) < 3) { return $value == '::'; } if (strpos($value, '.')) { $lastcolon = strrpos($value, ':'); if (!($lastcolon && $this->_validateIPv4(substr($value, $lastcolon + 1)))) { return false; } $value = substr($value, 0, $lastcolon) . ':0:0'; } if (strpos($value, '::') === false) { return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); } $colonCount = substr_count($value, ':'); if ($colonCount < 8) { return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); } if ($colonCount == 8) { return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); } return false; } } <?php
namespace Zend\Validator\Hostname; return array( 1 => '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu', 2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu', 3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu', 4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu', 5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}' . '\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}' . '\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}' . '\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}' . '\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}' . '\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}' . '\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}' . '\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}' . '\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}' . '\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}' . '\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}' . '\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}' . '\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}' . '\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}' . '\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}' . '\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}' . '\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}' . '\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}' . '\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}' . '\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}' . '\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}' . '\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}' . '\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}' . '\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}' . '\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}' . '\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}' . '\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}' . '\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}' . '\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}' . '\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}' . '\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}' . '\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}' . '\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}' . '\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}' . '\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}' . '\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}' . '\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}' . '\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}' . '\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}' . '\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}' . '\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}' . '\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}' . '\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}' . '\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}' . '\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}' . '\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}' . '\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}' . '\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}' . '\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}' . '\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}' . '\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}' . '\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}' . '\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}' . '\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}' . '\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}' . '\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}' . '\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}' . '\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}' . '\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}' . '\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}' . '\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}' . '\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}' . '\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}' . '\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}' . '\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}' . '\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}' . '\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}' . '\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}' . '\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}' . '\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}' . '\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}' . '\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}' . '\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}' . '\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}' . '\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}' . '\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}' . '\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}' . '\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}' . '\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}' . '\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}' . '\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}' . '\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}' . '\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}' . '\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}' . '\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}' . '\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}' . '\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu', 6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu', 7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu', 8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu', 9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu', 10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu', 11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu', 12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu', 13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu', 14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu', 15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu', 16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu', 17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu', 18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu', 19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu', 20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu', 21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu', 22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu', 23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu', 24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu', 25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu', 26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu', 27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu', 28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu', 29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu', 30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu', 31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu', 32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu', 33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu', 34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu', 35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu', 36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu', 37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu', 38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu', 39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu', 40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu', 41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu', 42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu', 43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu', 44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu', 45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu', 46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu', 47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu', 48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu', 49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu', 50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu', 51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu', 52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu', 53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu', 54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu', 55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu', 56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu', 57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu', 58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu', 59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu', 60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu', 61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu', 62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu', 63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu', 64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu', 65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu', 66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu', 67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu', 68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu', 69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu', 70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu', 71 => '/^[\x{D800}-\x{DB7F}]{1,63}$/iu', 72 => '/^[\x{DC00}-\x{DFFF}]{1,63}$/iu', 73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu', 74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu', 75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu', 76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu', 77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu', 78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu', 79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu', 80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu', ); <?php
namespace Zend\Validator\Hostname; return array( 1 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}' . '\x{30A1}-\x{30F6}\x{30FC}' . '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' . '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' . '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' . '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' . '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' . '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' . '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' . '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' . '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' . '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' . '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' . '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' . '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' . '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' . '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' . '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' . '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' . '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' . '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' . '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' . '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' . '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' . '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' . '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' . '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' . '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' . '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' . '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' . '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' . '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' . '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' . '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' . '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' . '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' . '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' . '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' . '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' . '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' . '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' . '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' . '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' . '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' . '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' . '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' . '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' . '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' . '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' . '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' . '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' . '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' . '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' . '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' . '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' . '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' . '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' . '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' . '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' . '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' . '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' . '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' . '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' . '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' . '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' . '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' . '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' . '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' . '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' . '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' . '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' . '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' . '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' . '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' . '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' . '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' . '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' . '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' . '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' . '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' . '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' . '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' . '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' . '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' . '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' . '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' . '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' . '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' . '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' . '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' . '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' . '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' . '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' . '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' . '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' . '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' . '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' . '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' . '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' . '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' . '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' . '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' . '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' . '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' . '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' . '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' . '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' . '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' . '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' . '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' . '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' . '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' . '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' . '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' . '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' . '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' . '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' . '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' . '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' . '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' . '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' . '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' . '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' . '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' . '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' . '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' . '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' . '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' . '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' . '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' . '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' . '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' . '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' . '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' . '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' . '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' . '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' . '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' . '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' . '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' . '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' . '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' . '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' . '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' . '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' . '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' . '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' . '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' . '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' . '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' . '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' . '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' . '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' . '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' . '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' . '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' . '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' . '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' . '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' . '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' . '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' . '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' . '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' . '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' . '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' . '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' . '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' . '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' . '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' . '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' . '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' . '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' . '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' . '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' . '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' . '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' . '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' . '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' . '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' . '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' . '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' . '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' . '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' . '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' . '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' . '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' . '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' . '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' . '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' . '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' . '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' . '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' . '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' . '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' . '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' . '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' . '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' . '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' . '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' . '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' . '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' . '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' . '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' . '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' . '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' . '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' . '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' . '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' . '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' . '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' . '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' . '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' . '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' . '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' . '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' . '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' . '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' . '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' . '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' . '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' . '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' . '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' . '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' . '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' . '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' . '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' . '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' . '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' . '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' . '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' . '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' . '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' . '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' . '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' . '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' . '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' . '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' . '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' . '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' . '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' . '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' . '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' . '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' . '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' . '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' . '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' . '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' . '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' . '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' . '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' . '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' . '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' . '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' . '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' . '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' . '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' . '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' . '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' . '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' . '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' . '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' . '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' . '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' . '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' . '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' . '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' . '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' . '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' . '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' . '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' . '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' . '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' . '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' . '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' . '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' . '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' . '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' . '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' . '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' . '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' . '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' . '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' . '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' . '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' . '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' . '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' . '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' . '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' . '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' . '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' . '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' . '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' . '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' . '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' . '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' . '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' . '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' . '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' . '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' . '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' . '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' . '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' . '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' . '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' . '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' . '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' . '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' . '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' . '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' . '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' . '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' . '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' . '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' . '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' . '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' . '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' . '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' . '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' . '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' . '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' . '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' . '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' . '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' . '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' . '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' . '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' . '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' . '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' . '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' . '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' . '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' . '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' . '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' . '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' . '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' . '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' . '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' . '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' . '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' . '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' . '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' . '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' . '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' . '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' . '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' . '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' . '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' . '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' . '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' . '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' . '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' . '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' . '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' . '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' . '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' . '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' . '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' . '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' . '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' . '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' . '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' . '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' . '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' . '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' . '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' . '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' . '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' . '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' . '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' . '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' . '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' . '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' . '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' . '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' . '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' . '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' . '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' . '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' . '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' . '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' . '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' . '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' . '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' . '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' . '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' . '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' . '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' . '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' . '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' . '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' . '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' . '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' . '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' . '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' . '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' . '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' . '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' . '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' . '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' . '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' . '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' . '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' . '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' . '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' . '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' . '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' . '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' . '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' . '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' . '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' . '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' . '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' . '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' . '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' . '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' . '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' . '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' . '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' . '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' . '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' . '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' . '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' . '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' . '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' . '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' . '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' . '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' . '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' . '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' . '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' . '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' . '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' . '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' . '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' . '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' . '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' . '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' . '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' . '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' . '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' . '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' . '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' . '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' . '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' . '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' . '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' . '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' . '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' . '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' . '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' . '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' . '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' . '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' . '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' . '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' . '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' . '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' . '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' . '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' . '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' . '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' . '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' . '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' . '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' . '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' . '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' . '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' . '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' . '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' . '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' . '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' . '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' . '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' . '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' . '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' . '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' . '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' . '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' . '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' . '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' . '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' . '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' . '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' . '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' . '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' . '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' . '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' . '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' . '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' . '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' . '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' . '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' . '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' . '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' . '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' . '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' . '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' . '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' . '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' . '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' . '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' . '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' . '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' . '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' . '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' . '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' . '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' . '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' . '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' . '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' . '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' . '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' . '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' . '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' . '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' . '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' . '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' . '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' . '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' . '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' . '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' . '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' . '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' . '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' . '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' . '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' . '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' . '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' . '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' . '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' . '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' . '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' . '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' . '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' . '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' . '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' . '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' . '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' . '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' . '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' . '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' . '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' . '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' . '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' . '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' . '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' . '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' . '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' . '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' . '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' . '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' . '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' . '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' . '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' . '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' . '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' . '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' . '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' . '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' . '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' . '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' . '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' . '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' . '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' . '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' . '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' . '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' . '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' . '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' . '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' . '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' . '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' . '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' . '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' . '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' . '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' . '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' . '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' . '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' . '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' . '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' . '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' . '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' . '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' . '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' . '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' . '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' . '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' . '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' . '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' . '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' . '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' . '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' . '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' . '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' . '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' . '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' . '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' . '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' . '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' . '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' . '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' . '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' . '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' . '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' . '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' . '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' . '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' . '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' . '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' . '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' . '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' . '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' . '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' . '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' . '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' . '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' . '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' . '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' . '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' . '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' . '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' . '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' . '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' . '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' . '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' . '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' . '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' . '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' . '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' . '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' . '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' . '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' . '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' . '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' . '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' . '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' . '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' . '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' . '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' . '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' . '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' . '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' . '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' . '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' . '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' . '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' . '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' . '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' . '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' . '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' . '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' . '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' . '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' . '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' . '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' . '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' . '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' . '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' . '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' . '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' . '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' . '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' . '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' . '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' . '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' . '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' . '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' . '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' . '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' . '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' . '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' . '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' . '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' . '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' . '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' . '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' . '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' . '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' . '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' . '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' . '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' . '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' . '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' . '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' . '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' . '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' . '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' . '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' . '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' . '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' . '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' . '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' . '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' . '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' . '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' . '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' . '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' . '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' . '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' . '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' . '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' . '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu', ); <?php
namespace Goutte; use Symfony\Component\BrowserKit\Client as BaseClient; use Symfony\Component\BrowserKit\History; use Symfony\Component\BrowserKit\CookieJar; use Symfony\Component\BrowserKit\Request; use Symfony\Component\BrowserKit\Response; use Zend\Http\Client as ZendClient; use Zend\Http\Response as ZendResponse; class Client extends BaseClient { const VERSION = '0.1'; protected $zendConfig; protected $headers = array(); protected $auth = null; public function __construct(array $zendConfig = array(), array $server = array(), History $history = null, CookieJar $cookieJar = null) { $this->zendConfig = $zendConfig; parent::__construct($server, $history, $cookieJar); } public function setHeader($name, $value) { $this->headers[$name] = $value; } public function setAuth($user, $password = '', $type = ZendClient::AUTH_BASIC) { $this->auth = array( 'user' => $user, 'password' => $password, 'type' => $type ); } protected function doRequest($request) { $client = $this->createClient($request); $response = $client->request(); return $this->createResponse($response); } protected function createClient(Request $request) { $client = $this->createZendClient(); $client->setUri($request->getUri()); $client->setConfig(array_merge(array( 'maxredirects' => 0, 'timeout' => 30, 'useragent' => $this->server['HTTP_USER_AGENT'], 'adapter' => 'Zend\\Http\\Client\\Adapter\\Socket', ), $this->zendConfig)); $client->setMethod(strtoupper($request->getMethod())); if ('POST' == $request->getMethod()) { $client->setParameterPost($request->getParameters()); } foreach ($this->headers as $name => $value) { $client->setHeaders($name, $value); } if ($this->auth !== null) { $client->setAuth( $this->auth['user'], $this->auth['password'], $this->auth['type'] ); } foreach ($this->getCookieJar()->allValues($request->getUri()) as $name => $value) { $client->setCookie($name, $value); } foreach ($request->getFiles() as $name => $info) { if (isset($info['tmp_name']) && '' !== $info['tmp_name']) { $filename = $info['name']; if (false === ($data = @file_get_contents($info['tmp_name']))) { throw new \RuntimeException("Unable to read file '{$filename}' for upload"); } $client->setFileUpload($filename, $name, $data); } } return $client; } protected function createResponse(ZendResponse $response) { return new Response($response->getBody(), $response->getStatus(), $response->getHeaders()); } protected function createZendClient() { return new ZendClient(); } } <?php
namespace Goutte; use Symfony\Component\Finder\Finder; class Compiler { public function compile($pharFile = 'goutte.phar') { if (file_exists($pharFile)) { unlink($pharFile); } $phar = new \Phar($pharFile, 0, 'Goutte'); $phar->setSignatureAlgorithm(\Phar::SHA1); $phar->startBuffering(); foreach ($this->getFiles() as $file) { $path = str_replace(__DIR__.'/', '', $file); $content = preg_replace("##", '', php_strip_whitespace($file)); $phar->addFromString($path, $content); } $phar['_cli_stub.php'] = $this->getCliStub(); $phar['_web_stub.php'] = $this->getWebStub(); $phar->setDefaultStub('_cli_stub.php', '_web_stub.php'); $phar->stopBuffering(); unset($phar); } protected function getCliStub() { return "<?php ".$this->getLicense()." require_once __DIR__.'/autoload.php'; __HALT_COMPILER();"; } protected function getWebStub() { return "<?php throw new \LogicException('This PHAR file can only be used from the CLI.'); __HALT_COMPILER();"; } protected function getLicense() { return '
/*
* This file is part of the Goutte utility.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/'; } protected function getFiles() { $files = array( 'LICENSE', 'autoload.php', 'vendor/Symfony/Component/ClassLoader/UniversalClassLoader.php', 'vendor/zend/library/Zend/Tool/Framework/Exception.php', 'vendor/zend/library/Zend/Registry.php', 'vendor/zend/library/Zend/Uri/Uri.php', 'vendor/zend/library/Zend/Validator/Validator.php', 'vendor/zend/library/Zend/Validator/AbstractValidator.php', 'vendor/zend/library/Zend/Validator/Hostname.php', 'vendor/zend/library/Zend/Validator/Ip.php', 'vendor/zend/library/Zend/Validator/Hostname/Com.php', 'vendor/zend/library/Zend/Validator/Hostname/Jp.php', ); $dirs = array( 'src/Goutte', 'vendor/Symfony/Component/BrowserKit', 'vendor/Symfony/Component/DomCrawler', 'vendor/Symfony/Component/CssSelector', 'vendor/Symfony/Component/Process', 'vendor/zend/library/Zend/Uri', 'vendor/zend/library/Zend/Http', ); $finder = new Finder(); $iterator = $finder->files()->name('*.php')->in($dirs); return array_merge($files, iterator_to_array($iterator)); } } <?php
namespace Symfony\Component\BrowserKit; use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\DomCrawler\Link; use Symfony\Component\DomCrawler\Form; use Symfony\Component\Process\PhpProcess; use Symfony\Component\BrowserKit\Request; use Symfony\Component\BrowserKit\Response; use Symfony\Component\BrowserKit\Client; abstract class Client { protected $history; protected $cookieJar; protected $server; protected $request; protected $response; protected $crawler; protected $insulated; protected $redirect; protected $followRedirects; public function __construct(array $server = array(), History $history = null, CookieJar $cookieJar = null) { $this->setServerParameters($server); $this->history = null === $history ? new History() : $history; $this->cookieJar = null === $cookieJar ? new CookieJar() : $cookieJar; $this->insulated = false; $this->followRedirects = true; } public function followRedirects($followRedirect = true) { $this->followRedirects = (Boolean) $followRedirect; } public function insulate($insulated = true) { if (!class_exists('Symfony\\Component\\Process\\Process')) { throw new \RuntimeException('Unable to isolate requests as the Symfony Process Component is not installed.'); } $this->insulated = (Boolean) $insulated; } public function setServerParameters(array $server) { $this->server = array_merge(array( 'HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Symfony2 BrowserKit', ), $server); } public function setServerParameter($key, $value) { $this->server[$key] = $value; } public function getServerParameter($key, $default = '') { return (isset($this->server[$key])) ? $this->server[$key] : $default; } public function getHistory() { return $this->history; } public function getCookieJar() { return $this->cookieJar; } public function getCrawler() { return $this->crawler; } public function getResponse() { return $this->response; } public function getRequest() { return $this->request; } public function click(Link $link) { if ($link instanceof Form) { return $this->submit($link); } return $this->request($link->getMethod(), $link->getUri()); } public function submit(Form $form, array $values = array()) { $form->setValues($values); return $this->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), $form->getPhpFiles()); } public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true) { $uri = $this->getAbsoluteUri($uri); $server = array_merge($this->server, $server); if (!$this->history->isEmpty()) { $server['HTTP_REFERER'] = $this->history->current()->getUri(); } $server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST); $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME); $request = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content); $this->request = $this->filterRequest($request); if (true === $changeHistory) { $this->history->add($request); } if ($this->insulated) { $this->response = $this->doRequestInProcess($this->request); } else { $this->response = $this->doRequest($this->request); } $response = $this->filterResponse($this->response); $this->cookieJar->updateFromResponse($response, $uri); $this->redirect = $response->getHeader('Location'); if ($this->followRedirects && $this->redirect) { return $this->crawler = $this->followRedirect(); } return $this->crawler = $this->createCrawlerFromContent($request->getUri(), $response->getContent(), $response->getHeader('Content-Type')); } protected function doRequestInProcess($request) { $process = new PhpProcess($this->getScript($request), null, array('TMPDIR' => sys_get_temp_dir(), 'TEMP' => sys_get_temp_dir())); $process->run(); if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) { throw new \RuntimeException($process->getErrorOutput()); } return unserialize($process->getOutput()); } abstract protected function doRequest($request); protected function getScript($request) { throw new \LogicException('To insulate requests, you need to override the getScript() method.'); } protected function filterRequest(Request $request) { return $request; } protected function filterResponse($response) { return $response; } protected function createCrawlerFromContent($uri, $content, $type) { $crawler = new Crawler(null, $uri); $crawler->addContent($content, $type); return $crawler; } public function back() { return $this->requestFromRequest($this->history->back(), false); } public function forward() { return $this->requestFromRequest($this->history->forward(), false); } public function reload() { return $this->requestFromRequest($this->history->current(), false); } public function followRedirect() { if (empty($this->redirect)) { throw new \LogicException('The request was not redirected.'); } return $this->request('get', $this->redirect); } public function restart() { $this->cookieJar->clear(); $this->history->clear(); } protected function getAbsoluteUri($uri) { if ('http' === substr($uri, 0, 4)) { return $uri; } if (!$this->history->isEmpty()) { $currentUri = $this->history->current()->getUri(); } else { $currentUri = sprintf('http%s://%s/', isset($this->server['HTTPS']) ? 's' : '', isset($this->server['HTTP_HOST']) ? $this->server['HTTP_HOST'] : 'localhost' ); } if (!$uri || '#' == $uri[0]) { return preg_replace('/#.*?$/', '', $currentUri).$uri; } if ('/' !== $uri[0]) { $path = parse_url($currentUri, PHP_URL_PATH); if ('/' !== substr($path, -1)) { $path = substr($path, 0, strrpos($path, '/') + 1); } $uri = $path.$uri; } return preg_replace('#^(.*?//[^/]+)\/.*$#', '$1', $currentUri).$uri; } protected function requestFromRequest(Request $request, $changeHistory = true) { return $this->request($request->getMethod(), $request->getUri(), $request->getParameters(), array(), $request->getFiles(), $request->getServer(), $request->getContent(), $changeHistory); } } <?php
namespace Symfony\Component\BrowserKit; class Cookie { private static $dateFormats = array( 'D, d M Y H:i:s T', 'D, d-M-y H:i:s T', 'D, d-M-Y H:i:s T', 'D M j G:i:s Y', ); protected $name; protected $value; protected $expires; protected $path; protected $domain; protected $secure; protected $httponly; protected $rawValue; public function __construct($name, $value, $expires = null, $path = null, $domain = '', $secure = false, $httponly = true, $encodedValue = false) { if ($encodedValue) { $this->value = urldecode($value); $this->rawValue = $value; } else { $this->value = $value; $this->rawValue = urlencode($value); } $this->name = $name; $this->expires = null === $expires ? null : (integer) $expires; $this->path = empty($path) ? null : $path; $this->domain = $domain; $this->secure = (Boolean) $secure; $this->httponly = (Boolean) $httponly; } public function __toString() { $cookie = sprintf('%s=%s', $this->name, $this->rawValue); if (null !== $this->expires) { $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'))->format(self::$dateFormats[0]), 0, -5); } if ('' !== $this->domain) { $cookie .= '; domain='.$this->domain; } if (null !== $this->path) { $cookie .= '; path='.$this->path; } if ($this->secure) { $cookie .= '; secure'; } if ($this->httponly) { $cookie .= '; httponly'; } return $cookie; } static public function fromString($cookie, $url = null) { $parts = explode(';', $cookie); if (false === strpos($parts[0], '=')) { throw new \InvalidArgumentException('The cookie string "%s" is not valid.'); } list($name, $value) = explode('=', array_shift($parts), 2); $values = array( 'name' => trim($name), 'value' => trim($value), 'expires' => null, 'path' => null, 'domain' => '', 'secure' => false, 'httponly' => false, 'passedRawValue' => true, ); if (null !== $url) { if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host']) || !isset($urlParts['path'])) { throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url)); } $parts = array_merge($urlParts, $parts); $values['domain'] = $parts['host']; $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/')); } foreach ($parts as $part) { $part = trim($part); if ('secure' === strtolower($part)) { if (!$url || !isset($urlParts['scheme']) || 'https' != $urlParts['scheme']) { continue; } $values['secure'] = true; continue; } if ('httponly' === strtolower($part)) { $values['httponly'] = true; continue; } if (2 === count($elements = explode('=', $part, 2))) { if ('expires' === $elements[0]) { $elements[1] = self::parseDate($elements[1]); } $values[strtolower($elements[0])] = $elements[1]; } } return new static( $values['name'], $values['value'], $values['expires'], $values['path'], $values['domain'], $values['secure'], $values['httponly'], $values['passedRawValue'] ); } private static function parseDate($dateValue) { if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length-1]) { $dateValue = substr($dateValue, 1, -1); } foreach (self::$dateFormats as $dateFormat) { if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) { return $date->getTimestamp(); } } throw new \InvalidArgumentException(sprintf('Could not parse date "%s".', $dateValue)); } public function getName() { return $this->name; } public function getValue() { return $this->value; } public function getRawValue() { return $this->rawValue; } public function getExpiresTime() { return $this->expires; } public function getPath() { return null !== $this->path ? $this->path : '/'; } public function getDomain() { return $this->domain; } public function isSecure() { return $this->secure; } public function isHttpOnly() { return $this->httponly; } public function isExpired() { return null !== $this->expires && 0 !== $this->expires && $this->expires < time(); } } <?php
namespace Symfony\Component\BrowserKit; class CookieJar { protected $cookieJar = array(); public function set(Cookie $cookie) { $this->cookieJar[$cookie->getName()] = $cookie; } public function get($name) { $this->flushExpiredCookies(); return isset($this->cookieJar[$name]) ? $this->cookieJar[$name] : null; } public function expire($name) { unset($this->cookieJar[$name]); } public function clear() { $this->cookieJar = array(); } public function updateFromResponse(Response $response, $uri = null) { foreach ($response->getHeader('Set-Cookie', false) as $cookie) { $this->set(Cookie::fromString($cookie, $uri)); } } public function all() { $this->flushExpiredCookies(); return $this->cookieJar; } public function allValues($uri, $returnsRawValue = false) { $this->flushExpiredCookies(); $parts = array_replace(array('path' => '/'), parse_url($uri)); $cookies = array(); foreach ($this->cookieJar as $cookie) { if ($cookie->getDomain()) { $domain = ltrim($cookie->getDomain(), '.'); if ($domain != substr($parts['host'], -strlen($domain))) { continue; } } if ($cookie->getPath() != substr($parts['path'], 0, strlen($cookie->getPath()))) { continue; } if ($cookie->isSecure() && 'https' != $parts['scheme']) { continue; } $cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue(); } return $cookies; } public function allRawValues($uri) { return $this->allValues($uri, true); } public function flushExpiredCookies() { $cookies = $this->cookieJar; foreach ($cookies as $name => $cookie) { if ($cookie->isExpired()) { unset($this->cookieJar[$name]); } } } } <?php
namespace Symfony\Component\BrowserKit; class History { protected $stack = array(); protected $position = -1; public function __construct() { $this->clear(); } public function clear() { $this->stack = array(); $this->position = -1; } public function add(Request $request) { $this->stack = array_slice($this->stack, 0, $this->position + 1); $this->stack[] = clone $request; $this->position = count($this->stack) - 1; } public function isEmpty() { return count($this->stack) == 0; } public function back() { if ($this->position < 1) { throw new \LogicException('You are already on the first page.'); } return clone $this->stack[--$this->position]; } public function forward() { if ($this->position > count($this->stack) - 2) { throw new \LogicException('You are already on the last page.'); } return clone $this->stack[++$this->position]; } public function current() { if (-1 == $this->position) { throw new \LogicException('The page history is empty.'); } return clone $this->stack[$this->position]; } } <?php
namespace Symfony\Component\BrowserKit; class Request { protected $uri; protected $method; protected $parameters; protected $files; protected $cookies; protected $server; protected $content; public function __construct($uri, $method, array $parameters = array(), array $files = array(), array $cookies = array(), array $server = array(), $content = null) { $this->uri = $uri; $this->method = $method; $this->parameters = $parameters; $this->files = $files; $this->cookies = $cookies; $this->server = $server; $this->content = $content; } public function getUri() { return $this->uri; } public function getMethod() { return $this->method; } public function getParameters() { return $this->parameters; } public function getFiles() { return $this->files; } public function getCookies() { return $this->cookies; } public function getServer() { return $this->server; } public function getContent() { return $this->content; } } <?php
namespace Symfony\Component\BrowserKit; class Response { protected $content; protected $status; protected $headers; public function __construct($content = '', $status = 200, array $headers = array()) { $this->content = $content; $this->status = $status; $this->headers = $headers; } public function __toString() { $headers = ''; foreach ($this->headers as $name => $value) { if (is_string($value)) { $headers .= $this->buildHeader($name, $value); } else { foreach ($value as $headerValue) { $headers .= $this->buildHeader($name, $headerValue); } } } return $headers."\n".$this->content; } protected function buildHeader($name, $value) { return sprintf("%s: %s\n", $name, $value); } public function getContent() { return $this->content; } public function getStatus() { return $this->status; } public function getHeaders() { return $this->headers; } public function getHeader($header, $first = true) { foreach ($this->headers as $key => $value) { if (str_replace('-', '_', strtolower($key)) == str_replace('-', '_', strtolower($header))) { if ($first) { return is_array($value) ? (count($value) ? $value[0] : '') : $value; } return is_array($value) ? $value : array($value); } } return $first ? null : array(); } } <?php
namespace Symfony\Component\DomCrawler; use Symfony\Component\CssSelector\CssSelector; class Crawler extends \SplObjectStorage { private $uri; public function __construct($node = null, $uri = null) { $this->uri = $uri; $this->add($node); } public function clear() { $this->removeAll($this); } public function add($node) { if ($node instanceof \DOMNodeList) { $this->addNodeList($node); } elseif (is_array($node)) { $this->addNodes($node); } elseif (is_string($node)) { $this->addContent($node); } elseif (is_object($node)) { $this->addNode($node); } } public function addContent($content, $type = null) { if (empty($type)) { $type = 'text/html'; } if (!preg_match('/(x|ht)ml/i', $type, $matches)) { return null; } $charset = 'ISO-8859-1'; if (false !== $pos = strpos($type, 'charset=')) { $charset = substr($type, $pos + 8); } if ('x' === $matches[1]) { $this->addXmlContent($content, $charset); } else { $this->addHtmlContent($content, $charset); } } public function addHtmlContent($content, $charset = 'UTF-8') { $dom = new \DOMDocument('1.0', $charset); $dom->validateOnParse = true; @$dom->loadHTML($content); $this->addDocument($dom); $base = $this->filter('base')->extract(array('href')); if (count($base)) { $this->uri = current($base); } } public function addXmlContent($content, $charset = 'UTF-8') { $dom = new \DOMDocument('1.0', $charset); $dom->validateOnParse = true; @$dom->loadXML(str_replace('xmlns', 'ns', $content)); $this->addDocument($dom); } public function addDocument(\DOMDocument $dom) { if ($dom->documentElement) { $this->addNode($dom->documentElement); } } public function addNodeList(\DOMNodeList $nodes) { foreach ($nodes as $node) { $this->addNode($node); } } public function addNodes(array $nodes) { foreach ($nodes as $node) { $this->add($node); } } public function addNode(\DOMNode $node) { if ($node instanceof \DOMDocument) { $this->attach($node->documentElement); } else { $this->attach($node); } } public function eq($position) { foreach ($this as $i => $node) { if ($i == $position) { return new static($node, $this->uri); } } return new static(null, $this->uri); } public function each(\Closure $closure) { $data = array(); foreach ($this as $i => $node) { $data[] = $closure($node, $i); } return $data; } public function reduce(\Closure $closure) { $nodes = array(); foreach ($this as $i => $node) { if (false !== $closure($node, $i)) { $nodes[] = $node; } } return new static($nodes, $this->uri); } public function first() { return $this->eq(0); } public function last() { return $this->eq(count($this) - 1); } public function siblings() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0)->parentNode->firstChild), $this->uri); } public function nextAll() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0)), $this->uri); } public function previousAll() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0), 'previousSibling'), $this->uri); } public function parents() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } $node = $this->getNode(0); $nodes = array(); while ($node = $node->parentNode) { if (1 === $node->nodeType && '_root' !== $node->nodeName) { $nodes[] = $node; } } return new static($nodes, $this->uri); } public function children() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return new static($this->sibling($this->getNode(0)->firstChild), $this->uri); } public function attr($attribute) { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return $this->getNode(0)->getAttribute($attribute); } public function text() { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } return $this->getNode(0)->nodeValue; } public function extract($attributes) { $attributes = (array) $attributes; $data = array(); foreach ($this as $node) { $elements = array(); foreach ($attributes as $attribute) { if ('_text' === $attribute) { $elements[] = $node->nodeValue; } else { $elements[] = $node->getAttribute($attribute); } } $data[] = count($attributes) > 1 ? $elements : $elements[0]; } return $data; } public function filterXPath($xpath) { $document = new \DOMDocument('1.0', 'UTF-8'); $root = $document->appendChild($document->createElement('_root')); foreach ($this as $node) { $root->appendChild($document->importNode($node, true)); } $domxpath = new \DOMXPath($document); return new static($domxpath->query($xpath), $this->uri); } public function filter($selector) { if (!class_exists('Symfony\\Component\\CssSelector\\CssSelector')) { throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector is not installed (you can use filterXPath instead).'); } return $this->filterXPath(CssSelector::toXPath($selector)); } public function selectLink($value) { $xpath = sprintf('//a[contains(concat(\' \', normalize-space(string(.)), \' \'), %s)] ', static::xpathLiteral(' '.$value.' ')). sprintf('| //a/img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)]/ancestor::a', static::xpathLiteral(' '.$value.' ')); return $this->filterXPath($xpath); } public function selectButton($value) { $xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')). sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value). sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value); return $this->filterXPath($xpath); } public function link($method = 'get') { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } $node = $this->getNode(0); return new Link($node, $this->uri, $method); } public function links() { $links = array(); foreach ($this as $node) { $links[] = new Link($node, $this->uri, 'get'); } return $links; } public function form(array $values = null, $method = null) { if (!count($this)) { throw new \InvalidArgumentException('The current node list is empty.'); } $form = new Form($this->getNode(0), $this->uri, $method); if (null !== $values) { $form->setValues($values); } return $form; } static public function xpathLiteral($s) { if (false === strpos($s, "'")) { return sprintf("'%s'", $s); } if (false === strpos($s, '"')) { return sprintf('"%s"', $s); } $string = $s; $parts = array(); while (true) { if (false !== $pos = strpos($string, "'")) { $parts[] = sprintf("'%s'", substr($string, 0, $pos)); $parts[] = "\"'\""; $string = substr($string, $pos + 1); } else { $parts[] = "'$string'"; break; } } return sprintf("concat(%s)", implode($parts, ', ')); } private function getNode($position) { foreach ($this as $i => $node) { if ($i == $position) { return $node; } } return null; } private function sibling($node, $siblingDir = 'nextSibling') { $nodes = array(); do { if ($node !== $this->getNode(0) && $node->nodeType === 1) { $nodes[] = $node; } } while ($node = $node->$siblingDir); return $nodes; } } <?php
namespace Symfony\Component\DomCrawler\Field; class ChoiceFormField extends FormField { private $type; private $multiple; private $options; public function hasValue() { if (in_array($this->type, array('checkbox', 'radio')) && null === $this->value) { return false; } return true; } public function select($value) { $this->setValue($value); } public function tick() { if ('checkbox' !== $this->type) { throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); } $this->setValue(true); } public function untick() { if ('checkbox' !== $this->type) { throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); } $this->setValue(false); } public function setValue($value) { if ('checkbox' == $this->type && false === $value) { $this->value = null; } elseif ('checkbox' == $this->type && true === $value) { $this->value = $this->options[0]; } else { if (is_array($value)) { if (!$this->multiple) { throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name)); } foreach ($value as $v) { if (!in_array($v, $this->options)) { throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->options))); } } } elseif (!in_array($value, $this->options)) { throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->options))); } if ($this->multiple) { $value = (array) $value; } if (is_array($value)) { $this->value = $value; } else { parent::setValue($value); } } } public function addChoice(\DOMNode $node) { if (!$this->multiple && 'radio' != $this->type) { throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); } $this->options[] = $value = $node->hasAttribute('value') ? $node->getAttribute('value') : '1'; if ($node->getAttribute('checked')) { $this->value = $value; } } public function getType() { return $this->type; } public function isMultiple() { return $this->multiple; } protected function initialize() { if ('input' != $this->node->nodeName && 'select' != $this->node->nodeName) { throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); } if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) { throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type'))); } $this->value = null; $this->options = array(); $this->multiple = false; if ('input' == $this->node->nodeName) { $this->type = $this->node->getAttribute('type'); $this->options[] = $value = $this->node->hasAttribute('value') ? $this->node->getAttribute('value') : '1'; if ($this->node->getAttribute('checked')) { $this->value = $value; } } else { $this->type = 'select'; if ($this->node->hasAttribute('multiple')) { $this->multiple = true; $this->value = array(); $this->name = str_replace('[]', '', $this->name); } $found = false; foreach ($this->xpath->query('descendant::option', $this->node) as $option) { $this->options[] = $option->getAttribute('value'); if ($option->getAttribute('selected')) { $found = true; if ($this->multiple) { $this->value[] = $option->getAttribute('value'); } else { $this->value = $option->getAttribute('value'); } } } $option = $this->xpath->query('descendant::option', $this->node)->item(0); if (!$found && !$this->multiple && $option instanceof \DOMElement) { $this->value = $option->getAttribute('value'); } } } } <?php
namespace Symfony\Component\DomCrawler\Field; class FileFormField extends FormField { public function setErrorCode($error) { $codes = array(UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_EXTENSION); if (!in_array($error, $codes)) { throw new \InvalidArgumentException(sprintf('The error code %s is not valid.', $error)); } $this->value = array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => $error, 'size' => 0); } public function upload($value) { $this->setValue($value); } public function setValue($value) { if (null !== $value && is_readable($value)) { $error = UPLOAD_ERR_OK; $size = filesize($value); $name = basename($value); $tmp = tempnam(sys_get_temp_dir(), 'upload'); unlink($tmp); copy($value, $tmp); $value = $tmp; } else { $error = UPLOAD_ERR_NO_FILE; $size = 0; $name = ''; $value = ''; } $this->value = array('name' => $name, 'type' => '', 'tmp_name' => $value, 'error' => $error, 'size' => $size); } protected function initialize() { if ('input' != $this->node->nodeName) { throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); } if ('file' != $this->node->getAttribute('type')) { throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type'))); } $this->setValue(null); } } <?php
namespace Symfony\Component\DomCrawler\Field; abstract class FormField { protected $node; protected $name; protected $value; protected $document; protected $xpath; public function __construct(\DOMNode $node) { $this->node = $node; $this->name = $node->getAttribute('name'); $this->document = new \DOMDocument('1.0', 'UTF-8'); $this->node = $this->document->importNode($this->node, true); $root = $this->document->appendChild($this->document->createElement('_root')); $root->appendChild($this->node); $this->xpath = new \DOMXPath($this->document); $this->initialize(); } public function getName() { return $this->name; } public function getValue() { return $this->value; } public function setValue($value) { $this->value = (string) $value; } public function hasValue() { return true; } abstract protected function initialize(); } <?php
namespace Symfony\Component\DomCrawler\Field; class InputFormField extends FormField { protected function initialize() { if ('input' != $this->node->nodeName) { throw new \LogicException(sprintf('An InputFormField can only be created from an input tag (%s given).', $this->node->nodeName)); } if ('checkbox' == $this->node->getAttribute('type')) { throw new \LogicException('Checkboxes should be instances of ChoiceFormField.'); } if ('file' == $this->node->getAttribute('type')) { throw new \LogicException('File inputs should be instances of FileFormField.'); } $this->value = $this->node->getAttribute('value'); } } <?php
namespace Symfony\Component\DomCrawler\Field; class TextareaFormField extends FormField { protected function initialize() { if ('textarea' != $this->node->nodeName) { throw new \LogicException(sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName)); } $this->value = null; foreach ($this->node->childNodes as $node) { $this->value .= $this->document->saveXML($node); } } } <?php
namespace Symfony\Component\DomCrawler; use Symfony\Component\DomCrawler\Field\FormField; class Form extends Link implements \ArrayAccess { private $document; private $button; private $fields; public function __construct(\DOMNode $node, $currentUri, $method = null) { parent::__construct($node, $currentUri, $method); $this->initialize(); } public function getFormNode() { return $this->node; } public function setValues(array $values) { foreach ($values as $name => $value) { $this[$name] = $value; } return $this; } public function getValues() { $values = array(); foreach ($this->fields as $name => $field) { if (!$field instanceof Field\FileFormField && $field->hasValue()) { $values[$name] = $field->getValue(); } } return $values; } public function getFiles() { if (!in_array($this->getMethod(), array('POST', 'PUT', 'DELETE'))) { return array(); } $files = array(); foreach ($this->fields as $name => $field) { if ($field instanceof Field\FileFormField) { $files[$name] = $field->getValue(); } } return $files; } public function getPhpValues() { $qs = http_build_query($this->getValues()); parse_str($qs, $values); return $values; } public function getPhpFiles() { $qs = http_build_query($this->getFiles()); parse_str($qs, $values); return $values; } public function getUri() { $uri = parent::getUri(); if (!in_array($this->getMethod(), array('POST', 'PUT', 'DELETE')) && $queryString = http_build_query($this->getValues(), null, '&')) { $sep = false === strpos($uri, '?') ? '?' : '&'; $uri .= $sep.$queryString; } return $uri; } protected function getRawUri() { return $this->node->getAttribute('action'); } public function getMethod() { if (null !== $this->method) { return $this->method; } return $this->node->getAttribute('method') ? strtoupper($this->node->getAttribute('method')) : 'GET'; } public function has($name) { return isset($this->fields[$name]); } public function remove($name) { unset($this->fields[$name]); } public function get($name) { if (!$this->has($name)) { throw new \InvalidArgumentException(sprintf('The form has no "%s" field', $name)); } return $this->fields[$name]; } public function set(Field\FormField $field) { $this->fields[$field->getName()] = $field; } public function all() { return $this->fields; } private function initialize() { $this->fields = array(); $document = new \DOMDocument('1.0', 'UTF-8'); $node = $document->importNode($this->node, true); $button = $document->importNode($this->button, true); $root = $document->appendChild($document->createElement('_root')); $root->appendChild($node); $root->appendChild($button); $xpath = new \DOMXPath($document); foreach ($xpath->query('descendant::input | descendant::textarea | descendant::select', $root) as $node) { if ($node->hasAttribute('disabled') || !$node->hasAttribute('name')) { continue; } $nodeName = $node->nodeName; if ($node === $button) { $this->set(new Field\InputFormField($node)); } elseif ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) { $this->set(new Field\ChoiceFormField($node)); } elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) { if ($this->has($node->getAttribute('name'))) { $this->get($node->getAttribute('name'))->addChoice($node); } else { $this->set(new Field\ChoiceFormField($node)); } } elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) { $this->set(new Field\FileFormField($node)); } elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) { $this->set(new Field\InputFormField($node)); } elseif ('textarea' == $nodeName) { $this->set(new Field\TextareaFormField($node)); } } } public function offsetExists($name) { return $this->has($name); } public function offsetGet($name) { if (!$this->has($name)) { throw new \InvalidArgumentException(sprintf('The form field "%s" does not exist', $name)); } return $this->fields[$name]; } public function offsetSet($name, $value) { if (!$this->has($name)) { throw new \InvalidArgumentException(sprintf('The form field "%s" does not exist', $name)); } $this->fields[$name]->setValue($value); } public function offsetUnset($name) { $this->remove($name); } protected function setNode(\DOMNode $node) { $this->button = $node; if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) { do { if (null === $node = $node->parentNode) { throw new \LogicException('The selected node does not have a form ancestor.'); } } while ('form' != $node->nodeName); } else { throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName)); } $this->node = $node; } } <?php
namespace Symfony\Component\DomCrawler; class Link { protected $node; protected $method; protected $currentUri; public function __construct(\DOMNode $node, $currentUri, $method = 'GET') { if (!in_array(substr($currentUri, 0, 4), array('http', 'file'))) { throw new \InvalidArgumentException(sprintf('Current URI must be an absolute URL ("%s").', $currentUri)); } $this->setNode($node); $this->method = $method ? strtoupper($method) : null; $this->currentUri = $currentUri; } public function getNode() { return $this->node; } public function getMethod() { return $this->method; } public function getUri() { $uri = $this->getRawUri(); if ('http' === substr($uri, 0, 4)) { return $uri; } if (!$uri) { return $this->currentUri; } if ('#' === $uri[0]) { $baseUri = $this->currentUri; if (false !== $pos = strpos($baseUri, '#')) { $baseUri = substr($baseUri, 0, $pos); } return $baseUri.$uri; } if ('?' === $uri[0]) { $baseUri = $this->currentUri; if (false !== $pos = strpos($baseUri, '?')) { $baseUri = substr($baseUri, 0, $pos); } return $baseUri.$uri; } if ('/' === $uri[0]) { return preg_replace('#^(.*?//[^/]+)(?:\/.*)?$#', '$1', $this->currentUri).$uri; } return substr($this->currentUri, 0, strrpos($this->currentUri, '/') + 1).$uri; } protected function getRawUri() { return $this->node->getAttribute('href'); } protected function setNode(\DOMNode $node) { if ('a' != $node->nodeName) { throw new \LogicException(sprintf('Unable to click on a "%s" tag.', $node->nodeName)); } $this->node = $node; } } <?php
namespace Symfony\Component\CssSelector; use Symfony\Component\CssSelector\Exception\ParseException; class CssSelector { static public function toXPath($cssExpr, $prefix = 'descendant-or-self::') { if (is_string($cssExpr)) { if (preg_match('#^\w+\s*$#u', $cssExpr, $match)) { return $prefix.trim($match[0]); } if (preg_match('~^(\w*)#(\w+)\s*$~u', $cssExpr, $match)) { return sprintf("%s%s[@id = '%s']", $prefix, $match[1] ? $match[1] : '*', $match[2]); } if (preg_match('#^(\w*)\.(\w+)\s*$#u', $cssExpr, $match)) { return sprintf("%s%s[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $prefix, $match[1] ? $match[1] : '*', $match[2]); } $parser = new self(); $cssExpr = $parser->parse($cssExpr); } $expr = $cssExpr->toXpath(); if (!$expr) { throw new ParseException(sprintf('Got None for xpath expression from %s.', $cssExpr)); } if ($prefix) { $expr->addPrefix($prefix); } return (string) $expr; } public function parse($string) { $tokenizer = new Tokenizer(); $stream = new TokenStream($tokenizer->tokenize($string), $string); try { return $this->parseSelectorGroup($stream); } catch (\Exception $e) { $class = get_class($e); throw new $class(sprintf('%s at %s -> %s', $e->getMessage(), implode($stream->getUsed(), ''), $stream->peek()), 0, $e); } } private function parseSelectorGroup($stream) { $result = array(); while (true) { $result[] = $this->parseSelector($stream); if ($stream->peek() == ',') { $stream->next(); } else { break; } } if (count($result) == 1) { return $result[0]; } return new Node\OrNode($result); } private function parseSelector($stream) { $result = $this->parseSimpleSelector($stream); while (true) { $peek = $stream->peek(); if (',' == $peek || null === $peek) { return $result; } elseif (in_array($peek, array('+', '>', '~'))) { $combinator = (string) $stream->next(); } else { $combinator = ' '; } $consumed = count($stream->getUsed()); $nextSelector = $this->parseSimpleSelector($stream); if ($consumed == count($stream->getUsed())) { throw new ParseException(sprintf("Expected selector, got '%s'", $stream->peek())); } $result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector); } return $result; } private function parseSimpleSelector($stream) { $peek = $stream->peek(); if ('*' != $peek && !$peek->isType('Symbol')) { $element = $namespace = '*'; } else { $next = $stream->next(); if ('*' != $next && !$next->isType('Symbol')) { throw new ParseException(sprintf("Expected symbol, got '%s'", $next)); } if ($stream->peek() == '|') { $namespace = $next; $stream->next(); $element = $stream->next(); if ('*' != $element && !$next->isType('Symbol')) { throw new ParseException(sprintf("Expected symbol, got '%s'", $next)); } } else { $namespace = '*'; $element = $next; } } $result = new Node\ElementNode($namespace, $element); $hasHash = false; while (true) { $peek = $stream->peek(); if ('#' == $peek) { if ($hasHash) { break; } $stream->next(); $result = new Node\HashNode($result, $stream->next()); $hasHash = true; continue; } elseif ('.' == $peek) { $stream->next(); $result = new Node\ClassNode($result, $stream->next()); continue; } elseif ('[' == $peek) { $stream->next(); $result = $this->parseAttrib($result, $stream); $next = $stream->next(); if (']' != $next) { throw new ParseException(sprintf("] expected, got '%s'", $next)); } continue; } elseif (':' == $peek || '::' == $peek) { $type = $stream->next(); $ident = $stream->next(); if (!$ident || !$ident->isType('Symbol')) { throw new ParseException(sprintf("Expected symbol, got '%s'", $ident)); } if ($stream->peek() == '(') { $stream->next(); $peek = $stream->peek(); if ($peek->isType('String')) { $selector = $stream->next(); } elseif ($peek->isType('Symbol') && is_int($peek)) { $selector = intval($stream->next()); } else { $selector = $this->parseSimpleSelector($stream); } $next = $stream->next(); if (')' != $next) { throw new ParseException(sprintf("Expected ')', got '%s' and '%s'", $next, $selector)); } $result = new Node\FunctionNode($result, $type, $ident, $selector); } else { $result = new Node\PseudoNode($result, $type, $ident); } continue; } else { if (' ' == $peek) { $stream->next(); } break; } } return $result; } private function parseAttrib($selector, $stream) { $attrib = $stream->next(); if ($stream->peek() == '|') { $namespace = $attrib; $stream->next(); $attrib = $stream->next(); } else { $namespace = '*'; } if ($stream->peek() == ']') { return new Node\AttribNode($selector, $namespace, $attrib, 'exists', null); } $op = $stream->next(); if (!in_array($op, array('^=', '$=', '*=', '=', '~=', '|=', '!='))) { throw new ParseException(sprintf("Operator expected, got '%s'", $op)); } $value = $stream->next(); if (!$value->isType('Symbol') && !$value->isType('String')) { throw new ParseException(sprintf("Expected string or symbol, got '%s'", $value)); } return new Node\AttribNode($selector, $namespace, $attrib, $op, $value); } } <?php
namespace Symfony\Component\CssSelector\Exception; class ParseException extends \Exception { } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; use Symfony\Component\CssSelector\Exception\ParseException; class AttribNode implements NodeInterface { protected $selector; protected $namespace; protected $attrib; protected $operator; protected $value; public function __construct($selector, $namespace, $attrib, $operator, $value) { $this->selector = $selector; $this->namespace = $namespace; $this->attrib = $attrib; $this->operator = $operator; $this->value = $value; } public function __toString() { if ($this->operator == 'exists') { return sprintf('%s[%s[%s]]', __CLASS__, $this->selector, $this->formatAttrib()); } return sprintf('%s[%s[%s %s %s]]', __CLASS__, $this->selector, $this->formatAttrib(), $this->operator, $this->value); } public function toXpath() { $path = $this->selector->toXpath(); $attrib = $this->xpathAttrib(); $value = $this->value; if ($this->operator == 'exists') { $path->addCondition($attrib); } elseif ($this->operator == '=') { $path->addCondition(sprintf('%s = %s', $attrib, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '!=') { if ($value) { $path->addCondition(sprintf('not(%s) or %s != %s', $attrib, $attrib, XPathExpr::xpathLiteral($value))); } else { $path->addCondition(sprintf('%s != %s', $attrib, XPathExpr::xpathLiteral($value))); } } elseif ($this->operator == '~=') { $path->addCondition(sprintf("contains(concat(' ', normalize-space(%s), ' '), %s)", $attrib, XPathExpr::xpathLiteral(' '.$value.' '))); } elseif ($this->operator == '|=') { $path->addCondition(sprintf('%s = %s or starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value), $attrib, XPathExpr::xpathLiteral($value.'-'))); } elseif ($this->operator == '^=') { $path->addCondition(sprintf('starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '$=') { $path->addCondition(sprintf('substring(%s, string-length(%s)-%s) = %s', $attrib, $attrib, strlen($value) - 1, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '*=') { $path->addCondition(sprintf('contains(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); } else { throw new ParseException(sprintf('Unknown operator: %s', $this->operator)); } return $path; } protected function xpathAttrib() { if ($this->namespace == '*') { return '@'.$this->attrib; } return sprintf('@%s:%s', $this->namespace, $this->attrib); } protected function formatAttrib() { if ($this->namespace == '*') { return $this->attrib; } return sprintf('%s|%s', $this->namespace, $this->attrib); } } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; class ClassNode implements NodeInterface { protected $selector; protected $className; public function __construct($selector, $className) { $this->selector = $selector; $this->className = $className; } public function __toString() { return sprintf('%s[%s.%s]', __CLASS__, $this->selector, $this->className); } public function toXpath() { $selXpath = $this->selector->toXpath(); $selXpath->addCondition(sprintf("contains(concat(' ', normalize-space(@class), ' '), %s)", XPathExpr::xpathLiteral(' '.$this->className.' '))); return $selXpath; } } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\Exception\ParseException; class CombinedSelectorNode implements NodeInterface { static protected $methodMapping = array( ' ' => 'descendant', '>' => 'child', '+' => 'direct_adjacent', '~' => 'indirect_adjacent', ); protected $selector; protected $combinator; protected $subselector; public function __construct($selector, $combinator, $subselector) { $this->selector = $selector; $this->combinator = $combinator; $this->subselector = $subselector; } public function __toString() { $comb = $this->combinator == ' ' ? '<followed>' : $this->combinator; return sprintf('%s[%s %s %s]', __CLASS__, $this->selector, $comb, $this->subselector); } public function toXpath() { if (!isset(self::$methodMapping[$this->combinator])) { throw new ParseException(sprintf('Unknown combinator: %s', $this->combinator)); } $method = '_xpath_'.self::$methodMapping[$this->combinator]; $path = $this->selector->toXpath(); return $this->$method($path, $this->subselector); } protected function _xpath_descendant($xpath, $sub) { $xpath->join('/descendant::', $sub->toXpath()); return $xpath; } protected function _xpath_child($xpath, $sub) { $xpath->join('/', $sub->toXpath()); return $xpath; } protected function _xpath_direct_adjacent($xpath, $sub) { $xpath->join('/following-sibling::', $sub->toXpath()); $xpath->addNameTest(); $xpath->addCondition('position() = 1'); return $xpath; } protected function _xpath_indirect_adjacent($xpath, $sub) { $xpath->join('/following-sibling::', $sub->toXpath()); return $xpath; } } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; class ElementNode implements NodeInterface { protected $namespace; protected $element; public function __construct($namespace, $element) { $this->namespace = $namespace; $this->element = $element; } public function __toString() { return sprintf('%s[%s]', __CLASS__, $this->formatElement()); } public function formatElement() { if ($this->namespace == '*') { return $this->element; } return sprintf('%s|%s', $this->namespace, $this->element); } public function toXpath() { if ($this->namespace == '*') { $el = strtolower($this->element); } else { $el = sprintf('%s:%s', $this->namespace, $this->element); } return new XPathExpr(null, null, $el); } } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\Exception\ParseException; use Symfony\Component\CssSelector\XPathExpr; class FunctionNode implements NodeInterface { static protected $unsupported = array('target', 'lang', 'enabled', 'disabled'); protected $selector; protected $type; protected $name; protected $expr; public function __construct($selector, $type, $name, $expr) { $this->selector = $selector; $this->type = $type; $this->name = $name; $this->expr = $expr; } public function __toString() { return sprintf('%s[%s%s%s(%s)]', __CLASS__, $this->selector, $this->type, $this->name, $this->expr); } public function toXpath() { $selPath = $this->selector->toXpath(); if (in_array($this->name, self::$unsupported)) { throw new ParseException(sprintf('The pseudo-class %s is not supported', $this->name)); } $method = '_xpath_'.str_replace('-', '_', $this->name); if (!method_exists($this, $method)) { throw new ParseException(sprintf('The pseudo-class %s is unknown', $this->name)); } return $this->$method($selPath, $this->expr); } protected function _xpath_nth_child($xpath, $expr, $last = false, $addNameTest = true) { list($a, $b) = $this->parseSeries($expr); if (!$a && !$b && !$last) { $xpath->addCondition('false() and position() = 0'); return $xpath; } if ($addNameTest) { $xpath->addNameTest(); } $xpath->addStarPrefix(); if ($a == 0) { if ($last) { $b = sprintf('last() - %s', $b); } $xpath->addCondition(sprintf('position() = %s', $b)); return $xpath; } if ($last) { $a = -$a; $b = -$b; } if ($b > 0) { $bNeg = -$b; } else { $bNeg = sprintf('+%s', -$b); } if ($a != 1) { $expr = array(sprintf('(position() %s) mod %s = 0', $bNeg, $a)); } else { $expr = array(); } if ($b >= 0) { $expr[] = sprintf('position() >= %s', $b); } elseif ($b < 0 && $last) { $expr[] = sprintf('position() < (last() %s)', $b); } $expr = implode($expr, ' and '); if ($expr) { $xpath->addCondition($expr); } return $xpath; } protected function _xpath_nth_last_child($xpath, $expr) { return $this->_xpath_nth_child($xpath, $expr, true); } protected function _xpath_nth_of_type($xpath, $expr) { if ($xpath->getElement() == '*') { throw new ParseException('*:nth-of-type() is not implemented'); } return $this->_xpath_nth_child($xpath, $expr, false, false); } protected function _xpath_nth_last_of_type($xpath, $expr) { return $this->_xpath_nth_child($xpath, $expr, true, false); } protected function _xpath_contains($xpath, $expr) { if ($expr instanceof ElementNode) { $expr = $expr->formatElement(); } $xpath->addCondition(sprintf('contains(string(.), %s)', XPathExpr::xpathLiteral($expr))); return $xpath; } protected function _xpath_not($xpath, $expr) { $expr = $expr->toXpath(); $cond = $expr->getCondition(); $xpath->addCondition(sprintf('not(%s)', $cond)); return $xpath; } protected function parseSeries($s) { if ($s instanceof ElementNode) { $s = $s->formatElement(); } if (!$s || '*' == $s) { return array(0, 0); } if (is_string($s)) { return array(0, $s); } if ('odd' == $s) { return array(2, 1); } if ('even' == $s) { return array(2, 0); } if ('n' == $s) { return array(1, 0); } if (false === strpos($s, 'n')) { return array(0, intval((string) $s)); } list($a, $b) = explode('n', $s); if (!$a) { $a = 1; } elseif ('-' == $a || '+' == $a) { $a = intval($a.'1'); } else { $a = intval($a); } if (!$b) { $b = 0; } elseif ('-' == $b || '+' == $b) { $b = intval($b.'1'); } else { $b = intval($b); } return array($a, $b); } } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExpr; class HashNode implements NodeInterface { protected $selector; protected $id; public function __construct($selector, $id) { $this->selector = $selector; $this->id = $id; } public function __toString() { return sprintf('%s[%s#%s]', __CLASS__, $this->selector, $this->id); } public function toXpath() { $path = $this->selector->toXpath(); $path->addCondition(sprintf('@id = %s', XPathExpr::xpathLiteral($this->id))); return $path; } } <?php
namespace Symfony\Component\CssSelector\Node; interface NodeInterface { function __toString(); function toXpath(); } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\XPathExprOr; class OrNode implements NodeInterface { protected $items; public function __construct($items) { $this->items = $items; } public function __toString() { return sprintf('%s(%s)', __CLASS__, $this->items); } public function toXpath() { $paths = array(); foreach ($this->items as $item) { $paths[] = $item->toXpath(); } return new XPathExprOr($paths); } } <?php
namespace Symfony\Component\CssSelector\Node; use Symfony\Component\CssSelector\Exception\ParseException; class PseudoNode implements NodeInterface { static protected $unsupported = array( 'indeterminate', 'first-line', 'first-letter', 'selection', 'before', 'after', 'link', 'visited', 'active', 'focus', 'hover', ); protected $element; protected $type; protected $ident; public function __construct($element, $type, $ident) { $this->element = $element; if (!in_array($type, array(':', '::'))) { throw new ParseException(sprintf('The PseudoNode type can only be : or :: (%s given).', $type)); } $this->type = $type; $this->ident = $ident; } public function __toString() { return sprintf('%s[%s%s%s]', __CLASS__, $this->element, $this->type, $this->ident); } public function toXpath() { $elXpath = $this->element->toXpath(); if (in_array($this->ident, self::$unsupported)) { throw new ParseException(sprintf('The pseudo-class %s is unsupported', $this->ident)); } $method = 'xpath_'.str_replace('-', '_', $this->ident); if (!method_exists($this, $method)) { throw new ParseException(sprintf('The pseudo-class %s is unknown', $this->ident)); } return $this->$method($elXpath); } protected function xpath_checked($xpath) { $xpath->addCondition("(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')"); return $xpath; } protected function xpath_root($xpath) { throw new ParseException(); } protected function xpath_first_child($xpath) { $xpath->addStarPrefix(); $xpath->addNameTest(); $xpath->addCondition('position() = 1'); return $xpath; } protected function xpath_last_child($xpath) { $xpath->addStarPrefix(); $xpath->addNameTest(); $xpath->addCondition('position() = last()'); return $xpath; } protected function xpath_first_of_type($xpath) { if ($xpath->getElement() == '*') { throw new ParseException('*:first-of-type is not implemented'); } $xpath->addStarPrefix(); $xpath->addCondition('position() = 1'); return $xpath; } protected function xpath_last_of_type($xpath) { if ($xpath->getElement() == '*') { throw new ParseException('*:last-of-type is not implemented'); } $xpath->addStarPrefix(); $xpath->addCondition('position() = last()'); return $xpath; } protected function xpath_only_child($xpath) { $xpath->addNameTest(); $xpath->addStarPrefix(); $xpath->addCondition('last() = 1'); return $xpath; } protected function xpath_only_of_type($xpath) { if ($xpath->getElement() == '*') { throw new ParseException('*:only-of-type is not implemented'); } $xpath->addCondition('last() = 1'); return $xpath; } protected function xpath_empty($xpath) { $xpath->addCondition('not(*) and not(normalize-space())'); return $xpath; } } <?php
namespace Symfony\Component\CssSelector; class Token { private $type; private $value; private $position; public function __construct($type, $value, $position) { $this->type = $type; $this->value = $value; $this->position = $position; } public function __toString() { return (string) $this->value; } public function isType($type) { return $this->type == $type; } public function getPosition() { return $this->position; } } <?php
namespace Symfony\Component\CssSelector; use Symfony\Component\CssSelector\Exception\ParseException; class Tokenizer { public function tokenize($s) { if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('ASCII'); } $tokens = array(); $pos = 0; $s = preg_replace('#/\*.*?\*/#s', '', $s); while (true) { if (preg_match('#\s+#A', $s, $match, 0, $pos)) { $precedingWhitespacePos = $pos; $pos += strlen($match[0]); } else { $precedingWhitespacePos = 0; } if ($pos >= strlen($s)) { if (isset($mbEncoding)) { mb_internal_encoding($mbEncoding); } return $tokens; } if (preg_match('#[+-]?\d*n(?:[+-]\d+)?#A', $s, $match, 0, $pos) && 'n' !== $match[0]) { $sym = substr($s, $pos, strlen($match[0])); $tokens[] = new Token('Symbol', $sym, $pos); $pos += strlen($match[0]); continue; } $c = $s[$pos]; $c2 = substr($s, $pos, 2); if (in_array($c2, array('~=', '|=', '^=', '$=', '*=', '::', '!='))) { $tokens[] = new Token('Token', $c2, $pos); $pos += 2; continue; } if (in_array($c, array('>', '+', '~', ',', '.', '*', '=', '[', ']', '(', ')', '|', ':', '#'))) { if (in_array($c, array('.', '#', '[')) && $precedingWhitespacePos > 0) { $tokens[] = new Token('Token', ' ', $precedingWhitespacePos); } $tokens[] = new Token('Token', $c, $pos); ++$pos; continue; } if ('"' === $c || "'" === $c) { $oldPos = $pos; list($sym, $pos) = $this->tokenizeEscapedString($s, $pos); $tokens[] = new Token('String', $sym, $oldPos); continue; } $oldPos = $pos; list($sym, $pos) = $this->tokenizeSymbol($s, $pos); $tokens[] = new Token('Symbol', $sym, $oldPos); continue; } } private function tokenizeEscapedString($s, $pos) { $quote = $s[$pos]; $pos = $pos + 1; $start = $pos; while (true) { $next = strpos($s, $quote, $pos); if (false === $next) { throw new ParseException(sprintf('Expected closing %s for string in: %s', $quote, substr($s, $start))); } $result = substr($s, $start, $next - $start); if ('\\' === $result[strlen($result) - 1]) { $pos = $next + 1; continue; } if (false !== strpos($result, '\\')) { $result = $this->unescapeStringLiteral($result); } return array($result, $next + 1); } } private function unescapeStringLiteral($literal) { return preg_replace_callback('#(\\\\(?:[A-Fa-f0-9]{1,6}(?:\r\n|\s)?|[^A-Fa-f0-9]))#', function ($matches) use ($literal) { if ($matches[0][0] == '\\' && strlen($matches[0]) > 1) { $matches[0] = substr($matches[0], 1); if (in_array($matches[0][0], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'))) { return chr(trim($matches[0])); } } else { throw new ParseException(sprintf('Invalid escape sequence %s in string %s', $matches[0], $literal)); } }, $literal); } private function tokenizeSymbol($s, $pos) { $start = $pos; if (!preg_match('#[^\w\-]#', $s, $match, PREG_OFFSET_CAPTURE, $pos)) { return array(substr($s, $start), strlen($s)); } $matchStart = $match[0][1]; if ($matchStart == $pos) { throw new ParseException(sprintf('Unexpected symbol: %s at %s', $s[$pos], $pos)); } $result = substr($s, $start, $matchStart - $start); $pos = $matchStart; return array($result, $pos); } } <?php
namespace Symfony\Component\CssSelector; class TokenStream { private $used; private $tokens; private $source; private $peeked; private $peeking; public function __construct($tokens, $source = null) { $this->used = array(); $this->tokens = $tokens; $this->source = $source; $this->peeked = null; $this->peeking = false; } public function getUsed() { return $this->used; } public function next() { if ($this->peeking) { $this->peeking = false; $this->used[] = $this->peeked; return $this->peeked; } if (!count($this->tokens)) { return null; } $next = array_shift($this->tokens); $this->used[] = $next; return $next; } public function peek() { if (!$this->peeking) { if (!count($this->tokens)) { return null; } $this->peeked = array_shift($this->tokens); $this->peeking = true; } return $this->peeked; } } <?php
namespace Symfony\Component\CssSelector; class XPathExpr { private $prefix; private $path; private $element; private $condition; private $starPrefix; public function __construct($prefix = null, $path = null, $element = '*', $condition = null, $starPrefix = false) { $this->prefix = $prefix; $this->path = $path; $this->element = $element; $this->condition = $condition; $this->starPrefix = $starPrefix; } public function getPrefix() { return $this->prefix; } public function getPath() { return $this->path; } public function hasStarPrefix() { return $this->starPrefix; } public function getElement() { return $this->element; } public function getCondition() { return $this->condition; } public function __toString() { $path = ''; if (null !== $this->prefix) { $path .= $this->prefix; } if (null !== $this->path) { $path .= $this->path; } $path .= $this->element; if ($this->condition) { $path .= sprintf('[%s]', $this->condition); } return $path; } public function addCondition($condition) { if ($this->condition) { $this->condition = sprintf('%s and (%s)', $this->condition, $condition); } else { $this->condition = $condition; } } public function addPrefix($prefix) { if ($this->prefix) { $this->prefix = $prefix.$this->prefix; } else { $this->prefix = $prefix; } } public function addNameTest() { if ($this->element == '*') { return; } $this->addCondition(sprintf('name() = %s', XPathExpr::xpathLiteral($this->element))); $this->element = '*'; } public function addStarPrefix() { if ($this->path) { $this->path .= '*/'; } else { $this->path = '*/'; } $this->starPrefix = true; } public function join($combiner, $other) { $prefix = (string) $this; $prefix .= $combiner; $path = $other->getPrefix().$other->getPath(); if ($other->hasStarPrefix() && '*/' == $path) { $path = ''; } $this->prefix = $prefix; $this->path = $path; $this->element = $other->getElement(); $this->condition = $other->GetCondition(); } static public function xpathLiteral($s) { if ($s instanceof Node\ElementNode) { $s = $s->formatElement(); } else { $s = (string) $s; } if (false === strpos($s, "'")) { return sprintf("'%s'", $s); } if (false === strpos($s, '"')) { return sprintf('"%s"', $s); } $string = $s; $parts = array(); while (true) { if (false !== $pos = strpos($string, "'")) { $parts[] = sprintf("'%s'", substr($string, 0, $pos)); $parts[] = "\"'\""; $string = substr($string, $pos + 1); } else { $parts[] = "'$string'"; break; } } return sprintf('concat(%s)', implode($parts, ', ')); } } <?php
namespace Symfony\Component\CssSelector; class XPathExprOr extends XPathExpr { public function __construct($items, $prefix = null) { $this->items = $items; $this->prefix = $prefix; } public function __toString() { $prefix = $this->prefix; $tmp = array(); foreach ($this->items as $i) { $tmp[] = sprintf('%s%s', $prefix, $i); } return implode($tmp, ' | '); } } <?php
namespace Symfony\Component\Process; class ExecutableFinder { private $suffixes = array('.exe', '.bat', '.cmd', '.com'); public function setSuffixes(array $suffixes) { $this->suffixes = $suffixes; } public function addSuffix($suffix) { $this->suffixes[] = $suffix; } public function find($name, $default = null) { if (ini_get('open_basedir')) { $searchPath = explode(PATH_SEPARATOR, getenv('open_basedir')); $dirs = array(); foreach ($searchPath as $path) { if (is_dir($path)) { $dirs[] = $path; } else { $file = str_replace(dirname($path), '', $path); if ($file == $name && is_executable($path)) { return $path; } } } } else { $dirs = explode(PATH_SEPARATOR, getenv('PATH') ? getenv('PATH') : getenv('Path')); } $suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : $this->suffixes) : array(''); foreach ($suffixes as $suffix) { foreach ($dirs as $dir) { if (is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && is_executable($file)) { return $file; } } } return $default; } } <?php
namespace Symfony\Component\Process; class PhpExecutableFinder { private $executableFinder; public function __construct() { $this->executableFinder = new ExecutableFinder(); } public function find() { if ($php = getenv('PHP_PATH')) { if (!is_executable($php)) { return false; } return $php; } $suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array(''); foreach ($suffixes as $suffix) { if (is_executable($php = PHP_BINDIR.DIRECTORY_SEPARATOR.'php'.$suffix)) { return $php; } } if ($php = getenv('PHP_PEAR_PHP_BIN')) { if (is_executable($php)) { return $php; } } return $this->executableFinder->find('php'); } } <?php
namespace Symfony\Component\Process; class PhpProcess extends Process { private $executableFinder; public function __construct($script, $cwd = null, array $env = array(), $timeout = 60, array $options = array()) { parent::__construct(null, $cwd, $env, $script, $timeout, $options); $this->executableFinder = new PhpExecutableFinder(); } public function setPhpBinary($php) { $this->setCommandLine($php); } public function run($callback = null) { if (null === $this->getCommandLine()) { if (false === $php = $this->executableFinder->find()) { throw new \RuntimeException('Unable to find the PHP executable.'); } $this->setCommandLine($php); } return parent::run($callback); } } <?php
namespace Symfony\Component\Process; class Process { private $commandline; private $cwd; private $env; private $stdin; private $timeout; private $options; private $exitcode; private $status; private $stdout; private $stderr; public function __construct($commandline, $cwd = null, array $env = null, $stdin = null, $timeout = 60, array $options = array()) { if (!function_exists('proc_open')) { throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); } $this->commandline = $commandline; $this->cwd = null === $cwd ? getcwd() : $cwd; if (null !== $env) { $this->env = array(); foreach ($env as $key => $value) { $this->env[(binary) $key] = (binary) $value; } } else { $this->env = null; } $this->stdin = $stdin; $this->timeout = $timeout; $this->options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false), $options); } public function run($callback = null) { $this->stdout = ''; $this->stderr = ''; $that = $this; $callback = function ($type, $data) use ($that, $callback) { if ('out' == $type) { $that->addOutput($data); } else { $that->addErrorOutput($data); } if (null !== $callback) { call_user_func($callback, $type, $data); } }; $descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); $process = proc_open($this->commandline, $descriptors, $pipes, $this->cwd, $this->env, $this->options); if (!is_resource($process)) { throw new \RuntimeException('Unable to launch a new process.'); } foreach ($pipes as $pipe) { stream_set_blocking($pipe, false); } if (null === $this->stdin) { fclose($pipes[0]); $writePipes = null; } else { $writePipes = array($pipes[0]); $stdinLen = strlen($this->stdin); $stdinOffset = 0; } unset($pipes[0]); while ($pipes || $writePipes) { $r = $pipes; $w = $writePipes; $e = null; $n = @stream_select($r, $w, $e, $this->timeout); if (false === $n) { break; } elseif ($n === 0) { proc_terminate($process); throw new \RuntimeException('The process timed out.'); } if ($w) { $written = fwrite($writePipes[0], (binary) substr($this->stdin, $stdinOffset), 8192); if (false !== $written) { $stdinOffset += $written; } if ($stdinOffset >= $stdinLen) { fclose($writePipes[0]); $writePipes = null; } } foreach ($r as $pipe) { $type = array_search($pipe, $pipes); $data = fread($pipe, 8192); if (strlen($data) > 0) { call_user_func($callback, $type == 1 ? 'out' : 'err', $data); } if (false === $data || feof($pipe)) { fclose($pipe); unset($pipes[$type]); } } } $this->status = proc_get_status($process); $time = 0; while (1 == $this->status['running'] && $time < 1000000) { $time += 1000; usleep(1000); $this->status = proc_get_status($process); } $exitcode = proc_close($process); if ($this->status['signaled']) { throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->status['stopsig'])); } return $this->exitcode = $this->status['running'] ? $exitcode : $this->status['exitcode']; } public function getOutput() { return $this->stdout; } public function getErrorOutput() { return $this->stderr; } public function getExitCode() { return $this->exitcode; } public function isSuccessful() { return 0 == $this->exitcode; } public function hasBeenSignaled() { return $this->status['signaled']; } public function getTermSignal() { return $this->status['termsig']; } public function hasBeenStopped() { return $this->status['stopped']; } public function getStopSignal() { return $this->status['stopsig']; } public function addOutput($line) { $this->stdout .= $line; } public function addErrorOutput($line) { $this->stderr .= $line; } public function getCommandLine() { return $this->commandline; } public function setCommandLine($commandline) { $this->commandline = $commandline; } public function getTimeout() { return $this->timeout; } public function setTimeout($timeout) { $this->timeout = $timeout; } public function getWorkingDirectory() { return $this->cwd; } public function setWorkingDirectory($cwd) { $this->cwd = $cwd; } public function getEnv() { return $this->env; } public function setEnv(array $env) { $this->env = $env; } public function getStdin() { return $this->stdin; } public function setStdin($stdin) { $this->stdin = $stdin; } public function getOptions() { return $this->options; } public function setOptions(array $options) { $this->options = $options; } } <?php
namespace Zend\Uri\Exception; class InvalidArgumentException extends \InvalidArgumentException implements \Zend\Uri\Exception {} <?php
namespace Zend\Uri\Exception; class InvalidUriException extends \InvalidArgumentException implements \Zend\Uri\Exception { } <?php
namespace Zend\Uri\Exception; class InvalidUriPartException extends \InvalidArgumentException implements \Zend\Uri\Exception { const INVALID_SCHEME = 1; const INVALID_USER = 2; const INVALID_PASSWORD = 4; const INVALID_USERINFO = 6; const INVALID_HOSTNAME = 8; const INVALID_PORT = 16; const INVALID_AUTHORITY = 30; const INVALID_PATH = 32; const INVALID_QUERY = 64; const INVALID_FRAGMENT = 128; }<?php
namespace Zend\Uri\Exception; class InvalidUriTypeException extends \InvalidArgumentException implements \Zend\Uri\Exception { } <?php
namespace Zend\Uri; interface Exception {} <?php
namespace Zend\Uri; class File extends Uri { static protected $validSchemes = array('file'); public function isValid() { if ($this->query) { return false; } return parent::isValid(); } public function setUserInfo($userInfo) { return $this; } public function setFragment($fragment) { return $this; } public static function fromUnixPath($path) { $url = new self('file:'); if (substr($path, 0, 1) == '/') { $url->setHost(''); } $url->setPath($path); return $url; } public static function fromWindowsPath($path) { $url = new self('file:'); $path = str_replace(array('/', '\\'), array('%2F', '/'), $path); if (preg_match('|^([a-zA-Z]:)?/|', $path)) { $url->setHost(''); } $url->setPath($path); return $url; } } <?php
namespace Zend\Uri; class Http extends Uri { protected static $validSchemes = array('http', 'https'); protected static $defaultPorts = array( 'http' => 80, 'https' => 443, ); protected $validHostTypes = self::HOST_DNSORIPV4; protected $user; protected $password; public function isValid() { return parent::isValid(); } public function getUser() { if (null !== $this->user) { return $this->user; } $this->parseUserInfo(); return $this->user; } public function getPassword() { if (null !== $this->password) { return $this->password; } $this->parseUserInfo(); return $this->password; } public function setUser($user) { $this->user = $user; return $this; } public function setPassword($password) { $this->password = $password; return $this; } public static function validateHost($host, $allowed = self::HOST_DNSORIPV4) { return parent::validateHost($host, $allowed); } protected function parseUserInfo() { if (null === $this->userInfo) { return; } if (false === strpos($this->userInfo, ':')) { $this->setUser($this->userInfo); return; } list($user, $password) = explode(':', $this->userInfo, 2); $this->setUser($user); $this->setPassword($password); } } <?php
namespace Zend\Uri; use Zend\Validator\Validator, Zend\Validator\EmailAddress as EmailValidator; class Mailto extends Uri { protected static $validSchemes = array('mailto'); protected $emailValidator; public function isValid() { if ($this->host || $this->userInfo || $this->port) { return false; } if (empty($this->path)) { return false; } if (0 === strpos($this->path, '/')) { return false; } $validator = $this->getValidator(); return $validator->isValid($this->path); } public function setEmail($email) { return $this->setPath($email); } public function getEmail() { return $this->getPath(); } public function setValidator(Validator $validator) { $this->emailValidator = $validator; return $this; } public function getValidator() { if (null === $this->emailValidator) { $this->setValidator(new EmailValidator()); } return $this->emailValidator; } } <?php
namespace Zend\Uri; use Zend\Uri\Uri; abstract class UriFactory { static protected $schemeClasses = array( 'http' => 'Zend\Uri\Http', 'https' => 'Zend\Uri\Http', 'mailto' => 'Zend\Uri\Mailto', 'file' => 'Zend\Uri\File', ); static public function registerScheme($scheme, $class) { $scheme = strtolower($scheme); static::$_schemeClasses[$scheme] = $class; } static public function factory($uriString, $defaultScheme = null) { if (!is_string($uriString)) { throw new Exception\InvalidArgumentException(sprintf( 'Expecting a string, received "%s"', (is_object($uriString) ? get_class($uriString) : gettype($uriString)) )); } $uri = new Uri($uriString); $scheme = strtolower($uri->getScheme()); if (!$scheme && $defaultScheme) { $scheme = $defaultScheme; } if ($scheme && isset(static::$schemeClasses[$scheme])) { $class = static::$schemeClasses[$scheme]; $uri = new $class($uri); if (! $uri instanceof Uri) { throw new Exception\InvalidArgumentException(sprintf( 'class "%s" registered for scheme "%s" is not a subclass of Zend\Uri\Uri', $class, $scheme )); } } return $uri; } } <?php
namespace Zend\Http\Client\Adapter; use Zend\Http\Client\Adapter as HttpAdapter, Zend\Http\Client\Adapter\Exception as AdapterException, Zend\Http\Client; class Curl implements HttpAdapter, Stream { protected $_config = array(); protected $_connected_to = array(null, null); protected $_curl = null; protected $_invalidOverwritableCurlOptions; protected $_response = null; protected $out_stream; public function __construct() { if (!extension_loaded('curl')) { throw new AdapterException\InitializationException('cURL extension has to be loaded to use this Zend\Http\Client adapter'); } $this->_invalidOverwritableCurlOptions = array( CURLOPT_HTTPGET, CURLOPT_POST, CURLOPT_PUT, CURLOPT_CUSTOMREQUEST, CURLOPT_HEADER, CURLOPT_RETURNTRANSFER, CURLOPT_HTTPHEADER, CURLOPT_POSTFIELDS, CURLOPT_INFILE, CURLOPT_INFILESIZE, CURLOPT_PORT, CURLOPT_MAXREDIRS, CURLOPT_CONNECTTIMEOUT, CURL_HTTP_VERSION_1_1, CURL_HTTP_VERSION_1_0, ); } public function setConfig($config = array()) { if ($config instanceof \Zend\Config\Config) { $config = $config->toArray(); } elseif (! is_array($config)) { throw new AdapterException\InvalidArgumentException( 'Array or Zend\Config\Config object expected, got ' . gettype($config) ); } if(isset($config['proxy_user']) && isset($config['proxy_pass'])) { $this->setCurlOption(CURLOPT_PROXYUSERPWD, $config['proxy_user'].":".$config['proxy_pass']); unset($config['proxy_user'], $config['proxy_pass']); } foreach ($config as $k => $v) { $option = strtolower($k); switch($option) { case 'proxy_host': $this->setCurlOption(CURLOPT_PROXY, $v); break; case 'proxy_port': $this->setCurlOption(CURLOPT_PROXYPORT, $v); break; default: $this->_config[$option] = $v; break; } } return $this; } public function getConfig() { return $this->_config; } public function setCurlOption($option, $value) { if (!isset($this->_config['curloptions'])) { $this->_config['curloptions'] = array(); } $this->_config['curloptions'][$option] = $value; return $this; } public function connect($host, $port = 80, $secure = false) { if ($this->_curl) { $this->close(); } if ($this->_curl && is_array($this->_connected_to) && ($this->_connected_to[0] != $host || $this->_connected_to[1] != $port) ) { $this->close(); } $this->_curl = curl_init(); if ($port != 80) { curl_setopt($this->_curl, CURLOPT_PORT, intval($port)); } curl_setopt($this->_curl, CURLOPT_CONNECTTIMEOUT, $this->_config['timeout']); curl_setopt($this->_curl, CURLOPT_MAXREDIRS, $this->_config['maxredirects']); if (!$this->_curl) { $this->close(); throw new AdapterException\RuntimeException('Unable to Connect to ' . $host . ':' . $port); } if ($secure !== false) { if (isset($this->_config['sslcert'])) { curl_setopt($this->_curl, CURLOPT_SSLCERT, $this->_config['sslcert']); } if (isset($this->_config['sslpassphrase'])) { curl_setopt($this->_curl, CURLOPT_SSLCERTPASSWD, $this->_config['sslpassphrase']); } } $this->_connected_to = array($host, $port); } public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $body = '') { if (!$this->_curl) { throw new AdapterException\RuntimeException("Trying to write but we are not connected"); } if ($this->_connected_to[0] != $uri->getHost() || $this->_connected_to[1] != $uri->getPort()) { throw new AdapterException\RuntimeException("Trying to write but we are connected to the wrong host"); } curl_setopt($this->_curl, CURLOPT_URL, $uri->__toString()); $curlValue = true; switch ($method) { case Client::GET: $curlMethod = CURLOPT_HTTPGET; break; case Client::POST: $curlMethod = CURLOPT_POST; break; case Client::PUT: if(is_resource($body)) { $this->_config['curloptions'][CURLOPT_INFILE] = $body; } if (isset($this->_config['curloptions'][CURLOPT_INFILE])) { foreach ($headers AS $k => $header) { if (preg_match('/Content-Length:\s*(\d+)/i', $header, $m)) { if(is_resource($body)) { $this->_config['curloptions'][CURLOPT_INFILESIZE] = (int)$m[1]; } unset($headers[$k]); } } if (!isset($this->_config['curloptions'][CURLOPT_INFILESIZE])) { throw new AdapterException\RuntimeException("Cannot set a file-handle for cURL option CURLOPT_INFILE without also setting its size in CURLOPT_INFILESIZE."); } if(is_resource($body)) { $body = ''; } $curlMethod = CURLOPT_PUT; } else { $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "PUT"; } break; case Client::DELETE: $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "DELETE"; break; case Client::OPTIONS: $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "OPTIONS"; break; case Client::TRACE: $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "TRACE"; break; case Client::HEAD: $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "HEAD"; break; default: throw new AdapterException\InvalidArgumentException("Method currently not supported"); } if(is_resource($body) && $curlMethod != CURLOPT_PUT) { throw new AdapterException\RuntimeException("Streaming requests are allowed only with PUT"); } $curlHttp = ($httpVersion == 1.1) ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0; curl_setopt($this->_curl, $curlHttp, true); curl_setopt($this->_curl, $curlMethod, $curlValue); if($this->out_stream) { curl_setopt($this->_curl, CURLOPT_HEADER, false); curl_setopt($this->_curl, CURLOPT_HEADERFUNCTION, array($this, "readHeader")); curl_setopt($this->_curl, CURLOPT_FILE, $this->out_stream); } else { curl_setopt($this->_curl, CURLOPT_HEADER, true); curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true); } $headers['Accept'] = ''; curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $headers); if ($method == Client::POST) { curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body); } elseif ($curlMethod == CURLOPT_PUT) { curl_setopt($this->_curl, CURLOPT_INFILE, $this->_config['curloptions'][CURLOPT_INFILE]); curl_setopt($this->_curl, CURLOPT_INFILESIZE, $this->_config['curloptions'][CURLOPT_INFILESIZE]); unset($this->_config['curloptions'][CURLOPT_INFILE]); unset($this->_config['curloptions'][CURLOPT_INFILESIZE]); } elseif ($method == Client::PUT) { curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body); } if (isset($this->_config['curloptions'])) { foreach ((array)$this->_config['curloptions'] as $k => $v) { if (!in_array($k, $this->_invalidOverwritableCurlOptions)) { if (curl_setopt($this->_curl, $k, $v) == false) { throw new AdapterException\RuntimeException(sprintf("Unknown or erroreous cURL option '%s' set", $k)); } } } } $response = curl_exec($this->_curl); if(!is_resource($this->out_stream)) { $this->_response = $response; } $request = curl_getinfo($this->_curl, CURLINFO_HEADER_OUT); $request .= $body; if (empty($this->_response)) { throw new AdapterException\RuntimeException("Error in cURL request: " . curl_error($this->_curl)); } if (stripos($this->_response, "Transfer-Encoding: chunked\r\n")) { $this->_response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $this->_response); } do { $parts = preg_split('|(?:\r?\n){2}|m', $this->_response, 2); $again = false; if (isset($parts[1]) && preg_match("|^HTTP/1\.[01](.*?)\r\n|mi", $parts[1])) { $this->_response = $parts[1]; $again = true; } } while ($again); if (stripos($this->_response, "HTTP/1.0 200 Connection established\r\n\r\n") !== false) { $this->_response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $this->_response); } return $request; } public function read() { return $this->_response; } public function close() { if(is_resource($this->_curl)) { curl_close($this->_curl); } $this->_curl = null; $this->_connected_to = array(null, null); } public function getHandle() { return $this->_curl; } public function setOutputStream($stream) { $this->out_stream = $stream; return $this; } public function readHeader($curl, $header) { $this->_response .= $header; return strlen($header); } } <?php
namespace Zend\Http\Client\Adapter\Exception; class InitializationException extends \RuntimeException implements \Zend\Http\Client\Adapter\Exception {} <?php
namespace Zend\Http\Client\Adapter\Exception; class InvalidArgumentException extends \InvalidArgumentException implements \Zend\Http\Client\Adapter\Exception {} <?php
namespace Zend\Http\Client\Adapter\Exception; class OutOfRangeException extends \OutOfRangeException implements \Zend\Http\Client\Adapter\Exception {} <?php
namespace Zend\Http\Client\Adapter\Exception; class RuntimeException extends \RuntimeException implements \Zend\Http\Client\Adapter\Exception {} <?php
namespace Zend\Http\Client\Adapter\Exception; class TimeoutException extends \RuntimeException implements \Zend\Http\Client\Adapter\Exception { const READ_TIMEOUT = 1000; } <?php
namespace Zend\Http\Client\Adapter; interface Exception extends \Zend\Http\Client\Exception {} <?php
namespace Zend\Http\Client\Adapter; use Zend\Http\Client, Zend\Http\Client\Adapter\Exception as AdapterException; class Proxy extends Socket { protected $config = array( 'ssltransport' => 'ssl', 'sslcert' => null, 'sslpassphrase' => null, 'sslusecontext' => false, 'proxy_host' => '', 'proxy_port' => 8080, 'proxy_user' => '', 'proxy_pass' => '', 'proxy_auth' => Client::AUTH_BASIC, 'persistent' => false ); protected $negotiated = false; public function connect($host, $port = 80, $secure = false) { if (! $this->config['proxy_host']) { return parent::connect($host, $port, $secure); } if ($secure) { $this->config['sslusecontext'] = true; } return parent::connect( $this->config['proxy_host'], $this->config['proxy_port'], false ); } public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') { if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body); if (! $this->socket) { throw new AdapterException\RuntimeException("Trying to write but we are not connected"); } $host = $this->config['proxy_host']; $port = $this->config['proxy_port']; if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) { throw new AdapterException\RuntimeException("Trying to write but we are connected to the wrong proxy server"); } if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) { $headers['proxy-authorization'] = Client::encodeAuthHeader( $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth'] ); } if ($uri->getScheme() == 'https' && (! $this->negotiated)) { $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers); $this->negotiated = true; } $this->method = $method; if ($this->negotiated) { $path = $uri->getPath(); if ($uri->getQuery()) { $path .= '?' . $uri->getQuery(); } $request = "$method $path HTTP/$http_ver\r\n"; } else { $request = "$method $uri HTTP/$http_ver\r\n"; } foreach ($headers as $k => $v) { if (is_string($k)) $v = "$k: $v"; $request .= "$v\r\n"; } if(is_resource($body)) { $request .= "\r\n"; } else { $request .= "\r\n" . $body; } if (! @fwrite($this->socket, $request)) { throw new AdapterException\RuntimeException("Error writing request to proxy server"); } if (is_resource($body)) { if(stream_copy_to_stream($body, $this->socket) == 0) { throw new AdapterException\RuntimeException('Error writing request to server'); } } return $request; } protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array()) { $request = "CONNECT $host:$port HTTP/$http_ver\r\n" . "Host: " . $this->config['proxy_host'] . "\r\n"; if (isset($this->config['useragent'])) { $request .= "User-agent: " . $this->config['useragent'] . "\r\n"; } if (isset($headers['proxy-authorization'])) { $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n"; unset($headers['proxy-authorization']); } $request .= "\r\n"; if (! @fwrite($this->socket, $request)) { throw new AdapterException\RuntimeException("Error writing request to proxy server"); } $response = ''; $gotStatus = false; while ($line = @fgets($this->socket)) { $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); if ($gotStatus) { $response .= $line; if (!rtrim($line)) break; } } if (\Zend\Http\Response::extractCode($response) != 200) { throw new AdapterException\RuntimeException("Unable to connect to HTTPS proxy. Server response: " . $response); } $modes = array( STREAM_CRYPTO_METHOD_TLS_CLIENT, STREAM_CRYPTO_METHOD_SSLv3_CLIENT, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, STREAM_CRYPTO_METHOD_SSLv2_CLIENT ); $success = false; foreach($modes as $mode) { $success = stream_socket_enable_crypto($this->socket, true, $mode); if ($success) break; } if (! $success) { throw new AdapterException\RuntimeException("Unable to connect to" . " HTTPS server through proxy: could not negotiate secure connection."); } } public function close() { parent::close(); $this->negotiated = false; } public function __destruct() { if ($this->socket) $this->close(); } } <?php
namespace Zend\Http\Client\Adapter; use Zend\Http\Client\Adapter as HttpAdapter, Zend\Http\Client\Adapter\Exception as AdapterException, Zend\Http\Response; class Socket implements HttpAdapter, Stream { protected $socket = null; protected $connected_to = array(null, null); protected $out_stream = null; protected $config = array( 'persistent' => false, 'ssltransport' => 'ssl', 'sslcert' => null, 'sslpassphrase' => null, 'sslusecontext' => false ); protected $method = null; protected $_context = null; public function __construct() { } public function setConfig($config = array()) { if ($config instanceof \Zend\Config\Config) { $config = $config->toArray(); } elseif (! is_array($config)) { throw new AdapterException\InvalidArgumentException( 'Array or Zend_Config object expected, got ' . gettype($config) ); } foreach ($config as $k => $v) { $this->config[strtolower($k)] = $v; } } public function getConfig() { return $this->config; } public function setStreamContext($context) { if (is_resource($context) && get_resource_type($context) == 'stream-context') { $this->_context = $context; } elseif (is_array($context)) { $this->_context = stream_context_create($context); } else { throw new AdapterException\InvalidArgumentException( "Expecting either a stream context resource or array, got " . gettype($context) ); } return $this; } public function getStreamContext() { if (! $this->_context) { $this->_context = stream_context_create(); } return $this->_context; } public function connect($host, $port = 80, $secure = false) { $host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host; if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) { if (is_resource($this->socket)) $this->close(); } if (! is_resource($this->socket) || ! $this->config['keepalive']) { $context = $this->getStreamContext(); if ($secure || $this->config['sslusecontext']) { if ($this->config['sslcert'] !== null) { if (! stream_context_set_option($context, 'ssl', 'local_cert', $this->config['sslcert'])) { throw new AdapterException\RuntimeException('Unable to set sslcert option'); } } if ($this->config['sslpassphrase'] !== null) { if (! stream_context_set_option($context, 'ssl', 'passphrase', $this->config['sslpassphrase'])) { throw new AdapterException\RuntimeException('Unable to set sslpassphrase option'); } } } $flags = STREAM_CLIENT_CONNECT; if ($this->config['persistent']) $flags |= STREAM_CLIENT_PERSISTENT; $this->socket = @stream_socket_client($host . ':' . $port, $errno, $errstr, (int) $this->config['timeout'], $flags, $context); if (! $this->socket) { $this->close(); throw new AdapterException\RuntimeException( 'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr); } if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) { throw new AdapterException\RuntimeException('Unable to set the connection timeout'); } $this->connected_to = array($host, $port); } } public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') { if (! $this->socket) { throw new AdapterException\RuntimeException('Trying to write but we are not connected'); } $host = $uri->getHost(); $host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host; if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) { throw new AdapterException\RuntimeException('Trying to write but we are connected to the wrong host'); } $this->method = $method; $path = $uri->getPath(); if ($uri->getQuery()) $path .= '?' . $uri->getQuery(); $request = "{$method} {$path} HTTP/{$http_ver}\r\n"; foreach ($headers as $k => $v) { if (is_string($k)) $v = ucfirst($k) . ": $v"; $request .= "$v\r\n"; } if(is_resource($body)) { $request .= "\r\n"; } else { $request .= "\r\n" . $body; } if (! @fwrite($this->socket, $request)) { throw new AdapterException\RuntimeException('Error writing request to server'); } if(is_resource($body)) { if(stream_copy_to_stream($body, $this->socket) == 0) { throw new AdapterException\RuntimeException('Error writing request to server'); } } return $request; } public function read() { $response = ''; $gotStatus = false; $stream = !empty($this->config['stream']); while (($line = @fgets($this->socket)) !== false) { $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); if ($gotStatus) { $response .= $line; if (rtrim($line) === '') break; } } $this->_checkSocketReadTimeout(); $statusCode = Response::extractCode($response); if ($statusCode == 100 || $statusCode == 101) return $this->read(); $headers = Response::extractHeaders($response); if ($statusCode == 304 || $statusCode == 204 || $this->method == \Zend\Http\Client::HEAD) { if (isset($headers['connection']) && $headers['connection'] == 'close') { $this->close(); } return $response; } if (isset($headers['transfer-encoding'])) { if (strtolower($headers['transfer-encoding']) == 'chunked') { do { $line = @fgets($this->socket); $this->_checkSocketReadTimeout(); $chunk = $line; $chunksize = trim($line); if (! ctype_xdigit($chunksize)) { $this->close(); throw new AdapterException\RuntimeException('Invalid chunk size "' . $chunksize . '" unable to read chunked body'); } $chunksize = hexdec($chunksize); $read_to = ftell($this->socket) + $chunksize; do { $current_pos = ftell($this->socket); if ($current_pos >= $read_to) break; if($this->out_stream) { if(stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) { $this->_checkSocketReadTimeout(); break; } } else { $line = @fread($this->socket, $read_to - $current_pos); if ($line === false || strlen($line) === 0) { $this->_checkSocketReadTimeout(); break; } $chunk .= $line; } } while (! feof($this->socket)); $chunk .= @fgets($this->socket); $this->_checkSocketReadTimeout(); if(!$this->out_stream) { $response .= $chunk; } } while ($chunksize > 0); } else { $this->close(); throw new AdapterException\RuntimeException('Cannot handle "' . $headers['transfer-encoding'] . '" transfer encoding'); } if ($this->out_stream) { $response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $response); } } elseif (isset($headers['content-length'])) { if (is_array($headers['content-length'])) { $contentLength = $headers['content-length'][count($headers['content-length']) - 1]; } else { $contentLength = $headers['content-length']; } $current_pos = ftell($this->socket); $chunk = ''; for ($read_to = $current_pos + $contentLength; $read_to > $current_pos; $current_pos = ftell($this->socket)) { if($this->out_stream) { if(@stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) { $this->_checkSocketReadTimeout(); break; } } else { $chunk = @fread($this->socket, $read_to - $current_pos); if ($chunk === false || strlen($chunk) === 0) { $this->_checkSocketReadTimeout(); break; } $response .= $chunk; } if (feof($this->socket)) break; } } else { do { if($this->out_stream) { if(@stream_copy_to_stream($this->socket, $this->out_stream) == 0) { $this->_checkSocketReadTimeout(); break; } } else { $buff = @fread($this->socket, 8192); if ($buff === false || strlen($buff) === 0) { $this->_checkSocketReadTimeout(); break; } else { $response .= $buff; } } } while (feof($this->socket) === false); $this->close(); } if (isset($headers['connection']) && $headers['connection'] == 'close') { $this->close(); } return $response; } public function close() { if (is_resource($this->socket)) @fclose($this->socket); $this->socket = null; $this->connected_to = array(null, null); } protected function _checkSocketReadTimeout() { if ($this->socket) { $info = stream_get_meta_data($this->socket); $timedout = $info['timed_out']; if ($timedout) { $this->close(); throw new AdapterException\TimeoutException( "Read timed out after {$this->config['timeout']} seconds", AdapterException\TimeoutException::READ_TIMEOUT ); } } } public function setOutputStream($stream) { $this->out_stream = $stream; return $this; } public function __destruct() { if (! $this->config['persistent']) { if ($this->socket) $this->close(); } } } <?php
namespace Zend\Http\Client\Adapter; interface Stream { function setOutputStream($stream); } <?php
namespace Zend\Http\Client\Adapter; use Zend\Http\Client\Adapter as HttpAdapter, Zend\Http\Client\Adapter\Exception as AdapterException, Zend\Http\Response; class Test implements HttpAdapter { protected $config = array(); protected $responses = array("HTTP/1.1 400 Bad Request\r\n\r\n"); protected $responseIndex = 0; protected $_nextRequestWillFail = false; public function __construct() { } public function setNextRequestWillFail($flag) { $this->_nextRequestWillFail = (bool) $flag; return $this; } public function setConfig($config = array()) { if ($config instanceof \Zend\Config\Config) { $config = $config->toArray(); } elseif (! is_array($config)) { throw new AdapterException\InvalidArgumentException( 'Array or Zend\Config\Config object expected, got ' . gettype($config) ); } foreach ($config as $k => $v) { $this->config[strtolower($k)] = $v; } } public function connect($host, $port = 80, $secure = false) { if ($this->_nextRequestWillFail) { $this->_nextRequestWillFail = false; throw new AdapterException\RuntimeException('Request failed'); } } public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') { $host = $uri->getHost(); $host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host); $path = $uri->getPath(); if (empty($path)) { $path = '/'; } if ($uri->getQuery()) $path .= '?' . $uri->getQuery(); $request = "{$method} {$path} HTTP/{$http_ver}\r\n"; foreach ($headers as $k => $v) { if (is_string($k)) $v = ucfirst($k) . ": $v"; $request .= "$v\r\n"; } $request .= "\r\n" . $body; return $request; } public function read() { if ($this->responseIndex >= count($this->responses)) { $this->responseIndex = 0; } return $this->responses[$this->responseIndex++]; } public function close() { } public function setResponse($response) { if ($response instanceof Response) { $response = $response->asString("\r\n"); } $this->responses = (array)$response; $this->responseIndex = 0; } public function addResponse($response) { if ($response instanceof Response) { $response = $response->asString("\r\n"); } $this->responses[] = $response; } public function setResponseIndex($index) { if ($index < 0 || $index >= count($this->responses)) { throw new AdapterException\OutOfRangeException( 'Index out of range of response buffer size'); } $this->responseIndex = $index; } } <?php
namespace Zend\Http\Client; interface Adapter { public function setConfig($config = array()); public function connect($host, $port = 80, $secure = false); public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = ''); public function read(); public function close(); } <?php
namespace Zend\Http\Client\Exception; class InvalidArgumentException extends \InvalidArgumentException implements \Zend\Http\Client\Exception {} <?php
namespace Zend\Http\Client\Exception; class RuntimeException extends \RuntimeException implements \Zend\Http\Client\Exception {} <?php
namespace Zend\Http\Client; interface Exception extends \Zend\Http\Exception {} <?php
namespace Zend\Http; use Zend\Config\Config, Zend\Uri; class Client { const GET = 'GET'; const POST = 'POST'; const PUT = 'PUT'; const HEAD = 'HEAD'; const DELETE = 'DELETE'; const TRACE = 'TRACE'; const OPTIONS = 'OPTIONS'; const CONNECT = 'CONNECT'; const MERGE = 'MERGE'; const AUTH_BASIC = 'basic'; const HTTP_1 = '1.1'; const HTTP_0 = '1.0'; const CONTENT_TYPE = 'Content-Type'; const CONTENT_LENGTH = 'Content-Length'; const ENC_URLENCODED = 'application/x-www-form-urlencoded'; const ENC_FORMDATA = 'multipart/form-data'; protected $config = array( 'maxredirects' => 5, 'strictredirects' => false, 'useragent' => 'Zend\\Http\\Client', 'timeout' => 10, 'adapter' => 'Zend\\Http\\Client\\Adapter\\Socket', 'httpversion' => self::HTTP_1, 'keepalive' => false, 'storeresponse' => true, 'strict' => true, 'output_stream' => false, 'encodecookies' => true, ); protected $adapter = null; protected $uri = null; protected $headers = array(); protected $method = self::GET; protected $paramsGet = array(); protected $paramsPost = array(); protected $enctype = null; protected $raw_post_data = null; protected $auth; protected $files = array(); protected $cookiejar = null; protected $last_request = null; protected $last_response = null; protected $redirectCounter = 0; static protected $_fileInfoDb = null; public function __construct($uri = null, $config = null) { if ($uri !== null) { $this->setUri($uri); } if ($config !== null) { $this->setConfig($config); } } public function setUri($uri) { if (is_string($uri)) { try { $uri = Uri\UriFactory::factory($uri, 'http'); $uri = new Uri\Uri($uri); } catch (Uri\Exception $e) { throw new Client\Exception\InvalidArgumentException('Passed parameter is not a valid HTTP URI', $e->getCode(), $e); } } $scheme = strtolower($uri->getScheme()); if (!empty($scheme) && !in_array($scheme, array('http', 'https'))) { throw new Client\Exception\InvalidArgumentException('Passed parameter is not a valid HTTP URI'); } if ($uri instanceof Uri\Http && $uri->getUser() && $uri->getPassword()) { $this->setAuth($uri->getUser(), $uri->getPassword()); } if (!$uri->getPort()) { $uri->setPort(($uri->getScheme() == 'https' ? 443 : 80)); } $this->uri = $uri; return $this; } public function getUri($as_string = false) { if ($as_string && $this->uri instanceof Uri\Uri) { return $this->uri->__toString(); } return $this->uri; } public function setConfig($config = array()) { if ($config instanceof Config) { $config = $config->toArray(); } elseif (! is_array($config)) { throw new Client\Exception\InvalidArgumentException('Array or Zend_Config object expected, got ' . gettype($config)); } foreach ($config as $k => $v) { $this->config[strtolower($k)] = $v; } if ($this->adapter instanceof Client\Adapter) { $this->adapter->setConfig($config); } return $this; } public function setMethod($method = self::GET) { if (! preg_match('/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/', $method)) { throw new Client\Exception\InvalidArgumentException("'{$method}' is not a valid HTTP request method."); } if ($method == self::POST && $this->enctype === null) { $this->setEncType(self::ENC_URLENCODED); } $this->method = $method; return $this; } public function setHeaders($name, $value = null) { if (is_array($name)) { foreach ($name as $k => $v) { if (is_string($k)) { $this->setHeaders($k, $v); } else { $this->setHeaders($v, null); } } } else { if ($value === null && (strpos($name, ':') > 0)) { list($name, $value) = explode(':', $name, 2); } if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) { throw new Client\Exception\InvalidArgumentException("{$name} is not a valid HTTP header name"); } $normalized_name = strtolower($name); if ($value === null || $value === false) { unset($this->headers[$normalized_name]); } else { if (is_string($value)) { $value = trim($value); } $this->headers[$normalized_name] = array($name, $value); } } return $this; } public function getHeader($key) { $key = strtolower($key); if (isset($this->headers[$key])) { return $this->headers[$key][1]; } else { return null; } } public function setParameterGet($name, $value = null) { if (is_array($name)) { foreach ($name as $k => $v) $this->_setParameter('GET', $k, $v); } else { $this->_setParameter('GET', $name, $value); } return $this; } public function setParameterPost($name, $value = null) { if (is_array($name)) { foreach ($name as $k => $v) $this->_setParameter('POST', $k, $v); } else { $this->_setParameter('POST', $name, $value); } return $this; } protected function _setParameter($type, $name, $value) { $parray = array(); $type = strtolower($type); switch ($type) { case 'get': $parray = &$this->paramsGet; break; case 'post': $parray = &$this->paramsPost; break; } if ($value === null) { if (isset($parray[$name])) unset($parray[$name]); } else { $parray[$name] = $value; } } public function getRedirectionsCount() { return $this->redirectCounter; } public function setAuth($user, $password = '', $type = self::AUTH_BASIC) { if ($user === false || $user === null) { $this->auth = null; if ($this->uri instanceof Uri\Http) { $this->getUri()->setUser(''); $this->getUri()->setPassword(''); } } else { if (! defined('self::AUTH_' . strtoupper($type))) { throw new Client\Exception\InvalidArgumentException("Invalid or not supported authentication type: '$type'"); } $this->auth = array( 'user' => (string) $user, 'password' => (string) $password, 'type' => $type ); } return $this; } public function setCookieJar($cookiejar = true) { if ($cookiejar instanceof CookieJar) { $this->cookiejar = $cookiejar; } elseif ($cookiejar === true) { $this->cookiejar = new CookieJar(); } elseif (! $cookiejar) { $this->cookiejar = null; } else { throw new Client\Exception\InvalidArgumentException('Invalid parameter type passed as CookieJar'); } return $this; } public function getCookieJar() { return $this->cookiejar; } public function setCookie($cookie, $value = null) { if (is_array($cookie)) { foreach ($cookie as $c => $v) { if (is_string($c)) { $this->setCookie($c, $v); } else { $this->setCookie($v); } } return $this; } if ($value !== null && $this->config['encodecookies']) { $value = urlencode($value); } if (isset($this->cookiejar)) { if ($cookie instanceof Cookie) { $this->cookiejar->addCookie($cookie); } elseif (is_string($cookie) && $value !== null) { $cookie = Cookie::fromString("{$cookie}={$value}", $this->uri, $this->config['encodecookies']); $this->cookiejar->addCookie($cookie); } } else { if ($cookie instanceof Cookie) { $name = $cookie->getName(); $value = $cookie->getValue(); $cookie = $name; } if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) { throw new Client\Exception\RuntimeException("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})"); } $value = addslashes($value); if (! isset($this->headers['cookie'])) { $this->headers['cookie'] = array('Cookie', ''); } $this->headers['cookie'][1] .= $cookie . '=' . $value . '; '; } return $this; } public function setFileUpload($filename, $formname, $data = null, $ctype = null) { if ($data === null) { if (($data = @file_get_contents($filename)) === false) { throw new Client\Exception\RuntimeException("Unable to read file '{$filename}' for upload"); } if (! $ctype) { $ctype = $this->_detectFileMimeType($filename); } } $this->setEncType(self::ENC_FORMDATA); $this->files[] = array( 'formname' => $formname, 'filename' => basename($filename), 'ctype' => $ctype, 'data' => $data ); return $this; } public function setEncType($enctype = self::ENC_URLENCODED) { $this->enctype = $enctype; return $this; } public function setRawData($data, $enctype = null) { $this->raw_post_data = $data; $this->setEncType($enctype); if (is_resource($data)) { $stat = @fstat($data); if($stat) { $this->setHeaders(self::CONTENT_LENGTH, $stat['size']); } } return $this; } public function resetParameters($clearAll = false) { $this->paramsGet = array(); $this->paramsPost = array(); $this->files = array(); $this->raw_post_data = null; if($clearAll) { $this->headers = array(); $this->last_request = null; $this->last_response = null; } else { if (isset($this->headers[strtolower(self::CONTENT_TYPE)])) { unset($this->headers[strtolower(self::CONTENT_TYPE)]); } if (isset($this->headers[strtolower(self::CONTENT_LENGTH)])) { unset($this->headers[strtolower(self::CONTENT_LENGTH)]); } } return $this; } public function getLastRequest() { return $this->last_request; } public function getLastResponse() { return $this->last_response; } public function setAdapter($adapter) { if (is_string($adapter)) { if (!class_exists($adapter)) { throw new Client\Exception\InvalidArgumentException('Unable to locate adapter class "' . $adapter . '"'); } $adapter = new $adapter; } if (! $adapter instanceof Client\Adapter) { throw new Client\Exception\InvalidArgumentException('Passed adapter is not a HTTP connection adapter'); } $this->adapter = $adapter; $config = $this->config; unset($config['adapter']); $this->adapter->setConfig($config); } public function getAdapter() { return $this->adapter; } public function setStream($streamfile = true) { $this->setConfig(array("output_stream" => $streamfile)); return $this; } public function getStream() { return $this->config["output_stream"]; } protected function _openTempStream() { $this->_stream_name = $this->config['output_stream']; if(!is_string($this->_stream_name)) { $this->_stream_name = tempnam(isset($this->config['stream_tmp_dir'])?$this->config['stream_tmp_dir']:sys_get_temp_dir(), 'Zend_Http_Client'); } if (false === ($fp = @fopen($this->_stream_name, "w+b"))) { if ($this->adapter instanceof Client\Adapter) { $this->adapter->close(); } throw new Client\Exception\RuntimeException("Could not open temp file {$this->_stream_name}"); } return $fp; } public function request($method = null) { if (!$this->uri instanceof Uri\Uri) { throw new Client\Exception\RuntimeException('No valid URI has been passed to the client'); } if ($method) { $this->setMethod($method); } $this->redirectCounter = 0; $response = null; if ($this->adapter == null) { $this->setAdapter($this->config['adapter']); } do { $uri = clone $this->uri; if (!empty($this->paramsGet)) { $query = $uri->getQuery(); if (! empty($query)) { $query .= '&'; } $query .= http_build_query($this->paramsGet, null, '&'); $uri->setQuery($query); } $body = $this->_prepareBody(); $headers = $this->_prepareHeaders(); if(is_resource($body) && !($this->adapter instanceof Client\Adapter\Stream)) { throw new Client\Exception\RuntimeException('Adapter does not support streaming'); } $this->adapter->connect($uri->getHost(), $uri->getPort(), ($uri->getScheme() == 'https' ? true : false)); if($this->config['output_stream']) { if($this->adapter instanceof Client\Adapter\Stream) { $stream = $this->_openTempStream(); $this->adapter->setOutputStream($stream); } else { throw new Client\Exception\RuntimeException('Adapter does not support streaming'); } } $this->last_request = $this->adapter->write($this->method, $uri, $this->config['httpversion'], $headers, $body); $response = $this->adapter->read(); if (! $response) { throw new Client\Exception\RuntimeException('Unable to read response, or response is empty'); } if($this->config['output_stream']) { rewind($stream); $this->adapter->setOutputStream(null); $response = Response\Stream::fromStream($response, $stream); $response->setStreamName($this->_stream_name); if(!is_string($this->config['output_stream'])) { $response->setCleanup(true); } } else { $response = Response::fromString($response); } if ($this->config['storeresponse']) { $this->last_response = $response; } if (isset($this->cookiejar)) { $this->cookiejar->addCookiesFromResponse($response, $uri); } if ($response->isRedirect() && ($location = $response->getHeader('location'))) { if ($response->getStatus() == 303 || ((! $this->config['strictredirects']) && ($response->getStatus() == 302 || $response->getStatus() == 301))) { $this->resetParameters(); $this->setMethod(self::GET); } $url = Uri\UriFactory::factory($location, 'http'); if ($url->isValid()) { $this->setHeaders('host', null); $this->setUri($location); } else { if (strpos($location, '?') !== false) { list($location, $query) = explode('?', $location, 2); } else { $query = ''; } $this->uri->setQuery($query); if(strpos($location, '/') === 0) { $this->uri->setPath($location); } else { $path = $this->uri->getPath(); $path = rtrim(substr($path, 0, strrpos($path, '/')), "/"); $this->uri->setPath($path . '/' . $location); } } ++$this->redirectCounter; } else { break; } } while ($this->redirectCounter < $this->config['maxredirects']); return $response; } protected function _prepareHeaders() { $headers = array(); if (! isset($this->headers['host'])) { $host = $this->uri->getHost(); if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) || ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) { $host .= ':' . $this->uri->getPort(); } $headers[] = "Host: {$host}"; } if (! isset($this->headers['connection'])) { if (! $this->config['keepalive']) { $headers[] = "Connection: close"; } } if (! isset($this->headers['accept-encoding'])) { if (function_exists('gzinflate')) { $headers[] = 'Accept-encoding: gzip, deflate'; } else { $headers[] = 'Accept-encoding: identity'; } } if ($this->method == self::POST && (! isset($this->headers[strtolower(self::CONTENT_TYPE)]) && isset($this->enctype))) { $headers[] = self::CONTENT_TYPE . ': ' . $this->enctype; } if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) { $headers[] = "User-Agent: {$this->config['useragent']}"; } if (is_array($this->auth)) { $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']); $headers[] = "Authorization: {$auth}"; } if (isset($this->cookiejar)) { $cookstr = $this->cookiejar->getMatchingCookies($this->uri, true, CookieJar::COOKIE_STRING_CONCAT); if ($cookstr) { $headers[] = "Cookie: {$cookstr}"; } } foreach ($this->headers as $header) { list($name, $value) = $header; if (is_array($value)) { $value = implode(', ', $value); } $headers[] = "$name: $value"; } return $headers; } protected function _prepareBody() { if ($this->method == self::TRACE) { return ''; } if (isset($this->raw_post_data) && is_resource($this->raw_post_data)) { return $this->raw_post_data; } if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbIntEnc = mb_internal_encoding(); mb_internal_encoding('ASCII'); } if (isset($this->raw_post_data)) { $this->setHeaders(self::CONTENT_LENGTH, strlen($this->raw_post_data)); if (isset($mbIntEnc)) { mb_internal_encoding($mbIntEnc); } return $this->raw_post_data; } $body = ''; if (count ($this->files) > 0) { $this->setEncType(self::ENC_FORMDATA); } if (count($this->paramsPost) > 0 || count($this->files) > 0) { switch($this->enctype) { case self::ENC_FORMDATA: $boundary = '---ZENDHTTPCLIENT-' . md5(microtime()); $this->setHeaders(self::CONTENT_TYPE, self::ENC_FORMDATA . "; boundary={$boundary}"); $params = self::_flattenParametersArray($this->paramsPost); foreach ($params as $pp) { $body .= self::encodeFormData($boundary, $pp[0], $pp[1]); } foreach ($this->files as $file) { $fhead = array(self::CONTENT_TYPE => $file['ctype']); $body .= self::encodeFormData($boundary, $file['formname'], $file['data'], $file['filename'], $fhead); } $body .= "--{$boundary}--\r\n"; break; case self::ENC_URLENCODED: $this->setHeaders(self::CONTENT_TYPE, self::ENC_URLENCODED); $body = http_build_query($this->paramsPost, '', '&'); break; default: if (isset($mbIntEnc)) { mb_internal_encoding($mbIntEnc); } throw new Client\Exception\RuntimeException("Cannot handle content type '{$this->enctype}' automatically." . " Please use Zend_Http_Client::setRawData to send this kind of content."); break; } } if ($body || $this->method == self::POST || $this->method == self::PUT) { $this->setHeaders(self::CONTENT_LENGTH, strlen($body)); } if (isset($mbIntEnc)) { mb_internal_encoding($mbIntEnc); } return $body; } protected function _getParametersRecursive($parray, $urlencode = false) { trigger_error("The " . __METHOD__ . " method is deprecated and will be dropped in 2.0.", E_USER_NOTICE); if (! is_array($parray)) { return $parray; } $parameters = array(); foreach ($parray as $name => $value) { if ($urlencode) { $name = urlencode($name); } if (is_array($value)) { $name .= ($urlencode ? '%5B%5D' : '[]'); foreach ($value as $subval) { if ($urlencode) { $subval = urlencode($subval); } $parameters[] = array($name, $subval); } } else { if ($urlencode) { $value = urlencode($value); } $parameters[] = array($name, $value); } } return $parameters; } protected function _detectFileMimeType($file) { $type = null; if (function_exists('finfo_open')) { if (self::$_fileInfoDb === null) { self::$_fileInfoDb = @finfo_open(FILEINFO_MIME); } if (self::$_fileInfoDb) { $type = finfo_file(self::$_fileInfoDb, $file); } } elseif (function_exists('mime_content_type')) { $type = mime_content_type($file); } if (! $type) { $type = 'application/octet-stream'; } return $type; } public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) { $ret = "--{$boundary}\r\n" . 'Content-Disposition: form-data; name="' . $name .'"'; if ($filename) { $ret .= '; filename="' . $filename . '"'; } $ret .= "\r\n"; foreach ($headers as $hname => $hvalue) { $ret .= "{$hname}: {$hvalue}\r\n"; } $ret .= "\r\n"; $ret .= "{$value}\r\n"; return $ret; } public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC) { $authHeader = null; switch ($type) { case self::AUTH_BASIC: if (strpos($user, ':') !== false) { throw new Client\Exception\InvalidArgumentException("The user name cannot contain ':' in 'Basic' HTTP authentication"); } $authHeader = 'Basic ' . base64_encode($user . ':' . $password); break; default: throw new Client\Exception\InvalidArgumentException("Not a supported HTTP authentication type: '$type'"); } return $authHeader; } static protected function _flattenParametersArray($parray, $prefix = null) { if (! is_array($parray)) { return $parray; } $parameters = array(); foreach($parray as $name => $value) { if ($prefix) { if (is_int($name)) { $key = $prefix . '[]'; } else { $key = $prefix . "[$name]"; } } else { $key = $name; } if (is_array($value)) { $parameters = array_merge($parameters, self::_flattenParametersArray($value, $key)); } else { $parameters[] = array($key, $value); } } return $parameters; } } <?php
namespace Zend\Http; use Zend\Uri; class Cookie { protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encodeValue; public function __construct($name, $value, $domain, $expires = null, $path = null, $secure = false) { if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { throw new Exception\InvalidArgumentException("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})"); } if (! $this->name = (string) $name) { throw new Exception\InvalidArgumentException('Cookies must have a name'); } if (! $this->domain = (string) $domain) { throw new Exception\InvalidArgumentException('Cookies must have a domain'); } $this->value = (string) $value; $this->expires = ($expires === null ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; } public function getName() { return $this->name; } public function getValue() { return $this->value; } public function getDomain() { return $this->domain; } public function getPath() { return $this->path; } public function getExpiryTime() { return $this->expires; } public function isSecure() { return $this->secure; } public function isExpired($now = null) { if ($now === null) $now = time(); if (is_int($this->expires) && $this->expires < $now) { return true; } else { return false; } } public function isSessionCookie() { return ($this->expires === null); } public function match($uri, $matchSessionCookies = true, $now = null) { if (is_string ($uri)) { $uri = Uri\UriFactory::factory($uri, 'http'); } if (!$uri instanceof Uri\Uri) { throw new Exception\InvalidArgumentException('Invalid URI provided; does not implement Zend\Uri\Uri'); } $scheme = $uri->getScheme(); if (! ($uri->isValid() && ($scheme == 'http' || $scheme =='https'))) { throw new Exception\InvalidArgumentException('Passed URI is not a valid HTTP or HTTPS URI'); } if ($this->secure && $scheme != 'https') { return false; } if ($this->isExpired($now)) { return false; } if ($this->isSessionCookie() && ! $matchSessionCookies) { return false; } if (! self::matchCookieDomain($this->getDomain(), $uri->getHost())) { return false; } if (! self::matchCookiePath($this->getPath(), $uri->getPath())) { return false; } return true; } public function __toString() { if ($this->encodeValue) { return $this->name . '=' . urlencode($this->value) . ';'; } return $this->name . '=' . $this->value . ';'; } public static function fromString($cookieStr, $refUri = null, $encodeValue = true) { if (is_string($refUri)) { $refUri = Uri\UriFactory::factory($refUri, 'http'); } $name = ''; $value = ''; $domain = ''; $path = ''; $expires = null; $secure = false; $parts = explode(';', $cookieStr); if (strpos($parts[0], '=') === false) return false; list($name, $value) = explode('=', trim(array_shift($parts)), 2); $name = trim($name); if ($encodeValue) { $value = urldecode(trim($value)); } if ($refUri instanceof Uri\Uri) { $domain = $refUri->getHost(); $path = $refUri->getPath(); $path = substr($path, 0, strrpos($path, '/')); } foreach ($parts as $part) { $part = trim($part); if (strtolower($part) == 'secure') { $secure = true; continue; } $keyValue = explode('=', $part, 2); if (count($keyValue) == 2) { list($k, $v) = $keyValue; switch (strtolower($k)) { case 'expires': if(($expires = strtotime($v)) === false) { $expireDate = new \Zend\Date\Date($v); $expires = $expireDate->getTimestamp(); } break; case 'path': $path = $v; break; case 'domain': $domain = $v; break; default: break; } } } if ($name !== '') { $ret = new self($name, $value, $domain, $expires, $path, $secure); $ret->encodeValue = ($encodeValue) ? true : false; return $ret; } else { return false; } } public static function matchCookieDomain($cookieDomain, $host) { if (! $cookieDomain) { throw new Exception\InvalidArgumentException("\$cookieDomain is expected to be a cookie domain"); } if (! $host) { throw new Exception\InvalidArgumentException("\$host is expected to be a host name"); } $cookieDomain = strtolower($cookieDomain); $host = strtolower($host); if ($cookieDomain[0] == '.') { $cookieDomain = substr($cookieDomain, 1); } return ($cookieDomain == $host || preg_match("/\.$cookieDomain$/", $host)); } public static function matchCookiePath($cookiePath, $path) { if (! $cookiePath) { throw new Exception\InvalidArgumentException("\$cookiePath is expected to be a cookie path"); } if ((null !== $path) && (!is_scalar($path) || is_numeric($path) || is_bool($path))) { throw new Exception\InvalidArgumentException("\$path is expected to be a cookie path"); } $path = (string) $path; if (empty($path)) { $path = '/'; } return (strpos($path, $cookiePath) === 0); } } <?php
namespace Zend\Http; use Countable, IteratorAggregate, Zend\Uri; class CookieJar implements Countable, IteratorAggregate { const COOKIE_OBJECT = 0; const COOKIE_STRING_ARRAY = 1; const COOKIE_STRING_CONCAT = 2; protected $cookies = array(); protected $_rawCookies = array(); public function __construct() { } public function addCookie($cookie, $ref_uri = null) { if (is_string($cookie)) { $cookie = Cookie::fromString($cookie, $ref_uri); } if ($cookie instanceof Cookie) { $domain = $cookie->getDomain(); $path = $cookie->getPath(); if (!isset($this->cookies[$domain])) { $this->cookies[$domain] = array(); } if (!isset($this->cookies[$domain][$path])) { $this->cookies[$domain][$path] = array(); } $this->cookies[$domain][$path][$cookie->getName()] = $cookie; $this->_rawCookies[] = $cookie; } else { throw new Exception\InvalidArgumentException('Supplient argument is not a valid cookie string or object'); } } public function addCookiesFromResponse($response, $ref_uri) { if (!$response instanceof Response) { throw new Exception\InvalidArgumentException('$response is expected to be a Response object, ' . gettype($response) . ' was passed'); } $cookie_hdrs = $response->getHeader('Set-Cookie'); if (is_array($cookie_hdrs)) { foreach ($cookie_hdrs as $cookie) { $this->addCookie($cookie, $ref_uri); } } elseif (is_string($cookie_hdrs)) { $this->addCookie($cookie_hdrs, $ref_uri); } } public function getAllCookies($ret_as = self::COOKIE_OBJECT) { $cookies = $this->_flattenCookiesArray($this->cookies, $ret_as); return $cookies; } public function getMatchingCookies($uri, $matchSessionCookies = true, $ret_as = self::COOKIE_OBJECT, $now = null) { if (is_string($uri)) { $uri = Uri\UriFactory::factory($uri, 'http'); } if (!$uri instanceof Uri\Uri) { throw new Exception\InvalidArgumentException("Invalid URI string or object passed"); } $host = $uri->getHost(); if (empty($host)) { throw new Exception\InvalidArgumentException('Invalid URI specified; does not contain a host'); } $cookies = $this->_matchDomain($host); $cookies = $this->_matchPath($cookies, $uri->getPath()); $cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT); $ret = array(); foreach ($cookies as $cookie) if ($cookie->match($uri, $matchSessionCookies, $now)) $ret[] = $cookie; $ret = $this->_flattenCookiesArray($ret, $ret_as); return $ret; } public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT) { if (is_string($uri)) { $uri = Uri\UriFactory::factory($uri, 'http'); } if (!$uri instanceof Uri\Uri) { throw new Exception\InvalidArgumentException('Invalid URI specified'); } $host = $uri->getHost(); if (empty($host)) { throw new Exception\InvalidArgumentException('Invalid URI specified; host missing'); } $path = $uri->getPath(); $path = substr($path, 0, strrpos($path, '/')); if (! $path) $path = '/'; if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) { $cookie = $this->cookies[$uri->getHost()][$path][$cookie_name]; switch ($ret_as) { case self::COOKIE_OBJECT: return $cookie; break; case self::COOKIE_STRING_ARRAY: case self::COOKIE_STRING_CONCAT: return $cookie->__toString(); break; default: throw new Exception\InvalidArgumentException("Invalid value passed for \$ret_as: {$ret_as}"); break; } } else { return false; } } protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) { if (is_array($ptr)) { $ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array()); foreach ($ptr as $item) { if ($ret_as == self::COOKIE_STRING_CONCAT) { $ret .= $this->_flattenCookiesArray($item, $ret_as); } else { $ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as)); } } return $ret; } elseif ($ptr instanceof Cookie) { switch ($ret_as) { case self::COOKIE_STRING_ARRAY: return array($ptr->__toString()); break; case self::COOKIE_STRING_CONCAT: return $ptr->__toString(); break; case self::COOKIE_OBJECT: default: return array($ptr); break; } } return null; } protected function _matchDomain($domain) { $ret = array(); foreach (array_keys($this->cookies) as $cdom) { if (Cookie::matchCookieDomain($cdom, $domain)) { $ret[$cdom] = $this->cookies[$cdom]; } } return $ret; } protected function _matchPath($domains, $path) { $ret = array(); foreach ($domains as $dom => $paths_array) { foreach (array_keys($paths_array) as $cpath) { if (Cookie::matchCookiePath($cpath, $path)) { if (! isset($ret[$dom])) { $ret[$dom] = array(); } $ret[$dom][$cpath] = $paths_array[$cpath]; } } } return $ret; } public static function fromResponse(Response $response, $ref_uri) { $jar = new self(); $jar->addCookiesFromResponse($response, $ref_uri); return $jar; } public function count() { return count($this->_rawCookies); } public function getIterator() { return new \ArrayIterator($this->_rawCookies); } public function isEmpty() { return count($this) == 0; } public function reset() { $this->cookies = $this->_rawCookies = array(); return $this; } } <?php
namespace Zend\Http\Exception; class InvalidArgumentException extends \InvalidArgumentException implements \Zend\Http\Exception {} <?php
namespace Zend\Http\Exception; class RuntimeException extends \RuntimeException implements \Zend\Http\Exception {} <?php
namespace Zend\Http; interface Exception {} <?php
namespace Zend\Http\Response; use Zend\Http\Response; class Stream extends Response { protected $stream; protected $stream_name; protected $_cleanup; public function getStream() { return $this->stream; } public function setStream($stream) { $this->stream = $stream; return $this; } public function getCleanup() { return $this->_cleanup; } public function setCleanup($cleanup = true) { $this->_cleanup = $cleanup; } public function getStreamName() { return $this->stream_name; } public function setStreamName($stream_name) { $this->stream_name = $stream_name; return $this; } public function __construct($code, $headers, $body = null, $version = '1.1', $message = null) { if(is_resource($body)) { $this->setStream($body); $body = ''; } parent::__construct($code, $headers, $body, $version, $message); } public static function fromStream($response_str, $stream) { $code = self::extractCode($response_str); $headers = self::extractHeaders($response_str); $version = self::extractVersion($response_str); $message = self::extractMessage($response_str); return new self($code, $headers, $stream, $version, $message); } public function getBody() { if($this->stream != null) { $this->readStream(); } return parent::getBody(); } public function getRawBody() { if($this->stream) { $this->readStream(); } return $this->body; } protected function readStream() { if(!is_resource($this->stream)) { return ''; } if(isset($headers['content-length'])) { $this->body = stream_get_contents($this->stream, $headers['content-length']); } else { $this->body = stream_get_contents($this->stream); } fclose($this->stream); $this->stream = null; } public function __destruct() { if(is_resource($this->stream)) { fclose($this->stream); $this->stream = null; } if($this->_cleanup) { @unlink($this->stream_name); } } } <?php
namespace Zend\Http; class Response { protected static $messages = array( 100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 509 => 'Bandwidth Limit Exceeded' ); protected $version; protected $code; protected $message; protected $headers = array(); protected $body; public function __construct($code, $headers, $body = null, $version = '1.1', $message = null) { if (self::responseCodeAsText($code) === null) { throw new Exception\InvalidArgumentException("{$code} is not a valid HTTP response code"); } $this->code = $code; if (! is_array($headers)) { throw new Exception\InvalidArgumentException('No valid headers were passed'); } foreach ($headers as $name => $value) { if (is_int($name)) list($name, $value) = explode(": ", $value, 1); $this->headers[ucwords(strtolower($name))] = $value; } $this->body = $body; if (! preg_match('|^\d\.\d$|', $version)) { throw new Exception\InvalidArgumentException("Invalid HTTP response version: $version"); } $this->version = $version; if (is_string($message)) { $this->message = $message; } else { $this->message = self::responseCodeAsText($code); } } public function isError() { $restype = floor($this->code / 100); if ($restype == 4 || $restype == 5) { return true; } return false; } public function isSuccessful() { $restype = floor($this->code / 100); if ($restype == 2 || $restype == 1) { return true; } return false; } public function isRedirect() { $restype = floor($this->code / 100); if ($restype == 3) { return true; } return false; } public function getBody() { $body = ''; switch (strtolower($this->getHeader('transfer-encoding'))) { case 'chunked': $body = self::decodeChunkedBody($this->body); break; default: $body = $this->body; break; } switch (strtolower($this->getHeader('content-encoding'))) { case 'gzip': $body = self::decodeGzip($body); break; case 'deflate': $body = self::decodeDeflate($body); break; default: break; } return $body; } public function getRawBody() { return $this->body; } public function getVersion() { return $this->version; } public function getStatus() { return $this->code; } public function getMessage() { return $this->message; } public function getHeaders() { return $this->headers; } public function getHeader($header) { $header = ucwords(strtolower($header)); if (! is_string($header) || ! isset($this->headers[$header])) return null; return $this->headers[$header]; } public function getHeadersAsString($status_line = true, $br = "\n") { $str = ''; if ($status_line) { $str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}"; } foreach ($this->headers as $name => $value) { if (is_string($value)) $str .= "{$name}: {$value}{$br}"; elseif (is_array($value)) { foreach ($value as $subval) { $str .= "{$name}: {$subval}{$br}"; } } } return $str; } public function asString($br = "\n") { return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody(); } public function __toString() { return $this->asString(); } public static function responseCodeAsText($code = null, $http11 = true) { $messages = self::$messages; if (! $http11) $messages[302] = 'Moved Temporarily'; if ($code === null) { return $messages; } elseif (isset($messages[$code])) { return $messages[$code]; } else { return 'Unknown'; } } public static function extractCode($response_str) { preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m); if (isset($m[1])) { return (int) $m[1]; } else { return false; } } public static function extractMessage($response_str) { preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m); if (isset($m[1])) { return $m[1]; } else { return false; } } public static function extractVersion($response_str) { preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m); if (isset($m[1])) { return $m[1]; } else { return false; } } public static function extractHeaders($response_str) { $headers = array(); $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2); if (! $parts[0]) return $headers; $lines = explode("\n", $parts[0]); unset($parts); $last_header = null; foreach($lines as $line) { $line = trim($line, "\r\n"); if ($line == "") break; if (preg_match("|^([\w-]+):\s*(.+)|", $line, $m)) { unset($last_header); $h_name = strtolower($m[1]); $h_value = $m[2]; if (isset($headers[$h_name])) { if (! is_array($headers[$h_name])) { $headers[$h_name] = array($headers[$h_name]); } $headers[$h_name][] = $h_value; } else { $headers[$h_name] = $h_value; } $last_header = $h_name; } elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) { if (is_array($headers[$last_header])) { end($headers[$last_header]); $last_header_key = key($headers[$last_header]); $headers[$last_header][$last_header_key] .= $m[1]; } else { $headers[$last_header] .= $m[1]; } } } return $headers; } public static function extractBody($response_str) { $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2); if (isset($parts[1])) { return $parts[1]; } return ''; } public static function decodeChunkedBody($body) { $decBody = ''; if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbIntEnc = mb_internal_encoding(); mb_internal_encoding('ASCII'); } while (trim($body)) { if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) { throw new Exception\RuntimeException("Error parsing body - doesn't seem to be a chunked message"); } $length = hexdec(trim($m[1])); $cut = strlen($m[0]); $decBody .= substr($body, $cut, $length); $body = substr($body, $cut + $length + 2); } if (isset($mbIntEnc)) { mb_internal_encoding($mbIntEnc); } return $decBody; } public static function decodeGzip($body) { if (! function_exists('gzinflate')) { throw new Exception\RuntimeException( 'zlib extension is required in order to decode "gzip" encoding' ); } return gzinflate(substr($body, 10)); } public static function decodeDeflate($body) { if (! function_exists('gzuncompress')) { throw new Exception\RuntimeException( 'zlib extension is required in order to decode "deflate" encoding' ); } $zlibHeader = unpack('n', substr($body, 0, 2)); if ($zlibHeader[1] % 31 == 0) { return gzuncompress($body); } else { return gzinflate($body); } } public static function fromString($response_str) { $code = self::extractCode($response_str); $headers = self::extractHeaders($response_str); $body = self::extractBody($response_str); $version = self::extractVersion($response_str); $message = self::extractMessage($response_str); return new Response($code, $headers, $body, $version, $message); } } <?php
/*
* This file is part of the Goutte utility.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/ require_once __DIR__.'/autoload.php'; __HALT_COMPILER();<?php throw new \LogicException('This PHAR file can only be used from the CLI.'); __HALT_COMPILER();gᄥOJ8L<38>| <20>`<60>̥<00><17>GBMB