PageRenderTime 135ms CodeModel.GetById 46ms RepoModel.GetById 0ms app.codeStats 0ms

/goutte.phar

https://github.com/ornicar/Goutte
Unknown | 292 lines | 259 code | 33 blank | 0 comment | 0 complexity | 6ff143d60302095e9d0f35485f3829bb MD5 | raw file
  1. <?php
  2. $web = '_web_stub.php';
  3. if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
  4. Phar::interceptFileFuncs();
  5. set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
  6. Phar::webPhar(null, $web);
  7. include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
  8. return;
  9. }
  10. if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
  11. Extract_Phar::go(true);
  12. $mimes = array(
  13. 'phps' => 2,
  14. 'c' => 'text/plain',
  15. 'cc' => 'text/plain',
  16. 'cpp' => 'text/plain',
  17. 'c++' => 'text/plain',
  18. 'dtd' => 'text/plain',
  19. 'h' => 'text/plain',
  20. 'log' => 'text/plain',
  21. 'rng' => 'text/plain',
  22. 'txt' => 'text/plain',
  23. 'xsd' => 'text/plain',
  24. 'php' => 1,
  25. 'inc' => 1,
  26. 'avi' => 'video/avi',
  27. 'bmp' => 'image/bmp',
  28. 'css' => 'text/css',
  29. 'gif' => 'image/gif',
  30. 'htm' => 'text/html',
  31. 'html' => 'text/html',
  32. 'htmls' => 'text/html',
  33. 'ico' => 'image/x-ico',
  34. 'jpe' => 'image/jpeg',
  35. 'jpg' => 'image/jpeg',
  36. 'jpeg' => 'image/jpeg',
  37. 'js' => 'application/x-javascript',
  38. 'midi' => 'audio/midi',
  39. 'mid' => 'audio/midi',
  40. 'mod' => 'audio/mod',
  41. 'mov' => 'movie/quicktime',
  42. 'mp3' => 'audio/mp3',
  43. 'mpg' => 'video/mpeg',
  44. 'mpeg' => 'video/mpeg',
  45. 'pdf' => 'application/pdf',
  46. 'png' => 'image/png',
  47. 'swf' => 'application/shockwave-flash',
  48. 'tif' => 'image/tiff',
  49. 'tiff' => 'image/tiff',
  50. 'wav' => 'audio/wav',
  51. 'xbm' => 'image/xbm',
  52. 'xml' => 'text/xml',
  53. );
  54. header("Cache-Control: no-cache, must-revalidate");
  55. header("Pragma: no-cache");
  56. $basename = basename(__FILE__);
  57. if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
  58. chdir(Extract_Phar::$temp);
  59. include $web;
  60. return;
  61. }
  62. $pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
  63. if (!$pt || $pt == '/') {
  64. $pt = $web;
  65. header('HTTP/1.1 301 Moved Permanently');
  66. header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
  67. exit;
  68. }
  69. $a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
  70. if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
  71. header('HTTP/1.0 404 Not Found');
  72. 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>";
  73. exit;
  74. }
  75. $b = pathinfo($a);
  76. if (!isset($b['extension'])) {
  77. header('Content-Type: text/plain');
  78. header('Content-Length: ' . filesize($a));
  79. readfile($a);
  80. exit;
  81. }
  82. if (isset($mimes[$b['extension']])) {
  83. if ($mimes[$b['extension']] === 1) {
  84. include $a;
  85. exit;
  86. }
  87. if ($mimes[$b['extension']] === 2) {
  88. highlight_file($a);
  89. exit;
  90. }
  91. header('Content-Type: ' .$mimes[$b['extension']]);
  92. header('Content-Length: ' . filesize($a));
  93. readfile($a);
  94. exit;
  95. }
  96. }
  97. class Extract_Phar
  98. {
  99. static $temp;
  100. static $origdir;
  101. const GZ = 0x1000;
  102. const BZ2 = 0x2000;
  103. const MASK = 0x3000;
  104. const START = '_cli_stub.php';
  105. const LEN = 6693;
  106. static function go($return = false)
  107. {
  108. $fp = fopen(__FILE__, 'rb');
  109. fseek($fp, self::LEN);
  110. $L = unpack('V', $a = (binary)fread($fp, 4));
  111. $m = (binary)'';
  112. do {
  113. $read = 8192;
  114. if ($L[1] - strlen($m) < 8192) {
  115. $read = $L[1] - strlen($m);
  116. }
  117. $last = (binary)fread($fp, $read);
  118. $m .= $last;
  119. } while (strlen($last) && strlen($m) < $L[1]);
  120. if (strlen($m) < $L[1]) {
  121. die('ERROR: manifest length read was "' .
  122. strlen($m) .'" should be "' .
  123. $L[1] . '"');
  124. }
  125. $info = self::_unpack($m);
  126. $f = $info['c'];
  127. if ($f & self::GZ) {
  128. if (!function_exists('gzinflate')) {
  129. die('Error: zlib extension is not enabled -' .
  130. ' gzinflate() function needed for zlib-compressed .phars');
  131. }
  132. }
  133. if ($f & self::BZ2) {
  134. if (!function_exists('bzdecompress')) {
  135. die('Error: bzip2 extension is not enabled -' .
  136. ' bzdecompress() function needed for bz2-compressed .phars');
  137. }
  138. }
  139. $temp = self::tmpdir();
  140. if (!$temp || !is_writable($temp)) {
  141. $sessionpath = session_save_path();
  142. if (strpos ($sessionpath, ";") !== false)
  143. $sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
  144. if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
  145. die('Could not locate temporary directory to extract phar');
  146. }
  147. $temp = $sessionpath;
  148. }
  149. $temp .= '/pharextract/'.basename(__FILE__, '.phar');
  150. self::$temp = $temp;
  151. self::$origdir = getcwd();
  152. @mkdir($temp, 0777, true);
  153. $temp = realpath($temp);
  154. if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
  155. self::_removeTmpFiles($temp, getcwd());
  156. @mkdir($temp, 0777, true);
  157. @file_put_contents($temp . '/' . md5_file(__FILE__), '');
  158. foreach ($info['m'] as $path => $file) {
  159. $a = !file_exists(dirname($temp . '/' . $path));
  160. @mkdir(dirname($temp . '/' . $path), 0777, true);
  161. clearstatcache();
  162. if ($path[strlen($path) - 1] == '/') {
  163. @mkdir($temp . '/' . $path, 0777);
  164. } else {
  165. file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
  166. @chmod($temp . '/' . $path, 0666);
  167. }
  168. }
  169. }
  170. chdir($temp);
  171. if (!$return) {
  172. include self::START;
  173. }
  174. }
  175. static function tmpdir()
  176. {
  177. if (strpos(PHP_OS, 'WIN') !== false) {
  178. if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
  179. return $var;
  180. }
  181. if (is_dir('/temp') || mkdir('/temp')) {
  182. return realpath('/temp');
  183. }
  184. return false;
  185. }
  186. if ($var = getenv('TMPDIR')) {
  187. return $var;
  188. }
  189. return realpath('/tmp');
  190. }
  191. static function _unpack($m)
  192. {
  193. $info = unpack('V', substr($m, 0, 4));
  194. $l = unpack('V', substr($m, 10, 4));
  195. $m = substr($m, 14 + $l[1]);
  196. $s = unpack('V', substr($m, 0, 4));
  197. $o = 0;
  198. $start = 4 + $s[1];
  199. $ret['c'] = 0;
  200. for ($i = 0; $i < $info[1]; $i++) {
  201. $len = unpack('V', substr($m, $start, 4));
  202. $start += 4;
  203. $savepath = substr($m, $start, $len[1]);
  204. $start += $len[1];
  205. $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
  206. $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
  207. & 0xffffffff);
  208. $ret['m'][$savepath][7] = $o;
  209. $o += $ret['m'][$savepath][2];
  210. $start += 24 + $ret['m'][$savepath][5];
  211. $ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
  212. }
  213. return $ret;
  214. }
  215. static function extractFile($path, $entry, $fp)
  216. {
  217. $data = '';
  218. $c = $entry[2];
  219. while ($c) {
  220. if ($c < 8192) {
  221. $data .= @fread($fp, $c);
  222. $c = 0;
  223. } else {
  224. $c -= 8192;
  225. $data .= @fread($fp, 8192);
  226. }
  227. }
  228. if ($entry[4] & self::GZ) {
  229. $data = gzinflate($data);
  230. } elseif ($entry[4] & self::BZ2) {
  231. $data = bzdecompress($data);
  232. }
  233. if (strlen($data) != $entry[0]) {
  234. die("Invalid internal .phar file (size error " . strlen($data) . " != " .
  235. $stat[7] . ")");
  236. }
  237. if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
  238. die("Invalid internal .phar file (checksum error)");
  239. }
  240. return $data;
  241. }
  242. static function _removeTmpFiles($temp, $origdir)
  243. {
  244. chdir($temp);
  245. foreach (glob('*') as $f) {
  246. if (file_exists($f)) {
  247. is_dir($f) ? @rmdir($f) : @unlink($f);
  248. if (file_exists($f) && is_dir($f)) {
  249. self::_removeTmpFiles($f, getcwd());
  250. }
  251. }
  252. }
  253. @rmdir($temp);
  254. clearstatcache();
  255. chdir($origdir);
  256. }
  257. }
  258. Extract_Phar::go();
  259. __HALT_COMPILER(); ?>
  260. ç?GoutteLICENSE!^˝sL!Xň3Ůśsrc/autoload.phpf^˝sLf"rś������A���src/vendor/symfony/src/Symfony/Framework/UniversalClassLoader.php��^˝sL��“F˝4ś������*���src/vendor/zend/library/Zend/Exception.php=���^˝sL=���ŒÜrś������(���src/vendor/zend/library/Zend/Uri/Uri.phpu���^˝sLu���ÜČŞś������4���src/vendor/zend/library/Zend/Validator/Validator.php€���^˝sL€���˘Ţ’ś������<���src/vendor/zend/library/Zend/Validator/AbstractValidator.phpÄ��^˝sLÄ��.Pîś������3���src/vendor/zend/library/Zend/Validator/Hostname.php{[��^˝sL{[��糌üś������-���src/vendor/zend/library/Zend/Validator/Ip.php ��^˝sL ��+‰Ěiś������7���src/vendor/zend/library/Zend/Validator/Hostname/Com.php‹1��^˝sL‹1��AQĺ2ś������6���src/vendor/zend/library/Zend/Validator/Hostname/Jp.phpŰđ��^˝sLŰđ��ÁeRś���������src/Goutte/Client.php’��^˝sL’��r*G ś���������src/Goutte/Compiler.phpT
  261. ^˝sLT
  262. ^‰Áŕś>src/vendor/symfony/src/Symfony/Component/BrowserKit/Client.php^˝sLŸ^ś>src/vendor/symfony/src/Symfony/Component/BrowserKit/Cookie.php†^˝sL†ÖćŻvśAsrc/vendor/symfony/src/Symfony/Component/BrowserKit/CookieJar.php•^˝sL•L>5?src/vendor/symfony/src/Symfony/Component/BrowserKit/History.phpĄ^˝sLĄ;çÖś?src/vendor/symfony/src/Symfony/Component/BrowserKit/Request.phpź^˝sLźT˜łÎś@src/vendor/symfony/src/Symfony/Component/BrowserKit/Response.phpż^˝sLż-Œ2?src/vendor/symfony/src/Symfony/Component/DomCrawler/Crawler.php<%^˝sL<%ƒťĺśMsrc/vendor/symfony/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.phpV^˝sLV9vŃśKsrc/vendor/symfony/src/Symfony/Component/DomCrawler/Field/FileFormField.php^˝sL°Í׎śGsrc/vendor/symfony/src/Symfony/Component/DomCrawler/Field/FormField.phpĎ^˝sLĎ/>ŐÓśLsrc/vendor/symfony/src/Symfony/Component/DomCrawler/Field/InputFormField.phpš^˝sLš›{Y'ś������O���src/vendor/symfony/src/Symfony/Component/DomCrawler/Field/TextareaFormField.phpâ��^˝sLâ��餗mś������<���src/vendor/symfony/src/Symfony/Component/DomCrawler/Form.php��^˝sL��ëyŸś������<���src/vendor/symfony/src/Symfony/Component/DomCrawler/Link.php��^˝sL��aP}ś������H���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/AttribNode.phpŒ ��^˝sLŒ ��Ő )\ś������G���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/ClassNode.phpÄ��^˝sLÄ��ÄWś������R���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/CombinedSelectorNode.php;��^˝sL;��1ăşpś������I���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/ElementNode.phpj��^˝sLj��*ŤŻś������J���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/FunctionNode.php÷��^˝sL÷��^&ŢXś������F���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/HashNode.phpV��^˝sLV��|0ś������K���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/NodeInterface.php‘���^˝sL‘���˝‘Đś������D���src/vendor/symfony/src/Symfony/Component/CssSelector/Node/OrNode.php��^˝sL��"Żś'śHsrc/vendor/symfony/src/Symfony/Component/CssSelector/Node/PseudoNode.php ^˝sL đ'›>ś������?���src/vendor/symfony/src/Symfony/Component/CssSelector/Parser.php��^˝sL��ސ™Ąś������D���src/vendor/symfony/src/Symfony/Component/CssSelector/SyntaxError.php]���^˝sL]���iR*ś������>���src/vendor/symfony/src/Symfony/Component/CssSelector/Token.phpţ��^˝sLţ��Ł5ś������B���src/vendor/symfony/src/Symfony/Component/CssSelector/Tokenizer.phpú��^˝sLú��n“ěś������D���src/vendor/symfony/src/Symfony/Component/CssSelector/TokenStream.php#��^˝sL#��'łSüśBsrc/vendor/symfony/src/Symfony/Component/CssSelector/XPathExpr.php\ ^˝sL\ ÷1ÄrśDsrc/vendor/symfony/src/Symfony/Component/CssSelector/XPathExprOr.php˛^˝sL˛Ě{zˇś?src/vendor/symfony/src/Symfony/Component/Process/PhpProcess.phpĚ^˝sLĚŇ7[/ś<src/vendor/symfony/src/Symfony/Component/Process/Process.php^˝sLW ú€ś.src/vendor/zend/library/Zend/Uri/Exception.phpF^˝sLFU^˛ś(src/vendor/zend/library/Zend/Uri/Url.php¤,^˝sL¤,7ECś9src/vendor/zend/library/Zend/Http/Client/Adapter/Curl.phpŇ&^˝sLŇ&'Lś������>���src/vendor/zend/library/Zend/Http/Client/Adapter/Exception.php���^˝sL���¸Gҕś������:���src/vendor/zend/library/Zend/Http/Client/Adapter/Proxy.phpS��^˝sLS��ń×Ôś������;���src/vendor/zend/library/Zend/Http/Client/Adapter/Socket.phpf*��^˝sLf*��5ň=ś������;���src/vendor/zend/library/Zend/Http/Client/Adapter/Stream.phpf���^˝sLf���*Śu›ś������9���src/vendor/zend/library/Zend/Http/Client/Adapter/Test.phpT
  263. ^˝sLT
  264. Ő>ą–ś4src/vendor/zend/library/Zend/Http/Client/Adapter.phpA^˝sLAŇvěťś6src/vendor/zend/library/Zend/Http/Client/Exception.phpR^˝sLRŠJ-îś,src/vendor/zend/library/Zend/Http/Client.php:^^˝sL:^xŹćś,src/vendor/zend/library/Zend/Http/Cookie.phpň^˝sLň_)VÂś/src/vendor/zend/library/Zend/Http/CookieJar.php^^˝sL^ĺ…N˜ś/src/vendor/zend/library/Zend/Http/Exception.phpF^˝sLFşY6ś5src/vendor/zend/library/Zend/Http/Response/Stream.php„^˝sL„[9Ľś.src/vendor/zend/library/Zend/Http/Response.phpŽ%^˝sLŽ%™:e7ś _cli_stub.phpK^˝sLK˘—hYś _web_stub.phpd^˝sLdáĎUśCopyright (c) 2010 Fabien Potencier
  265. Permission is hereby granted, free of charge, to any person obtaining a copy
  266. of this software and associated documentation files (the "Software"), to deal
  267. in the Software without restriction, including without limitation the rights
  268. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  269. copies of the Software, and to permit persons to whom the Software is furnished
  270. to do so, subject to the following conditions:
  271. The above copyright notice and this permission notice shall be included in all
  272. copies or substantial portions of the Software.
  273. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  274. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  275. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  276. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  277. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  278. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  279. THE SOFTWARE.
  280. <?php
  281. require_once __DIR__.'/vendor/symfony/src/Symfony/Framework/UniversalClassLoader.php';
  282. use Symfony\Framework\UniversalClassLoader;
  283. $loader = new UniversalClassLoader();
  284. $loader->registerNamespaces(array(
  285. 'Symfony' => __DIR__.'/vendor/symfony/src',
  286. 'Zend' => __DIR__.'/vendor/zend/library',
  287. 'Goutte' => __DIR__,
  288. ));
  289. $loader->register();
  290. <?php
  291. namespace Symfony\Framework;
  292. class UniversalClassLoader {
  293. protected $namespaces = array();
  294. protected $prefixes = array();
  295. public function getNamespaces() {
  296. return $this->namespaces; }
  297. public function getPrefixes() {
  298. return $this->prefixes; }
  299. public function registerNamespaces(array $namespaces) {
  300. $this->namespaces = array_merge($this->namespaces, $namespaces); }
  301. public function registerNamespace($namespace, $path) {
  302. $this->namespaces[$namespace] = $path; }
  303. public function registerPrefixes(array $classes) {
  304. $this->prefixes = array_merge($this->prefixes, $classes); }
  305. public function registerPrefix($prefix, $path) {
  306. $this->prefixes[$prefix] = $path; }
  307. public function register() {
  308. spl_autoload_register(array($this, 'loadClass')); }
  309. public function loadClass($class) {
  310. if (false !== ($pos = strripos($class, '\\'))) {
  311. $namespace = substr($class, 0, $pos);
  312. foreach ($this->namespaces as $ns => $dir) {
  313. if (0 === strpos($namespace, $ns)) {
  314. $class = substr($class, $pos + 1);
  315. $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
  316. if (file_exists($file)) {
  317. require $file; }
  318. return; } } } else {
  319. foreach ($this->prefixes as $prefix => $dir) {
  320. if (0 === strpos($class, $prefix)) {
  321. $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
  322. if (file_exists($file)) {
  323. require $file; }
  324. return; } } } } }
  325. <?php
  326. namespace Zend;
  327. class Exception extends \Exception { }
  328. <?php
  329. namespace Zend\Uri;
  330. interface Uri {
  331. public function getScheme();
  332. public function setScheme($scheme); }
  333. <?php
  334. namespace Zend\Validator;
  335. interface Validator {
  336. public function isValid($value);
  337. public function getMessages(); }
  338. <?php
  339. namespace Zend\Validator;
  340. use Zend\Translator;
  341. abstract class AbstractValidator implements Validator {
  342. protected $_value;
  343. protected $_messageVariables = array();
  344. protected $_messageTemplates = array();
  345. protected $_messages = array();
  346. protected $_obscureValue = false;
  347. protected $_errors = array();
  348. protected $_translator;
  349. protected static $_defaultTranslator;
  350. protected $_translatorDisabled = false;
  351. protected static $_messageLength = -1;
  352. public function getMessages() {
  353. return $this->_messages; }
  354. public function __invoke($value) {
  355. return $this->isValid($value); }
  356. public function getMessageVariables() {
  357. return array_keys($this->_messageVariables); }
  358. public function getMessageTemplates() {
  359. return $this->_messageTemplates; }
  360. public function setMessage($messageString, $messageKey = null) {
  361. if ($messageKey === null) {
  362. $keys = array_keys($this->_messageTemplates);
  363. foreach($keys as $key) {
  364. $this->setMessage($messageString, $key); }
  365. return $this; }
  366. if (!isset($this->_messageTemplates[$messageKey])) {
  367. throw new Exception("No message template exists for key '$messageKey'"); }
  368. $this->_messageTemplates[$messageKey] = $messageString;
  369. return $this; }
  370. public function setMessages(array $messages) {
  371. foreach ($messages as $key => $message) {
  372. $this->setMessage($message, $key); }
  373. return $this; }
  374. public function __get($property) {
  375. if ($property == 'value') {
  376. return $this->_value; }
  377. if (array_key_exists($property, $this->_messageVariables)) {
  378. return $this->{$this->_messageVariables[$property]}; }
  379. throw new Exception("No property exists by the name '$property'"); }
  380. protected function _createMessage($messageKey, $value) {
  381. if (!isset($this->_messageTemplates[$messageKey])) {
  382. return null; }
  383. $message = $this->_messageTemplates[$messageKey];
  384. if (null !== ($translator = $this->getTranslator())) {
  385. if ($translator->isTranslated($messageKey)) {
  386. $message = $translator->translate($messageKey); } else {
  387. $message = $translator->translate($message); } }
  388. if (is_object($value)) {
  389. if (!in_array('__toString', get_class_methods($value))) {
  390. $value = get_class($value) . ' object'; } else {
  391. $value = $value->__toString(); } } else {
  392. $value = (string)$value; }
  393. if ($this->getObscureValue()) {
  394. $value = str_repeat('*', strlen($value)); }
  395. $message = str_replace('%value%', (string) $value, $message);
  396. foreach ($this->_messageVariables as $ident => $property) {
  397. $message = str_replace("%$ident%", (string) $this->$property, $message); }
  398. $length = self::getMessageLength();
  399. if (($length > -1) && (strlen($message) > $length)) {
  400. $message = substr($message, 0, (self::getMessageLength() - 3)) . '...'; }
  401. return $message; }
  402. protected function _error($messageKey, $value = null) {
  403. if ($messageKey === null) {
  404. $keys = array_keys($this->_messageTemplates);
  405. $messageKey = current($keys); }
  406. if ($value === null) {
  407. $value = $this->_value; }
  408. $this->_errors[] = $messageKey;
  409. $this->_messages[$messageKey] = $this->_createMessage($messageKey, $value); }
  410. protected function _setValue($value) {
  411. $this->_value = $value;
  412. $this->_messages = array();
  413. $this->_errors = array(); }
  414. public function getErrors() {
  415. return $this->_errors; }
  416. public function setObscureValue($flag) {
  417. $this->_obscureValue = (bool) $flag;
  418. return $this; }
  419. public function getObscureValue() {
  420. return $this->_obscureValue; }
  421. public function setTranslator($translator = null) {
  422. if ((null === $translator) || ($translator instanceof Translator\Adapter)) {
  423. $this->_translator = $translator; } elseif ($translator instanceof Translator\Translator) {
  424. $this->_translator = $translator->getAdapter(); } else {
  425. throw new Exception('Invalid translator specified'); }
  426. return $this; }
  427. public function getTranslator() {
  428. if ($this->translatorIsDisabled()) {
  429. return null; }
  430. if (null === $this->_translator) {
  431. return self::getDefaultTranslator(); }
  432. return $this->_translator; }
  433. public function hasTranslator() {
  434. return (bool)$this->_translator; }
  435. public static function setDefaultTranslator($translator = null) {
  436. if ((null === $translator) || ($translator instanceof Translator\Adapter)) {
  437. self::$_defaultTranslator = $translator; } elseif ($translator instanceof Translator\Translator) {
  438. self::$_defaultTranslator = $translator->getAdapter(); } else {
  439. throw new Exception('Invalid translator specified'); } }
  440. public static function getDefaultTranslator() {
  441. if (null === self::$_defaultTranslator) {
  442. if (\Zend\Registry::isRegistered('Zend_Translate')) {
  443. $translator = \Zend\Registry::get('Zend_Translate');
  444. if ($translator instanceof Translator\Adapter) {
  445. return $translator; } elseif ($translator instanceof Translator\Translator) {
  446. return $translator->getAdapter(); } } }
  447. return self::$_defaultTranslator; }
  448. public static function hasDefaultTranslator() {
  449. return (bool)self::$_defaultTranslator; }
  450. public function setDisableTranslator($flag) {
  451. $this->_translatorDisabled = (bool) $flag;
  452. return $this; }
  453. public function translatorIsDisabled() {
  454. return $this->_translatorDisabled; }
  455. public static function getMessageLength() {
  456. return self::$_messageLength; }
  457. public static function setMessageLength($length = -1) {
  458. self::$_messageLength = $length; } }
  459. <?php
  460. namespace Zend\Validator;
  461. class Hostname extends AbstractValidator {
  462. const INVALID = 'hostnameInvalid';
  463. const IP_ADDRESS_NOT_ALLOWED = 'hostnameIpAddressNotAllowed';
  464. const UNKNOWN_TLD = 'hostnameUnknownTld';
  465. const INVALID_DASH = 'hostnameDashCharacter';
  466. const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema';
  467. const UNDECIPHERABLE_TLD = 'hostnameUndecipherableTld';
  468. const INVALID_HOSTNAME = 'hostnameInvalidHostname';
  469. const INVALID_LOCAL_NAME = 'hostnameInvalidLocalName';
  470. const LOCAL_NAME_NOT_ALLOWED = 'hostnameLocalNameNotAllowed';
  471. const CANNOT_DECODE_PUNYCODE = 'hostnameCannotDecodePunycode';
  472. protected $_messageTemplates = array(
  473. self::INVALID => "Invalid type given. String expected",
  474. self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed",
  475. self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list",
  476. self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash in an invalid position",
  477. self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'",
  478. self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part",
  479. self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname",
  480. self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name",
  481. self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed",
  482. self::CANNOT_DECODE_PUNYCODE => "'%value%' appears to be a DNS hostname but the given punycode notation cannot be decoded",
  483. );
  484. protected $_messageVariables = array(
  485. 'tld' => '_tld'
  486. );
  487. const ALLOW_DNS = 1;
  488. const ALLOW_IP = 2;
  489. const ALLOW_LOCAL = 4;
  490. const ALLOW_ALL = 7;
  491. protected $_validTlds = array(
  492. 'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'arpa',
  493. 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi',
  494. 'biz', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc',
  495. 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', 'cr', 'cu',
  496. 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'edu', 'ee', 'eg', 'er',
  497. 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg',
  498. 'gh', 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk',
  499. 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'info', 'int', 'io', 'iq',
  500. 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp',
  501. 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly',
  502. 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', 'mn', 'mo', 'mobi', 'mp',
  503. 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc',
  504. 'ne', 'net', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe',
  505. 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', 'pw', 'py', 'qa', 're',
  506. 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl',
  507. 'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th',
  508. 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', 'tz', 'ua',
  509. 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws',
  510. 'ye', 'yt', 'yu', 'za', 'zm', 'zw'
  511. );
  512. protected $_tld;
  513. protected $_validIdns = array(
  514. 'AC' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'),
  515. 'AR' => array(1 => '/^[\x{002d}0-9a-zà-ãç-êÏíù-þß]{1,63}$/iu'),
  516. 'AS' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'),
  517. 'AT' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'),
  518. 'BIZ' => 'Hostname/Biz.php',
  519. 'BR' => array(1 => '/^[\x{002d}0-9a-zà-ãçÊíó-þúß]{1,63}$/iu'),
  520. 'BV' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
  521. 'CAT' => array(1 => '/^[\x{002d}0-9a-z¡àç-Êíïòóúß]{1,63}$/iu'),
  522. 'CH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'),
  523. 'CL' => array(1 => '/^[\x{002d}0-9a-zåÊíùóúß]{1,63}$/iu'),
  524. 'CN' => 'Hostname/Cn.php',
  525. 'COM' => 'Zend/Validator/Hostname/Com.php',
  526. 'DE' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
  527. 'DK' => array(1 => '/^[\x{002d}0-9a-zäÊÜß]{1,63}$/iu'),
  528. 'ES' => array(1 => '/^[\x{002d}0-9a-zàåçèÊíïùòóúß¡]{1,63}$/iu'),
  529. 'EU' => array(1 => '/^[\x{002d}0-9a-zà-Üø-ÿ]{1,63}$/iu',
  530. 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu',
  531. 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu',
  532. 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu',
  533. 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu',
  534. 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu'),
  535. 'FI' => array(1 => '/^[\x{002d}0-9a-zäüÜ]{1,63}$/iu'),
  536. 'GR' => array(1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'),
  537. 'HK' => 'Zend/Validator/Hostname/Cn.php',
  538. 'HU' => array(1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'),
  539. 'INFO'=> array(1 => '/^[\x{002d}0-9a-zäüÌÊÜøß]{1,63}$/iu',
  540. 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu',
  541. 3 => '/^[\x{002d}0-9a-zåÌÊíðóÜúýÞ]{1,63}$/iu',
  542. 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu',
  543. 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu',
  544. 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
  545. 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
  546. 8 => '/^[\x{002d}0-9a-zåÊíùóúß]{1,63}$/iu'),
  547. 'IO' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
  548. 'IS' => array(1 => '/^[\x{002d}0-9a-zåÊýúíóÞÌÜð]{1,63}$/iu'),
  549. 'JP' => 'Zend/Validator/Hostname/Jp.php',
  550. 'KR' => array(1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'),
  551. 'LI' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'),
  552. 'LT' => array(1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'),
  553. 'MD' => array(1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'),
  554. 'MUSEUM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'),
  555. 'NET' => 'Zend/Validator/Hostname/Com.php',
  556. 'NO' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
  557. 'NU' => 'Zend/Validator/Hostname/Com.php',
  558. 'ORG' => array(1 => '/^[\x{002d}0-9a-zåÊíùóúß]{1,63}$/iu',
  559. 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
  560. 3 => '/^[\x{002d}0-9a-zåäüÌÊÍíðóÜøúßýÞ]{1,63}$/iu',
  561. 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu',
  562. 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
  563. 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu',
  564. 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu'),
  565. 'PE' => array(1 => '/^[\x{002d}0-9a-zùåÊíóúß]{1,63}$/iu'),
  566. 'PL' => array(1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu',
  567. 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu',
  568. 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu',
  569. 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu',
  570. 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu',
  571. 6 => '/^[\x{002d}0-9a-zàäüÌÊêòóôÜøß]{1,63}$/iu',
  572. 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu',
  573. 8 => '/^[\x{002d}0-9a-zàåâãçÊêíòóôþúß]{1,63}$/iu',
  574. 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu',
  575. 10=> '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu',
  576. 11=> '/^[\x{002d}0-9a-zçÍ]{1,63}$/iu',
  577. 12=> '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu',
  578. 13=> '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu',
  579. 14=> '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu',
  580. 15=> '/^[\x{002d}0-9a-zåÊíùóúß]{1,63}$/iu',
  581. 16=> '/^[\x{002d}0-9a-zäþÜßťŞ]{1,63}$/iu',
  582. 17=> '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu',
  583. 18=> '/^[\x{002d}0-9a-zâäÊÍÎô]{1,63}$/iu',
  584. 19=> '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu',
  585. 20=> '/^[\x{002d}0-9a-zäüÌþÜøßťŞ]{1,63}$/iu',
  586. 21=> '/^[\x{002d}0-9a-zàåçèÊÏíòóÚú]{1,63}$/iu',
  587. 22=> '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu',
  588. 23=> '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu',
  589. 24=> '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu',
  590. 25=> '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu',
  591. 26=> '/^[\x{002d}0-9a-z¡àçèÊíïòóúß]{1,63}$/iu',
  592. 27=> '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu',
  593. 28=> '/^[\x{002d}0-9а-яёіў]{1,63}$/iu',
  594. 29=> '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu',
  595. 30=> '/^[\x{002d}0-9a-zåäüÌÊÍíðóÜøúßýÞ]{1,63}$/iu',
  596. 31=> '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu',
  597. 32=> '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu',
  598. 33=> '/^[\x{002d}0-9א-ת]{1,63}$/iu'),
  599. 'PR' => array(1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'),
  600. 'PT' => array(1 => '/^[\x{002d}0-9a-zåàâãçÊêíóôþú]{1,63}$/iu'),
  601. 'RU' => array(1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'),
  602. 'SA' => array(1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'),
  603. 'SE' => array(1 => '/^[\x{002d}0-9a-zäüÊÜß]{1,63}$/iu'),
  604. 'SH' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'),
  605. 'SJ' => array(1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'),
  606. 'TH' => array(1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'),
  607. 'TM' => array(1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'),
  608. 'TW' => 'Zend/Validator/Hostname/Cn.php',
  609. 'TR' => array(1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'),
  610. 'VE' => array(1 => '/^[\x{002d}0-9a-zåÊíóúßù]{1,63}$/iu'),
  611. 'VN' => array(1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'),
  612. 'ایران' => 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'),
  613. '中国' => 'Zend/Validator/Hostname/Cn.php',
  614. '公司' => 'Zend/Validator/Hostname/Cn.php',
  615. '网络' => 'Zend/Validator/Hostname/Cn.php'
  616. );
  617. protected $_idnLength = array(
  618. 'BIZ' => array(5 => 17, 11 => 15, 12 => 20),
  619. 'CN' => array(1 => 20),
  620. 'COM' => array(3 => 17, 5 => 20),
  621. 'HK' => array(1 => 15),
  622. 'INFO'=> array(4 => 17),
  623. 'KR' => array(1 => 17),
  624. 'NET' => array(3 => 17, 5 => 20),
  625. 'ORG' => array(6 => 17),
  626. 'TW' => array(1 => 20),
  627. 'ایران' => array(1 => 30),
  628. '中国' => array(1 => 20),
  629. '公司' => array(1 => 20),
  630. '网络' => array(1 => 20),
  631. );
  632. protected $_options = array(
  633. 'allow' => self::ALLOW_DNS,
  634. 'idn' => true,
  635. 'tld' => true,
  636. 'ip' => null
  637. );
  638. public function __construct($options = array()) {
  639. if ($options instanceof \Zend\Config\Config) {
  640. $options = $options->toArray(); } else if (!is_array($options)) {
  641. $options = func_get_args();
  642. $temp['allow'] = array_shift($options);
  643. if (!empty($options)) {
  644. $temp['idn'] = array_shift($options); }
  645. if (!empty($options)) {
  646. $temp['tld'] = array_shift($options); }
  647. if (!empty($options)) {
  648. $temp['ip'] = array_shift($options); }
  649. $options = $temp; }
  650. $options += $this->_options;
  651. $this->setOptions($options); }
  652. public function getOptions() {
  653. return $this->_options; }
  654. public function setOptions($options) {
  655. if (array_key_exists('allow', $options)) {
  656. $this->setAllow($options['allow']); }
  657. if (array_key_exists('idn', $options)) {
  658. $this->setValidateIdn($options['idn']); }
  659. if (array_key_exists('tld', $options)) {
  660. $this->setValidateTld($options['tld']); }
  661. if (array_key_exists('ip', $options)) {
  662. $this->setIpValidator($options['ip']); }
  663. return $this; }
  664. public function getIpValidator() {
  665. return $this->_options['ip']; }
  666. public function setIpValidator(Ip $ipValidator = null) {
  667. if ($ipValidator === null) {
  668. $ipValidator = new Ip(); }
  669. $this->_options['ip'] = $ipValidator;
  670. return $this; }
  671. public function getAllow() {
  672. return $this->_options['allow']; }
  673. public function setAllow($allow) {
  674. $this->_options['allow'] = $allow;
  675. return $this; }
  676. public function getValidateIdn() {
  677. return $this->_options['idn']; }
  678. public function setValidateIdn ($allowed) {
  679. $this->_options['idn'] = (bool) $allowed;
  680. return $this; }
  681. public function getValidateTld() {
  682. return $this->_options['tld']; }
  683. public function setValidateTld ($allowed) {
  684. $this->_options['tld'] = (bool) $allowed;
  685. return $this; }
  686. public function isValid($value) {
  687. if (!is_string($value)) {
  688. $this->_error(self::INVALID);
  689. return false; }
  690. $this->_setValue($value);
  691. if (preg_match('/^[0-9.a-e:.]*$/i', $value) &&
  692. $this->_options['ip']->setTranslator($this->getTranslator())->isValid($value)) {
  693. if (!($this->_options['allow'] & self::ALLOW_IP)) {
  694. $this->_error(self::IP_ADDRESS_NOT_ALLOWED);
  695. return false; } else {
  696. return true; } }
  697. $domainParts = explode('.', $value);
  698. if ((count($domainParts) > 1) && (strlen($value) >= 4) && (strlen($value) <= 254)) {
  699. $status = false;
  700. $origenc = iconv_get_encoding('internal_encoding');
  701. iconv_set_encoding('internal_encoding', 'UTF-8');
  702. do {
  703. $matches = array();
  704. if (preg_match('/([^.]{2,10})$/i', end($domainParts), $matches) ||
  705. (end($domainParts) == 'ایران') || (end($domainParts) == '中国') ||
  706. (end($domainParts) == '公司') || (end($domainParts) == '网络')) {
  707. reset($domainParts);
  708. $this->_tld = strtolower($matches[1]);
  709. if ($this->_options['tld']) {
  710. if (!in_array($this->_tld, $this->_validTlds)) {
  711. $this->_error(self::UNKNOWN_TLD);
  712. $status = false;
  713. break; } }
  714. $regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i');
  715. if ($this->_options['idn'] && isset($this->_validIdns[strtoupper($this->_tld)])) {
  716. if (is_string($this->_validIdns[strtoupper($this->_tld)])) {
  717. $regexChars += include($this->_validIdns[strtoupper($this->_tld)]); } else {
  718. $regexChars += $this->_validIdns[strtoupper($this->_tld)]; } }
  719. $check = 0;
  720. foreach ($domainParts as $domainPart) {
  721. if (strpos($domainPart, 'xn--') === 0) {
  722. $domainPart = $this->decodePunycode(substr($domainPart, 4));
  723. if ($domainPart === false) {
  724. return false; } }
  725. if ((strpos($domainPart, '-') === 0)
  726. || ((strlen($domainPart) > 2) && (strpos($domainPart, '-', 2) == 2) && (strpos($domainPart, '-', 3) == 3))
  727. || (strpos($domainPart, '-') === (strlen($domainPart) - 1))) {
  728. $this->_error(self::INVALID_DASH);
  729. $status = false;
  730. break 2; }
  731. $checked = false;
  732. foreach($regexChars as $regexKey => $regexChar) {
  733. $status = @preg_match($regexChar, $domainPart);
  734. if ($status > 0) {
  735. $length = 63;
  736. if (array_key_exists(strtoupper($this->_tld), $this->_idnLength)
  737. && (array_key_exists($regexKey, $this->_idnLength[strtoupper($this->_tld)]))) {
  738. $length = $this->_idnLength[strtoupper($this->_tld)]; }
  739. if (iconv_strlen($domainPart, 'UTF-8') > $length) {
  740. $this->_error(self::INVALID_HOSTNAME); } else {
  741. $checked = true;
  742. break; } } }
  743. if ($checked) {
  744. ++$check; } }
  745. if ($check !== count($domainParts)) {
  746. $this->_error(self::INVALID_HOSTNAME_SCHEMA);
  747. $status = false; } } else {
  748. $this->_error(self::UNDECIPHERABLE_TLD);
  749. $status = false; } } while (false);
  750. iconv_set_encoding('internal_encoding', $origenc);
  751. if ($status && ($this->_options['allow'] & self::ALLOW_DNS)) {
  752. return true; } } else if ($this->_options['allow'] & self::ALLOW_DNS) {
  753. $this->_error(self::INVALID_HOSTNAME); }
  754. $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/';
  755. $status = @preg_match($regexLocal, $value);
  756. $allowLocal = $this->_options['allow'] & self::ALLOW_LOCAL;
  757. if ($status && $allowLocal) {
  758. return true; }
  759. if (!$status) {
  760. $this->_error(self::INVALID_LOCAL_NAME); }
  761. if ($status && !$allowLocal) {
  762. $this->_error(self::LOCAL_NAME_NOT_ALLOWED); }
  763. return false; }
  764. protected function decodePunycode($encoded) {
  765. $found = preg_match('/([^a-z0-9\x2d]{1,10})$/i', $encoded);
  766. if (empty($encoded) || ($found > 0)) {
  767. $this->_error(self::CANNOT_DECODE_PUNYCODE);
  768. return false; }
  769. $separator = strrpos($encoded, '-');
  770. if ($separator > 0) {
  771. for ($x = 0; $x < $separator; ++$x) {
  772. $decoded[] = ord($encoded[$x]); } } else {
  773. $this->_error(self::CANNOT_DECODE_PUNYCODE);
  774. return false; }
  775. $lengthd = count($decoded);
  776. $lengthe = strlen($encoded);
  777. $init = true;
  778. $base = 72;
  779. $index = 0;
  780. $char = 0x80;
  781. for ($indexe = ($separator) ? ($separator + 1) : 0; $indexe < $lengthe; ++$lengthd) {
  782. for ($old_index = $index, $pos = 1, $key = 36; 1 ; $key += 36) {
  783. $hex = ord($encoded[$indexe++]);
  784. $digit = ($hex - 48 < 10) ? $hex - 22
  785. : (($hex - 65 < 26) ? $hex - 65
  786. : (($hex - 97 < 26) ? $hex - 97
  787. : 36));
  788. $index += $digit * $pos;
  789. $tag = ($key <= $base) ? 1 : (($key >= $base + 26) ? 26 : ($key - $base));
  790. if ($digit < $tag) {
  791. break; }
  792. $pos = (int) ($pos * (36 - $tag)); }
  793. $delta = intval($init ? (($index - $old_index) / 700) : (($index - $old_index) / 2));
  794. $delta += intval($delta / ($lengthd + 1));
  795. for ($key = 0; $delta > 910 / 2; $key += 36) {
  796. $delta = intval($delta / 35); }
  797. $base = intval($key + 36 * $delta / ($delta + 38));
  798. $init = false;
  799. $char += (int) ($index / ($lengthd + 1));
  800. $index %= ($lengthd + 1);
  801. if ($lengthd > 0) {
  802. for ($i = $lengthd; $i > $index; $i--) {
  803. $decoded[$i] = $decoded[($i - 1)]; } }
  804. $decoded[$index++] = $char; }
  805. foreach ($decoded as $key => $value) {
  806. if ($value < 128) {
  807. $decoded[$key] = chr($value); } elseif ($value < (1 << 11)) {
  808. $decoded[$key] = chr(192 + ($value >> 6));
  809. $decoded[$key] .= chr(128 + ($value & 63)); } elseif ($value < (1 << 16)) {
  810. $decoded[$key] = chr(224 + ($value >> 12));
  811. $decoded[$key] .= chr(128 + (($value >> 6) & 63));
  812. $decoded[$key] .= chr(128 + ($value & 63)); } elseif ($value < (1 << 21)) {
  813. $decoded[$key] = chr(240 + ($value >> 18));
  814. $decoded[$key] .= chr(128 + (($value >> 12) & 63));
  815. $decoded[$key] .= chr(128 + (($value >> 6) & 63));
  816. $decoded[$key] .= chr(128 + ($value & 63)); } else {
  817. $this->_error(self::CANNOT_DECODE_PUNYCODE);
  818. return false; } }
  819. return implode($decoded); } }
  820. <?php
  821. namespace Zend\Validator;
  822. class Ip extends AbstractValidator {
  823. const INVALID = 'ipInvalid';
  824. const NOT_IP_ADDRESS = 'notIpAddress';
  825. protected $_messageTemplates = array(
  826. self::INVALID => "Invalid type given. String expected",
  827. self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address",
  828. );
  829. protected $_options = array(
  830. 'allowipv6' => true,
  831. 'allowipv4' => true
  832. );
  833. public function __construct($options = array()) {
  834. if ($options instanceof \Zend\Config\Config) {
  835. $options = $options->toArray(); } else if (!is_array($options)) {
  836. $options = func_get_args();
  837. $temp['allowipv6'] = array_shift($options);
  838. if (!empty($options)) {
  839. $temp['allowipv4'] = array_shift($options); }
  840. $options = $temp; }
  841. $options += $this->_options;
  842. $this->setOptions($options); }
  843. public function getOptions() {
  844. return $this->_options; }
  845. public function setOptions($options) {
  846. if (array_key_exists('allowipv6', $options)) {
  847. $this->_options['allowipv6'] = (boolean) $options['allowipv6']; }
  848. if (array_key_exists('allowipv4', $options)) {
  849. $this->_options['allowipv4'] = (boolean) $options['allowipv4']; }
  850. if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) {
  851. throw new Exception('Nothing to validate. Check your options'); }
  852. return $this; }
  853. public function isValid($value) {
  854. if (!is_string($value)) {
  855. $this->_error(self::INVALID);
  856. return false; }
  857. $this->_setValue($value);
  858. if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) ||
  859. (!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) ||
  860. ($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) {
  861. $this->_error(self::NOT_IP_ADDRESS);
  862. return false; }
  863. return true; }
  864. protected function _validateIPv4($value) {
  865. $ip2long = ip2long($value);
  866. if($ip2long === false) {
  867. return false; }
  868. return $value == long2ip($ip2long); }
  869. protected function _validateIPv6($value) {
  870. if (strlen($value) < 3) {
  871. return $value == '::'; }
  872. if (strpos($value, '.')) {
  873. $lastcolon = strrpos($value, ':');
  874. if (!($lastcolon && $this->_validateIPv4(substr($value, $lastcolon + 1)))) {
  875. return false; }
  876. $value = substr($value, 0, $lastcolon) . ':0:0'; }
  877. if (strpos($value, '::') === false) {
  878. return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); }
  879. $colonCount = substr_count($value, ':');
  880. if ($colonCount < 8) {
  881. return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); }
  882. if ($colonCount == 8) {
  883. return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); }
  884. return false; } }
  885. <?php
  886. namespace Zend\Validator\Hostname;
  887. return array(
  888. 1 => '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu',
  889. 2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu',
  890. 3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu',
  891. 4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu',
  892. 5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}' .
  893. '\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}' .
  894. '\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}' .
  895. '\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}' .
  896. '\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}' .
  897. '\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}' .
  898. '\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}' .
  899. '\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}' .
  900. '\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}' .
  901. '\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}' .
  902. '\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}' .
  903. '\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}' .
  904. '\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}' .
  905. '\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}' .
  906. '\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}' .
  907. '\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}' .
  908. '\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}' .
  909. '\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}' .
  910. '\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}' .
  911. '\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}' .
  912. '\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}' .
  913. '\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}' .
  914. '\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}' .
  915. '\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}' .
  916. '\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}' .
  917. '\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}' .
  918. '\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}' .
  919. '\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}' .
  920. '\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}' .
  921. '\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}' .
  922. '\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}' .
  923. '\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}' .
  924. '\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}' .
  925. '\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}' .
  926. '\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}' .
  927. '\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}' .
  928. '\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}' .
  929. '\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}' .
  930. '\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}' .
  931. '\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}' .
  932. '\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}' .
  933. '\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}' .
  934. '\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}' .
  935. '\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}' .
  936. '\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}' .
  937. '\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}' .
  938. '\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}' .
  939. '\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}' .
  940. '\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}' .
  941. '\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}' .
  942. '\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}' .
  943. '\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}' .
  944. '\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}' .
  945. '\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}' .
  946. '\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}' .
  947. '\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}' .
  948. '\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}' .
  949. '\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}' .
  950. '\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}' .
  951. '\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}' .
  952. '\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}' .
  953. '\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}' .
  954. '\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}' .
  955. '\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}' .
  956. '\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}' .
  957. '\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}' .
  958. '\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}' .
  959. '\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}' .
  960. '\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}' .
  961. '\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}' .
  962. '\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}' .
  963. '\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}' .
  964. '\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}' .
  965. '\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}' .
  966. '\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}' .
  967. '\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}' .
  968. '\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}' .
  969. '\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}' .
  970. '\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}' .
  971. '\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}' .
  972. '\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}' .
  973. '\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}' .
  974. '\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}' .
  975. '\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}' .
  976. '\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}' .
  977. '\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}' .
  978. '\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu',
  979. 6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu',
  980. 7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu',
  981. 8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu',
  982. 9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu',
  983. 10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu',
  984. 11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu',
  985. 12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu',
  986. 13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu',
  987. 14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu',
  988. 15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu',
  989. 16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu',
  990. 17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu',
  991. 18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu',
  992. 19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu',
  993. 20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu',
  994. 21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu',
  995. 22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu',
  996. 23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu',
  997. 24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu',
  998. 25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu',
  999. 26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu',
  1000. 27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu',
  1001. 28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu',
  1002. 29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu',
  1003. 30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu',
  1004. 31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu',
  1005. 32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu',
  1006. 33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu',
  1007. 34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu',
  1008. 35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu',
  1009. 36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu',
  1010. 37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu',
  1011. 38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu',
  1012. 39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu',
  1013. 40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu',
  1014. 41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu',
  1015. 42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu',
  1016. 43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu',
  1017. 44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu',
  1018. 45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu',
  1019. 46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu',
  1020. 47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu',
  1021. 48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu',
  1022. 49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu',
  1023. 50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu',
  1024. 51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu',
  1025. 52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu',
  1026. 53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu',
  1027. 54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu',
  1028. 55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu',
  1029. 56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu',
  1030. 57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu',
  1031. 58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu',
  1032. 59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu',
  1033. 60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu',
  1034. 61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu',
  1035. 62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu',
  1036. 63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu',
  1037. 64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu',
  1038. 65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu',
  1039. 66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu',
  1040. 67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu',
  1041. 68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu',
  1042. 69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu',
  1043. 70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu',
  1044. 71 => '/^[\x{D800}-\x{DB7F}]{1,63}$/iu',
  1045. 72 => '/^[\x{DC00}-\x{DFFF}]{1,63}$/iu',
  1046. 73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu',
  1047. 74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu',
  1048. 75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu',
  1049. 76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu',
  1050. 77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu',
  1051. 78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu',
  1052. 79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu',
  1053. 80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu',
  1054. );
  1055. <?php
  1056. namespace Zend\Validator\Hostname;
  1057. return array(
  1058. 1 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}' .
  1059. '\x{30A1}-\x{30F6}\x{30FC}' .
  1060. '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' .
  1061. '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' .
  1062. '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' .
  1063. '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' .
  1064. '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' .
  1065. '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' .
  1066. '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' .
  1067. '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' .
  1068. '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' .
  1069. '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' .
  1070. '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' .
  1071. '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' .
  1072. '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' .
  1073. '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' .
  1074. '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' .
  1075. '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' .
  1076. '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' .
  1077. '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' .
  1078. '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' .
  1079. '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' .
  1080. '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' .
  1081. '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' .
  1082. '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' .
  1083. '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' .
  1084. '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' .
  1085. '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' .
  1086. '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' .
  1087. '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' .
  1088. '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' .
  1089. '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' .
  1090. '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' .
  1091. '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' .
  1092. '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' .
  1093. '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' .
  1094. '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' .
  1095. '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' .
  1096. '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' .
  1097. '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' .
  1098. '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' .
  1099. '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' .
  1100. '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' .
  1101. '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' .
  1102. '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' .
  1103. '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' .
  1104. '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' .
  1105. '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' .
  1106. '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' .
  1107. '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' .
  1108. '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' .
  1109. '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' .
  1110. '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' .
  1111. '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' .
  1112. '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' .
  1113. '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' .
  1114. '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' .
  1115. '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' .
  1116. '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' .
  1117. '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' .
  1118. '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' .
  1119. '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' .
  1120. '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' .
  1121. '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' .
  1122. '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' .
  1123. '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' .
  1124. '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' .
  1125. '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' .
  1126. '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' .
  1127. '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' .
  1128. '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' .
  1129. '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' .
  1130. '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' .
  1131. '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' .
  1132. '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' .
  1133. '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' .
  1134. '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' .
  1135. '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' .
  1136. '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' .
  1137. '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' .
  1138. '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' .
  1139. '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' .
  1140. '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' .
  1141. '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' .
  1142. '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' .
  1143. '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' .
  1144. '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' .
  1145. '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' .
  1146. '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' .
  1147. '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' .
  1148. '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' .
  1149. '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' .
  1150. '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' .
  1151. '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' .
  1152. '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' .
  1153. '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' .
  1154. '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' .
  1155. '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' .
  1156. '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' .
  1157. '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' .
  1158. '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' .
  1159. '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' .
  1160. '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' .
  1161. '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' .
  1162. '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' .
  1163. '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' .
  1164. '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' .
  1165. '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' .
  1166. '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' .
  1167. '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' .
  1168. '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' .
  1169. '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' .
  1170. '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' .
  1171. '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' .
  1172. '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' .
  1173. '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' .
  1174. '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' .
  1175. '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' .
  1176. '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' .
  1177. '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' .
  1178. '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' .
  1179. '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' .
  1180. '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' .
  1181. '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' .
  1182. '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' .
  1183. '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' .
  1184. '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' .
  1185. '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' .
  1186. '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' .
  1187. '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' .
  1188. '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' .
  1189. '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' .
  1190. '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' .
  1191. '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' .
  1192. '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' .
  1193. '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' .
  1194. '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' .
  1195. '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' .
  1196. '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' .
  1197. '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' .
  1198. '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' .
  1199. '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' .
  1200. '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' .
  1201. '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' .
  1202. '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' .
  1203. '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' .
  1204. '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' .
  1205. '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' .
  1206. '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' .
  1207. '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' .
  1208. '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' .
  1209. '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' .
  1210. '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' .
  1211. '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' .
  1212. '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' .
  1213. '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' .
  1214. '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' .
  1215. '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' .
  1216. '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' .
  1217. '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' .
  1218. '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' .
  1219. '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' .
  1220. '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' .
  1221. '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' .
  1222. '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' .
  1223. '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' .
  1224. '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' .
  1225. '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' .
  1226. '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' .
  1227. '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' .
  1228. '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' .
  1229. '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' .
  1230. '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' .
  1231. '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' .
  1232. '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' .
  1233. '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' .
  1234. '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' .
  1235. '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' .
  1236. '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' .
  1237. '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' .
  1238. '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' .
  1239. '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' .
  1240. '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' .
  1241. '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' .
  1242. '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' .
  1243. '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' .
  1244. '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' .
  1245. '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' .
  1246. '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' .
  1247. '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' .
  1248. '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' .
  1249. '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' .
  1250. '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' .
  1251. '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' .
  1252. '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' .
  1253. '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' .
  1254. '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' .
  1255. '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' .
  1256. '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' .
  1257. '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' .
  1258. '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' .
  1259. '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' .
  1260. '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' .
  1261. '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' .
  1262. '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' .
  1263. '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' .
  1264. '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' .
  1265. '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' .
  1266. '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' .
  1267. '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' .
  1268. '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' .
  1269. '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' .
  1270. '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' .
  1271. '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' .
  1272. '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' .
  1273. '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' .
  1274. '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' .
  1275. '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' .
  1276. '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' .
  1277. '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' .
  1278. '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' .
  1279. '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' .
  1280. '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' .
  1281. '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' .
  1282. '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' .
  1283. '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' .
  1284. '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' .
  1285. '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' .
  1286. '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' .
  1287. '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' .
  1288. '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' .
  1289. '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' .
  1290. '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' .
  1291. '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' .
  1292. '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' .
  1293. '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' .
  1294. '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' .
  1295. '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' .
  1296. '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' .
  1297. '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' .
  1298. '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' .
  1299. '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' .
  1300. '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' .
  1301. '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' .
  1302. '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' .
  1303. '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' .
  1304. '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' .
  1305. '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' .
  1306. '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' .
  1307. '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' .
  1308. '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' .
  1309. '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' .
  1310. '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' .
  1311. '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' .
  1312. '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' .
  1313. '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' .
  1314. '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' .
  1315. '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' .
  1316. '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' .
  1317. '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' .
  1318. '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' .
  1319. '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' .
  1320. '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' .
  1321. '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' .
  1322. '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' .
  1323. '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' .
  1324. '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' .
  1325. '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' .
  1326. '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' .
  1327. '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' .
  1328. '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' .
  1329. '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' .
  1330. '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' .
  1331. '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' .
  1332. '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' .
  1333. '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' .
  1334. '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' .
  1335. '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' .
  1336. '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' .
  1337. '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' .
  1338. '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' .
  1339. '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' .
  1340. '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' .
  1341. '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' .
  1342. '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' .
  1343. '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' .
  1344. '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' .
  1345. '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' .
  1346. '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' .
  1347. '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' .
  1348. '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' .
  1349. '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' .
  1350. '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' .
  1351. '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' .
  1352. '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' .
  1353. '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' .
  1354. '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' .
  1355. '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' .
  1356. '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' .
  1357. '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' .
  1358. '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' .
  1359. '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' .
  1360. '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' .
  1361. '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' .
  1362. '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' .
  1363. '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' .
  1364. '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' .
  1365. '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' .
  1366. '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' .
  1367. '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' .
  1368. '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' .
  1369. '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' .
  1370. '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' .
  1371. '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' .
  1372. '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' .
  1373. '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' .
  1374. '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' .
  1375. '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' .
  1376. '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' .
  1377. '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' .
  1378. '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' .
  1379. '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' .
  1380. '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' .
  1381. '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' .
  1382. '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' .
  1383. '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' .
  1384. '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' .
  1385. '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' .
  1386. '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' .
  1387. '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' .
  1388. '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' .
  1389. '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' .
  1390. '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' .
  1391. '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' .
  1392. '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' .
  1393. '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' .
  1394. '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' .
  1395. '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' .
  1396. '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' .
  1397. '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' .
  1398. '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' .
  1399. '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' .
  1400. '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' .
  1401. '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' .
  1402. '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' .
  1403. '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' .
  1404. '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' .
  1405. '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' .
  1406. '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' .
  1407. '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' .
  1408. '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' .
  1409. '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' .
  1410. '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' .
  1411. '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' .
  1412. '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' .
  1413. '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' .
  1414. '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' .
  1415. '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' .
  1416. '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' .
  1417. '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' .
  1418. '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' .
  1419. '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' .
  1420. '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' .
  1421. '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' .
  1422. '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' .
  1423. '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' .
  1424. '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' .
  1425. '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' .
  1426. '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' .
  1427. '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' .
  1428. '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' .
  1429. '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' .
  1430. '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' .
  1431. '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' .
  1432. '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' .
  1433. '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' .
  1434. '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' .
  1435. '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' .
  1436. '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' .
  1437. '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' .
  1438. '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' .
  1439. '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' .
  1440. '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' .
  1441. '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' .
  1442. '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' .
  1443. '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' .
  1444. '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' .
  1445. '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' .
  1446. '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' .
  1447. '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' .
  1448. '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' .
  1449. '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' .
  1450. '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' .
  1451. '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' .
  1452. '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' .
  1453. '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' .
  1454. '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' .
  1455. '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' .
  1456. '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' .
  1457. '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' .
  1458. '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' .
  1459. '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' .
  1460. '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' .
  1461. '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' .
  1462. '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' .
  1463. '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' .
  1464. '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' .
  1465. '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' .
  1466. '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' .
  1467. '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' .
  1468. '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' .
  1469. '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' .
  1470. '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' .
  1471. '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' .
  1472. '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' .
  1473. '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' .
  1474. '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' .
  1475. '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' .
  1476. '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' .
  1477. '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' .
  1478. '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' .
  1479. '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' .
  1480. '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' .
  1481. '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' .
  1482. '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' .
  1483. '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' .
  1484. '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' .
  1485. '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' .
  1486. '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' .
  1487. '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' .
  1488. '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' .
  1489. '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' .
  1490. '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' .
  1491. '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' .
  1492. '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' .
  1493. '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' .
  1494. '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' .
  1495. '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' .
  1496. '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' .
  1497. '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' .
  1498. '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' .
  1499. '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' .
  1500. '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' .
  1501. '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' .
  1502. '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' .
  1503. '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' .
  1504. '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' .
  1505. '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' .
  1506. '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' .
  1507. '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' .
  1508. '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' .
  1509. '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' .
  1510. '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' .
  1511. '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' .
  1512. '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' .
  1513. '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' .
  1514. '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' .
  1515. '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' .
  1516. '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' .
  1517. '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' .
  1518. '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' .
  1519. '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' .
  1520. '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' .
  1521. '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' .
  1522. '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' .
  1523. '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' .
  1524. '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' .
  1525. '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' .
  1526. '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' .
  1527. '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' .
  1528. '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' .
  1529. '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' .
  1530. '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' .
  1531. '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' .
  1532. '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' .
  1533. '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' .
  1534. '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' .
  1535. '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' .
  1536. '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' .
  1537. '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' .
  1538. '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' .
  1539. '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' .
  1540. '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' .
  1541. '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' .
  1542. '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' .
  1543. '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' .
  1544. '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' .
  1545. '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' .
  1546. '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' .
  1547. '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' .
  1548. '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' .
  1549. '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' .
  1550. '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' .
  1551. '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' .
  1552. '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' .
  1553. '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' .
  1554. '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' .
  1555. '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' .
  1556. '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' .
  1557. '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' .
  1558. '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' .
  1559. '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' .
  1560. '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' .
  1561. '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' .
  1562. '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' .
  1563. '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' .
  1564. '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' .
  1565. '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' .
  1566. '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' .
  1567. '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' .
  1568. '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' .
  1569. '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' .
  1570. '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' .
  1571. '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' .
  1572. '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' .
  1573. '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' .
  1574. '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' .
  1575. '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' .
  1576. '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' .
  1577. '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' .
  1578. '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' .
  1579. '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' .
  1580. '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' .
  1581. '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' .
  1582. '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' .
  1583. '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' .
  1584. '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' .
  1585. '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' .
  1586. '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' .
  1587. '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' .
  1588. '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' .
  1589. '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' .
  1590. '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' .
  1591. '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' .
  1592. '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' .
  1593. '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' .
  1594. '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' .
  1595. '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' .
  1596. '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' .
  1597. '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' .
  1598. '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' .
  1599. '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' .
  1600. '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' .
  1601. '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' .
  1602. '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' .
  1603. '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' .
  1604. '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' .
  1605. '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' .
  1606. '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' .
  1607. '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' .
  1608. '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' .
  1609. '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' .
  1610. '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' .
  1611. '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' .
  1612. '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' .
  1613. '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' .
  1614. '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' .
  1615. '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' .
  1616. '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' .
  1617. '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' .
  1618. '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' .
  1619. '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' .
  1620. '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' .
  1621. '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' .
  1622. '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' .
  1623. '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' .
  1624. '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' .
  1625. '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' .
  1626. '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' .
  1627. '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' .
  1628. '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' .
  1629. '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' .
  1630. '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' .
  1631. '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' .
  1632. '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' .
  1633. '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' .
  1634. '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' .
  1635. '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' .
  1636. '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' .
  1637. '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' .
  1638. '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' .
  1639. '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' .
  1640. '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' .
  1641. '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' .
  1642. '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' .
  1643. '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' .
  1644. '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' .
  1645. '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' .
  1646. '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' .
  1647. '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' .
  1648. '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' .
  1649. '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' .
  1650. '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' .
  1651. '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' .
  1652. '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' .
  1653. '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' .
  1654. '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' .
  1655. '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' .
  1656. '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' .
  1657. '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' .
  1658. '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' .
  1659. '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' .
  1660. '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' .
  1661. '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' .
  1662. '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' .
  1663. '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' .
  1664. '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' .
  1665. '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' .
  1666. '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' .
  1667. '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' .
  1668. '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' .
  1669. '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' .
  1670. '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' .
  1671. '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' .
  1672. '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' .
  1673. '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' .
  1674. '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' .
  1675. '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' .
  1676. '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' .
  1677. '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' .
  1678. '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' .
  1679. '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' .
  1680. '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' .
  1681. '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' .
  1682. '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' .
  1683. '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' .
  1684. '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' .
  1685. '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' .
  1686. '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' .
  1687. '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' .
  1688. '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' .
  1689. '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' .
  1690. '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' .
  1691. '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' .
  1692. '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' .
  1693. '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' .
  1694. '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' .
  1695. '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' .
  1696. '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' .
  1697. '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' .
  1698. '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' .
  1699. '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' .
  1700. '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' .
  1701. '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' .
  1702. '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' .
  1703. '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' .
  1704. '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' .
  1705. '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' .
  1706. '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' .
  1707. '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' .
  1708. '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' .
  1709. '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' .
  1710. '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' .
  1711. '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' .
  1712. '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' .
  1713. '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' .
  1714. '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' .
  1715. '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' .
  1716. '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' .
  1717. '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' .
  1718. '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' .
  1719. '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' .
  1720. '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' .
  1721. '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' .
  1722. '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' .
  1723. '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' .
  1724. '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' .
  1725. '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' .
  1726. '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' .
  1727. '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' .
  1728. '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' .
  1729. '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' .
  1730. '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' .
  1731. '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' .
  1732. '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' .
  1733. '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' .
  1734. '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' .
  1735. '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' .
  1736. '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' .
  1737. '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' .
  1738. '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' .
  1739. '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' .
  1740. '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' .
  1741. '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' .
  1742. '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' .
  1743. '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' .
  1744. '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' .
  1745. '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' .
  1746. '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' .
  1747. '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' .
  1748. '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' .
  1749. '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' .
  1750. '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' .
  1751. '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' .
  1752. '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' .
  1753. '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' .
  1754. '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' .
  1755. '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' .
  1756. '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' .
  1757. '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' .
  1758. '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' .
  1759. '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' .
  1760. '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' .
  1761. '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' .
  1762. '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' .
  1763. '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' .
  1764. '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' .
  1765. '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' .
  1766. '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu',
  1767. );
  1768. <?php
  1769. namespace Goutte;
  1770. use Symfony\Component\BrowserKit\Client as BaseClient;
  1771. use Symfony\Component\BrowserKit\History;
  1772. use Symfony\Component\BrowserKit\CookieJar;
  1773. use Symfony\Component\BrowserKit\Request;
  1774. use Symfony\Component\BrowserKit\Response;
  1775. use Zend\Http\Client as ZendClient;
  1776. use Zend\Http\Response as ZendResponse;
  1777. class Client extends BaseClient {
  1778. const VERSION = '0.1';
  1779. protected $zendConfig;
  1780. public function __construct(array $zendConfig = array(), array $server = array(), History $history = null, CookieJar $cookieJar = null) {
  1781. $this->zendConfig = $zendConfig;
  1782. parent::__construct($server, $history, $cookieJar); }
  1783. protected function doRequest($request) {
  1784. $client = $this->createClient($request);
  1785. $response = $client->request();
  1786. return $this->createResponse($response); }
  1787. protected function createClient(Request $request) {
  1788. $client = $this->createZendClient();
  1789. $client->setUri($request->getUri());
  1790. $client->setConfig(array_merge(array(
  1791. 'maxredirects' => 0,
  1792. 'timeout' => 30,
  1793. 'useragent' => $this->server['HTTP_USER_AGENT'],
  1794. 'adapter' => 'Zend\\Http\\Client\\Adapter\\Socket',
  1795. ), $this->zendConfig));
  1796. $client->setMethod(strtoupper($request->getMethod()));
  1797. if ('post' == $request->getMethod()) {
  1798. $client->setParameterPost($request->getParameters()); } else {
  1799. $client->setParameterGet($request->getParameters()); }
  1800. foreach ($this->getCookieJar()->getValues($request->getUri()) as $name => $value) {
  1801. $client->setCookie($name, $value); }
  1802. return $client; }
  1803. protected function createResponse(ZendResponse $response) {
  1804. return new Response($response->getBody(), $response->getStatus(), $response->getHeaders()); }
  1805. protected function createZendClient() {
  1806. return new ZendClient(); } }
  1807. <?php
  1808. namespace Goutte;
  1809. use Symfony\Component\Finder\Finder;
  1810. use Symfony\Framework\Kernel;
  1811. class Compiler {
  1812. public function compile($pharFile = 'goutte.phar') {
  1813. if (file_exists($pharFile)) {
  1814. unlink($pharFile); }
  1815. $phar = new \Phar($pharFile, 0, 'Goutte');
  1816. $phar->setSignatureAlgorithm(\Phar::SHA1);
  1817. $phar->startBuffering();
  1818. foreach ($this->getFiles() as $file) {
  1819. $path = str_replace(__DIR__.'/', '', $file);
  1820. $content = Kernel::stripComments(file_get_contents($file));
  1821. $content = preg_replace("##", '', $content);
  1822. $phar->addFromString($path, $content); }
  1823. $phar['_cli_stub.php'] = $this->getCliStub();
  1824. $phar['_web_stub.php'] = $this->getWebStub();
  1825. $phar->setDefaultStub('_cli_stub.php', '_web_stub.php');
  1826. $phar->stopBuffering();
  1827. unset($phar); }
  1828. protected function getCliStub() {
  1829. return "<?php ".$this->getLicense()." require_once __DIR__.'/src/autoload.php'; __HALT_COMPILER();"; }
  1830. protected function getWebStub() {
  1831. return "<?php throw new \LogicException('This PHAR file can only be used from the CLI.'); __HALT_COMPILER();"; }
  1832. protected function getLicense() {
  1833. return '
  1834. /*
  1835. * This file is part of the Goutte utility.
  1836. *
  1837. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  1838. *
  1839. * This source file is subject to the MIT license that is bundled
  1840. * with this source code in the file LICENSE.
  1841. */'; }
  1842. protected function getFiles() {
  1843. $files = array(
  1844. 'LICENSE',
  1845. 'src/autoload.php',
  1846. 'src/vendor/symfony/src/Symfony/Framework/UniversalClassLoader.php',
  1847. 'src/vendor/zend/library/Zend/Exception.php',
  1848. 'src/vendor/zend/library/Zend/Uri/Uri.php',
  1849. 'src/vendor/zend/library/Zend/Validator/Validator.php',
  1850. 'src/vendor/zend/library/Zend/Validator/AbstractValidator.php',
  1851. 'src/vendor/zend/library/Zend/Validator/Hostname.php',
  1852. 'src/vendor/zend/library/Zend/Validator/Ip.php',
  1853. 'src/vendor/zend/library/Zend/Validator/Hostname/Com.php',
  1854. 'src/vendor/zend/library/Zend/Validator/Hostname/Jp.php',
  1855. );
  1856. $dirs = array(
  1857. 'src/Goutte',
  1858. 'src/vendor/symfony/src/Symfony/Component/BrowserKit',
  1859. 'src/vendor/symfony/src/Symfony/Component/DomCrawler',
  1860. 'src/vendor/symfony/src/Symfony/Component/CssSelector',
  1861. 'src/vendor/symfony/src/Symfony/Component/Process',
  1862. 'src/vendor/zend/library/Zend/Uri',
  1863. 'src/vendor/zend/library/Zend/Http',
  1864. );
  1865. $finder = new Finder();
  1866. $iterator = $finder->files()->name('*.php')->in($dirs);
  1867. return array_merge($files, iterator_to_array($iterator)); } }
  1868. <?php
  1869. namespace Symfony\Component\BrowserKit;
  1870. use Symfony\Component\DomCrawler\Crawler;
  1871. use Symfony\Component\DomCrawler\Link;
  1872. use Symfony\Component\DomCrawler\Form;
  1873. use Symfony\Component\Process\PhpProcess;
  1874. use Symfony\Component\BrowserKit\Request;
  1875. use Symfony\Component\BrowserKit\Response;
  1876. use Symfony\Component\BrowserKit\Client;
  1877. abstract class Client {
  1878. protected $history;
  1879. protected $cookieJar;
  1880. protected $server;
  1881. protected $request;
  1882. protected $response;
  1883. protected $crawler;
  1884. protected $insulated;
  1885. protected $redirect;
  1886. protected $followRedirects;
  1887. public function __construct(array $server = array(), History $history = null, CookieJar $cookieJar = null) {
  1888. $this->setServerParameters($server);
  1889. $this->history = null === $history ? new History() : $history;
  1890. $this->cookieJar = null === $cookieJar ? new CookieJar() : $cookieJar;
  1891. $this->insulated = false;
  1892. $this->followRedirects = true; }
  1893. public function followRedirects($followRedirect = true) {
  1894. $this->followRedirects = (Boolean) $followRedirect; }
  1895. public function insulate($insulated = true) {
  1896. if (!class_exists('Symfony\\Component\\Process\\Process')) {
  1897. throw new \RuntimeException('Unable to isolate requests as the Symfony Process Component is not installed.'); }
  1898. $this->insulated = (Boolean) $insulated; }
  1899. public function setServerParameters(array $server) {
  1900. $this->server = array_merge(array(
  1901. 'HTTP_HOST' => 'localhost',
  1902. 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3',
  1903. ), $server); }
  1904. public function getHistory() {
  1905. return $this->history; }
  1906. public function getCookieJar() {
  1907. return $this->cookieJar; }
  1908. public function getCrawler() {
  1909. return $this->crawler; }
  1910. public function getResponse() {
  1911. return $this->response; }
  1912. public function getRequest() {
  1913. return $this->request; }
  1914. public function click(Link $link) {
  1915. return $this->request($link->getMethod(), $link->getUri()); }
  1916. public function submit(Form $form, array $values = array()) {
  1917. $form->setValues($values);
  1918. return $this->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), array(), $form->getPhpFiles()); }
  1919. public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $changeHistory = true) {
  1920. $uri = $this->getAbsoluteUri($uri);
  1921. $server = array_merge($this->server, $server);
  1922. if (!$this->history->isEmpty()) {
  1923. $server['HTTP_REFERER'] = $this->history->current()->getUri(); }
  1924. $server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST);
  1925. $server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
  1926. $request = new Request($uri, $method, $parameters, $files, $this->cookieJar->getValues($uri), $server);
  1927. $this->request = $this->filterRequest($request);
  1928. if (true === $changeHistory) {
  1929. $this->history->add($request); }
  1930. if ($this->insulated) {
  1931. $this->response = $this->doRequestInProcess($this->request); } else {
  1932. $this->response = $this->doRequest($this->request); }
  1933. $response = $this->filterResponse($this->response);
  1934. $this->cookieJar->updateFromResponse($response, $uri);
  1935. $this->redirect = $response->getHeader('Location');
  1936. if ($this->followRedirects && $this->redirect) {
  1937. return $this->crawler = $this->followRedirect(); }
  1938. return $this->crawler = $this->createCrawlerFromContent($request->getUri(), $response->getContent(), $response->getHeader('Content-Type')); }
  1939. protected function doRequestInProcess($request) {
  1940. $process = new PhpProcess($this->getScript($request));
  1941. $process->run();
  1942. if ($process->getExitCode() > 0) {
  1943. throw new \RuntimeException($process->getErrorOutput()); }
  1944. return unserialize($process->getOutput()); }
  1945. abstract protected function doRequest($request);
  1946. protected function getScript($request) {
  1947. throw new \LogicException('To insulate requests, you need to override the getScript() method.'); }
  1948. protected function filterRequest(Request $request) {
  1949. return $request; }
  1950. protected function filterResponse($response) {
  1951. return $response; }
  1952. protected function createCrawlerFromContent($uri, $content, $type) {
  1953. $crawler = new Crawler(null, $uri);
  1954. $crawler->addContent($content, $type);
  1955. return $crawler; }
  1956. public function back() {
  1957. return $this->requestFromRequest($this->history->back(), false); }
  1958. public function forward() {
  1959. return $this->requestFromRequest($this->history->forward(), false); }
  1960. public function reload() {
  1961. return $this->requestFromRequest($this->history->current(), false); }
  1962. public function followRedirect() {
  1963. if (empty($this->redirect)) {
  1964. throw new \LogicException('The request was not redirected.'); }
  1965. return $this->request('get', $this->redirect); }
  1966. public function restart() {
  1967. $this->cookieJar->clear();
  1968. $this->history->clear(); }
  1969. protected function getAbsoluteUri($uri) {
  1970. if ('http' === substr($uri, 0, 4)) {
  1971. return $uri; }
  1972. if (!$this->history->isEmpty()) {
  1973. $currentUri = $this->history->current()->getUri(); } else {
  1974. $currentUri = sprintf('http%s://%s/',
  1975. isset($this->server['HTTPS']) ? 's' : '',
  1976. isset($this->server['HTTP_HOST']) ? $this->server['HTTP_HOST'] : 'localhost'
  1977. ); }
  1978. if (!$uri || '#' == $uri[0]) {
  1979. return preg_replace('/#.*?$/', '', $currentUri).$uri; }
  1980. if ('/' !== $uri[0]) {
  1981. $path = parse_url($currentUri, PHP_URL_PATH);
  1982. if ('/' !== substr($path, -1)) {
  1983. $path = substr($path, 0, strrpos($path, '/') + 1); }
  1984. $uri = $path.$uri; }
  1985. return preg_replace('#^(.*?//[^/]+)\/.*$#', '$1', $currentUri).$uri; }
  1986. protected function requestFromRequest(Request $request, $changeHistory = true) {
  1987. return $this->request($request->getMethod(), $request->getUri(), $request->getParameters(), array(), $request->getFiles(), $request->getServer(), $changeHistory); } }
  1988. <?php
  1989. namespace Symfony\Component\BrowserKit;
  1990. class Cookie {
  1991. const DATE_FORMAT = 'D, d-M-Y H:i:s T';
  1992. protected $name;
  1993. protected $value;
  1994. protected $expires;
  1995. protected $path;
  1996. protected $domain;
  1997. protected $secure;
  1998. protected $httponly;
  1999. public function __construct($name, $value, $expires = null, $path = '/', $domain = '', $secure = false, $httponly = false) {
  2000. $this->name = $name;
  2001. $this->value = $value;
  2002. $this->expires = null === $expires ? null : (integer) $expires;
  2003. $this->path = empty($path) ? '/' : $path;
  2004. $this->domain = $domain;
  2005. $this->secure = (Boolean) $secure;
  2006. $this->httponly = (Boolean) $httponly; }
  2007. public function __toString() {
  2008. $cookie = sprintf('%s=%s', $this->name, urlencode($this->value));
  2009. if (null !== $this->expires) {
  2010. $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('UTC'))->format(static::DATE_FORMAT), 0, -5); }
  2011. if ('' !== $this->domain) {
  2012. $cookie .= '; domain='.$this->domain; }
  2013. if ('/' !== $this->path) {
  2014. $cookie .= '; path='.$this->path; }
  2015. if ($this->secure) {
  2016. $cookie .= '; secure'; }
  2017. if ($this->httponly) {
  2018. $cookie .= '; httponly'; }
  2019. return $cookie; }
  2020. static public function fromString($cookie, $url = null) {
  2021. $parts = explode(';', $cookie);
  2022. if (false === strpos($parts[0], '=')) {
  2023. throw new \InvalidArgumentException('The cookie string "%s" is not valid.'); }
  2024. list($name, $value) = explode('=', array_shift($parts), 2);
  2025. $values = array(
  2026. 'name' => trim($name),
  2027. 'value' => urldecode(trim($value)),
  2028. 'expires' => null,
  2029. 'path' => '/',
  2030. 'domain' => '',
  2031. 'secure' => false,
  2032. 'httponly' => false,
  2033. );
  2034. if (null !== $url) {
  2035. if ((false === $parts = parse_url($url)) || !isset($parts['host']) || !isset($parts['path'])) {
  2036. throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url)); }
  2037. $values['domain'] = $parts['host'];
  2038. $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/')); }
  2039. foreach ($parts as $part) {
  2040. $part = trim($part);
  2041. if ('secure' === strtolower($part)) {
  2042. $values['secure'] = true;
  2043. continue; }
  2044. if ('httponly' === strtolower($part)) {
  2045. $values['httponly'] = true;
  2046. continue; }
  2047. if (2 === count($elements = explode('=', $part, 2))) {
  2048. if ('expires' === $elements[0]) {
  2049. if (false === $date = \DateTime::createFromFormat(static::DATE_FORMAT, $elements[1], new \DateTimeZone('UTC'))) {
  2050. throw new \InvalidArgumentException(sprintf('The expires part of cookie is not valid (%s).', $elements[1])); }
  2051. $elements[1] = $date->getTimestamp(); }
  2052. $values[strtolower($elements[0])] = $elements[1]; } }
  2053. return new static(
  2054. $values['name'],
  2055. $values['value'],
  2056. $values['expires'],
  2057. $values['path'],
  2058. $values['domain'],
  2059. $values['secure'],
  2060. $values['httponly']
  2061. ); }
  2062. public function getName() {
  2063. return $this->name; }
  2064. public function getValue() {
  2065. return $this->value; }
  2066. public function getExpiresTime() {
  2067. return $this->expires; }
  2068. public function getPath() {
  2069. return $this->path; }
  2070. public function getDomain() {
  2071. return $this->domain; }
  2072. public function isSecure() {
  2073. return $this->secure; }
  2074. public function isHttponly() {
  2075. return $this->httponly; }
  2076. public function isExpired() {
  2077. return (null !== $this->expires) && $this->expires < time(); } }
  2078. <?php
  2079. namespace Symfony\Component\BrowserKit;
  2080. class CookieJar {
  2081. protected $cookieJar = array();
  2082. public function set(Cookie $cookie) {
  2083. $this->cookieJar[$cookie->getName()] = $cookie; }
  2084. public function get($name) {
  2085. $this->flushExpiredCookies();
  2086. return isset($this->cookieJar[$name]) ? $this->cookieJar[$name] : null; }
  2087. public function expire($name) {
  2088. unset($this->cookieJar[$name]); }
  2089. public function clear() {
  2090. $this->cookieJar = array(); }
  2091. public function updateFromResponse(Response $response, $uri = null) {
  2092. foreach ($response->getHeader('Set-Cookie', false) as $cookie) {
  2093. $this->set(Cookie::fromString($cookie), $uri); } }
  2094. public function all() {
  2095. $this->flushExpiredCookies();
  2096. return $this->cookieJar; }
  2097. public function getValues($uri) {
  2098. $this->flushExpiredCookies();
  2099. $parts = parse_url($uri);
  2100. $cookies = array();
  2101. foreach ($this->cookieJar as $cookie) {
  2102. if ($cookie->getDomain() && $cookie->getDomain() != substr($parts['host'], -strlen($cookie->getDomain()))) {
  2103. continue; }
  2104. if ($cookie->getPath() != substr($parts['path'], 0, strlen($cookie->getPath()))) {
  2105. continue; }
  2106. if ($cookie->isSecure() && 'https' != $parts['scheme']) {
  2107. continue; }
  2108. $cookies[$cookie->getName()] = $cookie->getValue(); }
  2109. return $cookies; }
  2110. public function flushExpiredCookies() {
  2111. $cookies = $this->cookieJar;
  2112. foreach ($cookies as $name => $cookie) {
  2113. if ($cookie->isExpired()) {
  2114. unset($this->cookieJar[$name]); } } } }
  2115. <?php
  2116. namespace Symfony\Component\BrowserKit;
  2117. class History {
  2118. protected $stack = array();
  2119. protected $position = -1;
  2120. public function __construct() {
  2121. $this->clear(); }
  2122. public function clear() {
  2123. $this->stack = array();
  2124. $this->position = -1; }
  2125. public function add(Request $request) {
  2126. $this->stack = array_slice($this->stack, 0, $this->position + 1);
  2127. $this->stack[] = clone $request;
  2128. $this->position = count($this->stack) - 1; }
  2129. public function isEmpty() {
  2130. return count($this->stack) == 0; }
  2131. public function back() {
  2132. if ($this->position < 1) {
  2133. throw new \LogicException('You are already on the first page.'); }
  2134. return clone $this->stack[--$this->position]; }
  2135. public function forward() {
  2136. if ($this->position > count($this->stack) - 2) {
  2137. throw new \LogicException('You are already on the last page.'); }
  2138. return clone $this->stack[++$this->position]; }
  2139. public function current() {
  2140. if (-1 == $this->position) {
  2141. throw new \LogicException('The page history is empty.'); }
  2142. return clone $this->stack[$this->position]; } }
  2143. <?php
  2144. namespace Symfony\Component\BrowserKit;
  2145. class Request {
  2146. protected $uri;
  2147. protected $method;
  2148. protected $parameters;
  2149. protected $files;
  2150. protected $cookies;
  2151. protected $server;
  2152. public function __construct($uri, $method, array $parameters = array(), array $files = array(), array $cookies = array(), array $server = array()) {
  2153. $this->uri = $uri;
  2154. $this->method = $method;
  2155. $this->parameters = $parameters;
  2156. $this->files = $files;
  2157. $this->cookies = $cookies;
  2158. $this->server = $server; }
  2159. public function getUri() {
  2160. return $this->uri; }
  2161. public function getMethod() {
  2162. return $this->method; }
  2163. public function getParameters() {
  2164. return $this->parameters; }
  2165. public function getFiles() {
  2166. return $this->files; }
  2167. public function getCookies() {
  2168. return $this->cookies; }
  2169. public function getServer() {
  2170. return $this->server; } }
  2171. <?php
  2172. namespace Symfony\Component\BrowserKit;
  2173. class Response {
  2174. protected $content;
  2175. protected $status;
  2176. protected $headers;
  2177. public function __construct($content = '', $status = 200, array $headers = array()) {
  2178. $this->content = $content;
  2179. $this->status = $status;
  2180. $this->headers = $headers; }
  2181. public function __toString() {
  2182. $headers = '';
  2183. foreach ($this->headers as $name => $value) {
  2184. $headers .= sprintf("%s: %s\n", $name, $value); }
  2185. return $headers."\n".$this->content; }
  2186. public function getContent() {
  2187. return $this->content; }
  2188. public function getStatus() {
  2189. return $this->status; }
  2190. public function getHeaders() {
  2191. return $this->headers; }
  2192. public function getHeader($header, $first = true) {
  2193. foreach ($this->headers as $key => $value) {
  2194. if (str_replace('-', '_', strtolower($key)) == str_replace('-', '_', strtolower($header))) {
  2195. if ($first) {
  2196. return is_array($value) ? (count($value) ? $value[0] : '') : $value; } else {
  2197. return is_array($value) ? $value : array($value); } } }
  2198. return $first ? null : array(); } }
  2199. <?php
  2200. namespace Symfony\Component\DomCrawler;
  2201. use Symfony\Component\CssSelector\Parser as CssParser;
  2202. class Crawler extends \SplObjectStorage {
  2203. protected $uri;
  2204. protected $host;
  2205. protected $path;
  2206. public function __construct($node = null, $uri = null) {
  2207. $this->uri = $uri;
  2208. list($this->host, $this->path) = $this->parseUri($this->uri);
  2209. $this->add($node); }
  2210. public function clear() {
  2211. $this->removeAll($this); }
  2212. public function add($node) {
  2213. if ($node instanceof \DOMNodeList) {
  2214. $this->addNodeList($node); } elseif (is_array($node)) {
  2215. $this->addNodes($node); } elseif (is_string($node)) {
  2216. $this->addContent($node); } elseif (is_object($node)) {
  2217. $this->addNode($node); } }
  2218. public function addContent($content, $type = null) {
  2219. if (empty($type)) {
  2220. $type = 'text/html'; }
  2221. if (!preg_match('/(x|ht)ml/i', $type, $matches)) {
  2222. return null; }
  2223. $charset = 'ISO-8859-1';
  2224. if (false !== $pos = strpos($type, 'charset=')) {
  2225. $charset = substr($type, $pos + 8); }
  2226. if ('x' === $matches[1]) {
  2227. $this->addXmlContent($content, $charset); } else {
  2228. $this->addHtmlContent($content, $charset); } }
  2229. public function addHtmlContent($content, $charset = 'UTF-8') {
  2230. $dom = new \DOMDocument('1.0', $charset);
  2231. $dom->validateOnParse = true;
  2232. @$dom->loadHTML($content);
  2233. $this->addDocument($dom); }
  2234. public function addXmlContent($content, $charset = 'UTF-8') {
  2235. $dom = new \DOMDocument('1.0', $charset);
  2236. $dom->validateOnParse = true;
  2237. @$dom->loadXML(str_replace('xmlns', 'ns', $content));
  2238. $this->addDocument($dom); }
  2239. public function addDocument(\DOMDocument $dom) {
  2240. if ($dom->documentElement) {
  2241. $this->addNode($dom->documentElement); } }
  2242. public function addNodeList(\DOMNodeList $nodes) {
  2243. foreach ($nodes as $node) {
  2244. $this->addNode($node); } }
  2245. public function addNodes(array $nodes) {
  2246. foreach ($nodes as $node) {
  2247. $this->add($node); } }
  2248. public function addNode(\DOMNode $node) {
  2249. if ($node instanceof \DOMDocument) {
  2250. $this->attach($node->documentElement); } else {
  2251. $this->attach($node); } }
  2252. public function eq($position) {
  2253. foreach ($this as $i => $node) {
  2254. if ($i == $position) {
  2255. return new static($node, $this->uri); } }
  2256. return new static(null, $this->uri); }
  2257. public function each(\Closure $closure) {
  2258. $data = array();
  2259. foreach ($this as $i => $node) {
  2260. $data[] = $closure($node, $i); }
  2261. return $data; }
  2262. public function reduce(\Closure $closure) {
  2263. $nodes = array();
  2264. foreach ($this as $i => $node) {
  2265. if (false !== $closure($node, $i)) {
  2266. $nodes[] = $node; } }
  2267. return new static($nodes, $this->uri); }
  2268. public function first() {
  2269. return $this->eq(0); }
  2270. public function last() {
  2271. return $this->eq(count($this) - 1); }
  2272. public function siblings() {
  2273. if (!count($this)) {
  2274. throw new \InvalidArgumentException('The current node list is empty.'); }
  2275. return new static($this->sibling($this->getNode(0)->parentNode->firstChild), $this->uri); }
  2276. public function nextAll() {
  2277. if (!count($this)) {
  2278. throw new \InvalidArgumentException('The current node list is empty.'); }
  2279. return new static($this->sibling($this->getNode(0)), $this->uri); }
  2280. public function previousAll() {
  2281. if (!count($this)) {
  2282. throw new \InvalidArgumentException('The current node list is empty.'); }
  2283. return new static($this->sibling($this->getNode(0), 'previousSibling'), $this->uri); }
  2284. public function parents() {
  2285. if (!count($this)) {
  2286. throw new \InvalidArgumentException('The current node list is empty.'); }
  2287. $node = $this->getNode(0);
  2288. $nodes = array();
  2289. while ($node = $node->parentNode) {
  2290. if (1 === $node->nodeType && '_root' !== $node->nodeName) {
  2291. $nodes[] = $node; } }
  2292. return new static($nodes, $this->uri); }
  2293. public function children() {
  2294. if (!count($this)) {
  2295. throw new \InvalidArgumentException('The current node list is empty.'); }
  2296. return new static($this->sibling($this->getNode(0)->firstChild), $this->uri); }
  2297. public function attr($attribute) {
  2298. if (!count($this)) {
  2299. throw new \InvalidArgumentException('The current node list is empty.'); }
  2300. return $this->getNode(0)->getAttribute($attribute); }
  2301. public function text() {
  2302. if (!count($this)) {
  2303. throw new \InvalidArgumentException('The current node list is empty.'); }
  2304. return $this->getNode(0)->nodeValue; }
  2305. public function extract($attributes) {
  2306. if (!is_array($attributes)) {
  2307. $attributes = array($attributes); }
  2308. $data = array();
  2309. foreach ($this as $node) {
  2310. $elements = array();
  2311. foreach ($attributes as $attribute) {
  2312. if ('_text' === $attribute) {
  2313. $elements[] = $node->nodeValue; } else {
  2314. $elements[] = $node->getAttribute($attribute); } }
  2315. $data[] = count($attributes) > 1 ? $elements : $elements[0]; }
  2316. return $data; }
  2317. public function filterXPath($xpath) {
  2318. $document = new \DOMDocument('1.0', 'UTF-8');
  2319. $root = $document->appendChild($document->createElement('_root'));
  2320. foreach ($this as $node) {
  2321. $root->appendChild($document->importNode($node, true)); }
  2322. $domxpath = new \DOMXPath($document);
  2323. return new static($domxpath->query($xpath), $this->uri); }
  2324. public function filter($selector) {
  2325. if (!class_exists('Symfony\\Component\\CssSelector\\Parser')) {
  2326. throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector is not installed (you can use filterXPath instead).'); }
  2327. return $this->filterXPath(CssParser::cssToXpath($selector)); }
  2328. public function selectLink($value) {
  2329. $xpath = sprintf('//a[contains(concat(\' \', normalize-space(string(.)), \' \'), %s)] ', static::xpathLiteral(' '.$value.' ')).
  2330. sprintf('| //a/img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)]/ancestor::a', static::xpathLiteral(' '.$value.' '));
  2331. return $this->filterXPath($xpath); }
  2332. public function selectButton($value) {
  2333. $xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')).
  2334. sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value).
  2335. sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value);
  2336. return $this->filterXPath($xpath); }
  2337. public function link($method = 'get') {
  2338. if (!count($this)) {
  2339. throw new \InvalidArgumentException('The current node list is empty.'); }
  2340. $node = $this->getNode(0);
  2341. return new Link($node, $method, $this->host, $this->path); }
  2342. public function links() {
  2343. $links = array();
  2344. foreach ($this as $node) {
  2345. $links[] = new Link($node, 'get', $this->host, $this->path); }
  2346. return $links; }
  2347. public function form(array $values = null, $method = null) {
  2348. if (!count($this)) {
  2349. throw new \InvalidArgumentException('The current node list is empty.'); }
  2350. $form = new Form($this->getNode(0), $method, $this->host, $this->path);
  2351. if (null !== $values) {
  2352. $form->setValues($values); }
  2353. return $form; }
  2354. protected function getNode($position) {
  2355. foreach ($this as $i => $node) {
  2356. if ($i == $position) {
  2357. return $node; } }
  2358. return null; }
  2359. protected function parseUri($uri) {
  2360. if ('http' !== substr($uri, 0, 4)) {
  2361. return array(null, '/'); }
  2362. $path = parse_url($uri, PHP_URL_PATH);
  2363. if ('/' !== substr($path, -1)) {
  2364. $path = substr($path, 0, strrpos($path, '/') + 1); }
  2365. return array(preg_replace('#^(.*?//[^/]+)\/.*$#', '$1', $uri), $path); }
  2366. protected function sibling($node, $siblingDir = 'nextSibling') {
  2367. $nodes = array();
  2368. do {
  2369. if ($node !== $this->getNode(0) && $node->nodeType === 1) {
  2370. $nodes[] = $node; } } while($node = $node->$siblingDir);
  2371. return $nodes; }
  2372. static public function xpathLiteral($s) {
  2373. if (false === strpos($s, "'")) {
  2374. return sprintf("'%s'", $s); }
  2375. if (false === strpos($s, '"')) {
  2376. return sprintf('"%s"', $s); }
  2377. $string = $s;
  2378. $parts = array();
  2379. while (true) {
  2380. if (false !== $pos = strpos($string, "'")) {
  2381. $parts[] = sprintf("'%s'", substr($string, 0, $pos));
  2382. $parts[] = "\"'\"";
  2383. $string = substr($string, $pos + 1); } else {
  2384. $parts[] = "'$string'";
  2385. break; } }
  2386. return sprintf("concat(%s)", implode($parts, ', ')); } }
  2387. <?php
  2388. namespace Symfony\Component\DomCrawler\Field;
  2389. class ChoiceFormField extends FormField {
  2390. protected $type;
  2391. protected $multiple;
  2392. protected $options;
  2393. public function hasValue() {
  2394. if (in_array($this->type, array('checkbox', 'radio')) && null === $this->value) {
  2395. return false; }
  2396. return true; }
  2397. public function select($value) {
  2398. $this->setValue($value); }
  2399. public function tick() {
  2400. if ('checkbox' !== $this->type) {
  2401. throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); }
  2402. $this->setValue(true); }
  2403. public function untick() {
  2404. if ('checkbox' !== $this->type) {
  2405. throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); }
  2406. $this->setValue(false); }
  2407. public function setValue($value) {
  2408. if ('checkbox' == $this->type && false === $value) {
  2409. $this->value = null; } elseif ('checkbox' == $this->type && true === $value) {
  2410. $this->value = $this->options[0]; } else {
  2411. if (is_array($value)) {
  2412. if (!$this->multiple) {
  2413. throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name)); }
  2414. foreach ($value as $v) {
  2415. if (!in_array($v, $this->options)) {
  2416. 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)) {
  2417. throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->options))); }
  2418. if ($this->multiple && !is_array($value)) {
  2419. $value = array($value); }
  2420. if (is_array($value)) {
  2421. $this->value = $value; } else {
  2422. parent::setValue($value); } } }
  2423. public function addChoice(\DOMNode $node) {
  2424. if (!$this->multiple && 'radio' != $this->type) {
  2425. throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); }
  2426. $this->options[] = $value = $node->hasAttribute('value') ? $node->getAttribute('value') : '1';
  2427. if ($node->getAttribute('checked')) {
  2428. $this->value = $value; } }
  2429. public function getType() {
  2430. return $this->type; }
  2431. public function isMultiple() {
  2432. return $this->multiple; }
  2433. protected function initialize() {
  2434. if ('input' != $this->node->nodeName && 'select' != $this->node->nodeName) {
  2435. throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); }
  2436. if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) {
  2437. 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'))); }
  2438. $this->value = null;
  2439. $this->options = array();
  2440. $this->multiple = false;
  2441. if ('input' == $this->node->nodeName) {
  2442. $this->type = $this->node->getAttribute('type');
  2443. $this->options[] = $value = $this->node->hasAttribute('value') ? $this->node->getAttribute('value') : '1';
  2444. if ($this->node->getAttribute('checked')) {
  2445. $this->value = $value; } } else {
  2446. $this->type = 'select';
  2447. if ($this->node->hasAttribute('multiple')) {
  2448. $this->multiple = true;
  2449. $this->value = array();
  2450. $this->name = str_replace('[]', '', $this->name); }
  2451. $found = false;
  2452. foreach ($this->xpath->query('descendant::option', $this->node) as $option) {
  2453. $this->options[] = $option->getAttribute('value');
  2454. if ($option->getAttribute('selected')) {
  2455. $found = true;
  2456. if ($this->multiple) {
  2457. $this->value[] = $option->getAttribute('value'); } else {
  2458. $this->value = $option->getAttribute('value'); } } }
  2459. $option = $this->xpath->query('descendant::option', $this->node)->item(0);
  2460. if (!$found && !$this->multiple && $option instanceof \DOMElement) {
  2461. $this->value = $option->getAttribute('value'); } } } }
  2462. <?php
  2463. namespace Symfony\Component\DomCrawler\Field;
  2464. class FileFormField extends FormField {
  2465. public function setErrorCode($error) {
  2466. $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);
  2467. if (!in_array($error, $codes)) {
  2468. throw new \InvalidArgumentException(sprintf('The error code %s is not valid.', $error)); }
  2469. $this->value = array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => $error, 'size' => 0); }
  2470. public function upload($value) {
  2471. $this->setValue($value); }
  2472. public function setValue($value) {
  2473. if (null !== $value && is_readable($value)) {
  2474. $error = UPLOAD_ERR_OK;
  2475. $size = filesize($value); } else {
  2476. $error = UPLOAD_ERR_NO_FILE;
  2477. $size = 0;
  2478. $value = ''; }
  2479. $this->value = array('name' => basename($value), 'type' => '', 'tmp_name' => $value, 'error' => $error, 'size' => $size); }
  2480. protected function initialize() {
  2481. if ('input' != $this->node->nodeName) {
  2482. throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); }
  2483. if ('file' != $this->node->getAttribute('type')) {
  2484. 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'))); }
  2485. $this->setValue(null); } }
  2486. <?php
  2487. namespace Symfony\Component\DomCrawler\Field;
  2488. abstract class FormField {
  2489. protected $node;
  2490. protected $name;
  2491. protected $value;
  2492. protected $document;
  2493. protected $xpath;
  2494. public function __construct(\DOMNode $node) {
  2495. $this->node = $node;
  2496. $this->name = $node->getAttribute('name');
  2497. $this->document = new \DOMDocument('1.0', 'UTF-8');
  2498. $this->node = $this->document->importNode($this->node, true);
  2499. $root = $this->document->appendChild($this->document->createElement('_root'));
  2500. $root->appendChild($this->node);
  2501. $this->xpath = new \DOMXPath($this->document);
  2502. $this->initialize(); }
  2503. public function getName() {
  2504. return $this->name; }
  2505. public function getValue() {
  2506. return $this->value; }
  2507. public function setValue($value) {
  2508. $this->value = (string) $value; }
  2509. public function hasValue() {
  2510. return true; }
  2511. abstract protected function initialize(); }
  2512. <?php
  2513. namespace Symfony\Component\DomCrawler\Field;
  2514. class InputFormField extends FormField {
  2515. protected function initialize() {
  2516. if ('input' != $this->node->nodeName) {
  2517. throw new \LogicException(sprintf('An InputFormField can only be created from an input tag (%s given).', $this->node->nodeName)); }
  2518. if ('checkbox' == $this->node->getAttribute('type')) {
  2519. throw new \LogicException('Checkboxes should be instances of ChoiceFormField.'); }
  2520. if ('file' == $this->node->getAttribute('type')) {
  2521. throw new \LogicException('File inputs should be instances of FileFormField.'); }
  2522. $this->value = $this->node->getAttribute('value'); } }
  2523. <?php
  2524. namespace Symfony\Component\DomCrawler\Field;
  2525. class TextareaFormField extends FormField {
  2526. protected function initialize() {
  2527. if ('textarea' != $this->node->nodeName) {
  2528. throw new \LogicException(sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName)); }
  2529. $this->value = null;
  2530. foreach ($this->node->childNodes as $node) {
  2531. $this->value .= $this->document->saveXML($node); } } }
  2532. <?php
  2533. namespace Symfony\Component\DomCrawler;
  2534. use Symfony\Component\DomCrawler\FormField;
  2535. class Form implements \ArrayAccess {
  2536. protected $document;
  2537. protected $button;
  2538. protected $node;
  2539. protected $fields;
  2540. protected $method;
  2541. protected $host;
  2542. protected $path;
  2543. public function __construct(\DOMNode $node, $method = null, $host = null, $path = '/') {
  2544. $this->button = $node;
  2545. if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) {
  2546. do {
  2547. if (null === $node = $node->parentNode) {
  2548. throw new \LogicException('The selected node does not have a form ancestor.'); } } while ('form' != $node->nodeName); } else {
  2549. throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName)); }
  2550. $this->node = $node;
  2551. $this->method = $method;
  2552. $this->host = $host;
  2553. $this->path = empty($path) ? '/' : $path;
  2554. $this->initialize(); }
  2555. public function getFormNode() {
  2556. return $this->node; }
  2557. public function setValues(array $values) {
  2558. foreach ($values as $name => $value) {
  2559. $this[$name] = $value; }
  2560. return $this; }
  2561. public function getValues() {
  2562. $values = array();
  2563. foreach ($this->fields as $name => $field) {
  2564. if (!$field instanceof Field\FileFormField && $field->hasValue()) {
  2565. $values[$name] = $field->getValue(); } }
  2566. return $values; }
  2567. public function getFiles() {
  2568. if (!in_array($this->getMethod(), array('post', 'put', 'delete'))) {
  2569. return array(); }
  2570. $files = array();
  2571. foreach ($this->fields as $name => $field) {
  2572. if ($field instanceof Field\FileFormField) {
  2573. $files[$name] = $field->getValue(); } }
  2574. return $files; }
  2575. public function getPhpValues() {
  2576. $qs = http_build_query($this->getValues());
  2577. parse_str($qs, $values);
  2578. return $values; }
  2579. public function getPhpFiles() {
  2580. $qs = http_build_query($this->getFiles());
  2581. parse_str($qs, $values);
  2582. return $values; }
  2583. public function getUri($absolute = true) {
  2584. $uri = $this->node->getAttribute('action');
  2585. $urlHaveScheme = 'http' === substr($uri, 0, 4);
  2586. if (!in_array($this->getMethod(), array('post', 'put', 'delete')) && $queryString = http_build_query($this->getValues(), null, '&')) {
  2587. $sep = false === strpos($uri, '?') ? '?' : '&';
  2588. $uri .= $sep.$queryString; }
  2589. if ($uri && '/' !== $uri[0] && !$urlHaveScheme) {
  2590. $uri = $this->path.$uri; }
  2591. if ($absolute && null !== $this->host && !$urlHaveScheme) {
  2592. return $this->host.$uri; }
  2593. return $uri; }
  2594. public function getMethod() {
  2595. if (null !== $this->method) {
  2596. return $this->method; }
  2597. return $this->node->getAttribute('method') ? strtolower($this->node->getAttribute('method')) : 'get'; }
  2598. public function hasField($name) {
  2599. return isset($this->fields[$name]); }
  2600. public function getField($name) {
  2601. if (!$this->hasField($name)) {
  2602. throw new \InvalidArgumentException(sprintf('The form has no "%s" field', $name)); }
  2603. return $this->fields[$name]; }
  2604. public function setField(Field\FormField $field) {
  2605. $this->fields[$field->getName()] = $field; }
  2606. public function getFields() {
  2607. return $this->fields; }
  2608. protected function initialize() {
  2609. $this->fields = array();
  2610. $document = new \DOMDocument('1.0', 'UTF-8');
  2611. $node = $document->importNode($this->node, true);
  2612. $button = $document->importNode($this->button, true);
  2613. $root = $document->appendChild($document->createElement('_root'));
  2614. $root->appendChild($node);
  2615. $root->appendChild($button);
  2616. $xpath = new \DOMXPath($document);
  2617. foreach ($xpath->query('descendant::input | descendant::textarea | descendant::select', $root) as $node) {
  2618. if ($node->hasAttribute('disabled') || !$node->hasAttribute('name')) {
  2619. continue; }
  2620. $nodeName = $node->nodeName;
  2621. if ($node === $button) {
  2622. $this->setField(new Field\InputFormField($node)); } elseif ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) {
  2623. $this->setField(new Field\ChoiceFormField($node)); } elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) {
  2624. if ($this->hasField($node->getAttribute('name'))) {
  2625. $this->getField($node->getAttribute('name'))->addChoice($node); } else {
  2626. $this->setField(new Field\ChoiceFormField($node)); } } elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) {
  2627. $this->setField(new Field\FileFormField($node)); } elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) {
  2628. $this->setField(new Field\InputFormField($node)); } elseif ('textarea' == $nodeName) {
  2629. $this->setField(new Field\TextareaFormField($node)); } } }
  2630. public function offsetExists($name) {
  2631. return $this->hasField($name); }
  2632. public function offsetGet($name) {
  2633. if (!$this->hasField($name)) {
  2634. throw new \InvalidArgumentException(sprintf('The form field "%s" does not exist', $name)); }
  2635. return $this->fields[$name]; }
  2636. public function offsetSet($name, $value) {
  2637. if (!$this->hasField($name)) {
  2638. throw new \InvalidArgumentException(sprintf('The form field "%s" does not exist', $name)); }
  2639. $this->fields[$name]->setValue($value); }
  2640. public function offsetUnset($name) {
  2641. throw new \LogicException('The Form fields cannot be removed.'); } }
  2642. <?php
  2643. namespace Symfony\Component\DomCrawler;
  2644. class Link {
  2645. protected $node;
  2646. protected $method;
  2647. protected $host;
  2648. protected $path;
  2649. public function __construct(\DOMNode $node, $method = 'get', $host = null, $path = '/') {
  2650. if ('a' != $node->nodeName) {
  2651. throw new \LogicException(sprintf('Unable to click on a "%s" tag.', $node->nodeName)); }
  2652. $this->node = $node;
  2653. $this->method = $method;
  2654. $this->host = $host;
  2655. $this->path = empty($path) ? '/' : $path; }
  2656. public function getNode() {
  2657. return $this->node; }
  2658. public function getUri($absolute = true) {
  2659. $uri = $this->node->getAttribute('href');
  2660. $urlHaveScheme = 'http' === substr($uri, 0, 4);
  2661. if ($uri && '/' !== $uri[0] && !$urlHaveScheme) {
  2662. $uri = $this->path.$uri; }
  2663. if ($absolute && null !== $this->host && !$urlHaveScheme) {
  2664. return $this->host.$uri; }
  2665. return $uri; }
  2666. public function getMethod() {
  2667. return $this->method; } }
  2668. <?php
  2669. namespace Symfony\Component\CssSelector\Node;
  2670. use Symfony\Component\CssSelector\XPathExpr;
  2671. use Symfony\Component\CssSelector\SyntaxError;
  2672. class AttribNode implements NodeInterface {
  2673. protected $selector;
  2674. protected $namespace;
  2675. protected $attrib;
  2676. protected $operator;
  2677. protected $value;
  2678. public function __construct($selector, $namespace, $attrib, $operator, $value) {
  2679. $this->selector = $selector;
  2680. $this->namespace = $namespace;
  2681. $this->attrib = $attrib;
  2682. $this->operator = $operator;
  2683. $this->value = $value; }
  2684. public function __toString() {
  2685. if ($this->operator == 'exists') {
  2686. return sprintf('%s[%s[%s]]', __CLASS__, $this->selector, $this->formatAttrib()); } else {
  2687. return sprintf('%s[%s[%s %s %s]]', __CLASS__, $this->selector, $this->formatAttrib(), $this->operator, $this->value); } }
  2688. public function toXpath() {
  2689. $path = $this->selector->toXpath();
  2690. $attrib = $this->xpathAttrib();
  2691. $value = $this->value;
  2692. if ($this->operator == 'exists') {
  2693. $path->addCondition($attrib); } elseif ($this->operator == '=') {
  2694. $path->addCondition(sprintf('%s = %s', $attrib, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '!=') {
  2695. if ($value) {
  2696. $path->addCondition(sprintf('not(%s) or %s != %s', $attrib, $attrib, XPathExpr::xpathLiteral($value))); } else {
  2697. $path->addCondition(sprintf('%s != %s', $attrib, XPathExpr::xpathLiteral($value))); } } elseif ($this->operator == '~=') {
  2698. $path->addCondition(sprintf("contains(concat(' ', normalize-space(%s), ' '), %s)", $attrib, XPathExpr::xpathLiteral(' '.$value.' '))); } elseif ($this->operator == '|=') {
  2699. $path->addCondition(sprintf('%s = %s or starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value), $attrib, XPathExpr::xpathLiteral($value.'-'))); } elseif ($this->operator == '^=') {
  2700. $path->addCondition(sprintf('starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '$=') {
  2701. $path->addCondition(sprintf('substring(%s, string-length(%s)-%s) = %s', $attrib, $attrib, strlen($value) - 1, XPathExpr::xpathLiteral($value))); } elseif ($this->operator == '*=') {
  2702. $path->addCondition(sprintf('contains(%s, %s)', $attrib, XPathExpr::xpathLiteral($value))); } else {
  2703. throw new SyntaxError(sprintf('Unknown operator: %s', $this->operator)); }
  2704. return $path; }
  2705. protected function xpathAttrib() {
  2706. if ($this->namespace == '*') {
  2707. return '@'.$this->attrib; }
  2708. return sprintf('@%s:%s', $this->namespace, $this->attrib); }
  2709. protected function formatAttrib() {
  2710. if ($this->namespace == '*') {
  2711. return $this->attrib; }
  2712. return sprintf('%s|%s', $this->namespace, $this->attrib); } }
  2713. <?php
  2714. namespace Symfony\Component\CssSelector\Node;
  2715. use Symfony\Component\CssSelector\XPathExpr;
  2716. class ClassNode implements NodeInterface {
  2717. protected $selector;
  2718. protected $className;
  2719. public function __construct($selector, $className) {
  2720. $this->selector = $selector;
  2721. $this->className = $className; }
  2722. public function __toString() {
  2723. return sprintf('%s[%s.%s]', __CLASS__, $this->selector, $this->className); }
  2724. public function toXpath() {
  2725. $selXpath = $this->selector->toXpath();
  2726. $selXpath->addCondition(sprintf("contains(concat(' ', normalize-space(@class), ' '), %s)", XPathExpr::xpathLiteral(' '.$this->className.' ')));
  2727. return $selXpath; } }
  2728. <?php
  2729. namespace Symfony\Component\CssSelector\Node;
  2730. use Symfony\Component\CssSelector\SyntaxError;
  2731. class CombinedSelectorNode implements NodeInterface {
  2732. static protected $_method_mapping = array(
  2733. ' ' => 'descendant',
  2734. '>' => 'child',
  2735. '+' => 'direct_adjacent',
  2736. '~' => 'indirect_adjacent',
  2737. );
  2738. protected $selector;
  2739. protected $combinator;
  2740. protected $subselector;
  2741. public function __construct($selector, $combinator, $subselector) {
  2742. $this->selector = $selector;
  2743. $this->combinator = $combinator;
  2744. $this->subselector = $subselector; }
  2745. public function __toString() {
  2746. $comb = $this->combinator == ' ' ? '<followed>' : $this->combinator;
  2747. return sprintf('%s[%s %s %s]', __CLASS__, $this->selector, $comb, $this->subselector); }
  2748. public function toXpath() {
  2749. if (!isset(self::$_method_mapping[$this->combinator])) {
  2750. throw new SyntaxError(sprintf('Unknown combinator: %s', $this->combinator)); }
  2751. $method = '_xpath_'.self::$_method_mapping[$this->combinator];
  2752. $path = $this->selector->toXpath();
  2753. return $this->$method($path, $this->subselector); }
  2754. protected function _xpath_descendant($xpath, $sub) {
  2755. $xpath->join('/descendant::', $sub->toXpath());
  2756. return $xpath; }
  2757. protected function _xpath_child($xpath, $sub) {
  2758. $xpath->join('/', $sub->toXpath());
  2759. return $xpath; }
  2760. protected function _xpath_direct_adjacent($xpath, $sub) {
  2761. $xpath->join('/following-sibling::', $sub->toXpath());
  2762. $xpath->addNameTest();
  2763. $xpath->addCondition('position() = 1');
  2764. return $xpath; }
  2765. protected function _xpath_indirect_adjacent($xpath, $sub) {
  2766. $xpath->join('/following-sibling::', $sub->toXpath());
  2767. return $xpath; } }
  2768. <?php
  2769. namespace Symfony\Component\CssSelector\Node;
  2770. use Symfony\Component\CssSelector\XPathExpr;
  2771. class ElementNode implements NodeInterface {
  2772. protected $namespace;
  2773. protected $element;
  2774. public function __construct($namespace, $element) {
  2775. $this->namespace = $namespace;
  2776. $this->element = $element; }
  2777. public function __toString() {
  2778. return sprintf('%s[%s]', __CLASS__, $this->formatElement()); }
  2779. public function formatElement() {
  2780. if ($this->namespace == '*') {
  2781. return $this->element; }
  2782. return sprintf('%s|%s', $this->namespace, $this->element); }
  2783. public function toXpath() {
  2784. if ($this->namespace == '*') {
  2785. $el = strtolower($this->element); } else {
  2786. $el = sprintf('%s:%s', $this->namespace, $this->element); }
  2787. return new XPathExpr(null, null, $el); } }
  2788. <?php
  2789. namespace Symfony\Component\CssSelector\Node;
  2790. use Symfony\Component\CssSelector\SyntaxError;
  2791. use Symfony\Component\CssSelector\XPathExpr;
  2792. class FunctionNode implements NodeInterface {
  2793. static protected $unsupported = array('target', 'lang', 'enabled', 'disabled');
  2794. protected $selector;
  2795. protected $type;
  2796. protected $name;
  2797. protected $expr;
  2798. public function __construct($selector, $type, $name, $expr) {
  2799. $this->selector = $selector;
  2800. $this->type = $type;
  2801. $this->name = $name;
  2802. $this->expr = $expr; }
  2803. public function __toString() {
  2804. return sprintf('%s[%s%s%s(%s)]', __CLASS__, $this->selector, $this->type, $this->name, $this->expr); }
  2805. public function toXpath() {
  2806. $sel_path = $this->selector->toXpath();
  2807. if (in_array($this->name, self::$unsupported)) {
  2808. throw new SyntaxError(sprintf('The pseudo-class %s is not supported', $this->name)); }
  2809. $method = '_xpath_'.str_replace('-', '_', $this->name);
  2810. if (!method_exists($this, $method)) {
  2811. throw new SyntaxError(sprintf('The pseudo-class %s is unknown', $this->name)); }
  2812. return $this->$method($sel_path, $this->expr); }
  2813. protected function _xpath_nth_child($xpath, $expr, $last = false, $addNameTest = true) {
  2814. list($a, $b) = $this->parseSeries($expr);
  2815. if (!$a && !$b && !$last) {
  2816. $xpath->addCondition('false() and position() = 0');
  2817. return $xpath; }
  2818. if ($addNameTest) {
  2819. $xpath->addNameTest(); }
  2820. $xpath->addStarPrefix();
  2821. if ($a == 0) {
  2822. if ($last) {
  2823. $b = sprintf('last() - %s', $b); }
  2824. $xpath->addCondition(sprintf('position() = %s', $b));
  2825. return $xpath; }
  2826. if ($last) {
  2827. $a = -$a;
  2828. $b = -$b; }
  2829. if ($b > 0) {
  2830. $b_neg = -$b; } else {
  2831. $b_neg = sprintf('+%s', -$b); }
  2832. if ($a != 1) {
  2833. $expr = array(sprintf('(position() %s) mod %s = 0', $b_neg, $a)); } else {
  2834. $expr = array(); }
  2835. if ($b >= 0) {
  2836. $expr[] = sprintf('position() >= %s', $b); } elseif ($b < 0 && $last) {
  2837. $expr[] = sprintf('position() < (last() %s)', $b); }
  2838. $expr = implode($expr, ' and ');
  2839. if ($expr) {
  2840. $xpath->addCondition($expr); }
  2841. return $xpath; }
  2842. protected function _xpath_nth_last_child($xpath, $expr) {
  2843. return $this->_xpath_nth_child($xpath, $expr, true); }
  2844. protected function _xpath_nth_of_type($xpath, $expr) {
  2845. if ($xpath->getElement() == '*') {
  2846. throw new SyntaxError('*:nth-of-type() is not implemented'); }
  2847. return $this->_xpath_nth_child($xpath, $expr, false, false); }
  2848. protected function _xpath_nth_last_of_type($xpath, $expr) {
  2849. return $this->_xpath_nth_child($xpath, $expr, true, false); }
  2850. protected function _xpath_contains($xpath, $expr) {
  2851. if ($expr instanceof ElementNode) {
  2852. $expr = $expr->formatElement(); }
  2853. $xpath->addCondition(sprintf('contains(string(.), %s)', XPathExpr::xpathLiteral($expr)));
  2854. return $xpath; }
  2855. protected function _xpath_not($xpath, $expr) {
  2856. $expr = $expr->toXpath();
  2857. $cond = $expr->getCondition();
  2858. $xpath->addCondition(sprintf('not(%s)', $cond));
  2859. return $xpath; }
  2860. protected function parseSeries($s) {
  2861. if ($s instanceof ElementNode) {
  2862. $s = $s->formatElement(); }
  2863. if (!$s || $s == '*') {
  2864. return array(0, 0); }
  2865. if (is_string($s)) {
  2866. return array(0, $s); }
  2867. if ($s == 'odd') {
  2868. return array(2, 1); }
  2869. if ($s == 'even') {
  2870. return array(2, 0); }
  2871. if ($s == 'n') {
  2872. return array(1, 0); }
  2873. if (false === strpos($s, 'n')) {
  2874. return array(0, intval((string) $s)); }
  2875. list($a, $b) = explode('n', $s);
  2876. if (!$a) {
  2877. $a = 1; } elseif ($a == '-' || $a == '+') {
  2878. $a = intval($a.'1'); } else {
  2879. $a = intval($a); }
  2880. if (!$b) {
  2881. $b = 0; } elseif ($b == '-' || $b == '+') {
  2882. $b = intval($b.'1'); } else {
  2883. $b = intval($b); }
  2884. return array($a, $b); } }
  2885. <?php
  2886. namespace Symfony\Component\CssSelector\Node;
  2887. use Symfony\Component\CssSelector\XPathExpr;
  2888. class HashNode implements NodeInterface {
  2889. protected $selector;
  2890. protected $id;
  2891. public function __construct($selector, $id) {
  2892. $this->selector = $selector;
  2893. $this->id = $id; }
  2894. public function __toString() {
  2895. return sprintf('%s[%s#%s]', __CLASS__, $this->selector, $this->id); }
  2896. public function toXpath() {
  2897. $path = $this->selector->toXpath();
  2898. $path->addCondition(sprintf('@id = %s', XPathExpr::xpathLiteral($this->id)));
  2899. return $path; } }
  2900. <?php
  2901. namespace Symfony\Component\CssSelector\Node;
  2902. interface NodeInterface {
  2903. public function __toString();
  2904. public function toXpath(); }
  2905. <?php
  2906. namespace Symfony\Component\CssSelector\Node;
  2907. use Symfony\Component\CssSelector\XPathExprOr;
  2908. class OrNode implements NodeInterface {
  2909. protected $items;
  2910. public function __construct($items) {
  2911. $this->items = $items; }
  2912. public function __toString() {
  2913. return sprintf('%s(%s)', __CLASS__, $this->items); }
  2914. public function toXpath() {
  2915. $paths = array();
  2916. foreach ($this->items as $item) {
  2917. $paths[] = $item->toXpath(); }
  2918. return new XPathExprOr($paths); } }
  2919. <?php
  2920. namespace Symfony\Component\CssSelector\Node;
  2921. use Symfony\Component\CssSelector\SyntaxError;
  2922. class PseudoNode implements NodeInterface {
  2923. static protected $unsupported = array(
  2924. 'indeterminate', 'first-line', 'first-letter',
  2925. 'selection', 'before', 'after', 'link', 'visited',
  2926. 'active', 'focus', 'hover',
  2927. );
  2928. protected $element;
  2929. protected $type;
  2930. protected $ident;
  2931. public function __construct($element, $type, $ident) {
  2932. $this->element = $element;
  2933. if (!in_array($type, array(':', '::'))) {
  2934. throw new SyntaxError(sprintf('The PseudoNode type can only be : or :: (%s given).', $type)); }
  2935. $this->type = $type;
  2936. $this->ident = $ident; }
  2937. public function __toString() {
  2938. return sprintf('%s[%s%s%s]', __CLASS__, $this->element, $this->type, $this->ident); }
  2939. public function toXpath() {
  2940. $el_xpath = $this->element->toXpath();
  2941. if (in_array($this->ident, self::$unsupported)) {
  2942. throw new SyntaxError(sprintf('The pseudo-class %s is unsupported', $this->ident)); }
  2943. $method = 'xpath_'.str_replace('-', '_', $this->ident);
  2944. if (!method_exists($this, $method)) {
  2945. throw new SyntaxError(sprintf('The pseudo-class %s is unknown', $this->ident)); }
  2946. return $this->$method($el_xpath); }
  2947. protected function xpath_checked($xpath) {
  2948. $xpath->addCondition("(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')");
  2949. return $xpath; }
  2950. protected function xpath_root($xpath) {
  2951. throw new SyntaxError(); }
  2952. protected function xpath_first_child($xpath) {
  2953. $xpath->addStarPrefix();
  2954. $xpath->addNameTest();
  2955. $xpath->addCondition('position() = 1');
  2956. return $xpath; }
  2957. protected function xpath_last_child($xpath) {
  2958. $xpath->addStarPrefix();
  2959. $xpath->addNameTest();
  2960. $xpath->addCondition('position() = last()');
  2961. return $xpath; }
  2962. protected function xpath_first_of_type($xpath) {
  2963. if ($xpath->getElement() == '*') {
  2964. throw new SyntaxError('*:first-of-type is not implemented'); }
  2965. $xpath->addStarPrefix();
  2966. $xpath->addCondition('position() = 1');
  2967. return $xpath; }
  2968. protected function xpath_last_of_type($xpath) {
  2969. if ($xpath->getElement() == '*') {
  2970. throw new SyntaxError('*:last-of-type is not implemented'); }
  2971. $xpath->addStarPrefix();
  2972. $xpath->addCondition('position() = last()');
  2973. return $xpath; }
  2974. protected function xpath_only_child($xpath) {
  2975. $xpath->addNameTest();
  2976. $xpath->addStarPrefix();
  2977. $xpath->addCondition('last() = 1');
  2978. return $xpath; }
  2979. protected function xpath_only_of_type($xpath) {
  2980. if ($xpath->getElement() == '*') {
  2981. throw new SyntaxError('*:only-of-type is not implemented'); }
  2982. $xpath->addCondition('last() = 1');
  2983. return $xpath; }
  2984. protected function xpath_empty($xpath) {
  2985. $xpath->addCondition('not(*) and not(normalize-space())');
  2986. return $xpath; } }
  2987. <?php
  2988. namespace Symfony\Component\CssSelector;
  2989. class Parser {
  2990. static public function cssToXpath($cssExpr, $prefix = 'descendant-or-self::') {
  2991. if (is_string($cssExpr)) {
  2992. if (preg_match('#^\w+\s*$#u', $cssExpr, $match)) {
  2993. return $prefix.trim($match[0]); }
  2994. if (preg_match('~^(\w*)#(\w+)\s*$~u', $cssExpr, $match)) {
  2995. return sprintf("%s%s[@id = '%s']", $prefix, $match[1] ? $match[1] : '*', $match[2]); }
  2996. if (preg_match('#^(\w*)\.(\w+)\s*$#u', $cssExpr, $match)) {
  2997. return sprintf("%s%s[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $prefix, $match[1] ? $match[1] : '*', $match[2]); }
  2998. $parser = new self();
  2999. $cssExpr = $parser->parse($cssExpr); }
  3000. $expr = $cssExpr->toXpath();
  3001. if (!$expr) {
  3002. throw new SyntaxError(sprintf('Got None for xpath expression from %s.', $cssExpr)); }
  3003. if ($prefix) {
  3004. $expr->addPrefix($prefix); }
  3005. return (string) $expr; }
  3006. public function parse($string) {
  3007. $tokenizer = new Tokenizer();
  3008. $stream = new TokenStream($tokenizer->tokenize($string), $string);
  3009. try {
  3010. return $this->parseSelectorGroup($stream); } catch (\Exception $e) {
  3011. $class = get_class($e);
  3012. throw new $class(sprintf('%s at %s -> %s', $e->getMessage(), implode($stream->getUsed(), ''), $stream->peek())); } }
  3013. protected function parseSelectorGroup($stream) {
  3014. $result = array();
  3015. while (1) {
  3016. $result[] = $this->parseSelector($stream);
  3017. if ($stream->peek() == ',') {
  3018. $stream->next(); } else {
  3019. break; } }
  3020. if (count($result) == 1) {
  3021. return $result[0]; }
  3022. return new Node\OrNode($result); }
  3023. protected function parseSelector($stream) {
  3024. $result = $this->parseSimpleSelector($stream);
  3025. while (1) {
  3026. $peek = $stream->peek();
  3027. if ($peek == ',' || $peek === null) {
  3028. return $result; } elseif (in_array($peek, array('+', '>', '~'))) {
  3029. $combinator = (string) $stream->next(); } else {
  3030. $combinator = ' '; }
  3031. $consumed = count($stream->getUsed());
  3032. $next_selector = $this->parseSimpleSelector($stream);
  3033. if ($consumed == count($stream->getUsed())) {
  3034. throw new SyntaxError(sprintf("Expected selector, got '%s'", $stream->peek())); }
  3035. $result = new Node\CombinedSelectorNode($result, $combinator, $next_selector); }
  3036. return $result; }
  3037. protected function parseSimpleSelector($stream) {
  3038. $peek = $stream->peek();
  3039. if ($peek != '*' && !$peek->isType('Symbol')) {
  3040. $element = $namespace = '*'; } else {
  3041. $next = $stream->next();
  3042. if ($next != '*' && !$next->isType('Symbol')) {
  3043. throw new SyntaxError(sprintf("Expected symbol, got '%s'", $next)); }
  3044. if ($stream->peek() == '|') {
  3045. $namespace = $next;
  3046. $stream->next();
  3047. $element = $stream->next();
  3048. if ($element != '*' && !$next->isType('Symbol')) {
  3049. throw new SyntaxError(sprintf("Expected symbol, got '%s'", $next)); } } else {
  3050. $namespace = '*';
  3051. $element = $next; } }
  3052. $result = new Node\ElementNode($namespace, $element);
  3053. $has_hash = false;
  3054. while (1) {
  3055. $peek = $stream->peek();
  3056. if ($peek == '#') {
  3057. if ($has_hash) {
  3058. break; }
  3059. $stream->next();
  3060. $result = new Node\HashNode($result, $stream->next());
  3061. $has_hash = true;
  3062. continue; } elseif ($peek == '.') {
  3063. $stream->next();
  3064. $result = new Node\ClassNode($result, $stream->next());
  3065. continue; } elseif ($peek == '[') {
  3066. $stream->next();
  3067. $result = $this->parseAttrib($result, $stream);
  3068. $next = $stream->next();
  3069. if ($next != ']') {
  3070. throw new SyntaxError(sprintf("] expected, got '%s'", $next)); }
  3071. continue; } elseif ($peek == ':' || $peek == '::') {
  3072. $type = $stream->next();
  3073. $ident = $stream->next();
  3074. if (!$ident || !$ident->isType('Symbol')) {
  3075. throw new SyntaxError(sprintf("Expected symbol, got '%s'", $ident)); }
  3076. if ($stream->peek() == '(') {
  3077. $stream->next();
  3078. $peek = $stream->peek();
  3079. if ($peek->isType('String')) {
  3080. $selector = $stream->next(); } elseif ($peek->isType('Symbol') && is_int($peek)) {
  3081. $selector = intval($stream->next()); } else {
  3082. $selector = $this->parseSimpleSelector($stream); }
  3083. $next = $stream->next();
  3084. if ($next != ')') {
  3085. throw new SyntaxError(sprintf("Expected ')', got '%s' and '%s'", $next, $selector)); }
  3086. $result = new Node\FunctionNode($result, $type, $ident, $selector); } else {
  3087. $result = new Node\PseudoNode($result, $type, $ident); }
  3088. continue; } else {
  3089. if ($peek == ' ') {
  3090. $stream->next(); }
  3091. break; } }
  3092. return $result; }
  3093. protected function parseAttrib($selector, $stream) {
  3094. $attrib = $stream->next();
  3095. if ($stream->peek() == '|') {
  3096. $namespace = $attrib;
  3097. $stream->next();
  3098. $attrib = $stream->next(); } else {
  3099. $namespace = '*'; }
  3100. if ($stream->peek() == ']') {
  3101. return new Node\AttribNode($selector, $namespace, $attrib, 'exists', null); }
  3102. $op = $stream->next();
  3103. if (!in_array($op, array('^=', '$=', '*=', '=', '~=', '|=', '!='))) {
  3104. throw new SyntaxError(sprintf("Operator expected, got '%s'", $op)); }
  3105. $value = $stream->next();
  3106. if (!$value->isType('Symbol') && !$value->isType('String')) {
  3107. throw new SyntaxError(sprintf("Expected string or symbol, got '%s'", $value)); }
  3108. return new Node\AttribNode($selector, $namespace, $attrib, $op, $value); } }
  3109. <?php
  3110. namespace Symfony\Component\CssSelector;
  3111. class SyntaxError extends \LogicException { }
  3112. <?php
  3113. namespace Symfony\Component\CssSelector;
  3114. class Token {
  3115. protected $type;
  3116. protected $value;
  3117. protected $position;
  3118. public function __construct($type, $value, $position) {
  3119. $this->type = $type;
  3120. $this->value = $value;
  3121. $this->position = $position; }
  3122. public function __toString() {
  3123. return (string) $this->value; }
  3124. public function isType($type) {
  3125. return $this->type == $type; }
  3126. public function getPosition() {
  3127. return $this->position; } }
  3128. <?php
  3129. namespace Symfony\Component\CssSelector;
  3130. class Tokenizer {
  3131. public function tokenize($s) {
  3132. if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  3133. $mbEncoding = mb_internal_encoding();
  3134. mb_internal_encoding('ASCII'); }
  3135. $tokens = array();
  3136. $pos = 0;
  3137. $s = preg_replace('#/\*.*?\*/#s', '', $s);
  3138. while (1) {
  3139. if (preg_match('#\s+#A', $s, $match, 0, $pos)) {
  3140. $preceding_whitespace_pos = $pos;
  3141. $pos += strlen($match[0]); } else {
  3142. $preceding_whitespace_pos = 0; }
  3143. if ($pos >= strlen($s)) {
  3144. if (isset($mbEncoding)) {
  3145. mb_internal_encoding($mbEncoding); }
  3146. return $tokens; }
  3147. if (preg_match('#[+-]?\d*n(?:[+-]\d+)?#A', $s, $match, 0, $pos) && 'n' !== $match[0]) {
  3148. $sym = substr($s, $pos, strlen($match[0]));
  3149. $tokens[] = new Token('Symbol', $sym, $pos);
  3150. $pos += strlen($match[0]);
  3151. continue; }
  3152. $c = $s[$pos];
  3153. $c2 = substr($s, $pos, 2);
  3154. if (in_array($c2, array('~=', '|=', '^=', '$=', '*=', '::', '!='))) {
  3155. $tokens[] = new Token('Token', $c2, $pos);
  3156. $pos += 2;
  3157. continue; }
  3158. if (in_array($c, array('>', '+', '~', ',', '.', '*', '=', '[', ']', '(', ')', '|', ':', '#'))) {
  3159. if (in_array($c, array('.', '#', '[')) && $preceding_whitespace_pos > 0) {
  3160. $tokens[] = new Token('Token', ' ', $preceding_whitespace_pos); }
  3161. $tokens[] = new Token('Token', $c, $pos);
  3162. ++$pos;
  3163. continue; }
  3164. if ($c === '"' || $c === "'") {
  3165. $old_pos = $pos;
  3166. list($sym, $pos) = $this->tokenizeEscapedString($s, $pos);
  3167. $tokens[] = new Token('String', $sym, $old_pos);
  3168. continue; }
  3169. $old_pos = $pos;
  3170. list($sym, $pos) = $this->tokenizeSymbol($s, $pos);
  3171. $tokens[] = new Token('Symbol', $sym, $old_pos);
  3172. continue; } }
  3173. protected function tokenizeEscapedString($s, $pos) {
  3174. $quote = $s[$pos];
  3175. $pos = $pos + 1;
  3176. $start = $pos;
  3177. while (1) {
  3178. $next = strpos($s, $quote, $pos);
  3179. if (false === $next) {
  3180. throw new SyntaxError(sprintf('Expected closing %s for string in: %s', $quote, substr($s, $start))); }
  3181. $result = substr($s, $start, $next - $start);
  3182. if ('\\' === $result[strlen($result) - 1]) {
  3183. $pos = $next + 1;
  3184. $continue; }
  3185. if (false !== strpos($result, '\\')) {
  3186. $result = $this->unescapeStringLiteral($result); }
  3187. return array($result, $next + 1); } }
  3188. protected function unescapeStringLiteral($literal) {
  3189. return preg_replace_callback('#(\\\\(?:[A-Fa-f0-9]{1,6}(?:\r\n|\s)?|[^A-Fa-f0-9]))#', function ($matches) use ($literal) {
  3190. if ($matches[0][0] == '\\' && strlen($matches[0]) > 1) {
  3191. $matches[0] = substr($matches[0], 1);
  3192. 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'))) {
  3193. return chr(trim($matches[0])); } } else {
  3194. throw new SyntaxError(sprintf('Invalid escape sequence %s in string %s', $matches[0], $literal)); } }, $literal); }
  3195. protected function tokenizeSymbol($s, $pos) {
  3196. $start = $pos;
  3197. if (!preg_match('#[^\w\-]#', $s, $match, PREG_OFFSET_CAPTURE, $pos)) {
  3198. return array(substr($s, $start), strlen($s)); }
  3199. $matchStart = $match[0][1];
  3200. if ($matchStart == $pos) {
  3201. throw new SyntaxError(sprintf('Unexpected symbol: %s at %s', $s[$pos], $pos)); }
  3202. $result = substr($s, $start, $matchStart - $start);
  3203. $pos = $matchStart;
  3204. return array($result, $pos); } }
  3205. <?php
  3206. namespace Symfony\Component\CssSelector;
  3207. class TokenStream {
  3208. protected $used;
  3209. protected $tokens;
  3210. protected $source;
  3211. protected $peeked;
  3212. protected $peeking;
  3213. public function __construct($tokens, $source = null) {
  3214. $this->used = array();
  3215. $this->tokens = $tokens;
  3216. $this->source = $source;
  3217. $this->peeked = null;
  3218. $this->peeking = false; }
  3219. public function getUsed() {
  3220. return $this->used; }
  3221. public function next() {
  3222. if ($this->peeking) {
  3223. $this->peeking = false;
  3224. $this->used[] = $this->peeked;
  3225. return $this->peeked; }
  3226. if (!count($this->tokens)) {
  3227. return null; }
  3228. $next = array_shift($this->tokens);
  3229. $this->used[] = $next;
  3230. return $next; }
  3231. public function peek() {
  3232. if (!$this->peeking) {
  3233. if (!count($this->tokens)) {
  3234. return null; }
  3235. $this->peeked = array_shift($this->tokens);
  3236. $this->peeking = true; }
  3237. return $this->peeked; } }
  3238. <?php
  3239. namespace Symfony\Component\CssSelector;
  3240. class XPathExpr {
  3241. protected $prefix;
  3242. protected $path;
  3243. protected $element;
  3244. protected $condition;
  3245. protected $starPrefix;
  3246. public function __construct($prefix = null, $path = null, $element = '*', $condition = null, $starPrefix = false) {
  3247. $this->prefix = $prefix;
  3248. $this->path = $path;
  3249. $this->element = $element;
  3250. $this->condition = $condition;
  3251. $this->starPrefix = $starPrefix; }
  3252. public function getPrefix() {
  3253. return $this->prefix; }
  3254. public function getPath() {
  3255. return $this->path; }
  3256. public function hasStarPrefix() {
  3257. return $this->starPrefix; }
  3258. public function getElement() {
  3259. return $this->element; }
  3260. public function getCondition() {
  3261. return $this->condition; }
  3262. public function __toString() {
  3263. $path = '';
  3264. if (null !== $this->prefix) {
  3265. $path .= $this->prefix; }
  3266. if (null !== $this->path) {
  3267. $path .= $this->path; }
  3268. $path .= $this->element;
  3269. if ($this->condition) {
  3270. $path .= sprintf('[%s]', $this->condition); }
  3271. return $path; }
  3272. public function addCondition($condition) {
  3273. if ($this->condition) {
  3274. $this->condition = sprintf('%s and (%s)', $this->condition, $condition); } else {
  3275. $this->condition = $condition; } }
  3276. public function addPrefix($prefix) {
  3277. if ($this->prefix) {
  3278. $this->prefix = $prefix.$this->prefix; } else {
  3279. $this->prefix = $prefix; } }
  3280. public function addNameTest() {
  3281. if ($this->element == '*') {
  3282. return; }
  3283. $this->addCondition(sprintf('name() = %s', XPathExpr::xpathLiteral($this->element)));
  3284. $this->element = '*'; }
  3285. public function addStarPrefix() {
  3286. if ($this->path) {
  3287. $this->path .= '*/'; } else {
  3288. $this->path = '*/'; }
  3289. $this->starPrefix = true; }
  3290. public function join($combiner, $other) {
  3291. $prefix = (string) $this;
  3292. $prefix .= $combiner;
  3293. $path = $other->getPrefix().$other->getPath();
  3294. if ($other->hasStarPrefix() && $path == '*/') {
  3295. $path = ''; }
  3296. $this->prefix = $prefix;
  3297. $this->path = $path;
  3298. $this->element = $other->getElement();
  3299. $this->condition = $other->GetCondition(); }
  3300. static public function xpathLiteral($s) {
  3301. if ($s instanceof Node\ElementNode) {
  3302. $s = $s->formatElement(); } else {
  3303. $s = (string) $s; }
  3304. if (false === strpos($s, "'")) {
  3305. return sprintf("'%s'", $s); }
  3306. if (false === strpos($s, '"')) {
  3307. return sprintf('"%s"', $s); }
  3308. $string = $s;
  3309. $parts = array();
  3310. while (true) {
  3311. if (false !== $pos = strpos($string, "'")) {
  3312. $parts[] = sprintf("'%s'", substr($string, 0, $pos));
  3313. $parts[] = "\"'\"";
  3314. $string = substr($string, $pos + 1); } else {
  3315. $parts[] = "'$string'";
  3316. break; } }
  3317. return sprintf('concat(%s)', implode($parts, ', ')); } }
  3318. <?php
  3319. namespace Symfony\Component\CssSelector;
  3320. class XPathExprOr extends XPathExpr {
  3321. public function __construct($items, $prefix = null) {
  3322. $this->items = $items;
  3323. $this->prefix = $prefix; }
  3324. public function __toString() {
  3325. $prefix = $this->prefix;
  3326. $tmp = array();
  3327. foreach ($this->items as $i) {
  3328. $tmp[] = sprintf('%s%s', $prefix, $i); }
  3329. return implode($tmp, ' | '); } }
  3330. <?php
  3331. namespace Symfony\Component\Process;
  3332. class PhpProcess extends Process {
  3333. public function __construct($script, $cwd = null, array $env = array(), $timeout = 60, array $options = array()) {
  3334. parent::__construct(null, $cwd, $env, $script, $timeout, $options); }
  3335. public function setPhpBinary($php) {
  3336. $this->commandline = $php; }
  3337. public function run($callback = null) {
  3338. if (null === $this->commandline) {
  3339. $this->commandline = $this->getPhpBinary(); }
  3340. parent::run($callback); }
  3341. static public function getPhpBinary() {
  3342. if (getenv('PHP_PATH')) {
  3343. if (!is_executable($php = getenv('PHP_PATH'))) {
  3344. throw new \RuntimeException('The defined PHP_PATH environment variable is not a valid PHP executable.'); }
  3345. return $php; }
  3346. $suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array('');
  3347. foreach ($suffixes as $suffix) {
  3348. if (is_executable($php = PHP_BINDIR.DIRECTORY_SEPARATOR.'php'.$suffix)) {
  3349. return $php; } }
  3350. throw new \RuntimeException('Unable to find the PHP executable.'); } }
  3351. <?php
  3352. namespace Symfony\Component\Process;
  3353. class Process {
  3354. protected $commandline;
  3355. protected $cwd;
  3356. protected $env;
  3357. protected $stdin;
  3358. protected $timeout;
  3359. protected $options;
  3360. protected $exitcode;
  3361. protected $status;
  3362. protected $stdout;
  3363. protected $stderr;
  3364. public function __construct($commandline, $cwd, array $env = array(), $stdin = null, $timeout = 60, array $options = array()) {
  3365. if (!function_exists('proc_open')) {
  3366. throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); }
  3367. $this->commandline = $commandline;
  3368. $this->cwd = null === $cwd ? getcwd() : $cwd;
  3369. $this->env = array();
  3370. foreach ($env as $key => $value) {
  3371. $this->env[(binary) $key] = (binary) $value; }
  3372. $this->stdin = $stdin;
  3373. $this->timeout = $timeout;
  3374. $this->options = array_merge($options, array('suppress_errors' => true, 'binary_pipes' => true)); }
  3375. public function run($callback = null) {
  3376. if (null === $callback) {
  3377. $this->stdout = '';
  3378. $this->stderr = '';
  3379. $that = $this;
  3380. $callback = function ($type, $line) use ($that) {
  3381. if ('out' == $type) {
  3382. $that->addOutput($line); } else {
  3383. $that->addErrorOutput($line); } }; }
  3384. $descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
  3385. $process = proc_open($this->commandline, $descriptors, $pipes, $this->cwd, $this->env, $this->options);
  3386. stream_set_blocking($pipes[1], false);
  3387. stream_set_blocking($pipes[2], false);
  3388. if (!is_resource($process)) {
  3389. throw new \RuntimeException('Unable to launch a new process.'); }
  3390. if (null !== $this->stdin) {
  3391. fwrite($pipes[0], (binary) $this->stdin); }
  3392. fclose($pipes[0]);
  3393. while (true) {
  3394. $r = $pipes;
  3395. $w = null;
  3396. $e = null;
  3397. $n = @stream_select($r, $w, $e, $this->timeout);
  3398. if ($n === false) {
  3399. break; } elseif ($n === 0) {
  3400. proc_terminate($process);
  3401. throw new \RuntimeException('The process timed out.'); } elseif ($n > 0) {
  3402. $called = false;
  3403. while (true) {
  3404. $c = false;
  3405. if ($line = (binary) fgets($pipes[1], 1024)) {
  3406. $called = $c = true;
  3407. call_user_func($callback, 'out', $line); }
  3408. if ($line = fgets($pipes[2], 1024)) {
  3409. $called = $c = true;
  3410. call_user_func($callback, 'err', $line); }
  3411. if (!$c) {
  3412. break; } }
  3413. if (!$called) {
  3414. break; } } }
  3415. $this->status = proc_get_status($process);
  3416. proc_close($process);
  3417. if ($this->status['signaled']) {
  3418. throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->status['stopsig'])); }
  3419. return $this->exitcode = $this->status['exitcode']; }
  3420. public function getOutput() {
  3421. return $this->stdout; }
  3422. public function getErrorOutput() {
  3423. return $this->stderr; }
  3424. public function getExitCode() {
  3425. return $this->exitcode; }
  3426. public function hasBeenSignaled() {
  3427. return $this->status['signaled']; }
  3428. public function getTermSignal() {
  3429. return $this->status['termsig']; }
  3430. public function hasBeenStopped() {
  3431. return $this->status['stopped']; }
  3432. public function getStopSignal() {
  3433. return $this->status['stopsig']; }
  3434. public function addOutput($line) {
  3435. $this->stdout .= $line; }
  3436. public function addErrorOutput($line) {
  3437. $this->stderr .= $line; } }
  3438. <?php
  3439. namespace Zend\Uri;
  3440. class Exception extends \Zend\Exception { }
  3441. <?php
  3442. namespace Zend\Uri;
  3443. use Zend\Validator\Hostname;
  3444. class Url implements Uri {
  3445. private static $_regex = array(
  3446. 'initialized' => false,
  3447. 'charAlnum' => 'A-Za-z0-9',
  3448. 'charMark' => '-_.!~*\'()\[\]',
  3449. 'charReserved' => ';\/?:@&=+$,',
  3450. 'charSegment' => ':@&=+$,;',
  3451. 'escaped' => '%[[:xdigit:]]{2}',
  3452. 'unreserved' => null,
  3453. 'path' => null,
  3454. 'segment' => null,
  3455. 'uric' => null,
  3456. 'unwise' => '{}|\\\\^`'
  3457. );
  3458. protected $_allowUnwise = false;
  3459. protected $_scheme = null;
  3460. protected $_username = null;
  3461. protected $_password = null;
  3462. protected $_host = null;
  3463. protected $_port = null;
  3464. protected $_path = null;
  3465. protected $_query = null;
  3466. protected $_fragment = null;
  3467. final protected static function _getRegex($regexName, $allowUnwiseCharset = false) {
  3468. if (!self::$_regex['initialized']) {
  3469. self::$_regex['unreserved'] = '[' . self::$_regex['charAlnum']
  3470. . self::$_regex['charMark'] . ']';
  3471. self::$_regex['segment'] = '(?:' . self::$_regex['escaped'] . '|['
  3472. . self::$_regex['charAlnum'] . self::$_regex['charMark']
  3473. . self::$_regex['charSegment'] . '])*';
  3474. self::$_regex['path'] = '(?:\/(?:' . self::$_regex['segment'] . ')?)+';
  3475. self::$_regex['uric'] = '(?:' . self::$_regex['escaped'] . '|['
  3476. . self::$_regex['charAlnum'] . self::$_regex['charMark']
  3477. . self::$_regex['charReserved']
  3478. . '])';
  3479. self::$_regex['initialized'] = true; }
  3480. if (!array_key_exists($regexName, self::$_regex)) {
  3481. throw new \InvalidArgumentException('Requested regex ' . $regexName . ' is not a valid regexName'); }
  3482. switch ($regexName) {
  3483. case 'uric':
  3484. $regex = self::$_regex['uric'];
  3485. if ($allowUnwiseCharset) {
  3486. $regex = substr($regex, 0, -2) . self::$_regex['unwise'] . '])'; }
  3487. break;
  3488. default:
  3489. $regex = self::$_regex[$regexName];
  3490. break; }
  3491. return $regex; }
  3492. public static function validate($url) {
  3493. if (empty($url)) {
  3494. return false; }
  3495. try {
  3496. $url = new self($url); } catch (\Exception $exception) {
  3497. return false; }
  3498. if (!$url->getScheme()) {
  3499. return false; }
  3500. return $url->isValid(); }
  3501. public static function validateUsername($username) {
  3502. if (strlen($username) === 0) {
  3503. return true; }
  3504. $escapedRegex = self::_getRegex('escaped');
  3505. $charAlnumRegex = self::_getRegex('charAlnum');
  3506. $charMarkRegex = self::_getRegex('charMark');
  3507. $status = preg_match(
  3508. '/^(?:' . $escapedRegex . '|[' . $charAlnumRegex . $charMarkRegex . ';:&=+$,' . '])+$/',
  3509. $username
  3510. );
  3511. return $status === 1; }
  3512. public static function validatePassword($password) {
  3513. if (strlen($password) === 0) {
  3514. return true; }
  3515. $escapedRegex = self::_getRegex('escaped');
  3516. $charAlnumRegex = self::_getRegex('charAlnum');
  3517. $charMarkRegex = self::_getRegex('charMark');
  3518. $status = preg_match(
  3519. '/^(?:' . $escapedRegex . '|[' . $charAlnumRegex . $charMarkRegex . ';:&=+$,' . '])+$/',
  3520. $password
  3521. );
  3522. return $status == 1; }
  3523. public static function validateHost($host) {
  3524. if (strlen($host) === 0) {
  3525. return false; }
  3526. $validate = new Hostname(Hostname::ALLOW_ALL);
  3527. return $validate->isValid($host); }
  3528. public static function validatePort($port) {
  3529. if (strlen($port) === 0) {
  3530. return true; }
  3531. return (ctype_digit((string) $port) && 1 <= $port && $port <= 0xffff); }
  3532. public static function validatePath($path) {
  3533. if (strlen($path) === 0) {
  3534. return true; }
  3535. $pathRegex = self::_getRegex('path');
  3536. $status = preg_match('/^' . $pathRegex . '$/', $path);
  3537. return (boolean) $status; }
  3538. public static function validateQuery($query, $allowUnwiseCharacters = false) {
  3539. if (strlen($query) === 0) {
  3540. return true; }
  3541. $uricRegex = self::_getRegex('uric', $allowUnwiseCharacters);
  3542. $status = preg_match('/^' . $uricRegex . '*$/', $query, $matches);
  3543. return ($status == 1); }
  3544. public static function validateFragment($fragment, $allowUnwiseCharacters = false) {
  3545. if (strlen($fragment) === 0) {
  3546. return true; }
  3547. $uricRegex = self::_getRegex('uric', $allowUnwiseCharacters);
  3548. $status = preg_match('/^' . $uricRegex . '*$/', $fragment);
  3549. return (boolean) $status; }
  3550. public function __construct($optionsOrURL = null) {
  3551. if (is_string($optionsOrURL)) {
  3552. $this->parse($optionsOrURL); } elseif (is_array($optionsOrURL) && $optionsOrURL) {
  3553. $this->setOptions($optionsOrURL); } }
  3554. public function setOptions(Array $options) {
  3555. foreach ($options as $optionName => $optionValue) {
  3556. $methodName = 'set' . $optionName;
  3557. if (method_exists($this, $methodName)) {
  3558. $this->{$methodName}($optionValue); } }
  3559. return $this; }
  3560. public function setAllowUnwise($allowUnwise = false) {
  3561. $this->_allowUnwise = (bool) $allowUnwise;
  3562. return $this; }
  3563. public function parse($url) {
  3564. $parts = parse_url($url);
  3565. if ($parts === false) {
  3566. throw new Exception('The url provided ' . $url . ' is not parsable.'); }
  3567. $options = array();
  3568. foreach ($parts as $partName => $partValue) {
  3569. switch (strtolower($partName)) {
  3570. case 'url':
  3571. case 'fromurl':
  3572. $this->parse($partValue);
  3573. break;
  3574. case 'user':
  3575. $options['username'] = $partValue;
  3576. break;
  3577. case 'pass':
  3578. $options['password'] = $partValue;
  3579. break;
  3580. default:
  3581. $options[$partName] = $partValue;
  3582. break; } }
  3583. if ($options) {
  3584. $this->setOptions($options); }
  3585. return $this; }
  3586. public function getScheme() {
  3587. return $this->_scheme; }
  3588. public function setScheme($scheme) {
  3589. $this->_scheme = strtolower($scheme);
  3590. return $this; }
  3591. public function getHost() {
  3592. return $this->_host; }
  3593. public function setHost($host) {
  3594. $this->_host = $host;
  3595. return $this; }
  3596. public function isValidHost() {
  3597. if ($this->_host) {
  3598. return self::validateHost($this->_host); }
  3599. return true; }
  3600. public function getPort() {
  3601. return $this->_port; }
  3602. public function setPort($port) {
  3603. $this->_port = $port;
  3604. return $this; }
  3605. public function isValidPort() {
  3606. if ($this->_port) {
  3607. return self::validatePort($this->_port); }
  3608. return true; }
  3609. public function getUsername() {
  3610. return $this->_username; }
  3611. public function setUsername($username) {
  3612. $this->_username = $username;
  3613. return $this; }
  3614. public function isValidUsername() {
  3615. if ($this->_username) {
  3616. return self::validateUsername($this->_username); }
  3617. return true; }
  3618. public function getPassword() {
  3619. return $this->_password; }
  3620. public function setPassword($password) {
  3621. $this->_password = $password;
  3622. return $this; }
  3623. public function isValidPassword() {
  3624. if (strlen($this->_password) > 0 and strlen($this->_username) === 0) {
  3625. return false; } elseif ($this->_password != '') {
  3626. return self::validatePassword($this->_password); }
  3627. return true; }
  3628. public function getPath() {
  3629. return $this->_path; }
  3630. public function setPath($path) {
  3631. if (empty($path)) {
  3632. $path = '/'; }
  3633. $this->_path = $path;
  3634. return $this; }
  3635. public function isValidPath() {
  3636. if ($this->_path) {
  3637. return self::validatePath($this->_path); }
  3638. return true; }
  3639. public function getQuery() {
  3640. return $this->_query; }
  3641. public function setQuery($query) {
  3642. if (empty($query) === true) {
  3643. $this->_query = '';
  3644. return $this; }
  3645. if (is_array($query) === true) {
  3646. $query = http_build_query($query, '', '&'); } else {
  3647. $query = (string) $query;
  3648. if (self::validateQuery($query, $this->_allowUnwise) === false) {
  3649. parse_str($query, $queryArray);
  3650. $query = http_build_query($queryArray, '', '&'); } }
  3651. $this->_query = $query;
  3652. return $this; }
  3653. public function isValidQuery() {
  3654. if ($this->_query) {
  3655. return self::validateQuery($this->_query, $this->_allowUnwise); }
  3656. return true; }
  3657. public function getQueryAsArray() {
  3658. $query = $this->getQuery();
  3659. $queryParts = array();
  3660. if ($query !== false) {
  3661. parse_str($query, $queryParts); }
  3662. return $queryParts; }
  3663. public function addReplaceQueryParameters(array $queryParams) {
  3664. $queryParams = array_merge($this->getQueryAsArray(), $queryParams);
  3665. return $this->setQuery($queryParams); }
  3666. public function removeQueryParameters(array $queryParamKeys) {
  3667. $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0));
  3668. return $this->setQuery($queryParams); }
  3669. public function getFragment() {
  3670. return $this->_fragment; }
  3671. public function setFragment($fragment) {
  3672. $this->_fragment = $fragment;
  3673. return $this; }
  3674. public function isValidFragment() {
  3675. if ($this->_fragment) {
  3676. return self::validateFragment($this->_fragment); }
  3677. return true; }
  3678. public function isValid() {
  3679. if ($this->isValidUsername()
  3680. && $this->isValidPassword()
  3681. && $this->isValidHost()
  3682. && $this->isValidPort()
  3683. && $this->isValidPath()
  3684. && $this->isValidQuery()
  3685. && $this->isValidFragment()
  3686. ) {
  3687. if (!$this->getScheme()) {
  3688. return false; }
  3689. if (!$this->getHost()) {
  3690. return false; }
  3691. return true; }
  3692. return false; }
  3693. public function generate() {
  3694. $url = '';
  3695. $password = strlen($this->_password) > 0 ? ":$this->_password" : '';
  3696. $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : '';
  3697. $port = strlen($this->_port) > 0 ? ":$this->_port" : '';
  3698. $query = strlen($this->_query) > 0 ? "?$this->_query" : '';
  3699. $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : '';
  3700. $url = $this->_scheme
  3701. . '://'
  3702. . $auth
  3703. . $this->_host
  3704. . $port
  3705. . $this->_path
  3706. . $query
  3707. . $fragment;
  3708. return $url; }
  3709. public function __toString() {
  3710. return $this->generate(); } }
  3711. <?php
  3712. namespace Zend\Http\Client\Adapter;
  3713. use Zend\Http\Client\Adapter as HTTPAdapter,
  3714. Zend\Http\Client;
  3715. class Curl implements HTTPAdapter, Stream {
  3716. protected $_config = array();
  3717. protected $_connected_to = array(null, null);
  3718. protected $_curl = null;
  3719. protected $_invalidOverwritableCurlOptions;
  3720. protected $_response = null;
  3721. protected $out_stream;
  3722. public function __construct() {
  3723. if (!extension_loaded('curl')) {
  3724. throw new Exception('cURL extension has to be loaded to use this Zend\Http\Client adapter'); }
  3725. $this->_invalidOverwritableCurlOptions = array(
  3726. CURLOPT_HTTPGET,
  3727. CURLOPT_POST,
  3728. CURLOPT_PUT,
  3729. CURLOPT_CUSTOMREQUEST,
  3730. CURLOPT_HEADER,
  3731. CURLOPT_RETURNTRANSFER,
  3732. CURLOPT_HTTPHEADER,
  3733. CURLOPT_POSTFIELDS,
  3734. CURLOPT_INFILE,
  3735. CURLOPT_INFILESIZE,
  3736. CURLOPT_PORT,
  3737. CURLOPT_MAXREDIRS,
  3738. CURLOPT_CONNECTTIMEOUT,
  3739. CURL_HTTP_VERSION_1_1,
  3740. CURL_HTTP_VERSION_1_0,
  3741. ); }
  3742. public function setConfig($config = array()) {
  3743. if ($config instanceof \Zend\Config\Config) {
  3744. $config = $config->toArray(); } elseif (! is_array($config)) {
  3745. throw new Exception(
  3746. 'Array or Zend\Config\Config object expected, got ' . gettype($config)
  3747. ); }
  3748. if(isset($config['proxy_user']) && isset($config['proxy_pass'])) {
  3749. $this->setCurlOption(CURLOPT_PROXYUSERPWD, $config['proxy_user'].":".$config['proxy_pass']);
  3750. unset($config['proxy_user'], $config['proxy_pass']); }
  3751. foreach ($config as $k => $v) {
  3752. $option = strtolower($k);
  3753. switch($option) {
  3754. case 'proxy_host':
  3755. $this->setCurlOption(CURLOPT_PROXY, $v);
  3756. break;
  3757. case 'proxy_port':
  3758. $this->setCurlOption(CURLOPT_PROXYPORT, $v);
  3759. break;
  3760. default:
  3761. $this->_config[$option] = $v;
  3762. break; } }
  3763. return $this; }
  3764. public function getConfig() {
  3765. return $this->_config; }
  3766. public function setCurlOption($option, $value) {
  3767. if (!isset($this->_config['curloptions'])) {
  3768. $this->_config['curloptions'] = array(); }
  3769. $this->_config['curloptions'][$option] = $value;
  3770. return $this; }
  3771. public function connect($host, $port = 80, $secure = false) {
  3772. if ($this->_curl) {
  3773. $this->close(); }
  3774. if ($this->_curl
  3775. && is_array($this->_connected_to)
  3776. && ($this->_connected_to[0] != $host
  3777. || $this->_connected_to[1] != $port)
  3778. ) {
  3779. $this->close(); }
  3780. $this->_curl = curl_init();
  3781. if ($port != 80) {
  3782. curl_setopt($this->_curl, CURLOPT_PORT, intval($port)); }
  3783. curl_setopt($this->_curl, CURLOPT_CONNECTTIMEOUT, $this->_config['timeout']);
  3784. curl_setopt($this->_curl, CURLOPT_MAXREDIRS, $this->_config['maxredirects']);
  3785. if (!$this->_curl) {
  3786. $this->close();
  3787. throw new Exception('Unable to Connect to ' . $host . ':' . $port); }
  3788. if ($secure !== false) {
  3789. if (isset($this->_config['sslcert'])) {
  3790. curl_setopt($this->_curl, CURLOPT_SSLCERT, $this->_config['sslcert']); }
  3791. if (isset($this->_config['sslpassphrase'])) {
  3792. curl_setopt($this->_curl, CURLOPT_SSLCERTPASSWD, $this->_config['sslpassphrase']); } }
  3793. $this->_connected_to = array($host, $port); }
  3794. public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $body = '') {
  3795. if (!$this->_curl) {
  3796. throw new Exception("Trying to write but we are not connected"); }
  3797. if ($this->_connected_to[0] != $uri->getHost() || $this->_connected_to[1] != $uri->getPort()) {
  3798. throw new Exception("Trying to write but we are connected to the wrong host"); }
  3799. curl_setopt($this->_curl, CURLOPT_URL, $uri->__toString());
  3800. $curlValue = true;
  3801. switch ($method) {
  3802. case Client::GET:
  3803. $curlMethod = CURLOPT_HTTPGET;
  3804. break;
  3805. case Client::POST:
  3806. $curlMethod = CURLOPT_POST;
  3807. break;
  3808. case Client::PUT:
  3809. if(is_resource($body)) {
  3810. $this->_config['curloptions'][CURLOPT_INFILE] = $body; }
  3811. if (isset($this->_config['curloptions'][CURLOPT_INFILE])) {
  3812. foreach ($headers AS $k => $header) {
  3813. if (preg_match('/Content-Length:\s*(\d+)/i', $header, $m)) {
  3814. if(is_resource($body)) {
  3815. $this->_config['curloptions'][CURLOPT_INFILESIZE] = (int)$m[1]; }
  3816. unset($headers[$k]); } }
  3817. if (!isset($this->_config['curloptions'][CURLOPT_INFILESIZE])) {
  3818. throw new Exception("Cannot set a file-handle for cURL option CURLOPT_INFILE without also setting its size in CURLOPT_INFILESIZE."); }
  3819. if(is_resource($body)) {
  3820. $body = ''; }
  3821. $curlMethod = CURLOPT_PUT; } else {
  3822. $curlMethod = CURLOPT_CUSTOMREQUEST;
  3823. $curlValue = "PUT"; }
  3824. break;
  3825. case Client::DELETE:
  3826. $curlMethod = CURLOPT_CUSTOMREQUEST;
  3827. $curlValue = "DELETE";
  3828. break;
  3829. case Client::OPTIONS:
  3830. $curlMethod = CURLOPT_CUSTOMREQUEST;
  3831. $curlValue = "OPTIONS";
  3832. break;
  3833. case Client::TRACE:
  3834. $curlMethod = CURLOPT_CUSTOMREQUEST;
  3835. $curlValue = "TRACE";
  3836. break;
  3837. case Client::HEAD:
  3838. $curlMethod = CURLOPT_CUSTOMREQUEST;
  3839. $curlValue = "HEAD";
  3840. break;
  3841. default:
  3842. throw new Exception("Method currently not supported"); }
  3843. if(is_resource($body) && $curlMethod != CURLOPT_PUT) {
  3844. throw new Exception("Streaming requests are allowed only with PUT"); }
  3845. $curlHttp = ($httpVersion == 1.1) ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0;
  3846. curl_setopt($this->_curl, $curlHttp, true);
  3847. curl_setopt($this->_curl, $curlMethod, $curlValue);
  3848. if($this->out_stream) {
  3849. curl_setopt($this->_curl, CURLOPT_HEADER, false);
  3850. curl_setopt($this->_curl, CURLOPT_HEADERFUNCTION, array($this, "readHeader"));
  3851. curl_setopt($this->_curl, CURLOPT_FILE, $this->out_stream); } else {
  3852. curl_setopt($this->_curl, CURLOPT_HEADER, true);
  3853. curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true); }
  3854. $headers['Accept'] = '';
  3855. curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $headers);
  3856. if ($method == Client::POST) {
  3857. curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body); } elseif ($curlMethod == CURLOPT_PUT) {
  3858. curl_setopt($this->_curl, CURLOPT_INFILE, $this->_config['curloptions'][CURLOPT_INFILE]);
  3859. curl_setopt($this->_curl, CURLOPT_INFILESIZE, $this->_config['curloptions'][CURLOPT_INFILESIZE]);
  3860. unset($this->_config['curloptions'][CURLOPT_INFILE]);
  3861. unset($this->_config['curloptions'][CURLOPT_INFILESIZE]); } elseif ($method == Client::PUT) {
  3862. curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body); }
  3863. if (isset($this->_config['curloptions'])) {
  3864. foreach ((array)$this->_config['curloptions'] as $k => $v) {
  3865. if (!in_array($k, $this->_invalidOverwritableCurlOptions)) {
  3866. if (curl_setopt($this->_curl, $k, $v) == false) {
  3867. throw new Client\Exception(sprintf("Unknown or erroreous cURL option '%s' set", $k)); } } } }
  3868. $response = curl_exec($this->_curl);
  3869. if(!is_resource($this->out_stream)) {
  3870. $this->_response = $response; }
  3871. $request = curl_getinfo($this->_curl, CURLINFO_HEADER_OUT);
  3872. $request .= $body;
  3873. if (empty($this->_response)) {
  3874. throw new Client\Exception("Error in cURL request: " . curl_error($this->_curl)); }
  3875. if (stripos($this->_response, "Transfer-Encoding: chunked\r\n")) {
  3876. $this->_response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $this->_response); }
  3877. do {
  3878. $parts = preg_split('|(?:\r?\n){2}|m', $this->_response, 2);
  3879. $again = false;
  3880. if (isset($parts[1]) && preg_match("|^HTTP/1\.[01](.*?)\r\n|mi", $parts[1])) {
  3881. $this->_response = $parts[1];
  3882. $again = true; } } while ($again);
  3883. if (stripos($this->_response, "HTTP/1.0 200 Connection established\r\n\r\n") !== false) {
  3884. $this->_response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $this->_response); }
  3885. return $request; }
  3886. public function read() {
  3887. return $this->_response; }
  3888. public function close() {
  3889. if(is_resource($this->_curl)) {
  3890. curl_close($this->_curl); }
  3891. $this->_curl = null;
  3892. $this->_connected_to = array(null, null); }
  3893. public function getHandle() {
  3894. return $this->_curl; }
  3895. public function setOutputStream($stream) {
  3896. $this->out_stream = $stream;
  3897. return $this; }
  3898. public function readHeader($curl, $header) {
  3899. $this->_response .= $header;
  3900. return strlen($header); } }
  3901. <?php
  3902. namespace Zend\Http\Client\Adapter;
  3903. class Exception extends \Zend\Http\Client\Exception {
  3904. const READ_TIMEOUT = 1000; }
  3905. <?php
  3906. namespace Zend\Http\Client\Adapter;
  3907. use Zend\Http\Client;
  3908. class Proxy extends Socket {
  3909. protected $config = array(
  3910. 'ssltransport' => 'ssl',
  3911. 'sslcert' => null,
  3912. 'sslpassphrase' => null,
  3913. 'sslusecontext' => false,
  3914. 'proxy_host' => '',
  3915. 'proxy_port' => 8080,
  3916. 'proxy_user' => '',
  3917. 'proxy_pass' => '',
  3918. 'proxy_auth' => Client::AUTH_BASIC,
  3919. 'persistent' => false
  3920. );
  3921. protected $negotiated = false;
  3922. public function connect($host, $port = 80, $secure = false) {
  3923. if (! $this->config['proxy_host']) {
  3924. return parent::connect($host, $port, $secure); }
  3925. if ($secure) {
  3926. $this->config['sslusecontext'] = true; }
  3927. return parent::connect(
  3928. $this->config['proxy_host'],
  3929. $this->config['proxy_port'],
  3930. false
  3931. ); }
  3932. public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') {
  3933. if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body);
  3934. if (! $this->socket) {
  3935. throw new Exception("Trying to write but we are not connected"); }
  3936. $host = $this->config['proxy_host'];
  3937. $port = $this->config['proxy_port'];
  3938. if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) {
  3939. throw new Exception("Trying to write but we are connected to the wrong proxy server"); }
  3940. if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) {
  3941. $headers['proxy-authorization'] = Client\Client::encodeAuthHeader(
  3942. $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth']
  3943. ); }
  3944. if ($uri->getScheme() == 'https' && (! $this->negotiated)) {
  3945. $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers);
  3946. $this->negotiated = true; }
  3947. $this->method = $method;
  3948. if ($this->negotiated) {
  3949. $path = $uri->getPath();
  3950. if ($uri->getQuery()) {
  3951. $path .= '?' . $uri->getQuery(); }
  3952. $request = "$method $path HTTP/$http_ver\r\n"; } else {
  3953. $request = "$method $uri HTTP/$http_ver\r\n"; }
  3954. foreach ($headers as $k => $v) {
  3955. if (is_string($k)) $v = "$k: $v";
  3956. $request .= "$v\r\n"; }
  3957. if(is_resource($body)) {
  3958. $request .= "\r\n"; } else {
  3959. $request .= "\r\n" . $body; }
  3960. if (! @fwrite($this->socket, $request)) {
  3961. throw new Exception("Error writing request to proxy server"); }
  3962. if (is_resource($body)) {
  3963. if(stream_copy_to_stream($body, $this->socket) == 0) {
  3964. throw new _Exception('Error writing request to server'); } }
  3965. return $request; }
  3966. protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array()) {
  3967. $request = "CONNECT $host:$port HTTP/$http_ver\r\n" .
  3968. "Host: " . $this->config['proxy_host'] . "\r\n";
  3969. if (isset($this->config['useragent'])) {
  3970. $request .= "User-agent: " . $this->config['useragent'] . "\r\n"; }
  3971. if (isset($headers['proxy-authorization'])) {
  3972. $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n";
  3973. unset($headers['proxy-authorization']); }
  3974. $request .= "\r\n";
  3975. if (! @fwrite($this->socket, $request)) {
  3976. throw new Exception("Error writing request to proxy server"); }
  3977. $response = '';
  3978. $gotStatus = false;
  3979. while ($line = @fgets($this->socket)) {
  3980. $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
  3981. if ($gotStatus) {
  3982. $response .= $line;
  3983. if (!chop($line)) break; } }
  3984. if (\Zend\Http\Response::extractCode($response) != 200) {
  3985. throw new Exception("Unable to connect to HTTPS proxy. Server response: " . $response); }
  3986. $modes = array(
  3987. STREAM_CRYPTO_METHOD_TLS_CLIENT,
  3988. STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
  3989. STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
  3990. STREAM_CRYPTO_METHOD_SSLv2_CLIENT
  3991. );
  3992. $success = false;
  3993. foreach($modes as $mode) {
  3994. $success = stream_socket_enable_crypto($this->socket, true, $mode);
  3995. if ($success) break; }
  3996. if (! $success) {
  3997. throw new Exception("Unable to connect to" .
  3998. " HTTPS server through proxy: could not negotiate secure connection."); } }
  3999. public function close() {
  4000. parent::close();
  4001. $this->negotiated = false; }
  4002. public function __destruct() {
  4003. if ($this->socket) $this->close(); } }
  4004. <?php
  4005. namespace Zend\Http\Client\Adapter;
  4006. use Zend\Http\Client\Adapter as HTTPAdapter,
  4007. Zend\Http\Response;
  4008. class Socket implements HTTPAdapter, Stream {
  4009. protected $socket = null;
  4010. protected $connected_to = array(null, null);
  4011. protected $out_stream = null;
  4012. protected $config = array(
  4013. 'persistent' => false,
  4014. 'ssltransport' => 'ssl',
  4015. 'sslcert' => null,
  4016. 'sslpassphrase' => null,
  4017. 'sslusecontext' => false
  4018. );
  4019. protected $method = null;
  4020. protected $_context = null;
  4021. public function __construct() { }
  4022. public function setConfig($config = array()) {
  4023. if ($config instanceof \Zend\Config\Config) {
  4024. $config = $config->toArray(); } elseif (! is_array($config)) {
  4025. throw new Exception(
  4026. 'Array or Zend_Config object expected, got ' . gettype($config)
  4027. ); }
  4028. foreach ($config as $k => $v) {
  4029. $this->config[strtolower($k)] = $v; } }
  4030. public function getConfig() {
  4031. return $this->config; }
  4032. public function setStreamContext($context) {
  4033. if (is_resource($context) && get_resource_type($context) == 'stream-context') {
  4034. $this->_context = $context; } elseif (is_array($context)) {
  4035. $this->_context = stream_context_create($context); } else {
  4036. throw new Exception(
  4037. "Expecting either a stream context resource or array, got " . gettype($context)
  4038. ); }
  4039. return $this; }
  4040. public function getStreamContext() {
  4041. if (! $this->_context) {
  4042. $this->_context = stream_context_create(); }
  4043. return $this->_context; }
  4044. public function connect($host, $port = 80, $secure = false) {
  4045. $host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
  4046. if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
  4047. if (is_resource($this->socket)) $this->close(); }
  4048. if (! is_resource($this->socket) || ! $this->config['keepalive']) {
  4049. $context = $this->getStreamContext();
  4050. if ($secure || $this->config['sslusecontext']) {
  4051. if ($this->config['sslcert'] !== null) {
  4052. if (! stream_context_set_option($context, 'ssl', 'local_cert',
  4053. $this->config['sslcert'])) {
  4054. throw new Exception('Unable to set sslcert option'); } }
  4055. if ($this->config['sslpassphrase'] !== null) {
  4056. if (! stream_context_set_option($context, 'ssl', 'passphrase',
  4057. $this->config['sslpassphrase'])) {
  4058. throw new Exception('Unable to set sslpassphrase option'); } } }
  4059. $flags = STREAM_CLIENT_CONNECT;
  4060. if ($this->config['persistent']) $flags |= STREAM_CLIENT_PERSISTENT;
  4061. $this->socket = @stream_socket_client($host . ':' . $port,
  4062. $errno,
  4063. $errstr,
  4064. (int) $this->config['timeout'],
  4065. $flags,
  4066. $context);
  4067. if (! $this->socket) {
  4068. $this->close();
  4069. throw new Exception(
  4070. 'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr); }
  4071. if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
  4072. throw new Exception('Unable to set the connection timeout'); }
  4073. $this->connected_to = array($host, $port); } }
  4074. public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') {
  4075. if (! $this->socket) {
  4076. throw new Exception('Trying to write but we are not connected'); }
  4077. $host = $uri->getHost();
  4078. $host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
  4079. if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) {
  4080. throw new Exception('Trying to write but we are connected to the wrong host'); }
  4081. $this->method = $method;
  4082. $path = $uri->getPath();
  4083. if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
  4084. $request = "{$method} {$path} HTTP/{$http_ver}\r\n";
  4085. foreach ($headers as $k => $v) {
  4086. if (is_string($k)) $v = ucfirst($k) . ": $v";
  4087. $request .= "$v\r\n"; }
  4088. if(is_resource($body)) {
  4089. $request .= "\r\n"; } else {
  4090. $request .= "\r\n" . $body; }
  4091. if (! @fwrite($this->socket, $request)) {
  4092. throw new Exception('Error writing request to server'); }
  4093. if(is_resource($body)) {
  4094. if(stream_copy_to_stream($body, $this->socket) == 0) {
  4095. throw new Exception('Error writing request to server'); } }
  4096. return $request; }
  4097. public function read() {
  4098. $response = '';
  4099. $gotStatus = false;
  4100. $stream = !empty($this->config['stream']);
  4101. while (($line = @fgets($this->socket)) !== false) {
  4102. $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
  4103. if ($gotStatus) {
  4104. $response .= $line;
  4105. if (rtrim($line) === '') break; } }
  4106. $this->_checkSocketReadTimeout();
  4107. $statusCode = Response::extractCode($response);
  4108. if ($statusCode == 100 || $statusCode == 101) return $this->read();
  4109. $headers = Response::extractHeaders($response);
  4110. if ($statusCode == 304 || $statusCode == 204 ||
  4111. $this->method == \Zend\Http\Client::HEAD) {
  4112. if (isset($headers['connection']) && $headers['connection'] == 'close') {
  4113. $this->close(); }
  4114. return $response; }
  4115. if (isset($headers['transfer-encoding'])) {
  4116. if (strtolower($headers['transfer-encoding']) == 'chunked') {
  4117. do {
  4118. $line = @fgets($this->socket);
  4119. $this->_checkSocketReadTimeout();
  4120. $chunk = $line;
  4121. $chunksize = trim($line);
  4122. if (! ctype_xdigit($chunksize)) {
  4123. $this->close();
  4124. throw new Exception('Invalid chunk size "' .
  4125. $chunksize . '" unable to read chunked body'); }
  4126. $chunksize = hexdec($chunksize);
  4127. $read_to = ftell($this->socket) + $chunksize;
  4128. do {
  4129. $current_pos = ftell($this->socket);
  4130. if ($current_pos >= $read_to) break;
  4131. if($this->out_stream) {
  4132. if(stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) {
  4133. $this->_checkSocketReadTimeout();
  4134. break; } } else {
  4135. $line = @fread($this->socket, $read_to - $current_pos);
  4136. if ($line === false || strlen($line) === 0) {
  4137. $this->_checkSocketReadTimeout();
  4138. break; }
  4139. $chunk .= $line; } } while (! feof($this->socket));
  4140. $chunk .= @fgets($this->socket);
  4141. $this->_checkSocketReadTimeout();
  4142. if(!$this->out_stream) {
  4143. $response .= $chunk; } } while ($chunksize > 0); } else {
  4144. $this->close();
  4145. throw new Exception('Cannot handle "' .
  4146. $headers['transfer-encoding'] . '" transfer encoding'); }
  4147. if ($this->out_stream) {
  4148. $response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $response); } } elseif (isset($headers['content-length'])) {
  4149. if (is_array($headers['content-length'])) {
  4150. $contentLength = $headers['content-length'][count($headers['content-length']) - 1]; } else {
  4151. $contentLength = $headers['content-length']; }
  4152. $current_pos = ftell($this->socket);
  4153. $chunk = '';
  4154. for ($read_to = $current_pos + $contentLength;
  4155. $read_to > $current_pos;
  4156. $current_pos = ftell($this->socket)) {
  4157. if($this->out_stream) {
  4158. if(@stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) {
  4159. $this->_checkSocketReadTimeout();
  4160. break; } } else {
  4161. $chunk = @fread($this->socket, $read_to - $current_pos);
  4162. if ($chunk === false || strlen($chunk) === 0) {
  4163. $this->_checkSocketReadTimeout();
  4164. break; }
  4165. $response .= $chunk; }
  4166. if (feof($this->socket)) break; } } else {
  4167. do {
  4168. if($this->out_stream) {
  4169. if(@stream_copy_to_stream($this->socket, $this->out_stream) == 0) {
  4170. $this->_checkSocketReadTimeout();
  4171. break; } } else {
  4172. $buff = @fread($this->socket, 8192);
  4173. if ($buff === false || strlen($buff) === 0) {
  4174. $this->_checkSocketReadTimeout();
  4175. break; } else {
  4176. $response .= $buff; } } } while (feof($this->socket) === false);
  4177. $this->close(); }
  4178. if (isset($headers['connection']) && $headers['connection'] == 'close') {
  4179. $this->close(); }
  4180. return $response; }
  4181. public function close() {
  4182. if (is_resource($this->socket)) @fclose($this->socket);
  4183. $this->socket = null;
  4184. $this->connected_to = array(null, null); }
  4185. protected function _checkSocketReadTimeout() {
  4186. if ($this->socket) {
  4187. $info = stream_get_meta_data($this->socket);
  4188. $timedout = $info['timed_out'];
  4189. if ($timedout) {
  4190. $this->close();
  4191. throw new Exception(
  4192. "Read timed out after {$this->config['timeout']} seconds",
  4193. Exception::READ_TIMEOUT
  4194. ); } } }
  4195. public function setOutputStream($stream) {
  4196. $this->out_stream = $stream;
  4197. return $this; }
  4198. public function __destruct() {
  4199. if (! $this->config['persistent']) {
  4200. if ($this->socket) $this->close(); } } }
  4201. <?php
  4202. namespace Zend\Http\Client\Adapter;
  4203. interface Stream {
  4204. function setOutputStream($stream); }
  4205. <?php
  4206. namespace Zend\Http\Client\Adapter;
  4207. use Zend\Http\Client\Adapter as HTTPAdapter,
  4208. Zend\Http\Response;
  4209. class Test implements HTTPAdapter {
  4210. protected $config = array();
  4211. protected $responses = array("HTTP/1.1 400 Bad Request\r\n\r\n");
  4212. protected $responseIndex = 0;
  4213. protected $_nextRequestWillFail = false;
  4214. public function __construct() { }
  4215. public function setNextRequestWillFail($flag) {
  4216. $this->_nextRequestWillFail = (bool) $flag;
  4217. return $this; }
  4218. public function setConfig($config = array()) {
  4219. if ($config instanceof \Zend\Config\Config) {
  4220. $config = $config->toArray(); } elseif (! is_array($config)) {
  4221. throw new Exception(
  4222. 'Array or Zend_Config object expected, got ' . gettype($config)
  4223. ); }
  4224. foreach ($config as $k => $v) {
  4225. $this->config[strtolower($k)] = $v; } }
  4226. public function connect($host, $port = 80, $secure = false) {
  4227. if ($this->_nextRequestWillFail) {
  4228. $this->_nextRequestWillFail = false;
  4229. throw new Exception('Request failed'); } }
  4230. public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') {
  4231. $host = $uri->getHost();
  4232. $host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host);
  4233. $path = $uri->getPath();
  4234. if (empty($path)) {
  4235. $path = '/'; }
  4236. if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
  4237. $request = "{$method} {$path} HTTP/{$http_ver}\r\n";
  4238. foreach ($headers as $k => $v) {
  4239. if (is_string($k)) $v = ucfirst($k) . ": $v";
  4240. $request .= "$v\r\n"; }
  4241. $request .= "\r\n" . $body;
  4242. return $request; }
  4243. public function read() {
  4244. if ($this->responseIndex >= count($this->responses)) {
  4245. $this->responseIndex = 0; }
  4246. return $this->responses[$this->responseIndex++]; }
  4247. public function close() { }
  4248. public function setResponse($response) {
  4249. if ($response instanceof Response) {
  4250. $response = $response->asString("\r\n"); }
  4251. $this->responses = (array)$response;
  4252. $this->responseIndex = 0; }
  4253. public function addResponse($response) {
  4254. if ($response instanceof Response) {
  4255. $response = $response->asString("\r\n"); }
  4256. $this->responses[] = $response; }
  4257. public function setResponseIndex($index) {
  4258. if ($index < 0 || $index >= count($this->responses)) {
  4259. throw new Exception(
  4260. 'Index out of range of response buffer size'); }
  4261. $this->responseIndex = $index; } }
  4262. <?php
  4263. namespace Zend\Http\Client;
  4264. interface Adapter {
  4265. public function setConfig($config = array());
  4266. public function connect($host, $port = 80, $secure = false);
  4267. public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = '');
  4268. public function read();
  4269. public function close(); }
  4270. <?php
  4271. namespace Zend\Http\Client;
  4272. class Exception extends \Zend\Http\Exception {}
  4273. <?php
  4274. namespace Zend\Http;
  4275. use Zend\Config\Config,
  4276. Zend\Uri;
  4277. class Client {
  4278. const GET = 'GET';
  4279. const POST = 'POST';
  4280. const PUT = 'PUT';
  4281. const HEAD = 'HEAD';
  4282. const DELETE = 'DELETE';
  4283. const TRACE = 'TRACE';
  4284. const OPTIONS = 'OPTIONS';
  4285. const CONNECT = 'CONNECT';
  4286. const MERGE = 'MERGE';
  4287. const AUTH_BASIC = 'basic';
  4288. const HTTP_1 = '1.1';
  4289. const HTTP_0 = '1.0';
  4290. const CONTENT_TYPE = 'Content-Type';
  4291. const CONTENT_LENGTH = 'Content-Length';
  4292. const ENC_URLENCODED = 'application/x-www-form-urlencoded';
  4293. const ENC_FORMDATA = 'multipart/form-data';
  4294. protected $config = array(
  4295. 'maxredirects' => 5,
  4296. 'strictredirects' => false,
  4297. 'useragent' => 'Zend\\Http\\Client',
  4298. 'timeout' => 10,
  4299. 'adapter' => 'Zend\\Http\\Client\\Adapter\\Socket',
  4300. 'httpversion' => self::HTTP_1,
  4301. 'keepalive' => false,
  4302. 'storeresponse' => true,
  4303. 'strict' => true,
  4304. 'output_stream' => false,
  4305. 'encodecookies' => true,
  4306. );
  4307. protected $adapter = null;
  4308. protected $uri = null;
  4309. protected $headers = array();
  4310. protected $method = self::GET;
  4311. protected $paramsGet = array();
  4312. protected $paramsPost = array();
  4313. protected $enctype = null;
  4314. protected $raw_post_data = null;
  4315. protected $auth;
  4316. protected $files = array();
  4317. protected $cookiejar = null;
  4318. protected $last_request = null;
  4319. protected $last_response = null;
  4320. protected $redirectCounter = 0;
  4321. static protected $_fileInfoDb = null;
  4322. public function __construct($uri = null, $config = null) {
  4323. if ($uri !== null) {
  4324. $this->setUri($uri); }
  4325. if ($config !== null) {
  4326. $this->setConfig($config); } }
  4327. public function setUri($uri) {
  4328. if (is_string($uri)) {
  4329. try {
  4330. $uri = new Uri\Url($uri); } catch (URI\Exception $e) {
  4331. throw new Client\Exception('Passed parameter is not a valid HTTP URI.'); } }
  4332. $scheme = strtolower($uri->getScheme());
  4333. if (!empty($scheme) && !in_array($scheme, array('http', 'https'))) {
  4334. throw new Client\Exception('Passed parameter is not a valid HTTP URI.'); }
  4335. if ($uri->getUsername() && $uri->getPassword()) {
  4336. $this->setAuth($uri->getUsername(), $uri->getPassword()); }
  4337. if (! $uri->getPort()) {
  4338. $uri->setPort(($uri->getScheme() == 'https' ? 443 : 80)); }
  4339. $this->uri = $uri;
  4340. return $this; }
  4341. public function getUri($as_string = false) {
  4342. if ($as_string && $this->uri instanceof Uri\Url) {
  4343. return $this->uri->__toString(); } else {
  4344. return $this->uri; } }
  4345. public function setConfig($config = array()) {
  4346. if ($config instanceof Config) {
  4347. $config = $config->toArray(); } elseif (! is_array($config)) {
  4348. throw new Client\Exception('Array or Zend_Config object expected, got ' . gettype($config)); }
  4349. foreach ($config as $k => $v) {
  4350. $this->config[strtolower($k)] = $v; }
  4351. if ($this->adapter instanceof Client\Adapter) {
  4352. $this->adapter->setConfig($config); }
  4353. return $this; }
  4354. public function setMethod($method = self::GET) {
  4355. if (! preg_match('/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/', $method)) {
  4356. throw new Client\Exception("'{$method}' is not a valid HTTP request method."); }
  4357. if ($method == self::POST && $this->enctype === null) {
  4358. $this->setEncType(self::ENC_URLENCODED); }
  4359. $this->method = $method;
  4360. return $this; }
  4361. public function setHeaders($name, $value = null) {
  4362. if (is_array($name)) {
  4363. foreach ($name as $k => $v) {
  4364. if (is_string($k)) {
  4365. $this->setHeaders($k, $v); } else {
  4366. $this->setHeaders($v, null); } } } else {
  4367. if ($value === null && (strpos($name, ':') > 0)) {
  4368. list($name, $value) = explode(':', $name, 2); }
  4369. if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) {
  4370. throw new Client\Exception("{$name} is not a valid HTTP header name"); }
  4371. $normalized_name = strtolower($name);
  4372. if ($value === null || $value === false) {
  4373. unset($this->headers[$normalized_name]); } else {
  4374. if (is_string($value)) {
  4375. $value = trim($value); }
  4376. $this->headers[$normalized_name] = array($name, $value); } }
  4377. return $this; }
  4378. public function getHeader($key) {
  4379. $key = strtolower($key);
  4380. if (isset($this->headers[$key])) {
  4381. return $this->headers[$key][1]; } else {
  4382. return null; } }
  4383. public function setParameterGet($name, $value = null) {
  4384. if (is_array($name)) {
  4385. foreach ($name as $k => $v)
  4386. $this->_setParameter('GET', $k, $v); } else {
  4387. $this->_setParameter('GET', $name, $value); }
  4388. return $this; }
  4389. public function setParameterPost($name, $value = null) {
  4390. if (is_array($name)) {
  4391. foreach ($name as $k => $v)
  4392. $this->_setParameter('POST', $k, $v); } else {
  4393. $this->_setParameter('POST', $name, $value); }
  4394. return $this; }
  4395. protected function _setParameter($type, $name, $value) {
  4396. $parray = array();
  4397. $type = strtolower($type);
  4398. switch ($type) {
  4399. case 'get':
  4400. $parray = &$this->paramsGet;
  4401. break;
  4402. case 'post':
  4403. $parray = &$this->paramsPost;
  4404. break; }
  4405. if ($value === null) {
  4406. if (isset($parray[$name])) unset($parray[$name]); } else {
  4407. $parray[$name] = $value; } }
  4408. public function getRedirectionsCount() {
  4409. return $this->redirectCounter; }
  4410. public function setAuth($user, $password = '', $type = self::AUTH_BASIC) {
  4411. if ($user === false || $user === null) {
  4412. $this->auth = null;
  4413. if ($this->uri instanceof Uri\Url) {
  4414. $this->getUri()->setUsername('');
  4415. $this->getUri()->setPassword(''); } } else {
  4416. if (! defined('self::AUTH_' . strtoupper($type))) {
  4417. throw new Client\Exception("Invalid or not supported authentication type: '$type'"); }
  4418. $this->auth = array(
  4419. 'user' => (string) $user,
  4420. 'password' => (string) $password,
  4421. 'type' => $type
  4422. ); }
  4423. return $this; }
  4424. public function setCookieJar($cookiejar = true) {
  4425. if ($cookiejar instanceof CookieJar) {
  4426. $this->cookiejar = $cookiejar; } elseif ($cookiejar === true) {
  4427. $this->cookiejar = new CookieJar(); } elseif (! $cookiejar) {
  4428. $this->cookiejar = null; } else {
  4429. throw new Client\Exception('Invalid parameter type passed as CookieJar'); }
  4430. return $this; }
  4431. public function getCookieJar() {
  4432. return $this->cookiejar; }
  4433. public function setCookie($cookie, $value = null) {
  4434. if (is_array($cookie)) {
  4435. foreach ($cookie as $c => $v) {
  4436. if (is_string($c)) {
  4437. $this->setCookie($c, $v); } else {
  4438. $this->setCookie($v); } }
  4439. return $this; }
  4440. if ($value !== null && $this->config['encodecookies']) {
  4441. $value = urlencode($value); }
  4442. if (isset($this->cookiejar)) {
  4443. if ($cookie instanceof Cookie) {
  4444. $this->cookiejar->addCookie($cookie); } elseif (is_string($cookie) && $value !== null) {
  4445. $cookie = Cookie::fromString("{$cookie}={$value}",
  4446. $this->uri,
  4447. $this->config['encodecookies']);
  4448. $this->cookiejar->addCookie($cookie); } } else {
  4449. if ($cookie instanceof Cookie) {
  4450. $name = $cookie->getName();
  4451. $value = $cookie->getValue();
  4452. $cookie = $name; }
  4453. if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) {
  4454. throw new Client\Exception("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})"); }
  4455. $value = addslashes($value);
  4456. if (! isset($this->headers['cookie'])) {
  4457. $this->headers['cookie'] = array('Cookie', ''); }
  4458. $this->headers['cookie'][1] .= $cookie . '=' . $value . '; '; }
  4459. return $this; }
  4460. public function setFileUpload($filename, $formname, $data = null, $ctype = null) {
  4461. if ($data === null) {
  4462. if (($data = @file_get_contents($filename)) === false) {
  4463. throw new Client\Exception("Unable to read file '{$filename}' for upload"); }
  4464. if (! $ctype) {
  4465. $ctype = $this->_detectFileMimeType($filename); } }
  4466. $this->setEncType(self::ENC_FORMDATA);
  4467. $this->files[] = array(
  4468. 'formname' => $formname,
  4469. 'filename' => basename($filename),
  4470. 'ctype' => $ctype,
  4471. 'data' => $data
  4472. );
  4473. return $this; }
  4474. public function setEncType($enctype = self::ENC_URLENCODED) {
  4475. $this->enctype = $enctype;
  4476. return $this; }
  4477. public function setRawData($data, $enctype = null) {
  4478. $this->raw_post_data = $data;
  4479. $this->setEncType($enctype);
  4480. if (is_resource($data)) {
  4481. $stat = @fstat($data);
  4482. if($stat) {
  4483. $this->setHeaders(self::CONTENT_LENGTH, $stat['size']); } }
  4484. return $this; }
  4485. public function resetParameters($clearAll = false) {
  4486. $this->paramsGet = array();
  4487. $this->paramsPost = array();
  4488. $this->files = array();
  4489. $this->raw_post_data = null;
  4490. if($clearAll) {
  4491. $this->headers = array();
  4492. $this->last_request = null;
  4493. $this->last_response = null; } else {
  4494. if (isset($this->headers[strtolower(self::CONTENT_TYPE)])) {
  4495. unset($this->headers[strtolower(self::CONTENT_TYPE)]); }
  4496. if (isset($this->headers[strtolower(self::CONTENT_LENGTH)])) {
  4497. unset($this->headers[strtolower(self::CONTENT_LENGTH)]); } }
  4498. return $this; }
  4499. public function getLastRequest() {
  4500. return $this->last_request; }
  4501. public function getLastResponse() {
  4502. return $this->last_response; }
  4503. public function setAdapter($adapter) {
  4504. if (is_string($adapter)) {
  4505. if (!class_exists($adapter)) {
  4506. throw new Client\Exception('Unable to locate adapter class "' . $adapter . '"'); }
  4507. $adapter = new $adapter; }
  4508. if (! $adapter instanceof Client\Adapter) {
  4509. throw new Client\Exception('Passed adapter is not a HTTP connection adapter'); }
  4510. $this->adapter = $adapter;
  4511. $config = $this->config;
  4512. unset($config['adapter']);
  4513. $this->adapter->setConfig($config); }
  4514. public function getAdapter() {
  4515. return $this->adapter; }
  4516. public function setStream($streamfile = true) {
  4517. $this->setConfig(array("output_stream" => $streamfile));
  4518. return $this; }
  4519. public function getStream() {
  4520. return $this->config["output_stream"]; }
  4521. protected function _openTempStream() {
  4522. $this->_stream_name = $this->config['output_stream'];
  4523. if(!is_string($this->_stream_name)) {
  4524. $this->_stream_name = tempnam(isset($this->config['stream_tmp_dir'])?$this->config['stream_tmp_dir']:sys_get_temp_dir(),
  4525. 'Zend_Http_Client'); }
  4526. if (false === ($fp = @fopen($this->_stream_name, "w+b"))) {
  4527. if ($this->adapter instanceof Client\Adapter) {
  4528. $this->adapter->close(); }
  4529. throw new Client\Exception("Could not open temp file {$this->_stream_name}"); }
  4530. return $fp; }
  4531. public function request($method = null) {
  4532. if (! $this->uri instanceof Uri\Url) {
  4533. throw new Client\Exception('No valid URI has been passed to the client'); }
  4534. if ($method) {
  4535. $this->setMethod($method); }
  4536. $this->redirectCounter = 0;
  4537. $response = null;
  4538. if ($this->adapter == null) {
  4539. $this->setAdapter($this->config['adapter']); }
  4540. do {
  4541. $uri = clone $this->uri;
  4542. if (! empty($this->paramsGet)) {
  4543. $query = $uri->getQuery();
  4544. if (! empty($query)) {
  4545. $query .= '&'; }
  4546. $query .= http_build_query($this->paramsGet, null, '&');
  4547. $uri->setQuery($query); }
  4548. $body = $this->_prepareBody();
  4549. $headers = $this->_prepareHeaders();
  4550. if(is_resource($body) && !($this->adapter instanceof Client\Adapter\Stream)) {
  4551. throw new Client\Exception('Adapter does not support streaming'); }
  4552. $this->adapter->connect($uri->getHost(), $uri->getPort(),
  4553. ($uri->getScheme() == 'https' ? true : false));
  4554. if($this->config['output_stream']) {
  4555. if($this->adapter instanceof Client\Adapter\Stream) {
  4556. $stream = $this->_openTempStream();
  4557. $this->adapter->setOutputStream($stream); } else {
  4558. throw new Client\Exception('Adapter does not support streaming'); } }
  4559. $this->last_request = $this->adapter->write($this->method,
  4560. $uri, $this->config['httpversion'], $headers, $body);
  4561. $response = $this->adapter->read();
  4562. if (! $response) {
  4563. throw new Client\Exception('Unable to read response, or response is empty'); }
  4564. if($this->config['output_stream']) {
  4565. rewind($stream);
  4566. $this->adapter->setOutputStream(null);
  4567. $response = Response\Stream::fromStream($response, $stream);
  4568. $response->setStreamName($this->_stream_name);
  4569. if(!is_string($this->config['output_stream'])) {
  4570. $response->setCleanup(true); } } else {
  4571. $response = Response::fromString($response); }
  4572. if ($this->config['storeresponse']) {
  4573. $this->last_response = $response; }
  4574. if (isset($this->cookiejar)) {
  4575. $this->cookiejar->addCookiesFromResponse($response, $uri); }
  4576. if ($response->isRedirect() && ($location = $response->getHeader('location'))) {
  4577. if ($response->getStatus() == 303 ||
  4578. ((! $this->config['strictredirects']) && ($response->getStatus() == 302 ||
  4579. $response->getStatus() == 301))) {
  4580. $this->resetParameters();
  4581. $this->setMethod(self::GET); }
  4582. $url = new Uri\Url($location);
  4583. if ($url->isValid()) {
  4584. $this->setHeaders('host', null);
  4585. $this->setUri($location); } else {
  4586. if (strpos($location, '?') !== false) {
  4587. list($location, $query) = explode('?', $location, 2); } else {
  4588. $query = ''; }
  4589. $this->uri->setQuery($query);
  4590. if(strpos($location, '/') === 0) {
  4591. $this->uri->setPath($location); } else {
  4592. $path = $this->uri->getPath();
  4593. $path = rtrim(substr($path, 0, strrpos($path, '/')), "/");
  4594. $this->uri->setPath($path . '/' . $location); } }
  4595. ++$this->redirectCounter; } else {
  4596. break; } } while ($this->redirectCounter < $this->config['maxredirects']);
  4597. return $response; }
  4598. protected function _prepareHeaders() {
  4599. $headers = array();
  4600. if (! isset($this->headers['host'])) {
  4601. $host = $this->uri->getHost();
  4602. if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) ||
  4603. ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) {
  4604. $host .= ':' . $this->uri->getPort(); }
  4605. $headers[] = "Host: {$host}"; }
  4606. if (! isset($this->headers['connection'])) {
  4607. if (! $this->config['keepalive']) {
  4608. $headers[] = "Connection: close"; } }
  4609. if (! isset($this->headers['accept-encoding'])) {
  4610. if (function_exists('gzinflate')) {
  4611. $headers[] = 'Accept-encoding: gzip, deflate'; } else {
  4612. $headers[] = 'Accept-encoding: identity'; } }
  4613. if ($this->method == self::POST &&
  4614. (! isset($this->headers[strtolower(self::CONTENT_TYPE)]) && isset($this->enctype))) {
  4615. $headers[] = self::CONTENT_TYPE . ': ' . $this->enctype; }
  4616. if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) {
  4617. $headers[] = "User-Agent: {$this->config['useragent']}"; }
  4618. if (is_array($this->auth)) {
  4619. $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']);
  4620. $headers[] = "Authorization: {$auth}"; }
  4621. if (isset($this->cookiejar)) {
  4622. $cookstr = $this->cookiejar->getMatchingCookies($this->uri,
  4623. true, CookieJar::COOKIE_STRING_CONCAT);
  4624. if ($cookstr) {
  4625. $headers[] = "Cookie: {$cookstr}"; } }
  4626. foreach ($this->headers as $header) {
  4627. list($name, $value) = $header;
  4628. if (is_array($value)) {
  4629. $value = implode(', ', $value); }
  4630. $headers[] = "$name: $value"; }
  4631. return $headers; }
  4632. protected function _prepareBody() {
  4633. if ($this->method == self::TRACE) {
  4634. return ''; }
  4635. if (isset($this->raw_post_data) && is_resource($this->raw_post_data)) {
  4636. return $this->raw_post_data; }
  4637. if (function_exists('mb_internal_encoding') &&
  4638. ((int) ini_get('mbstring.func_overload')) & 2) {
  4639. $mbIntEnc = mb_internal_encoding();
  4640. mb_internal_encoding('ASCII'); }
  4641. if (isset($this->raw_post_data)) {
  4642. $this->setHeaders(self::CONTENT_LENGTH, strlen($this->raw_post_data));
  4643. if (isset($mbIntEnc)) {
  4644. mb_internal_encoding($mbIntEnc); }
  4645. return $this->raw_post_data; }
  4646. $body = '';
  4647. if (count ($this->files) > 0) {
  4648. $this->setEncType(self::ENC_FORMDATA); }
  4649. if (count($this->paramsPost) > 0 || count($this->files) > 0) {
  4650. switch($this->enctype) {
  4651. case self::ENC_FORMDATA:
  4652. $boundary = '---ZENDHTTPCLIENT-' . md5(microtime());
  4653. $this->setHeaders(self::CONTENT_TYPE, self::ENC_FORMDATA . "; boundary={$boundary}");
  4654. $params = self::_flattenParametersArray($this->paramsPost);
  4655. foreach ($params as $pp) {
  4656. $body .= self::encodeFormData($boundary, $pp[0], $pp[1]); }
  4657. foreach ($this->files as $file) {
  4658. $fhead = array(self::CONTENT_TYPE => $file['ctype']);
  4659. $body .= self::encodeFormData($boundary, $file['formname'], $file['data'], $file['filename'], $fhead); }
  4660. $body .= "--{$boundary}--\r\n";
  4661. break;
  4662. case self::ENC_URLENCODED:
  4663. $this->setHeaders(self::CONTENT_TYPE, self::ENC_URLENCODED);
  4664. $body = http_build_query($this->paramsPost, '', '&');
  4665. break;
  4666. default:
  4667. if (isset($mbIntEnc)) {
  4668. mb_internal_encoding($mbIntEnc); }
  4669. throw new Client\Exception("Cannot handle content type '{$this->enctype}' automatically." .
  4670. " Please use Zend_Http_Client::setRawData to send this kind of content.");
  4671. break; } }
  4672. if ($body || $this->method == self::POST || $this->method == self::PUT) {
  4673. $this->setHeaders(self::CONTENT_LENGTH, strlen($body)); }
  4674. if (isset($mbIntEnc)) {
  4675. mb_internal_encoding($mbIntEnc); }
  4676. return $body; }
  4677. protected function _getParametersRecursive($parray, $urlencode = false) {
  4678. trigger_error("The " . __METHOD__ . " method is deprecated and will be dropped in 2.0.",
  4679. E_USER_NOTICE);
  4680. if (! is_array($parray)) {
  4681. return $parray; }
  4682. $parameters = array();
  4683. foreach ($parray as $name => $value) {
  4684. if ($urlencode) {
  4685. $name = urlencode($name); }
  4686. if (is_array($value)) {
  4687. $name .= ($urlencode ? '%5B%5D' : '[]');
  4688. foreach ($value as $subval) {
  4689. if ($urlencode) {
  4690. $subval = urlencode($subval); }
  4691. $parameters[] = array($name, $subval); } } else {
  4692. if ($urlencode) {
  4693. $value = urlencode($value); }
  4694. $parameters[] = array($name, $value); } }
  4695. return $parameters; }
  4696. protected function _detectFileMimeType($file) {
  4697. $type = null;
  4698. if (function_exists('finfo_open')) {
  4699. if (self::$_fileInfoDb === null) {
  4700. self::$_fileInfoDb = @finfo_open(FILEINFO_MIME); }
  4701. if (self::$_fileInfoDb) {
  4702. $type = finfo_file(self::$_fileInfoDb, $file); } } elseif (function_exists('mime_content_type')) {
  4703. $type = mime_content_type($file); }
  4704. if (! $type) {
  4705. $type = 'application/octet-stream'; }
  4706. return $type; }
  4707. public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) {
  4708. $ret = "--{$boundary}\r\n" .
  4709. 'Content-Disposition: form-data; name="' . $name .'"';
  4710. if ($filename) {
  4711. $ret .= '; filename="' . $filename . '"'; }
  4712. $ret .= "\r\n";
  4713. foreach ($headers as $hname => $hvalue) {
  4714. $ret .= "{$hname}: {$hvalue}\r\n"; }
  4715. $ret .= "\r\n";
  4716. $ret .= "{$value}\r\n";
  4717. return $ret; }
  4718. public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC) {
  4719. $authHeader = null;
  4720. switch ($type) {
  4721. case self::AUTH_BASIC:
  4722. if (strpos($user, ':') !== false) {
  4723. throw new Client\Exception("The user name cannot contain ':' in 'Basic' HTTP authentication"); }
  4724. $authHeader = 'Basic ' . base64_encode($user . ':' . $password);
  4725. break;
  4726. default:
  4727. throw new Client\Exception("Not a supported HTTP authentication type: '$type'"); }
  4728. return $authHeader; }
  4729. static protected function _flattenParametersArray($parray, $prefix = null) {
  4730. if (! is_array($parray)) {
  4731. return $parray; }
  4732. $parameters = array();
  4733. foreach($parray as $name => $value) {
  4734. if ($prefix) {
  4735. if (is_int($name)) {
  4736. $key = $prefix . '[]'; } else {
  4737. $key = $prefix . "[$name]"; } } else {
  4738. $key = $name; }
  4739. if (is_array($value)) {
  4740. $parameters = array_merge($parameters, self::_flattenParametersArray($value, $key)); } else {
  4741. $parameters[] = array($key, $value); } }
  4742. return $parameters; } }
  4743. <?php
  4744. namespace Zend\Http;
  4745. use Zend\Uri;
  4746. class Cookie {
  4747. protected $name;
  4748. protected $value;
  4749. protected $expires;
  4750. protected $domain;
  4751. protected $path;
  4752. protected $secure;
  4753. protected $encodeValue;
  4754. public function __construct($name, $value, $domain, $expires = null, $path = null, $secure = false) {
  4755. if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
  4756. throw new Exception("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})"); }
  4757. if (! $this->name = (string) $name) {
  4758. throw new Exception('Cookies must have a name'); }
  4759. if (! $this->domain = (string) $domain) {
  4760. throw new Exception('Cookies must have a domain'); }
  4761. $this->value = (string) $value;
  4762. $this->expires = ($expires === null ? null : (int) $expires);
  4763. $this->path = ($path ? $path : '/');
  4764. $this->secure = $secure; }
  4765. public function getName() {
  4766. return $this->name; }
  4767. public function getValue() {
  4768. return $this->value; }
  4769. public function getDomain() {
  4770. return $this->domain; }
  4771. public function getPath() {
  4772. return $this->path; }
  4773. public function getExpiryTime() {
  4774. return $this->expires; }
  4775. public function isSecure() {
  4776. return $this->secure; }
  4777. public function isExpired($now = null) {
  4778. if ($now === null) $now = time();
  4779. if (is_int($this->expires) && $this->expires < $now) {
  4780. return true; } else {
  4781. return false; } }
  4782. public function isSessionCookie() {
  4783. return ($this->expires === null); }
  4784. public function match($uri, $matchSessionCookies = true, $now = null) {
  4785. if (is_string ($uri)) {
  4786. $uri = new Uri\Url($uri); }
  4787. if (! ($uri->isValid() && ($uri->getScheme() == 'http' || $uri->getScheme() =='https'))) {
  4788. throw new Exception('Passed URI is not a valid HTTP or HTTPS URI'); }
  4789. if ($this->secure && $uri->getScheme() != 'https') return false;
  4790. if ($this->isExpired($now)) return false;
  4791. if ($this->isSessionCookie() && ! $matchSessionCookies) return false;
  4792. if (! self::matchCookieDomain($this->getDomain(), $uri->getHost())) {
  4793. return false; }
  4794. if (! self::matchCookiePath($this->getPath(), $uri->getPath())) {
  4795. return false; }
  4796. return true; }
  4797. public function __toString() {
  4798. if ($this->encodeValue) {
  4799. return $this->name . '=' . urlencode($this->value) . ';'; }
  4800. return $this->name . '=' . $this->value . ';'; }
  4801. public static function fromString($cookieStr, $refUri = null, $encodeValue = true) {
  4802. if (is_string($refUri)) {
  4803. $refUri = new Uri\Url($refUri); }
  4804. $name = '';
  4805. $value = '';
  4806. $domain = '';
  4807. $path = '';
  4808. $expires = null;
  4809. $secure = false;
  4810. $parts = explode(';', $cookieStr);
  4811. if (strpos($parts[0], '=') === false) return false;
  4812. list($name, $value) = explode('=', trim(array_shift($parts)), 2);
  4813. $name = trim($name);
  4814. if ($encodeValue) {
  4815. $value = urldecode(trim($value)); }
  4816. if ($refUri instanceof Uri\Url) {
  4817. $domain = $refUri->getHost();
  4818. $path = $refUri->getPath();
  4819. $path = substr($path, 0, strrpos($path, '/')); }
  4820. foreach ($parts as $part) {
  4821. $part = trim($part);
  4822. if (strtolower($part) == 'secure') {
  4823. $secure = true;
  4824. continue; }
  4825. $keyValue = explode('=', $part, 2);
  4826. if (count($keyValue) == 2) {
  4827. list($k, $v) = $keyValue;
  4828. switch (strtolower($k)) {
  4829. case 'expires':
  4830. if(($expires = strtotime($v)) === false) {
  4831. $expireDate = new \Zend\Date\Date($v);
  4832. $expires = $expireDate->getTimestamp(); }
  4833. break;
  4834. case 'path':
  4835. $path = $v;
  4836. break;
  4837. case 'domain':
  4838. $domain = $v;
  4839. break;
  4840. default:
  4841. break; } } }
  4842. if ($name !== '') {
  4843. $ret = new self($name, $value, $domain, $expires, $path, $secure);
  4844. $ret->encodeValue = ($encodeValue) ? true : false;
  4845. return $ret; } else {
  4846. return false; } }
  4847. public static function matchCookieDomain($cookieDomain, $host) {
  4848. if (! $cookieDomain) {
  4849. throw new Exception("\$cookieDomain is expected to be a cookie domain"); }
  4850. if (! $host) {
  4851. throw new Exception("\$host is expected to be a host name"); }
  4852. $cookieDomain = strtolower($cookieDomain);
  4853. $host = strtolower($host);
  4854. if ($cookieDomain[0] == '.') {
  4855. $cookieDomain = substr($cookieDomain, 1); }
  4856. return ($cookieDomain == $host ||
  4857. preg_match("/\.$cookieDomain$/", $host)); }
  4858. public static function matchCookiePath($cookiePath, $path) {
  4859. if (! $cookiePath) {
  4860. throw new Exception("\$cookiePath is expected to be a cookie path"); }
  4861. if ((null !== $path) && (!is_scalar($path) || is_numeric($path) || is_bool($path))) {
  4862. throw new Exception("\$path is expected to be a cookie path"); }
  4863. $path = (string) $path;
  4864. if (empty($path)) {
  4865. $path = '/'; }
  4866. return (strpos($path, $cookiePath) === 0); } }
  4867. <?php
  4868. namespace Zend\Http;
  4869. use Zend\Uri;
  4870. class CookieJar implements \Countable, \IteratorAggregate {
  4871. const COOKIE_OBJECT = 0;
  4872. const COOKIE_STRING_ARRAY = 1;
  4873. const COOKIE_STRING_CONCAT = 2;
  4874. protected $cookies = array();
  4875. protected $_rawCookies = array();
  4876. public function __construct() { }
  4877. public function addCookie($cookie, $ref_uri = null) {
  4878. if (is_string($cookie)) {
  4879. $cookie = Cookie::fromString($cookie, $ref_uri); }
  4880. if ($cookie instanceof Cookie) {
  4881. $domain = $cookie->getDomain();
  4882. $path = $cookie->getPath();
  4883. if (! isset($this->cookies[$domain])) $this->cookies[$domain] = array();
  4884. if (! isset($this->cookies[$domain][$path])) $this->cookies[$domain][$path] = array();
  4885. $this->cookies[$domain][$path][$cookie->getName()] = $cookie;
  4886. $this->_rawCookies[] = $cookie; } else {
  4887. throw new Exception('Supplient argument is not a valid cookie string or object'); } }
  4888. public function addCookiesFromResponse($response, $ref_uri) {
  4889. if (! $response instanceof Response) {
  4890. throw new Exception('$response is expected to be a Response object, ' .
  4891. gettype($response) . ' was passed'); }
  4892. $cookie_hdrs = $response->getHeader('Set-Cookie');
  4893. if (is_array($cookie_hdrs)) {
  4894. foreach ($cookie_hdrs as $cookie) {
  4895. $this->addCookie($cookie, $ref_uri); } } elseif (is_string($cookie_hdrs)) {
  4896. $this->addCookie($cookie_hdrs, $ref_uri); } }
  4897. public function getAllCookies($ret_as = self::COOKIE_OBJECT) {
  4898. $cookies = $this->_flattenCookiesArray($this->cookies, $ret_as);
  4899. return $cookies; }
  4900. public function getMatchingCookies($uri, $matchSessionCookies = true,
  4901. $ret_as = self::COOKIE_OBJECT, $now = null) {
  4902. if (is_string($uri)) $uri = new Uri\Url($uri);
  4903. if (! $uri instanceof Uri\Url) {
  4904. throw new Exception("Invalid URI string or object passed"); }
  4905. $host = $uri->getHost();
  4906. if (empty($host)) {
  4907. throw new Exception('Invalid URI specified; does not contain a host'); }
  4908. $cookies = $this->_matchDomain($host);
  4909. $cookies = $this->_matchPath($cookies, $uri->getPath());
  4910. $cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT);
  4911. $ret = array();
  4912. foreach ($cookies as $cookie)
  4913. if ($cookie->match($uri, $matchSessionCookies, $now))
  4914. $ret[] = $cookie;
  4915. $ret = $this->_flattenCookiesArray($ret, $ret_as);
  4916. return $ret; }
  4917. public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT) {
  4918. if (is_string($uri)) {
  4919. $uri = new Uri\Url($uri); }
  4920. if (! $uri instanceof Uri\Url) {
  4921. throw new Exception('Invalid URI specified'); }
  4922. $host = $uri->getHost();
  4923. if (empty($host)) {
  4924. throw new Exception('Invalid URI specified; host missing'); }
  4925. $path = $uri->getPath();
  4926. $path = substr($path, 0, strrpos($path, '/'));
  4927. if (! $path) $path = '/';
  4928. if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) {
  4929. $cookie = $this->cookies[$uri->getHost()][$path][$cookie_name];
  4930. switch ($ret_as) {
  4931. case self::COOKIE_OBJECT:
  4932. return $cookie;
  4933. break;
  4934. case self::COOKIE_STRING_ARRAY:
  4935. case self::COOKIE_STRING_CONCAT:
  4936. return $cookie->__toString();
  4937. break;
  4938. default:
  4939. throw new Exception("Invalid value passed for \$ret_as: {$ret_as}");
  4940. break; } } else {
  4941. return false; } }
  4942. protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) {
  4943. if (is_array($ptr)) {
  4944. $ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array());
  4945. foreach ($ptr as $item) {
  4946. if ($ret_as == self::COOKIE_STRING_CONCAT) {
  4947. $ret .= $this->_flattenCookiesArray($item, $ret_as); } else {
  4948. $ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as)); } }
  4949. return $ret; } elseif ($ptr instanceof Cookie) {
  4950. switch ($ret_as) {
  4951. case self::COOKIE_STRING_ARRAY:
  4952. return array($ptr->__toString());
  4953. break;
  4954. case self::COOKIE_STRING_CONCAT:
  4955. return $ptr->__toString();
  4956. break;
  4957. case self::COOKIE_OBJECT:
  4958. default:
  4959. return array($ptr);
  4960. break; } }
  4961. return null; }
  4962. protected function _matchDomain($domain) {
  4963. $ret = array();
  4964. foreach (array_keys($this->cookies) as $cdom) {
  4965. if (Cookie::matchCookieDomain($cdom, $domain)) {
  4966. $ret[$cdom] = $this->cookies[$cdom]; } }
  4967. return $ret; }
  4968. protected function _matchPath($domains, $path) {
  4969. $ret = array();
  4970. foreach ($domains as $dom => $paths_array) {
  4971. foreach (array_keys($paths_array) as $cpath) {
  4972. if (Cookie::matchCookiePath($cpath, $path)) {
  4973. if (! isset($ret[$dom])) {
  4974. $ret[$dom] = array(); }
  4975. $ret[$dom][$cpath] = $paths_array[$cpath]; } } }
  4976. return $ret; }
  4977. public static function fromResponse(Response $response, $ref_uri) {
  4978. $jar = new self();
  4979. $jar->addCookiesFromResponse($response, $ref_uri);
  4980. return $jar; }
  4981. public function count() {
  4982. return count($this->_rawCookies); }
  4983. public function getIterator() {
  4984. return new \ArrayIterator($this->_rawCookies); }
  4985. public function isEmpty() {
  4986. return count($this) == 0; }
  4987. public function reset() {
  4988. $this->cookies = $this->_rawCookies = array();
  4989. return $this; } }
  4990. <?php
  4991. namespace Zend\Http;
  4992. class Exception extends \Zend\Exception {}
  4993. <?php
  4994. namespace Zend\Http\Response;
  4995. use Zend\Http\Response;
  4996. class Stream extends Response {
  4997. protected $stream;
  4998. protected $stream_name;
  4999. protected $_cleanup;
  5000. public function getStream() {
  5001. return $this->stream; }
  5002. public function setStream($stream) {
  5003. $this->stream = $stream;
  5004. return $this; }
  5005. public function getCleanup() {
  5006. return $this->_cleanup; }
  5007. public function setCleanup($cleanup = true) {
  5008. $this->_cleanup = $cleanup; }
  5009. public function getStreamName() {
  5010. return $this->stream_name; }
  5011. public function setStreamName($stream_name) {
  5012. $this->stream_name = $stream_name;
  5013. return $this; }
  5014. public function __construct($code, $headers, $body = null, $version = '1.1', $message = null) {
  5015. if(is_resource($body)) {
  5016. $this->setStream($body);
  5017. $body = ''; }
  5018. parent::__construct($code, $headers, $body, $version, $message); }
  5019. public static function fromStream($response_str, $stream) {
  5020. $code = self::extractCode($response_str);
  5021. $headers = self::extractHeaders($response_str);
  5022. $version = self::extractVersion($response_str);
  5023. $message = self::extractMessage($response_str);
  5024. return new self($code, $headers, $stream, $version, $message); }
  5025. public function getBody() {
  5026. if($this->stream != null) {
  5027. $this->readStream(); }
  5028. return parent::getBody(); }
  5029. public function getRawBody() {
  5030. if($this->stream) {
  5031. $this->readStream(); }
  5032. return $this->body; }
  5033. protected function readStream() {
  5034. if(!is_resource($this->stream)) {
  5035. return ''; }
  5036. if(isset($headers['content-length'])) {
  5037. $this->body = stream_get_contents($this->stream, $headers['content-length']); } else {
  5038. $this->body = stream_get_contents($this->stream); }
  5039. fclose($this->stream);
  5040. $this->stream = null; }
  5041. public function __destruct() {
  5042. if(is_resource($this->stream)) {
  5043. fclose($this->stream);
  5044. $this->stream = null; }
  5045. if($this->_cleanup) {
  5046. @unlink($this->stream_name); } } }
  5047. <?php
  5048. namespace Zend\Http;
  5049. class Response {
  5050. protected static $messages = array(
  5051. 100 => 'Continue',
  5052. 101 => 'Switching Protocols',
  5053. 200 => 'OK',
  5054. 201 => 'Created',
  5055. 202 => 'Accepted',
  5056. 203 => 'Non-Authoritative Information',
  5057. 204 => 'No Content',
  5058. 205 => 'Reset Content',
  5059. 206 => 'Partial Content',
  5060. 300 => 'Multiple Choices',
  5061. 301 => 'Moved Permanently',
  5062. 302 => 'Found', 303 => 'See Other',
  5063. 304 => 'Not Modified',
  5064. 305 => 'Use Proxy',
  5065. 307 => 'Temporary Redirect',
  5066. 400 => 'Bad Request',
  5067. 401 => 'Unauthorized',
  5068. 402 => 'Payment Required',
  5069. 403 => 'Forbidden',
  5070. 404 => 'Not Found',
  5071. 405 => 'Method Not Allowed',
  5072. 406 => 'Not Acceptable',
  5073. 407 => 'Proxy Authentication Required',
  5074. 408 => 'Request Timeout',
  5075. 409 => 'Conflict',
  5076. 410 => 'Gone',
  5077. 411 => 'Length Required',
  5078. 412 => 'Precondition Failed',
  5079. 413 => 'Request Entity Too Large',
  5080. 414 => 'Request-URI Too Long',
  5081. 415 => 'Unsupported Media Type',
  5082. 416 => 'Requested Range Not Satisfiable',
  5083. 417 => 'Expectation Failed',
  5084. 500 => 'Internal Server Error',
  5085. 501 => 'Not Implemented',
  5086. 502 => 'Bad Gateway',
  5087. 503 => 'Service Unavailable',
  5088. 504 => 'Gateway Timeout',
  5089. 505 => 'HTTP Version Not Supported',
  5090. 509 => 'Bandwidth Limit Exceeded'
  5091. );
  5092. protected $version;
  5093. protected $code;
  5094. protected $message;
  5095. protected $headers = array();
  5096. protected $body;
  5097. public function __construct($code, $headers, $body = null, $version = '1.1', $message = null) {
  5098. if (self::responseCodeAsText($code) === null) {
  5099. throw new Exception("{$code} is not a valid HTTP response code"); }
  5100. $this->code = $code;
  5101. if (! is_array($headers)) {
  5102. throw new Exception('No valid headers were passed'); }
  5103. foreach ($headers as $name => $value) {
  5104. if (is_int($name))
  5105. list($name, $value) = explode(": ", $value, 1);
  5106. $this->headers[ucwords(strtolower($name))] = $value; }
  5107. $this->body = $body;
  5108. if (! preg_match('|^\d\.\d$|', $version)) {
  5109. throw new Exception("Invalid HTTP response version: $version"); }
  5110. $this->version = $version;
  5111. if (is_string($message)) {
  5112. $this->message = $message; } else {
  5113. $this->message = self::responseCodeAsText($code); } }
  5114. public function isError() {
  5115. $restype = floor($this->code / 100);
  5116. if ($restype == 4 || $restype == 5) {
  5117. return true; }
  5118. return false; }
  5119. public function isSuccessful() {
  5120. $restype = floor($this->code / 100);
  5121. if ($restype == 2 || $restype == 1) { return true; }
  5122. return false; }
  5123. public function isRedirect() {
  5124. $restype = floor($this->code / 100);
  5125. if ($restype == 3) {
  5126. return true; }
  5127. return false; }
  5128. public function getBody() {
  5129. $body = '';
  5130. switch (strtolower($this->getHeader('transfer-encoding'))) {
  5131. case 'chunked':
  5132. $body = self::decodeChunkedBody($this->body);
  5133. break;
  5134. default:
  5135. $body = $this->body;
  5136. break; }
  5137. switch (strtolower($this->getHeader('content-encoding'))) {
  5138. case 'gzip':
  5139. $body = self::decodeGzip($body);
  5140. break;
  5141. case 'deflate':
  5142. $body = self::decodeDeflate($body);
  5143. break;
  5144. default:
  5145. break; }
  5146. return $body; }
  5147. public function getRawBody() {
  5148. return $this->body; }
  5149. public function getVersion() {
  5150. return $this->version; }
  5151. public function getStatus() {
  5152. return $this->code; }
  5153. public function getMessage() {
  5154. return $this->message; }
  5155. public function getHeaders() {
  5156. return $this->headers; }
  5157. public function getHeader($header) {
  5158. $header = ucwords(strtolower($header));
  5159. if (! is_string($header) || ! isset($this->headers[$header])) return null;
  5160. return $this->headers[$header]; }
  5161. public function getHeadersAsString($status_line = true, $br = "\n") {
  5162. $str = '';
  5163. if ($status_line) {
  5164. $str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}"; }
  5165. foreach ($this->headers as $name => $value) {
  5166. if (is_string($value))
  5167. $str .= "{$name}: {$value}{$br}";
  5168. elseif (is_array($value)) {
  5169. foreach ($value as $subval) {
  5170. $str .= "{$name}: {$subval}{$br}"; } } }
  5171. return $str; }
  5172. public function asString($br = "\n") {
  5173. return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody(); }
  5174. public function __toString() {
  5175. return $this->asString(); }
  5176. public static function responseCodeAsText($code = null, $http11 = true) {
  5177. $messages = self::$messages;
  5178. if (! $http11) $messages[302] = 'Moved Temporarily';
  5179. if ($code === null) {
  5180. return $messages; } elseif (isset($messages[$code])) {
  5181. return $messages[$code]; } else {
  5182. return 'Unknown'; } }
  5183. public static function extractCode($response_str) {
  5184. preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m);
  5185. if (isset($m[1])) {
  5186. return (int) $m[1]; } else {
  5187. return false; } }
  5188. public static function extractMessage($response_str) {
  5189. preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m);
  5190. if (isset($m[1])) {
  5191. return $m[1]; } else {
  5192. return false; } }
  5193. public static function extractVersion($response_str) {
  5194. preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m);
  5195. if (isset($m[1])) {
  5196. return $m[1]; } else {
  5197. return false; } }
  5198. public static function extractHeaders($response_str) {
  5199. $headers = array();
  5200. $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
  5201. if (! $parts[0]) return $headers;
  5202. $lines = explode("\n", $parts[0]);
  5203. unset($parts);
  5204. $last_header = null;
  5205. foreach($lines as $line) {
  5206. $line = trim($line, "\r\n");
  5207. if ($line == "") break;
  5208. if (preg_match("|^([\w-]+):\s*(.+)|", $line, $m)) {
  5209. unset($last_header);
  5210. $h_name = strtolower($m[1]);
  5211. $h_value = $m[2];
  5212. if (isset($headers[$h_name])) {
  5213. if (! is_array($headers[$h_name])) {
  5214. $headers[$h_name] = array($headers[$h_name]); }
  5215. $headers[$h_name][] = $h_value; } else {
  5216. $headers[$h_name] = $h_value; }
  5217. $last_header = $h_name; } elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) {
  5218. if (is_array($headers[$last_header])) {
  5219. end($headers[$last_header]);
  5220. $last_header_key = key($headers[$last_header]);
  5221. $headers[$last_header][$last_header_key] .= $m[1]; } else {
  5222. $headers[$last_header] .= $m[1]; } } }
  5223. return $headers; }
  5224. public static function extractBody($response_str) {
  5225. $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
  5226. if (isset($parts[1])) {
  5227. return $parts[1]; }
  5228. return ''; }
  5229. public static function decodeChunkedBody($body) {
  5230. $decBody = '';
  5231. if (function_exists('mb_internal_encoding') &&
  5232. ((int) ini_get('mbstring.func_overload')) & 2) {
  5233. $mbIntEnc = mb_internal_encoding();
  5234. mb_internal_encoding('ASCII'); }
  5235. while (trim($body)) {
  5236. if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
  5237. throw new Exception("Error parsing body - doesn't seem to be a chunked message"); }
  5238. $length = hexdec(trim($m[1]));
  5239. $cut = strlen($m[0]);
  5240. $decBody .= substr($body, $cut, $length);
  5241. $body = substr($body, $cut + $length + 2); }
  5242. if (isset($mbIntEnc)) {
  5243. mb_internal_encoding($mbIntEnc); }
  5244. return $decBody; }
  5245. public static function decodeGzip($body) {
  5246. if (! function_exists('gzinflate')) {
  5247. throw new Exception(
  5248. 'zlib extension is required in order to decode "gzip" encoding'
  5249. ); }
  5250. return gzinflate(substr($body, 10)); }
  5251. public static function decodeDeflate($body) {
  5252. if (! function_exists('gzuncompress')) {
  5253. throw new Exception(
  5254. 'zlib extension is required in order to decode "deflate" encoding'
  5255. ); }
  5256. $zlibHeader = unpack('n', substr($body, 0, 2));
  5257. if ($zlibHeader[1] % 31 == 0) {
  5258. return gzuncompress($body); } else {
  5259. return gzinflate($body); } }
  5260. public static function fromString($response_str) {
  5261. $code = self::extractCode($response_str);
  5262. $headers = self::extractHeaders($response_str);
  5263. $body = self::extractBody($response_str);
  5264. $version = self::extractVersion($response_str);
  5265. $message = self::extractMessage($response_str);
  5266. return new Response($code, $headers, $body, $version, $message); } }
  5267. <?php
  5268. /*
  5269. * This file is part of the Goutte utility.
  5270. *
  5271. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  5272. *
  5273. * This source file is subject to the MIT license that is bundled
  5274. * with this source code in the file LICENSE.
  5275. */ require_once __DIR__.'/src/autoload.php'; __HALT_COMPILER();<?php throw new \LogicException('This PHAR file can only be used from the CLI.'); __HALT_COMPILER();ŠOB ‰vÍΉú~Ę-ťPGBMB