[TASK] Update PEAR packages 70/33770/6
authorMarkus Klein <klein.t3@reelworx.at>
Tue, 4 Nov 2014 00:57:04 +0000 (01:57 +0100)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Wed, 26 Nov 2014 12:53:26 +0000 (13:53 +0100)
Update the PEAR packages in the contrib folder to the current versions.
That is from 2.1.1 to 2.2.1

Mainly this includes bugfixes and some minor features like
"100 Continue" support.

Relevant changelogs:
http://pear.php.net/package/HTTP_Request2/download/2.2.0
http://pear.php.net/package/HTTP_Request2/download/2.2.1

Resolves: #62672
Releases: master
Change-Id: I20efe703a8db75e2ae579693639b4c3afb7e0f77
Reviewed-on: http://review.typo3.org/33770
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
17 files changed:
typo3/contrib/pear/HTTP/Request2.php
typo3/contrib/pear/HTTP/Request2/Adapter.php
typo3/contrib/pear/HTTP/Request2/Adapter/Curl.php
typo3/contrib/pear/HTTP/Request2/Adapter/Mock.php
typo3/contrib/pear/HTTP/Request2/Adapter/Socket.php
typo3/contrib/pear/HTTP/Request2/CookieJar.php
typo3/contrib/pear/HTTP/Request2/Exception.php
typo3/contrib/pear/HTTP/Request2/MultipartBody.php
typo3/contrib/pear/HTTP/Request2/Observer/Log.php
typo3/contrib/pear/HTTP/Request2/Response.php
typo3/contrib/pear/HTTP/Request2/SOCKS5.php
typo3/contrib/pear/HTTP/Request2/SocketWrapper.php
typo3/contrib/pear/Net/URL2.php
typo3/contrib/pear/PEAR/Exception.php
typo3/contrib/pear/data/public-suffix-list.php
typo3/sysext/core/Classes/Http/HttpRequest.php
typo3/sysext/linkvalidator/Classes/Linktype/ExternalLinktype.php

index 4e3b588..36c413f 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Request2.php 324936 2012-04-07 07:49:03Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -57,8 +34,8 @@ require_once 'HTTP/Request2/Exception.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  * @link     http://tools.ietf.org/html/rfc2616#section-5
  */
@@ -152,6 +129,7 @@ class HTTP_Request2 implements SplSubject
         'protocol_version'  => '1.1',
         'buffer_size'       => 16384,
         'store_body'        => true,
+        'local_ip'          => null,
 
         'proxy_host'        => '',
         'proxy_port'        => '',
@@ -235,7 +213,7 @@ class HTTP_Request2 implements SplSubject
             $this->setMethod($method);
         }
         $this->setHeader(
-            'user-agent', 'HTTP_Request2/2.1.1 ' .
+            'user-agent', 'HTTP_Request2/2.2.1 ' .
             '(http://pear.php.net/package/http_request2) PHP/' . phpversion()
         );
     }
@@ -338,6 +316,8 @@ class HTTP_Request2 implements SplSubject
      *   <li> 'store_body'        - Whether to store response body in response object.
      *                              Set to false if receiving a huge response and
      *                              using an Observer to save it (boolean)</li>
+     *   <li> 'local_ip'          - Specifies the IP address that will be used for accessing
+     *                              the network (string)</li>
      *   <li> 'proxy_type'        - Proxy type, 'http' or 'socks5' (string)</li>
      *   <li> 'proxy_host'        - Proxy server host (string)</li>
      *   <li> 'proxy_port'        - Proxy server port (integer)</li>
index 76eb7ec..2b29fce 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Adapter.php 324415 2012-03-21 10:50:50Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -56,8 +33,8 @@ require_once 'HTTP/Request2/Response.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 abstract class HTTP_Request2_Adapter
@@ -150,7 +127,10 @@ abstract class HTTP_Request2_Adapter
             if (empty($headers['content-type'])) {
                 $headers['content-type'] = 'application/x-www-form-urlencoded';
             }
-            $headers['content-length'] = $this->contentLength;
+            // Content-Length should not be sent for chunked Transfer-Encoding (bug #20125)
+            if (!isset($headers['transfer-encoding'])) {
+                $headers['content-length'] = $this->contentLength;
+            }
         }
     }
 }
index 5aed001..4fb8eb5 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Curl.php 324746 2012-04-03 15:09:16Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -52,8 +29,8 @@ require_once 'HTTP/Request2/Adapter.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
@@ -238,6 +215,7 @@ class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
      *
      * @return   resource    a cURL handle, as created by curl_init()
      * @throws   HTTP_Request2_LogicException
+     * @throws   HTTP_Request2_NotImplementedException
      */
     protected function createCurlHandle()
     {
@@ -278,6 +256,11 @@ class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
             }
         }
 
+        // set local IP via CURLOPT_INTERFACE (request #19515)
+        if ($ip = $this->request->getConfig('local_ip')) {
+            curl_setopt($ch, CURLOPT_INTERFACE, $ip);
+        }
+
         // request timeout
         if ($timeout = $this->request->getConfig('timeout')) {
             curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
@@ -389,7 +372,7 @@ class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
         }
 
         $this->calculateRequestLength($headers);
-        if (isset($headers['content-length'])) {
+        if (isset($headers['content-length']) || isset($headers['transfer-encoding'])) {
             $this->workaroundPhpBug47204($ch, $headers);
         }
 
index 0d89e06..9659e62 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Mock.php 324937 2012-04-07 10:05:57Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -66,8 +43,8 @@ require_once 'HTTP/Request2/Adapter.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
@@ -89,7 +66,7 @@ class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
      * @param HTTP_Request2 $request HTTP request message
      *
      * @return   HTTP_Request2_Response
-     * @throws   \Exception
+     * @throws   Exception
      */
     public function sendRequest(HTTP_Request2 $request)
     {
index 4faef35..62507fd 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Socket.php 324953 2012-04-08 07:24:12Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /** Base class for HTTP_Request2 adapters */
@@ -56,8 +33,8 @@ require_once 'HTTP/Request2/SocketWrapper.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
@@ -70,7 +47,7 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
     /**
      * Regular expression for 'quoted-string' rule from RFC 2616
      */
-    const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';
+    const REGEXP_QUOTED_STRING = '"(?>[^"\\\\]+|\\\\.)*"';
 
     /**
      * Connected sockets, needed for Keep-Alive support
@@ -130,6 +107,12 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
     protected $redirectCountdown = null;
 
     /**
+     * Whether to wait for "100 Continue" response before sending request body
+     * @var bool
+     */
+    protected $expect100Continue = false;
+
+    /**
      * Sends request to the remote server and returns its response
      *
      * @param HTTP_Request2 $request HTTP request message
@@ -147,9 +130,21 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             $this->socket->write($headers);
             // provide request headers to the observer, see request #7633
             $this->request->setLastEvent('sentHeaders', $headers);
-            $this->writeBody();
 
-            $response = $this->readResponse();
+            if (!$this->expect100Continue) {
+                $this->writeBody();
+                $response = $this->readResponse();
+
+            } else {
+                $response = $this->readResponse();
+                if (!$response || 100 == $response->getStatus()) {
+                    $this->expect100Continue = false;
+                    // either got "100 Continue" or timed out -> send body
+                    $this->writeBody();
+                    $response = $this->readResponse();
+                }
+            }
+
 
             if ($jar = $request->getCookieJar()) {
                 $jar->addCookiesFromResponse($response, $request->getUrl());
@@ -256,19 +251,25 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
                       'Keep-Alive' == $headers['connection']);
 
         $options = array();
+        if ($ip = $this->request->getConfig('local_ip')) {
+            $options['socket'] = array(
+                'bindto' => (false === strpos($ip, ':') ? $ip : '[' . $ip . ']') . ':0'
+            );
+        }
         if ($secure || $tunnel) {
+            $options['ssl'] = array();
             foreach ($this->request->getConfig() as $name => $value) {
                 if ('ssl_' == substr($name, 0, 4) && null !== $value) {
                     if ('ssl_verify_host' == $name) {
                         if ($value) {
-                            $options['CN_match'] = $reqHost;
+                            $options['ssl']['CN_match'] = $reqHost;
                         }
                     } else {
-                        $options[substr($name, 4)] = $value;
+                        $options['ssl'][substr($name, 4)] = $value;
                     }
                 }
             }
-            ksort($options);
+            ksort($options['ssl']);
         }
 
         // Use global request timeout if given, see feature requests #5735, #8964
@@ -863,6 +864,11 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         $this->addAuthorizationHeader($headers, $host, $requestUrl);
         $this->addProxyAuthorizationHeader($headers, $requestUrl);
         $this->calculateRequestLength($headers);
+        if ('1.1' == $this->request->getConfig('protocol_version')) {
+            $this->updateExpectHeader($headers);
+        } else {
+            $this->expect100Continue = false;
+        }
 
         $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' .
                       $this->request->getConfig('protocol_version') . "\r\n";
@@ -874,6 +880,78 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
     }
 
     /**
+     * Adds or removes 'Expect: 100-continue' header from request headers
+     *
+     * Also sets the $expect100Continue property. Parsing of existing header
+     * is somewhat needed due to its complex structure and due to the
+     * requirement in section 8.2.3 of RFC 2616:
+     * > A client MUST NOT send an Expect request-header field (section
+     * > 14.20) with the "100-continue" expectation if it does not intend
+     * > to send a request body.
+     *
+     * @param array &$headers Array of headers prepared for the request
+     *
+     * @throws HTTP_Request2_LogicException
+     * @link http://pear.php.net/bugs/bug.php?id=19233
+     * @link http://tools.ietf.org/html/rfc2616#section-8.2.3
+     */
+    protected function updateExpectHeader(&$headers)
+    {
+        $this->expect100Continue = false;
+        $expectations = array();
+        if (isset($headers['expect'])) {
+            if ('' === $headers['expect']) {
+                // empty 'Expect' header is technically invalid, so just get rid of it
+                unset($headers['expect']);
+                return;
+            }
+            // build regexp to parse the value of existing Expect header
+            $expectParam     = ';\s*' . self::REGEXP_TOKEN . '(?:\s*=\s*(?:'
+                               . self::REGEXP_TOKEN . '|'
+                               . self::REGEXP_QUOTED_STRING . '))?\s*';
+            $expectExtension = self::REGEXP_TOKEN . '(?:\s*=\s*(?:'
+                               . self::REGEXP_TOKEN . '|'
+                               . self::REGEXP_QUOTED_STRING . ')\s*(?:'
+                               . $expectParam . ')*)?';
+            $expectItem      = '!(100-continue|' . $expectExtension . ')!A';
+
+            $pos    = 0;
+            $length = strlen($headers['expect']);
+
+            while ($pos < $length) {
+                $pos += strspn($headers['expect'], " \t", $pos);
+                if (',' === substr($headers['expect'], $pos, 1)) {
+                    $pos++;
+                    continue;
+
+                } elseif (!preg_match($expectItem, $headers['expect'], $m, 0, $pos)) {
+                    throw new HTTP_Request2_LogicException(
+                        "Cannot parse value '{$headers['expect']}' of Expect header",
+                        HTTP_Request2_Exception::INVALID_ARGUMENT
+                    );
+
+                } else {
+                    $pos += strlen($m[0]);
+                    if (strcasecmp('100-continue', $m[0])) {
+                        $expectations[]  = $m[0];
+                    }
+                }
+            }
+        }
+
+        if (1024 < $this->contentLength) {
+            $expectations[] = '100-continue';
+            $this->expect100Continue = true;
+        }
+
+        if (empty($expectations)) {
+            unset($headers['expect']);
+        } else {
+            $headers['expect'] = implode(',', $expectations);
+        }
+    }
+
+    /**
      * Sends the request body
      *
      * @throws   HTTP_Request2_MessageException
@@ -888,6 +966,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
 
         $position   = 0;
         $bufferSize = $this->request->getConfig('buffer_size');
+        $headers    = $this->request->getHeaders();
+        $chunked    = isset($headers['transfer-encoding']);
         while ($position < $this->contentLength) {
             if (is_string($this->requestBody)) {
                 $str = substr($this->requestBody, $position, $bufferSize);
@@ -896,11 +976,20 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             } else {
                 $str = $this->requestBody->read($bufferSize);
             }
-            $this->socket->write($str);
+            if (!$chunked) {
+                $this->socket->write($str);
+            } else {
+                $this->socket->write(dechex(strlen($str)) . "\r\n{$str}\r\n");
+            }
             // Provide the length of written string to the observer, request #7630
             $this->request->setLastEvent('sentBodyPart', strlen($str));
             $position += strlen($str);
         }
+
+        // write zero-length chunk
+        if ($chunked) {
+            $this->socket->write("0\r\n\r\n");
+        }
         $this->request->setLastEvent('sentBody', $this->contentLength);
     }
 
@@ -913,15 +1002,31 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
     protected function readResponse()
     {
         $bufferSize = $this->request->getConfig('buffer_size');
+        // http://tools.ietf.org/html/rfc2616#section-8.2.3
+        // ...the client SHOULD NOT wait for an indefinite period before sending the request body
+        $timeout    = $this->expect100Continue ? 1 : null;
 
         do {
-            $response = new HTTP_Request2_Response(
-                $this->socket->readLine($bufferSize), true, $this->request->getUrl()
-            );
-            do {
-                $headerLine = $this->socket->readLine($bufferSize);
-                $response->parseHeaderLine($headerLine);
-            } while ('' != $headerLine);
+            try {
+                $response = new HTTP_Request2_Response(
+                    $this->socket->readLine($bufferSize, $timeout), true, $this->request->getUrl()
+                );
+                do {
+                    $headerLine = $this->socket->readLine($bufferSize);
+                    $response->parseHeaderLine($headerLine);
+                } while ('' != $headerLine);
+
+            } catch (HTTP_Request2_MessageException $e) {
+                if (HTTP_Request2_Exception::TIMEOUT === $e->getCode()
+                    && $this->expect100Continue
+                ) {
+                    return null;
+                }
+                throw $e;
+            }
+            if ($this->expect100Continue && 100 == $response->getStatus()) {
+                return $response;
+            }
         } while (in_array($response->getStatus(), array(100, 101)));
 
         $this->request->setLastEvent('receivedHeaders', $response);
index a171034..ed6352e 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: CookieJar.php 324415 2012-03-21 10:50:50Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /** Class representing a HTTP request message */
@@ -50,8 +27,8 @@ require_once 'HTTP/Request2.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: @package_version@
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_CookieJar implements Serializable
@@ -514,4 +491,4 @@ class HTTP_Request2_CookieJar implements Serializable
         return (strlen($result) > 0) ? ($result . '.' . $sub) : null;
     }
 }
-?>
+?>
\ No newline at end of file
index d440fdf..5fcd691 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
- *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Exception.php 324415 2012-03-21 10:50:50Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * LICENSE
+ *
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
+ *
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -52,8 +29,8 @@ require_once 'PEAR/Exception.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  * @link     http://pear.php.net/pepr/pepr-proposal-show.php?id=132
  */
@@ -119,8 +96,8 @@ class HTTP_Request2_Exception extends PEAR_Exception
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception
@@ -140,8 +117,8 @@ class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_LogicException extends HTTP_Request2_Exception
@@ -157,8 +134,8 @@ class HTTP_Request2_LogicException extends HTTP_Request2_Exception
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception
@@ -173,8 +150,8 @@ class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_MessageException extends HTTP_Request2_Exception
index 9e9a178..198f563 100644 (file)
@@ -4,43 +4,23 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: MultipartBody.php 324415 2012-03-21 10:50:50Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
+/** Exception class for HTTP_Request2 package */
+require_once 'HTTP/Request2/Exception.php';
+
 /**
  * Class for building multipart/form-data request body
  *
@@ -50,8 +30,8 @@
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  * @link     http://tools.ietf.org/html/rfc1867
  */
@@ -167,6 +147,7 @@ class HTTP_Request2_MultipartBody
      * @param integer $length Number of bytes to read
      *
      * @return   string  Up to $length bytes of data, empty string if at end
+     * @throws   HTTP_Request2_LogicException
      */
     public function read($length)
     {
@@ -194,9 +175,16 @@ class HTTP_Request2_MultipartBody
                     $length -= min(strlen($header) - $this->_pos[1], $length);
                 }
                 $filePos  = max(0, $this->_pos[1] - strlen($header));
-                if ($length > 0 && $filePos < $this->_uploads[$pos]['size']) {
-                    $ret     .= fread($this->_uploads[$pos]['fp'], $length);
-                    $length  -= min($length, $this->_uploads[$pos]['size'] - $filePos);
+                if ($filePos < $this->_uploads[$pos]['size']) {
+                    while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) {
+                        if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) {
+                            throw new HTTP_Request2_LogicException(
+                                'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR
+                            );
+                        }
+                        $ret    .= $chunk;
+                        $length -= strlen($chunk);
+                    }
                 }
                 if ($length > 0) {
                     $start   = $this->_pos[1] + ($oldLength - $length) -
index d83bcef..96733de 100644 (file)
@@ -4,42 +4,19 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   David Jean Louis <izi@php.net>
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Log.php 324415 2012-03-21 10:50:50Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    David Jean Louis <izi@php.net>
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -86,8 +63,8 @@ require_once 'HTTP/Request2/Exception.php';
  * @package  HTTP_Request2
  * @author   David Jean Louis <izi@php.net>
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  */
 class HTTP_Request2_Observer_Log implements SplObserver
index d26a613..7acbeaa 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *     * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: Response.php 324936 2012-04-07 07:49:03Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /**
@@ -69,8 +46,8 @@ require_once 'HTTP/Request2/Exception.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  * @link     http://tools.ietf.org/html/rfc2616#section-6
  */
index 50d8e94..0b86445 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: SOCKS5.php 324953 2012-04-08 07:24:12Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /** Socket wrapper class used by Socket Adapter */
@@ -50,8 +27,8 @@ require_once 'HTTP/Request2/SocketWrapper.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  * @link     http://pear.php.net/bugs/bug.php?id=19332
  * @link     http://tools.ietf.org/html/rfc1928
@@ -61,21 +38,21 @@ class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper
     /**
      * Constructor, tries to connect and authenticate to a SOCKS5 proxy
      *
-     * @param string $address    Proxy address, e.g. 'tcp://localhost:1080'
-     * @param int    $timeout    Connection timeout (seconds)
-     * @param array  $sslOptions SSL context options
-     * @param string $username   Proxy user name
-     * @param string $password   Proxy password
+     * @param string $address        Proxy address, e.g. 'tcp://localhost:1080'
+     * @param int    $timeout        Connection timeout (seconds)
+     * @param array  $contextOptions Stream context options
+     * @param string $username       Proxy user name
+     * @param string $password       Proxy password
      *
      * @throws HTTP_Request2_LogicException
      * @throws HTTP_Request2_ConnectionException
      * @throws HTTP_Request2_MessageException
      */
     public function __construct(
-        $address, $timeout = 10, array $sslOptions = array(),
+        $address, $timeout = 10, array $contextOptions = array(),
         $username = null, $password = null
     ) {
-        parent::__construct($address, $timeout, $sslOptions);
+        parent::__construct($address, $timeout, $contextOptions);
 
         if (strlen($username)) {
             $request = pack('C4', 5, 2, 0, 2);
index af12957..388c1b6 100644 (file)
@@ -4,41 +4,18 @@
  *
  * PHP version 5
  *
- * LICENSE:
+ * LICENSE
  *
- * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>
- * All rights reserved.
+ * This source file is subject to BSD 3-Clause License that is bundled
+ * with this package in the file LICENSE and available at the URL
+ * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *    * The names of the authors may not be used to endorse or promote products
- *      derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category HTTP
- * @package  HTTP_Request2
- * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  SVN: $Id: SocketWrapper.php 324935 2012-04-07 07:10:50Z avb $
- * @link     http://pear.php.net/package/HTTP_Request2
+ * @category  HTTP
+ * @package   HTTP_Request2
+ * @author    Alexey Borzov <avb@php.net>
+ * @copyright 2008-2014 Alexey Borzov <avb@php.net>
+ * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @link      http://pear.php.net/package/HTTP_Request2
  */
 
 /** Exception classes for HTTP_Request2 package */
@@ -53,8 +30,8 @@ require_once 'HTTP/Request2/Exception.php';
  * @category HTTP
  * @package  HTTP_Request2
  * @author   Alexey Borzov <avb@php.net>
- * @license  http://opensource.org/licenses/bsd-license.php New BSD License
- * @version  Release: 2.1.1
+ * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
+ * @version  Release: 2.2.1
  * @link     http://pear.php.net/package/HTTP_Request2
  * @link     http://pear.php.net/bugs/bug.php?id=19332
  * @link     http://tools.ietf.org/html/rfc1928
@@ -88,22 +65,30 @@ class HTTP_Request2_SocketWrapper
     /**
      * Class constructor, tries to establish connection
      *
-     * @param string $address    Address for stream_socket_client() call,
-     *                           e.g. 'tcp://localhost:80'
-     * @param int    $timeout    Connection timeout (seconds)
-     * @param array  $sslOptions SSL context options
+     * @param string $address        Address for stream_socket_client() call,
+     *                               e.g. 'tcp://localhost:80'
+     * @param int    $timeout        Connection timeout (seconds)
+     * @param array  $contextOptions Context options
      *
      * @throws HTTP_Request2_LogicException
      * @throws HTTP_Request2_ConnectionException
      */
-    public function __construct($address, $timeout, array $sslOptions = array())
+    public function __construct($address, $timeout, array $contextOptions = array())
     {
+        if (!empty($contextOptions)
+            && !isset($contextOptions['socket']) && !isset($contextOptions['ssl'])
+        ) {
+            // Backwards compatibility with 2.1.0 and 2.1.1 releases
+            $contextOptions = array('ssl' => $contextOptions);
+        }
         $context = stream_context_create();
-        foreach ($sslOptions as $name => $value) {
-            if (!stream_context_set_option($context, 'ssl', $name, $value)) {
-                throw new HTTP_Request2_LogicException(
-                    "Error setting SSL context option '{$name}'"
-                );
+        foreach ($contextOptions as $wrapper => $options) {
+            foreach ($options as $name => $value) {
+                if (!stream_context_set_option($context, $wrapper, $name, $value)) {
+                    throw new HTTP_Request2_LogicException(
+                        "Error setting '{$wrapper}' wrapper context option '{$name}'"
+                    );
+                }
             }
         }
         set_error_handler(array($this, 'connectionWarningsHandler'));
@@ -111,7 +96,14 @@ class HTTP_Request2_SocketWrapper
             $address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context
         );
         restore_error_handler();
-        if (!$this->socket) {
+        // if we fail to bind to a specified local address (see request #19515),
+        // connection still succeeds, albeit with a warning. Throw an Exception
+        // with the warning text in this case as that connection is unlikely
+        // to be what user wants and as Curl throws an error in similar case.
+        if ($this->connectionWarnings) {
+            if ($this->socket) {
+                fclose($this->socket);
+            }
             $error = $errstr ? $errstr : implode("\n", $this->connectionWarnings);
             throw new HTTP_Request2_ConnectionException(
                 "Unable to connect to {$address}. Error: {$error}", 0, $errno
@@ -151,20 +143,42 @@ class HTTP_Request2_SocketWrapper
      * Strips the trailing newline from the returned data, handles global
      * request timeout. Method idea borrowed from Net_Socket PEAR package.
      *
-     * @param int $bufferSize buffer size to use for reading
+     * @param int $bufferSize   buffer size to use for reading
+     * @param int $localTimeout timeout value to use just for this call
+     *                          (used when waiting for "100 Continue" response)
      *
      * @return   string Available data up to the newline (not including newline)
      * @throws   HTTP_Request2_MessageException     In case of timeout
      */
-    public function readLine($bufferSize)
+    public function readLine($bufferSize, $localTimeout = null)
     {
         $line = '';
         while (!feof($this->socket)) {
-            if ($this->deadline) {
+            if (null !== $localTimeout) {
+                stream_set_timeout($this->socket, $localTimeout);
+            } elseif ($this->deadline) {
                 stream_set_timeout($this->socket, max($this->deadline - time(), 1));
             }
+
             $line .= @fgets($this->socket, $bufferSize);
-            $this->checkTimeout();
+
+            if (null === $localTimeout) {
+                $this->checkTimeout();
+
+            } else {
+                $info = stream_get_meta_data($this->socket);
+                // reset socket timeout if we don't have request timeout specified,
+                // prevents further calls failing with a bogus Exception
+                if (!$this->deadline) {
+                    $default = (int)@ini_get('default_socket_timeout');
+                    stream_set_timeout($this->socket, $default > 0 ? $default : PHP_INT_MAX);
+                }
+                if ($info['timed_out']) {
+                    throw new HTTP_Request2_MessageException(
+                        "readLine() call timed out", HTTP_Request2_Exception::TIMEOUT
+                    );
+                }
+            }
             if (substr($line, -1) == "\n") {
                 return rtrim($line, "\r\n");
             }
index 9989404..aee1153 100644 (file)
@@ -38,9 +38,9 @@
  * @package   Net_URL2
  * @author    Christian Schmidt <schmidt@php.net>
  * @copyright 2007-2009 Peytz & Co. A/S
- * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version   CVS: $Id: URL2.php 309223 2011-03-14 14:26:32Z till $
- * @link      http://www.rfc-editor.org/rfc/rfc3986.txt
+ * @license   https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
+ * @version   CVS: $Id$
+ * @link      https://tools.ietf.org/html/rfc3986
  */
 
 /**
@@ -50,9 +50,9 @@
  * @package   Net_URL2
  * @author    Christian Schmidt <schmidt@php.net>
  * @copyright 2007-2009 Peytz & Co. A/S
- * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version   Release: @package_version@
- * @link      http://pear.php.net/package/Net_URL2
+ * @license   https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
+ * @version   Release: 2.1.0
+ * @link      https://pear.php.net/package/Net_URL2
  */
 class Net_URL2
 {
@@ -68,6 +68,12 @@ class Net_URL2
     const OPTION_USE_BRACKETS = 'use_brackets';
 
     /**
+     * Drop zero-based integer sequences in query using PHP's [] notation. Default
+     * is true.
+     */
+    const OPTION_DROP_SEQUENCE = 'drop_sequence';
+
+    /**
      * URL-encode query variable keys. Default is true.
      */
     const OPTION_ENCODE_KEYS = 'encode_keys';
@@ -90,6 +96,7 @@ class Net_URL2
     private $_options = array(
         self::OPTION_STRICT           => true,
         self::OPTION_USE_BRACKETS     => true,
+        self::OPTION_DROP_SEQUENCE    => true,
         self::OPTION_ENCODE_KEYS      => true,
         self::OPTION_SEPARATOR_INPUT  => '&',
         self::OPTION_SEPARATOR_OUTPUT => '&',
@@ -136,7 +143,6 @@ class Net_URL2
      * @param string $url     an absolute or relative URL
      * @param array  $options an array of OPTION_xxx constants
      *
-     * @return $this
      * @uses   self::parseUrl()
      */
     public function __construct($url, array $options = array())
@@ -156,8 +162,9 @@ class Net_URL2
      * This method will magically set the value of a private variable ($var)
      * with the value passed as the args
      *
-     * @param  string $var      The private variable to set.
-     * @param  mixed  $arg      An argument of any type.
+     * @param string $var The private variable to set.
+     * @param mixed  $arg An argument of any type.
+     *
      * @return void
      */
     public function __set($var, $arg)
@@ -174,10 +181,11 @@ class Net_URL2
      * This is the magic get method to retrieve the private variable
      * that was set by either __set() or it's setter...
      *
-     * @param  string $var         The property name to retrieve.
-     * @return mixed  $this->$var  Either a boolean false if the
-     *                             property is not set or the value
-     *                             of the private property.
+     * @param string $var The property name to retrieve.
+     *
+     * @return mixed  $this->$var Either a boolean false if the
+     *                            property is not set or the value
+     *                            of the private property.
      */
     public function __get($var)
     {
@@ -193,7 +201,7 @@ class Net_URL2
      * Returns the scheme, e.g. "http" or "urn", or false if there is no
      * scheme specified, i.e. if this is a relative URL.
      *
-     * @return  string|bool
+     * @return string|bool
      */
     public function getScheme()
     {
@@ -209,7 +217,7 @@ class Net_URL2
      *                            URL
      *
      * @return $this
-     * @see    getScheme()
+     * @see    getScheme
      */
     public function setScheme($scheme)
     {
@@ -221,12 +229,12 @@ class Net_URL2
      * Returns the user part of the userinfo part (the part preceding the first
      *  ":"), or false if there is no userinfo part.
      *
-     * @return  string|bool
+     * @return string|bool
      */
     public function getUser()
     {
         return $this->_userinfo !== false
-            ? preg_replace('@:.*$@', '', $this->_userinfo)
+            ? preg_replace('(:.*$)', '', $this->_userinfo)
             : false;
     }
 
@@ -236,7 +244,7 @@ class Net_URL2
      * contain "@" in front of the hostname) or the userinfo part does not
      * contain ":".
      *
-     * @return  string|bool
+     * @return string|bool
      */
     public function getPassword()
     {
@@ -249,7 +257,7 @@ class Net_URL2
      * Returns the userinfo part, or false if there is none, i.e. if the
      * authority part does not contain "@".
      *
-     * @return  string|bool
+     * @return string|bool
      */
     public function getUserinfo()
     {
@@ -267,10 +275,15 @@ class Net_URL2
      */
     public function setUserinfo($userinfo, $password = false)
     {
-        $this->_userinfo = $userinfo;
         if ($password !== false) {
-            $this->_userinfo .= ':' . $password;
+            $userinfo .= ':' . $password;
         }
+
+        if ($userinfo !== false) {
+            $userinfo = $this->_encodeData($userinfo);
+        }
+
+        $this->_userinfo = $userinfo;
         return $this;
     }
 
@@ -278,7 +291,7 @@ class Net_URL2
      * Returns the host part, or false if there is no authority part, e.g.
      * relative URLs.
      *
-     * @return  string|bool a hostname, an IP address, or false
+     * @return string|bool a hostname, an IP address, or false
      */
     public function getHost()
     {
@@ -303,7 +316,7 @@ class Net_URL2
      * Returns the port number, or false if there is no port number specified,
      * i.e. if the default port is to be used.
      *
-     * @return  string|bool
+     * @return string|bool
      */
     public function getPort()
     {
@@ -332,13 +345,13 @@ class Net_URL2
      */
     public function getAuthority()
     {
-        if (!$this->_host) {
+        if (false === $this->_host) {
             return false;
         }
 
         $authority = '';
 
-        if ($this->_userinfo !== false) {
+        if (strlen($this->_userinfo)) {
             $authority .= $this->_userinfo . '@';
         }
 
@@ -355,7 +368,7 @@ class Net_URL2
      * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
      * false if there is no authority.
      *
-     * @param string|false $authority a hostname or an IP addresse, possibly
+     * @param string|bool $authority a hostname or an IP address, possibly
      *                                with userinfo prefixed and port number
      *                                appended, e.g. "foo:bar@example.org:81".
      *
@@ -366,15 +379,24 @@ class Net_URL2
         $this->_userinfo = false;
         $this->_host     = false;
         $this->_port     = false;
-        if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
-            if ($reg[1]) {
-                $this->_userinfo = $reg[2];
-            }
 
-            $this->_host = $reg[3];
-            if (isset($reg[5])) {
-                $this->_port = $reg[5];
-            }
+        if ('' === $authority) {
+            $this->_host = $authority;
+            return $this;
+        }
+
+        if (!preg_match('(^(([^\@]*)\@)?(.+?)(:(\d*))?$)', $authority, $matches)) {
+            return $this;
+        }
+
+        if ($matches[1]) {
+            $this->_userinfo = $this->_encodeData($matches[2]);
+        }
+
+        $this->_host = $matches[3];
+
+        if (isset($matches[5]) && strlen($matches[5])) {
+            $this->_port = $matches[5];
         }
         return $this;
     }
@@ -407,7 +429,7 @@ class Net_URL2
      * is not present in the URL.
      *
      * @return  string|bool
-     * @see     self::getQueryVariables()
+     * @see     getQueryVariables
      */
     public function getQuery()
     {
@@ -421,7 +443,7 @@ class Net_URL2
      * @param string|bool $query a query string, e.g. "foo=1&bar=2"
      *
      * @return $this
-     * @see    self::setQueryVariables()
+     * @see    setQueryVariables
      */
     public function setQuery($query)
     {
@@ -432,7 +454,7 @@ class Net_URL2
     /**
      * Returns the fragment name, or false if "#" is not present in the URL.
      *
-     * @return  string|bool
+     * @return string|bool
      */
     public function getFragment()
     {
@@ -458,57 +480,165 @@ class Net_URL2
      * $_GET in a PHP script. If the URL does not contain a "?", an empty array
      * is returned.
      *
-     * @return  array
+     * @return array
      */
     public function getQueryVariables()
     {
-        $pattern = '/[' .
-                   preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
-                   ']/';
-        $parts   = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
+        $separator   = $this->getOption(self::OPTION_SEPARATOR_INPUT);
+        $encodeKeys  = $this->getOption(self::OPTION_ENCODE_KEYS);
+        $useBrackets = $this->getOption(self::OPTION_USE_BRACKETS);
+
         $return  = array();
 
-        foreach ($parts as $part) {
-            if (strpos($part, '=') !== false) {
-                list($key, $value) = explode('=', $part, 2);
-            } else {
-                $key   = $part;
-                $value = null;
-            }
+        for ($part = strtok($this->_query, $separator);
+            strlen($part);
+            $part = strtok($separator)
+        ) {
+            list($key, $value) = explode('=', $part, 2) + array(1 => '');
 
-            if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
+            if ($encodeKeys) {
                 $key = rawurldecode($key);
             }
             $value = rawurldecode($value);
 
-            if ($this->getOption(self::OPTION_USE_BRACKETS) &&
-                preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
+            if ($useBrackets) {
+                $return = $this->_queryArrayByKey($key, $value, $return);
+            } else {
+                if (isset($return[$key])) {
+                    $return[$key]  = (array) $return[$key];
+                    $return[$key][] = $value;
+                } else {
+                    $return[$key] = $value;
+                }
+            }
+        }
 
-                $key = $matches[1];
-                $idx = $matches[2];
+        return $return;
+    }
 
-                // Ensure is an array
-                if (empty($return[$key]) || !is_array($return[$key])) {
-                    $return[$key] = array();
-                }
+    /**
+     * Parse a single query key=value pair into an existing php array
+     *
+     * @param string $key   query-key
+     * @param string $value query-value
+     * @param array  $array of existing query variables (if any)
+     *
+     * @return mixed
+     */
+    private function _queryArrayByKey($key, $value, array $array = array())
+    {
+        if (!strlen($key)) {
+            return $array;
+        }
 
-                // Add data
-                if ($idx === '') {
-                    $return[$key][] = $value;
-                } else {
-                    $return[$key][$idx] = $value;
+        $offset = $this->_queryKeyBracketOffset($key);
+        if ($offset === false) {
+            $name = $key;
+        } else {
+            $name = substr($key, 0, $offset);
+        }
+
+        if (!strlen($name)) {
+            return $array;
+        }
+
+        if (!$offset) {
+            // named value
+            $array[$name] = $value;
+        } else {
+            // array
+            $brackets = substr($key, $offset);
+            if (!isset($array[$name])) {
+                $array[$name] = null;
+            }
+            $array[$name] = $this->_queryArrayByBrackets(
+                $brackets, $value, $array[$name]
+            );
+        }
+
+        return $array;
+    }
+
+    /**
+     * Parse a key-buffer to place value in array
+     *
+     * @param string $buffer to consume all keys from
+     * @param string $value  to be set/add
+     * @param array  $array  to traverse and set/add value in
+     *
+     * @throws Exception
+     * @return array
+     */
+    private function _queryArrayByBrackets($buffer, $value, array $array = null)
+    {
+        $entry = &$array;
+
+        for ($iteration = 0; strlen($buffer); $iteration++) {
+            $open = $this->_queryKeyBracketOffset($buffer);
+            if ($open !== 0) {
+                // Opening bracket [ must exist at offset 0, if not, there is
+                // no bracket to parse and the value dropped.
+                // if this happens in the first iteration, this is flawed, see
+                // as well the second exception below.
+                if ($iteration) {
+                    break;
                 }
-            } elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
-                      && !empty($return[$key])
-            ) {
-                $return[$key]   = (array) $return[$key];
-                $return[$key][] = $value;
+                // @codeCoverageIgnoreStart
+                throw new Exception(
+                    'Net_URL2 Internal Error: '. __METHOD__ .'(): ' .
+                    'Opening bracket [ must exist at offset 0'
+                );
+                // @codeCoverageIgnoreEnd
+            }
+
+            $close = strpos($buffer, ']', 1);
+            if (!$close) {
+                // this error condition should never be reached as this is a
+                // private method and bracket pairs are checked beforehand.
+                // See as well the first exception for the opening bracket.
+                // @codeCoverageIgnoreStart
+                throw new Exception(
+                    'Net_URL2 Internal Error: '. __METHOD__ .'(): ' .
+                    'Closing bracket ] must exist, not found'
+                );
+                // @codeCoverageIgnoreEnd
+            }
+
+            $index = substr($buffer, 1, $close - 1);
+            if (strlen($index)) {
+                $entry = &$entry[$index];
             } else {
-                $return[$key] = $value;
+                if (!is_array($entry)) {
+                    $entry = array();
+                }
+                $entry[] = &$new;
+                $entry = &$new;
+                unset($new);
             }
+            $buffer = substr($buffer, $close + 1);
         }
 
-        return $return;
+        $entry = $value;
+
+        return $array;
+    }
+
+    /**
+     * Query-key has brackets ("...[]")
+     *
+     * @param string $key query-key
+     *
+     * @return bool|int offset of opening bracket, false if no brackets
+     */
+    private function _queryKeyBracketOffset($key)
+    {
+        if (false !== $open = strpos($key, '[')
+            and false === strpos($key, ']', $open + 1)
+        ) {
+            $open = false;
+        }
+
+        return $open;
     }
 
     /**
@@ -548,7 +678,7 @@ class Net_URL2
     }
 
     /**
-     * Removes the specifed variable from the query string.
+     * Removes the specified variable from the query string.
      *
      * @param string $name a query string variable, e.g. "foo" in "?foo=1"
      *
@@ -564,22 +694,23 @@ class Net_URL2
     /**
      * Returns a string representation of this URL.
      *
-     * @return  string
+     * @return string
      */
     public function getURL()
     {
         // See RFC 3986, section 5.3
-        $url = "";
+        $url = '';
 
         if ($this->_scheme !== false) {
             $url .= $this->_scheme . ':';
         }
 
         $authority = $this->getAuthority();
-        if ($authority !== false) {
-            $url .= '//' . $authority;
+        if ($authority === false && strtolower($this->_scheme) === 'file') {
+            $authority = '';
         }
-        $url .= $this->_path;
+
+        $url .= $this->_buildAuthorityAndPath($authority, $this->_path);
 
         if ($this->_query !== false) {
             $url .= '?' . $this->_query;
@@ -588,26 +719,46 @@ class Net_URL2
         if ($this->_fragment !== false) {
             $url .= '#' . $this->_fragment;
         }
-    
+
         return $url;
     }
 
     /**
+     * Put authority and path together, wrapping authority
+     * into proper separators/terminators.
+     *
+     * @param string|bool $authority authority
+     * @param string      $path      path
+     *
+     * @return string
+     */
+    private function _buildAuthorityAndPath($authority, $path)
+    {
+        if ($authority === false) {
+            return $path;
+        }
+
+        $terminator = ($path !== '' && $path[0] !== '/') ? '/' : '';
+
+        return '//' . $authority . $terminator . $path;
+    }
+
+    /**
      * Returns a string representation of this URL.
      *
-     * @return  string
-     * @see toString()
+     * @return string
+     * @link https://php.net/language.oop5.magic#object.tostring
      */
     public function __toString()
     {
         return $this->getURL();
     }
 
-    /** 
+    /**
      * Returns a normalized string representation of this URL. This is useful
      * for comparison of URLs.
      *
-     * @return  string
+     * @return string
      */
     public function getNormalizedURL()
     {
@@ -616,55 +767,102 @@ class Net_URL2
         return $url->getUrl();
     }
 
-    /** 
-     * Returns a normalized Net_URL2 instance.
+    /**
+     * Normalizes the URL
      *
-     * @return  Net_URL2
+     * See RFC 3986, Section 6.  Normalization and Comparison
+     *
+     * @link https://tools.ietf.org/html/rfc3986#section-6
+     *
+     * @return void
      */
     public function normalize()
     {
-        // See RFC 3886, section 6
+        // See RFC 3986, section 6
 
-        // Schemes are case-insensitive
+        // Scheme is case-insensitive
         if ($this->_scheme) {
             $this->_scheme = strtolower($this->_scheme);
         }
 
-        // Hostnames are case-insensitive
+        // Hostname is case-insensitive
         if ($this->_host) {
             $this->_host = strtolower($this->_host);
         }
 
         // Remove default port number for known schemes (RFC 3986, section 6.2.3)
-        if ($this->_port &&
-            $this->_scheme &&
-            $this->_port == getservbyname($this->_scheme, 'tcp')) {
-
+        if ('' === $this->_port
+            || $this->_port
+            && $this->_scheme
+            && $this->_port == getservbyname($this->_scheme, 'tcp')
+        ) {
             $this->_port = false;
         }
 
         // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
-        foreach (array('_userinfo', '_host', '_path') as $part) {
-            if ($this->$part) {
-                $this->$part = preg_replace('/%[0-9a-f]{2}/ie',
-                                            'strtoupper("\0")',
-                                            $this->$part);
+        // Normalize percentage-encoded unreserved characters (section 6.2.2.2)
+        $fields = array(&$this->_userinfo, &$this->_host, &$this->_path);
+        foreach ($fields as &$field) {
+            if ($field !== false) {
+                $field = $this->_normalize("$field");
             }
         }
+        unset($field);
 
         // Path segment normalization (RFC 3986, section 6.2.2.3)
         $this->_path = self::removeDotSegments($this->_path);
 
         // Scheme based normalization (RFC 3986, section 6.2.3)
-        if ($this->_host && !$this->_path) {
+        if (false !== $this->_host && '' === $this->_path) {
             $this->_path = '/';
         }
+
+        // path should start with '/' if there is authority (section 3.3.)
+        if (strlen($this->getAuthority())
+            && strlen($this->_path)
+            && $this->_path[0] !== '/'
+        ) {
+            $this->_path = '/' . $this->_path;
+        }
+    }
+
+    /**
+     * Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
+     * Normalize percentage-encoded unreserved characters (section 6.2.2.2)
+     *
+     * @param string|array $mixed string or array of strings to normalize
+     *
+     * @return string|array
+     * @see normalize
+     * @see _normalizeCallback()
+     */
+    private function _normalize($mixed)
+    {
+        return preg_replace_callback(
+            '((?:%[0-9a-fA-Z]{2})+)', array($this, '_normalizeCallback'),
+            $mixed
+        );
+    }
+
+    /**
+     * Callback for _normalize() of %XX percentage-encodings
+     *
+     * @param array $matches as by preg_replace_callback
+     *
+     * @return string
+     * @see normalize
+     * @see _normalize
+     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
+     */
+    private function _normalizeCallback($matches)
+    {
+        return self::urlencode(urldecode($matches[0]));
     }
 
     /**
      * Returns whether this instance represents an absolute URL.
      *
-     * @return  bool
+     * @return bool
      */
     public function isAbsolute()
     {
@@ -677,20 +875,25 @@ class Net_URL2
      *
      * @param Net_URL2|string $reference relative URL
      *
-     * @return Net_URL2
+     * @throws Exception
+     * @return $this
      */
     public function resolve($reference)
     {
         if (!$reference instanceof Net_URL2) {
             $reference = new self($reference);
         }
-        if (!$this->isAbsolute()) {
-            throw new Exception('Base-URL must be absolute');
+        if (!$reference->_isFragmentOnly() && !$this->isAbsolute()) {
+            throw new Exception(
+                'Base-URL must be absolute if reference is not fragment-only'
+            );
         }
 
         // A non-strict parser may ignore a scheme in the reference if it is
         // identical to the base URI's scheme.
-        if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
+        if (!$this->getOption(self::OPTION_STRICT)
+            && $reference->_scheme == $this->_scheme
+        ) {
             $reference->_scheme = false;
         }
 
@@ -720,7 +923,7 @@ class Net_URL2
                     } else {
                         // Merge paths (RFC 3986, section 5.2.3)
                         if ($this->_host !== false && $this->_path == '') {
-                            $target->_path = '/' . $this->_path;
+                            $target->_path = '/' . $reference->_path;
                         } else {
                             $i = strrpos($this->_path, '/');
                             if ($i !== false) {
@@ -743,6 +946,25 @@ class Net_URL2
     }
 
     /**
+     * URL is fragment-only
+     *
+     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
+     * @return bool
+     */
+    private function _isFragmentOnly()
+    {
+        return (
+            $this->_fragment !== false
+            && $this->_query === false
+            && $this->_path === ''
+            && $this->_port === false
+            && $this->_host === false
+            && $this->_userinfo === false
+            && $this->_scheme === false
+        );
+    }
+
+    /**
      * Removes dots as described in RFC 3986, section 5.2.4, e.g.
      * "/foo/../bar/baz" => "/bar/baz"
      *
@@ -752,43 +974,52 @@ class Net_URL2
      */
     public static function removeDotSegments($path)
     {
+        $path = (string) $path;
         $output = '';
 
         // Make sure not to be trapped in an infinite loop due to a bug in this
         // method
+        $loopLimit = 256;
         $j = 0;
-        while ($path && $j++ < 100) {
-            if (substr($path, 0, 2) == './') {
+        while ('' !== $path && $j++ < $loopLimit) {
+            if (substr($path, 0, 2) === './') {
                 // Step 2.A
                 $path = substr($path, 2);
-            } elseif (substr($path, 0, 3) == '../') {
+            } elseif (substr($path, 0, 3) === '../') {
                 // Step 2.A
                 $path = substr($path, 3);
-            } elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
+            } elseif (substr($path, 0, 3) === '/./' || $path === '/.') {
                 // Step 2.B
                 $path = '/' . substr($path, 3);
-            } elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
+            } elseif (substr($path, 0, 4) === '/../' || $path === '/..') {
                 // Step 2.C
                 $path   = '/' . substr($path, 4);
                 $i      = strrpos($output, '/');
                 $output = $i === false ? '' : substr($output, 0, $i);
-            } elseif ($path == '.' || $path == '..') {
+            } elseif ($path === '.' || $path === '..') {
                 // Step 2.D
                 $path = '';
             } else {
                 // Step 2.E
-                $i = strpos($path, '/');
-                if ($i === 0) {
-                    $i = strpos($path, '/', 1);
-                }
+                $i = strpos($path, '/', $path[0] === '/');
                 if ($i === false) {
-                    $i = strlen($path);
+                    $output .= $path;
+                    $path = '';
+                    break;
                 }
                 $output .= substr($path, 0, $i);
                 $path = substr($path, $i);
             }
         }
 
+        if ($path !== '') {
+            $message = sprintf(
+                'Unable to remove dot segments; hit loop limit %d (left: %s)',
+                $j, var_export($path, true)
+            );
+            trigger_error($message, E_USER_WARNING);
+        }
+
         return $output;
     }
 
@@ -797,12 +1028,13 @@ class Net_URL2
      * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
      * 5.2.x and earlier.
      *
-     * @param  $raw the string to encode
+     * @param string $string string to encode
+     *
      * @return string
      */
     public static function urlencode($string)
     {
-       $encoded = rawurlencode($string);
+        $encoded = rawurlencode($string);
 
         // This is only necessary in PHP < 5.3.
         $encoded = str_replace('%7E', '~', $encoded);
@@ -813,7 +1045,8 @@ class Net_URL2
      * Returns a Net_URL2 instance representing the canonical URL of the
      * currently executing PHP script.
      *
-     * @return  string
+     * @throws Exception
+     * @return string
      */
     public static function getCanonical()
     {
@@ -827,9 +1060,9 @@ class Net_URL2
         $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
         $url->_host   = $_SERVER['SERVER_NAME'];
         $port = $_SERVER['SERVER_PORT'];
-        if ($url->_scheme == 'http' && $port != 80 ||
-            $url->_scheme == 'https' && $port != 443) {
-
+        if ($url->_scheme == 'http' && $port != 80
+            || $url->_scheme == 'https' && $port != 443
+        ) {
             $url->_port = $port;
         }
         return $url;
@@ -849,7 +1082,8 @@ class Net_URL2
      * Returns a Net_URL2 instance representing the URL used to retrieve the
      * current request.
      *
-     * @return  Net_URL2
+     * @throws Exception
+     * @return $this
      */
     public static function getRequested()
     {
@@ -871,7 +1105,7 @@ class Net_URL2
      *
      * @param string $optionName The name of the option to retrieve
      *
-     * @return  mixed
+     * @return mixed
      */
     public function getOption($optionName)
     {
@@ -885,7 +1119,7 @@ class Net_URL2
      *
      * @param array  $data      An array, which has to be converted into
      *                          QUERY_STRING. Anything is possible.
-     * @param string $seperator See {@link self::OPTION_SEPARATOR_OUTPUT}
+     * @param string $separator Separator {@link self::OPTION_SEPARATOR_OUTPUT}
      * @param string $key       For stacked values (arrays in an array).
      *
      * @return string
@@ -893,12 +1127,17 @@ class Net_URL2
     protected function buildQuery(array $data, $separator, $key = null)
     {
         $query = array();
+        $drop_names = (
+            $this->_options[self::OPTION_DROP_SEQUENCE] === true
+            && array_keys($data) === array_keys(array_values($data))
+        );
         foreach ($data as $name => $value) {
             if ($this->getOption(self::OPTION_ENCODE_KEYS) === true) {
                 $name = rawurlencode($name);
             }
             if ($key !== null) {
                 if ($this->getOption(self::OPTION_USE_BRACKETS) === true) {
+                    $drop_names && $name = '';
                     $name = $key . '[' . $name . ']';
                 } else {
                     $name = $key;
@@ -914,29 +1153,66 @@ class Net_URL2
     }
 
     /**
-     * This method uses a funky regex to parse the url into the designated parts.
+     * This method uses a regex to parse the url into the designated parts.
      *
-     * @param string $url
+     * @param string $url URL
      *
      * @return void
      * @uses   self::$_scheme, self::setAuthority(), self::$_path, self::$_query,
      *         self::$_fragment
-     * @see    self::__construct()
+     * @see    __construct
      */
     protected function parseUrl($url)
     {
         // The regular expression is copied verbatim from RFC 3986, appendix B.
         // The expression does not validate the URL but matches any string.
-        preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!',
-                   $url,
-                   $matches);
+        preg_match(
+            '(^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)',
+            $url, $matches
+        );
 
         // "path" is always present (possibly as an empty string); the rest
         // are optional.
         $this->_scheme   = !empty($matches[1]) ? $matches[2] : false;
         $this->setAuthority(!empty($matches[3]) ? $matches[4] : false);
-        $this->_path     = $matches[5];
-        $this->_query    = !empty($matches[6]) ? $matches[7] : false;
+        $this->_path     = $this->_encodeData($matches[5]);
+        $this->_query    = !empty($matches[6])
+                           ? $this->_encodeData($matches[7])
+                           : false
+            ;
         $this->_fragment = !empty($matches[8]) ? $matches[9] : false;
     }
+
+    /**
+     * Encode characters that might have been forgotten to encode when passing
+     * in an URL. Applied onto Userinfo, Path and Query.
+     *
+     * @param string $url URL
+     *
+     * @return string
+     * @see parseUrl
+     * @see setAuthority
+     * @link https://pear.php.net/bugs/bug.php?id=20425
+     */
+    private function _encodeData($url)
+    {
+        return preg_replace_callback(
+            '([\x-\x20\x22\x3C\x3E\x7F-\xFF]+)',
+            array($this, '_encodeCallback'), $url
+        );
+    }
+
+    /**
+     * callback for encoding character data
+     *
+     * @param array $matches Matches
+     *
+     * @return string
+     * @see _encodeData
+     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
+     */
+    private function _encodeCallback(array $matches)
+    {
+        return rawurlencode($matches[0]);
+    }
 }
index ef1cfe2..2990cb6 100644 (file)
@@ -13,7 +13,7 @@
  * @author     Greg Beaver <cellog@php.net>
  * @copyright  1997-2009 The Authors
  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
- * @version    CVS: $Id: Exception.php 313023 2011-07-06 19:17:11Z dufuz $
+ * @version    CVS: $Id$
  * @link       http://pear.php.net/package/PEAR
  * @since      File available since Release 1.3.3
  */
@@ -89,7 +89,7 @@
  * @author     Greg Beaver <cellog@php.net>
  * @copyright  1997-2009 The Authors
  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
- * @version    Release: 1.9.4
+ * @version    Release: 1.9.5
  * @link       http://pear.php.net/package/PEAR
  * @since      Class available since Release 1.3.3
  *
@@ -386,5 +386,4 @@ class PEAR_Exception extends Exception
         }
         return $causeMsg . $this->getTraceAsString();
     }
-}
-?>
\ No newline at end of file
+}
\ No newline at end of file
index d5df48d..af92733 100644 (file)
@@ -1,45 +1,7 @@
 <?php
-// ***** BEGIN LICENSE BLOCK *****
-// Version: MPL 1.1/GPL 2.0/LGPL 2.1
-//
-// The contents of this file are subject to the Mozilla Public License Version
-// 1.1 (the "License"); you may not use this file except in compliance with
-// the License. You may obtain a copy of the License at
-// http://www.mozilla.org/MPL/
-//
-// Software distributed under the License is distributed on an "AS IS" basis,
-// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-// for the specific language governing rights and limitations under the
-// License.
-//
-// The Original Code is the Public Suffix List.
-//
-// The Initial Developer of the Original Code is
-// Jo Hermans <jo.hermans@gmail.com>.
-// Portions created by the Initial Developer are Copyright (C) 2007
-// the Initial Developer. All Rights Reserved.
-//
-// Contributor(s):
-//   Ruben Arakelyan <ruben@rubenarakelyan.com>
-//   Gervase Markham <gerv@gerv.net>
-//   Pamela Greene <pamg.bugs@gmail.com>
-//   David Triendl <david@triendl.name>
-//   Jothan Frakes <jothan@gmail.com>
-//   The kind representatives of many TLD registries
-//
-// Alternatively, the contents of this file may be used under the terms of
-// either the GNU General Public License Version 2 or later (the "GPL"), or
-// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-// in which case the provisions of the GPL or the LGPL are applicable instead
-// of those above. If you wish to allow use of your version of this file only
-// under the terms of either the GPL or the LGPL, and not to allow others to
-// use your version of this file under the terms of the MPL, indicate your
-// decision by deleting the provisions above and replace them with the notice
-// and other provisions required by the GPL or the LGPL. If you do not delete
-// the provisions above, a recipient may use your version of this file under
-// the terms of any one of the MPL, the GPL or the LGPL.
-//
-// ***** END LICENSE BLOCK *****
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 return array(
  'ac' => array(
@@ -198,16 +160,16 @@ return array(
  ),
  'aq' => true,
  'ar' => array(
-  '*' => true,
-  '!congresodelalengua3' => true,
-  '!educ' => true,
-  '!gobiernoelectronico' => true,
-  '!mecon' => true,
-  '!nacion' => true,
-  '!nic' => true,
-  '!promocion' => true,
-  '!retina' => true,
-  '!uba' => true
+  'com' => array(
+   'blogspot' => true
+  ),
+  'edu' => true,
+  'gob' => true,
+  'int' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true,
+  'tur' => true
  ),
  'arpa' => array(
   'e164' => true,
@@ -223,7 +185,9 @@ return array(
  'asia' => true,
  'at' => array(
   'ac' => true,
-  'co' => true,
+  'co' => array(
+   'blogspot' => true
+  ),
   'gv' => true,
   'or' => true,
   'biz' => true,
@@ -231,7 +195,9 @@ return array(
   'priv' => true
  ),
  'au' => array(
-  'com' => true,
+  'com' => array(
+   'blogspot' => true
+  ),
   'net' => true,
   'org' => true,
   'edu' => array(
@@ -246,16 +212,15 @@ return array(
   ),
   'gov' => array(
    'act' => true,
-   'nt' => true,
    'qld' => true,
    'sa' => true,
    'tas' => true,
    'vic' => true,
    'wa' => true
   ),
-  'csiro' => true,
   'asn' => true,
   'id' => true,
+  'csiro' => true,
   'info' => true,
   'conf' => true,
   'oz' => true,
@@ -312,7 +277,8 @@ return array(
   '*' => true
  ),
  'be' => array(
-  'ac' => true
+  'ac' => true,
+  'blogspot' => true
  ),
  'bf' => array(
   'gov' => true
@@ -381,7 +347,8 @@ return array(
  'bj' => array(
   'asso' => true,
   'barreau' => true,
-  'gouv' => true
+  'gouv' => true,
+  'blogspot' => true
  ),
  'bm' => array(
   'com' => true,
@@ -416,13 +383,15 @@ return array(
   'bio' => true,
   'blog' => true,
   'bmd' => true,
-  'can' => true,
   'cim' => true,
   'cng' => true,
   'cnt' => true,
-  'com' => true,
+  'com' => array(
+   'blogspot' => true
+  ),
   'coop' => true,
   'ecn' => true,
+  'eco' => true,
   'edu' => true,
   'emp' => true,
   'eng' => true,
@@ -443,6 +412,7 @@ return array(
   'inf' => true,
   'jor' => true,
   'jus' => true,
+  'leg' => true,
   'lel' => true,
   'mat' => true,
   'med' => true,
@@ -488,6 +458,7 @@ return array(
   'net' => true,
   'org' => true
  ),
+ 'bv' => true,
  'bw' => array(
   'co' => true,
   'org' => true
@@ -521,7 +492,8 @@ return array(
   'sk' => true,
   'yk' => true,
   'gc' => true,
-  'co' => true
+  'co' => true,
+  'blogspot' => true
  ),
  'cat' => true,
  'cc' => array(
@@ -533,9 +505,13 @@ return array(
  'cd' => array(
   'gov' => true
  ),
- 'cf' => true,
+ 'cf' => array(
+  'blogspot' => true
+ ),
  'cg' => true,
- 'ch' => true,
+ 'ch' => array(
+  'blogspot' => true
+ ),
  'ci' => array(
   'org' => true,
   'or' => true,
@@ -628,6 +604,45 @@ return array(
   'web' => true
  ),
  'com' => array(
+  'amazonaws' => array(
+   'compute' => array(
+    'ap-northeast-1' => true,
+    'ap-southeast-1' => true,
+    'ap-southeast-2' => true,
+    'eu-west-1' => true,
+    'sa-east-1' => true,
+    'us-gov-west-1' => true,
+    'us-west-1' => true,
+    'us-west-2' => true
+   ),
+   'us-east-1' => true,
+   'compute-1' => array(
+    'z-1' => true,
+    'z-2' => true
+   ),
+   'elb' => true,
+   's3' => true,
+   's3-us-west-2' => true,
+   's3-us-west-1' => true,
+   's3-eu-west-1' => true,
+   's3-ap-southeast-1' => true,
+   's3-ap-southeast-2' => true,
+   's3-ap-northeast-1' => true,
+   's3-sa-east-1' => true,
+   's3-us-gov-west-1' => true,
+   's3-fips-us-gov-west-1' => true,
+   's3-website-us-east-1' => true,
+   's3-website-us-west-2' => true,
+   's3-website-us-west-1' => true,
+   's3-website-eu-west-1' => true,
+   's3-website-ap-southeast-1' => true,
+   's3-website-ap-southeast-2' => true,
+   's3-website-ap-northeast-1' => true,
+   's3-website-sa-east-1' => true,
+   's3-website-us-gov-west-1' => true
+  ),
+  'elasticbeanstalk' => true,
+  'betainabox' => true,
   'ar' => true,
   'br' => true,
   'cn' => true,
@@ -647,8 +662,9 @@ return array(
   'us' => true,
   'uy' => true,
   'za' => true,
-  'operaunite' => true,
-  'appspot' => true,
+  'cloudcontrolled' => true,
+  'cloudcontrolapp' => true,
+  'dreamhosters' => true,
   'dyndns-at-home' => true,
   'dyndns-at-work' => true,
   'dyndns-blog' => true,
@@ -798,7 +814,17 @@ return array(
   'simple-url' => true,
   'space-to-rent' => true,
   'teaches-yoga' => true,
-  'writesthisblog' => true
+  'writesthisblog' => true,
+  'ro' => true,
+  'appspot' => true,
+  'blogspot' => true,
+  'codespot' => true,
+  'googleapis' => true,
+  'googlecode' => true,
+  'herokuapp' => true,
+  'herokussl' => true,
+  'operaunite' => true,
+  'rhcloud' => true
  ),
  'coop' => true,
  'cr' => array(
@@ -818,7 +844,15 @@ return array(
   'gov' => true,
   'inf' => true
  ),
- 'cv' => true,
+ 'cv' => array(
+  'blogspot' => true
+ ),
+ 'cw' => array(
+  'com' => true,
+  'edu' => true,
+  'net' => true,
+  'org' => true
+ ),
  'cx' => array(
   'gov' => true,
   'ath' => true
@@ -826,7 +860,9 @@ return array(
  'cy' => array(
   '*' => true
  ),
- 'cz' => true,
+ 'cz' => array(
+  'blogspot' => true
+ ),
  'de' => array(
   'com' => true,
   'fuettertdasnetz' => true,
@@ -834,10 +870,13 @@ return array(
   'istmein' => true,
   'lebtimnetz' => true,
   'leitungsen' => true,
-  'traeumtgerade' => true
+  'traeumtgerade' => true,
+  'blogspot' => true
  ),
  'dj' => true,
- 'dk' => true,
+ 'dk' => array(
+  'blogspot' => true
+ ),
  'dm' => array(
   'com' => true,
   'net' => true,
@@ -909,7 +948,9 @@ return array(
   '*' => true
  ),
  'es' => array(
-  'com' => true,
+  'com' => array(
+   'blogspot' => true
+  ),
   'nom' => true,
   'org' => true,
   'gob' => true,
@@ -921,6 +962,7 @@ return array(
  'eu' => true,
  'fi' => array(
   'aland' => true,
+  'blogspot' => true,
   'iki' => true
  ),
  'fj' => array(
@@ -954,9 +996,11 @@ return array(
   'notaires' => true,
   'pharmacien' => true,
   'port' => true,
-  'veterinaire' => true
+  'veterinaire' => true,
+  'blogspot' => true
  ),
  'ga' => true,
+ 'gb' => true,
  'gd' => true,
  'ge' => array(
   'com' => true,
@@ -970,10 +1014,8 @@ return array(
  'gf' => true,
  'gg' => array(
   'co' => true,
-  'org' => true,
   'net' => true,
-  'sch' => true,
-  'gov' => true
+  'org' => true
  ),
  'gh' => array(
   'com' => true,
@@ -1015,12 +1057,18 @@ return array(
   'edu' => true,
   'net' => true,
   'org' => true,
-  'gov' => true
+  'gov' => true,
+  'blogspot' => true
  ),
  'gs' => true,
  'gt' => array(
-  '*' => true,
-  '!www' => true
+  'com' => true,
+  'edu' => true,
+  'gob' => true,
+  'ind' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true
  ),
  'gu' => array(
   '*' => true
@@ -1052,7 +1100,8 @@ return array(
   '网絡' => true,
   '组织' => true,
   '組織' => true,
-  '組织' => true
+  '組织' => true,
+  'blogspot' => true
  ),
  'hm' => true,
  'hn' => array(
@@ -1119,34 +1168,42 @@ return array(
   'szex' => true,
   'tozsde' => true,
   'utazas' => true,
-  'video' => true
+  'video' => true,
+  'blogspot' => true
  ),
  'id' => array(
   'ac' => true,
+  'biz' => true,
   'co' => true,
   'go' => true,
   'mil' => true,
+  'my' => true,
   'net' => true,
   'or' => true,
   'sch' => true,
   'web' => true
  ),
  'ie' => array(
-  'gov' => true
+  'gov' => true,
+  'blogspot' => true
  ),
  'il' => array(
-  '*' => true
+  '*' => true,
+  'co' => array(
+   'blogspot' => true
+  )
  ),
  'im' => array(
+  'ac' => true,
   'co' => array(
    'ltd' => true,
    'plc' => true
   ),
+  'com' => true,
   'net' => true,
-  'gov' => true,
   'org' => true,
-  'nic' => true,
-  'ac' => true
+  'tt' => true,
+  'tv' => true
  ),
  'in' => array(
   'co' => true,
@@ -1160,7 +1217,8 @@ return array(
   'edu' => true,
   'res' => true,
   'gov' => true,
-  'mil' => true
+  'mil' => true,
+  'blogspot' => true
  ),
  'info' => array(
   'dyndns' => true,
@@ -1178,7 +1236,8 @@ return array(
   'eu' => true
  ),
  'io' => array(
-  'com' => true
+  'com' => true,
+  'github' => true
  ),
  'iq' => array(
   'gov' => true,
@@ -1205,7 +1264,8 @@ return array(
   'edu' => true,
   'gov' => true,
   'org' => true,
-  'int' => true
+  'int' => true,
+  'cupcake' => true
  ),
  'it' => array(
   'gov' => true,
@@ -1484,14 +1544,13 @@ return array(
   'vicenza' => true,
   'vi' => true,
   'viterbo' => true,
-  'vt' => true
+  'vt' => true,
+  'blogspot' => true
  ),
  'je' => array(
   'co' => true,
-  'org' => true,
   'net' => true,
-  'sch' => true,
-  'gov' => true
+  'org' => true
  ),
  'jm' => array(
   '*' => true
@@ -1518,230 +1577,1807 @@ return array(
   'ne' => true,
   'or' => true,
   'aichi' => array(
-   '*' => true,
-   '!pref' => true
+   'aisai' => true,
+   'ama' => true,
+   'anjo' => true,
+   'asuke' => true,
+   'chiryu' => true,
+   'chita' => true,
+   'fuso' => true,
+   'gamagori' => true,
+   'handa' => true,
+   'hazu' => true,
+   'hekinan' => true,
+   'higashiura' => true,
+   'ichinomiya' => true,
+   'inazawa' => true,
+   'inuyama' => true,
+   'isshiki' => true,
+   'iwakura' => true,
+   'kanie' => true,
+   'kariya' => true,
+   'kasugai' => true,
+   'kira' => true,
+   'kiyosu' => true,
+   'komaki' => true,
+   'konan' => true,
+   'kota' => true,
+   'mihama' => true,
+   'miyoshi' => true,
+   'nagakute' => true,
+   'nishio' => true,
+   'nisshin' => true,
+   'obu' => true,
+   'oguchi' => true,
+   'oharu' => true,
+   'okazaki' => true,
+   'owariasahi' => true,
+   'seto' => true,
+   'shikatsu' => true,
+   'shinshiro' => true,
+   'shitara' => true,
+   'tahara' => true,
+   'takahama' => true,
+   'tobishima' => true,
+   'toei' => true,
+   'togo' => true,
+   'tokai' => true,
+   'tokoname' => true,
+   'toyoake' => true,
+   'toyohashi' => true,
+   'toyokawa' => true,
+   'toyone' => true,
+   'toyota' => true,
+   'tsushima' => true,
+   'yatomi' => true
   ),
   'akita' => array(
-   '*' => true,
-   '!pref' => true
+   'akita' => true,
+   'daisen' => true,
+   'fujisato' => true,
+   'gojome' => true,
+   'hachirogata' => true,
+   'happou' => true,
+   'higashinaruse' => true,
+   'honjo' => true,
+   'honjyo' => true,
+   'ikawa' => true,
+   'kamikoani' => true,
+   'kamioka' => true,
+   'katagami' => true,
+   'kazuno' => true,
+   'kitaakita' => true,
+   'kosaka' => true,
+   'kyowa' => true,
+   'misato' => true,
+   'mitane' => true,
+   'moriyoshi' => true,
+   'nikaho' => true,
+   'noshiro' => true,
+   'odate' => true,
+   'oga' => true,
+   'ogata' => true,
+   'semboku' => true,
+   'yokote' => true,
+   'yurihonjo' => true
   ),
   'aomori' => array(
-   '*' => true,
-   '!pref' => true
+   'aomori' => true,
+   'gonohe' => true,
+   'hachinohe' => true,
+   'hashikami' => true,
+   'hiranai' => true,
+   'hirosaki' => true,
+   'itayanagi' => true,
+   'kuroishi' => true,
+   'misawa' => true,
+   'mutsu' => true,
+   'nakadomari' => true,
+   'noheji' => true,
+   'oirase' => true,
+   'owani' => true,
+   'rokunohe' => true,
+   'sannohe' => true,
+   'shichinohe' => true,
+   'shingo' => true,
+   'takko' => true,
+   'towada' => true,
+   'tsugaru' => true,
+   'tsuruta' => true
   ),
   'chiba' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'abiko' => true,
+   'asahi' => true,
+   'chonan' => true,
+   'chosei' => true,
+   'choshi' => true,
+   'chuo' => true,
+   'funabashi' => true,
+   'futtsu' => true,
+   'hanamigawa' => true,
+   'ichihara' => true,
+   'ichikawa' => true,
+   'ichinomiya' => true,
+   'inzai' => true,
+   'isumi' => true,
+   'kamagaya' => true,
+   'kamogawa' => true,
+   'kashiwa' => true,
+   'katori' => true,
+   'katsuura' => true,
+   'kimitsu' => true,
+   'kisarazu' => true,
+   'kozaki' => true,
+   'kujukuri' => true,
+   'kyonan' => true,
+   'matsudo' => true,
+   'midori' => true,
+   'mihama' => true,
+   'minamiboso' => true,
+   'mobara' => true,
+   'mutsuzawa' => true,
+   'nagara' => true,
+   'nagareyama' => true,
+   'narashino' => true,
+   'narita' => true,
+   'noda' => true,
+   'oamishirasato' => true,
+   'omigawa' => true,
+   'onjuku' => true,
+   'otaki' => true,
+   'sakae' => true,
+   'sakura' => true,
+   'shimofusa' => true,
+   'shirako' => true,
+   'shiroi' => true,
+   'shisui' => true,
+   'sodegaura' => true,
+   'sosa' => true,
+   'tako' => true,
+   'tateyama' => true,
+   'togane' => true,
+   'tohnosho' => true,
+   'tomisato' => true,
+   'urayasu' => true,
+   'yachimata' => true,
+   'yachiyo' => true,
+   'yokaichiba' => true,
+   'yokoshibahikari' => true,
+   'yotsukaido' => true
   ),
   'ehime' => array(
-   '*' => true,
-   '!pref' => true
+   'ainan' => true,
+   'honai' => true,
+   'ikata' => true,
+   'imabari' => true,
+   'iyo' => true,
+   'kamijima' => true,
+   'kihoku' => true,
+   'kumakogen' => true,
+   'masaki' => true,
+   'matsuno' => true,
+   'matsuyama' => true,
+   'namikata' => true,
+   'niihama' => true,
+   'ozu' => true,
+   'saijo' => true,
+   'seiyo' => true,
+   'shikokuchuo' => true,
+   'tobe' => true,
+   'toon' => true,
+   'uchiko' => true,
+   'uwajima' => true,
+   'yawatahama' => true
   ),
   'fukui' => array(
-   '*' => true,
-   '!pref' => true
+   'echizen' => true,
+   'eiheiji' => true,
+   'fukui' => true,
+   'ikeda' => true,
+   'katsuyama' => true,
+   'mihama' => true,
+   'minamiechizen' => true,
+   'obama' => true,
+   'ohi' => true,
+   'ono' => true,
+   'sabae' => true,
+   'sakai' => true,
+   'takahama' => true,
+   'tsuruga' => true,
+   'wakasa' => true
   ),
   'fukuoka' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'ashiya' => true,
+   'buzen' => true,
+   'chikugo' => true,
+   'chikuho' => true,
+   'chikujo' => true,
+   'chikushino' => true,
+   'chikuzen' => true,
+   'chuo' => true,
+   'dazaifu' => true,
+   'fukuchi' => true,
+   'hakata' => true,
+   'higashi' => true,
+   'hirokawa' => true,
+   'hisayama' => true,
+   'iizuka' => true,
+   'inatsuki' => true,
+   'kaho' => true,
+   'kasuga' => true,
+   'kasuya' => true,
+   'kawara' => true,
+   'keisen' => true,
+   'koga' => true,
+   'kurate' => true,
+   'kurogi' => true,
+   'kurume' => true,
+   'minami' => true,
+   'miyako' => true,
+   'miyama' => true,
+   'miyawaka' => true,
+   'mizumaki' => true,
+   'munakata' => true,
+   'nakagawa' => true,
+   'nakama' => true,
+   'nishi' => true,
+   'nogata' => true,
+   'ogori' => true,
+   'okagaki' => true,
+   'okawa' => true,
+   'oki' => true,
+   'omuta' => true,
+   'onga' => true,
+   'onojo' => true,
+   'oto' => true,
+   'saigawa' => true,
+   'sasaguri' => true,
+   'shingu' => true,
+   'shinyoshitomi' => true,
+   'shonai' => true,
+   'soeda' => true,
+   'sue' => true,
+   'tachiarai' => true,
+   'tagawa' => true,
+   'takata' => true,
+   'toho' => true,
+   'toyotsu' => true,
+   'tsuiki' => true,
+   'ukiha' => true,
+   'umi' => true,
+   'usui' => true,
+   'yamada' => true,
+   'yame' => true,
+   'yanagawa' => true,
+   'yukuhashi' => true
   ),
   'fukushima' => array(
-   '*' => true,
-   '!pref' => true
+   'aizubange' => true,
+   'aizumisato' => true,
+   'aizuwakamatsu' => true,
+   'asakawa' => true,
+   'bandai' => true,
+   'date' => true,
+   'fukushima' => true,
+   'furudono' => true,
+   'futaba' => true,
+   'hanawa' => true,
+   'higashi' => true,
+   'hirata' => true,
+   'hirono' => true,
+   'iitate' => true,
+   'inawashiro' => true,
+   'ishikawa' => true,
+   'iwaki' => true,
+   'izumizaki' => true,
+   'kagamiishi' => true,
+   'kaneyama' => true,
+   'kawamata' => true,
+   'kitakata' => true,
+   'kitashiobara' => true,
+   'koori' => true,
+   'koriyama' => true,
+   'kunimi' => true,
+   'miharu' => true,
+   'mishima' => true,
+   'namie' => true,
+   'nango' => true,
+   'nishiaizu' => true,
+   'nishigo' => true,
+   'okuma' => true,
+   'omotego' => true,
+   'ono' => true,
+   'otama' => true,
+   'samegawa' => true,
+   'shimogo' => true,
+   'shirakawa' => true,
+   'showa' => true,
+   'soma' => true,
+   'sukagawa' => true,
+   'taishin' => true,
+   'tamakawa' => true,
+   'tanagura' => true,
+   'tenei' => true,
+   'yabuki' => true,
+   'yamato' => true,
+   'yamatsuri' => true,
+   'yanaizu' => true,
+   'yugawa' => true
   ),
   'gifu' => array(
-   '*' => true,
-   '!pref' => true
+   'anpachi' => true,
+   'ena' => true,
+   'gifu' => true,
+   'ginan' => true,
+   'godo' => true,
+   'gujo' => true,
+   'hashima' => true,
+   'hichiso' => true,
+   'hida' => true,
+   'higashishirakawa' => true,
+   'ibigawa' => true,
+   'ikeda' => true,
+   'kakamigahara' => true,
+   'kani' => true,
+   'kasahara' => true,
+   'kasamatsu' => true,
+   'kawaue' => true,
+   'kitagata' => true,
+   'mino' => true,
+   'minokamo' => true,
+   'mitake' => true,
+   'mizunami' => true,
+   'motosu' => true,
+   'nakatsugawa' => true,
+   'ogaki' => true,
+   'sakahogi' => true,
+   'seki' => true,
+   'sekigahara' => true,
+   'shirakawa' => true,
+   'tajimi' => true,
+   'takayama' => true,
+   'tarui' => true,
+   'toki' => true,
+   'tomika' => true,
+   'wanouchi' => true,
+   'yamagata' => true,
+   'yaotsu' => true,
+   'yoro' => true
   ),
   'gunma' => array(
-   '*' => true,
-   '!pref' => true
+   'annaka' => true,
+   'chiyoda' => true,
+   'fujioka' => true,
+   'higashiagatsuma' => true,
+   'isesaki' => true,
+   'itakura' => true,
+   'kanna' => true,
+   'kanra' => true,
+   'katashina' => true,
+   'kawaba' => true,
+   'kiryu' => true,
+   'kusatsu' => true,
+   'maebashi' => true,
+   'meiwa' => true,
+   'midori' => true,
+   'minakami' => true,
+   'naganohara' => true,
+   'nakanojo' => true,
+   'nanmoku' => true,
+   'numata' => true,
+   'oizumi' => true,
+   'ora' => true,
+   'ota' => true,
+   'shibukawa' => true,
+   'shimonita' => true,
+   'shinto' => true,
+   'showa' => true,
+   'takasaki' => true,
+   'takayama' => true,
+   'tamamura' => true,
+   'tatebayashi' => true,
+   'tomioka' => true,
+   'tsukiyono' => true,
+   'tsumagoi' => true,
+   'ueno' => true,
+   'yoshioka' => true
   ),
   'hiroshima' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'asaminami' => true,
+   'daiwa' => true,
+   'etajima' => true,
+   'fuchu' => true,
+   'fukuyama' => true,
+   'hatsukaichi' => true,
+   'higashihiroshima' => true,
+   'hongo' => true,
+   'jinsekikogen' => true,
+   'kaita' => true,
+   'kui' => true,
+   'kumano' => true,
+   'kure' => true,
+   'mihara' => true,
+   'miyoshi' => true,
+   'naka' => true,
+   'onomichi' => true,
+   'osakikamijima' => true,
+   'otake' => true,
+   'saka' => true,
+   'sera' => true,
+   'seranishi' => true,
+   'shinichi' => true,
+   'shobara' => true,
+   'takehara' => true
   ),
   'hokkaido' => array(
-   '*' => true,
-   '!pref' => true
+   'abashiri' => true,
+   'abira' => true,
+   'aibetsu' => true,
+   'akabira' => true,
+   'akkeshi' => true,
+   'asahikawa' => true,
+   'ashibetsu' => true,
+   'ashoro' => true,
+   'assabu' => true,
+   'atsuma' => true,
+   'bibai' => true,
+   'biei' => true,
+   'bifuka' => true,
+   'bihoro' => true,
+   'biratori' => true,
+   'chippubetsu' => true,
+   'chitose' => true,
+   'date' => true,
+   'ebetsu' => true,
+   'embetsu' => true,
+   'eniwa' => true,
+   'erimo' => true,
+   'esan' => true,
+   'esashi' => true,
+   'fukagawa' => true,
+   'fukushima' => true,
+   'furano' => true,
+   'furubira' => true,
+   'haboro' => true,
+   'hakodate' => true,
+   'hamatonbetsu' => true,
+   'hidaka' => true,
+   'higashikagura' => true,
+   'higashikawa' => true,
+   'hiroo' => true,
+   'hokuryu' => true,
+   'hokuto' => true,
+   'honbetsu' => true,
+   'horokanai' => true,
+   'horonobe' => true,
+   'ikeda' => true,
+   'imakane' => true,
+   'ishikari' => true,
+   'iwamizawa' => true,
+   'iwanai' => true,
+   'kamifurano' => true,
+   'kamikawa' => true,
+   'kamishihoro' => true,
+   'kamisunagawa' => true,
+   'kamoenai' => true,
+   'kayabe' => true,
+   'kembuchi' => true,
+   'kikonai' => true,
+   'kimobetsu' => true,
+   'kitahiroshima' => true,
+   'kitami' => true,
+   'kiyosato' => true,
+   'koshimizu' => true,
+   'kunneppu' => true,
+   'kuriyama' => true,
+   'kuromatsunai' => true,
+   'kushiro' => true,
+   'kutchan' => true,
+   'kyowa' => true,
+   'mashike' => true,
+   'matsumae' => true,
+   'mikasa' => true,
+   'minamifurano' => true,
+   'mombetsu' => true,
+   'moseushi' => true,
+   'mukawa' => true,
+   'muroran' => true,
+   'naie' => true,
+   'nakagawa' => true,
+   'nakasatsunai' => true,
+   'nakatombetsu' => true,
+   'nanae' => true,
+   'nanporo' => true,
+   'nayoro' => true,
+   'nemuro' => true,
+   'niikappu' => true,
+   'niki' => true,
+   'nishiokoppe' => true,
+   'noboribetsu' => true,
+   'numata' => true,
+   'obihiro' => true,
+   'obira' => true,
+   'oketo' => true,
+   'okoppe' => true,
+   'otaru' => true,
+   'otobe' => true,
+   'otofuke' => true,
+   'otoineppu' => true,
+   'oumu' => true,
+   'ozora' => true,
+   'pippu' => true,
+   'rankoshi' => true,
+   'rebun' => true,
+   'rikubetsu' => true,
+   'rishiri' => true,
+   'rishirifuji' => true,
+   'saroma' => true,
+   'sarufutsu' => true,
+   'shakotan' => true,
+   'shari' => true,
+   'shibecha' => true,
+   'shibetsu' => true,
+   'shikabe' => true,
+   'shikaoi' => true,
+   'shimamaki' => true,
+   'shimizu' => true,
+   'shimokawa' => true,
+   'shinshinotsu' => true,
+   'shintoku' => true,
+   'shiranuka' => true,
+   'shiraoi' => true,
+   'shiriuchi' => true,
+   'sobetsu' => true,
+   'sunagawa' => true,
+   'taiki' => true,
+   'takasu' => true,
+   'takikawa' => true,
+   'takinoue' => true,
+   'teshikaga' => true,
+   'tobetsu' => true,
+   'tohma' => true,
+   'tomakomai' => true,
+   'tomari' => true,
+   'toya' => true,
+   'toyako' => true,
+   'toyotomi' => true,
+   'toyoura' => true,
+   'tsubetsu' => true,
+   'tsukigata' => true,
+   'urakawa' => true,
+   'urausu' => true,
+   'uryu' => true,
+   'utashinai' => true,
+   'wakkanai' => true,
+   'wassamu' => true,
+   'yakumo' => true,
+   'yoichi' => true
   ),
   'hyogo' => array(
-   '*' => true,
-   '!pref' => true
+   'aioi' => true,
+   'akashi' => true,
+   'ako' => true,
+   'amagasaki' => true,
+   'aogaki' => true,
+   'asago' => true,
+   'ashiya' => true,
+   'awaji' => true,
+   'fukusaki' => true,
+   'goshiki' => true,
+   'harima' => true,
+   'himeji' => true,
+   'ichikawa' => true,
+   'inagawa' => true,
+   'itami' => true,
+   'kakogawa' => true,
+   'kamigori' => true,
+   'kamikawa' => true,
+   'kasai' => true,
+   'kasuga' => true,
+   'kawanishi' => true,
+   'miki' => true,
+   'minamiawaji' => true,
+   'nishinomiya' => true,
+   'nishiwaki' => true,
+   'ono' => true,
+   'sanda' => true,
+   'sannan' => true,
+   'sasayama' => true,
+   'sayo' => true,
+   'shingu' => true,
+   'shinonsen' => true,
+   'shiso' => true,
+   'sumoto' => true,
+   'taishi' => true,
+   'taka' => true,
+   'takarazuka' => true,
+   'takasago' => true,
+   'takino' => true,
+   'tamba' => true,
+   'tatsuno' => true,
+   'toyooka' => true,
+   'yabu' => true,
+   'yashiro' => true,
+   'yoka' => true,
+   'yokawa' => true
   ),
   'ibaraki' => array(
-   '*' => true,
-   '!pref' => true
+   'ami' => true,
+   'asahi' => true,
+   'bando' => true,
+   'chikusei' => true,
+   'daigo' => true,
+   'fujishiro' => true,
+   'hitachi' => true,
+   'hitachinaka' => true,
+   'hitachiomiya' => true,
+   'hitachiota' => true,
+   'ibaraki' => true,
+   'ina' => true,
+   'inashiki' => true,
+   'itako' => true,
+   'iwama' => true,
+   'joso' => true,
+   'kamisu' => true,
+   'kasama' => true,
+   'kashima' => true,
+   'kasumigaura' => true,
+   'koga' => true,
+   'miho' => true,
+   'mito' => true,
+   'moriya' => true,
+   'naka' => true,
+   'namegata' => true,
+   'oarai' => true,
+   'ogawa' => true,
+   'omitama' => true,
+   'ryugasaki' => true,
+   'sakai' => true,
+   'sakuragawa' => true,
+   'shimodate' => true,
+   'shimotsuma' => true,
+   'shirosato' => true,
+   'sowa' => true,
+   'suifu' => true,
+   'takahagi' => true,
+   'tamatsukuri' => true,
+   'tokai' => true,
+   'tomobe' => true,
+   'tone' => true,
+   'toride' => true,
+   'tsuchiura' => true,
+   'tsukuba' => true,
+   'uchihara' => true,
+   'ushiku' => true,
+   'yachiyo' => true,
+   'yamagata' => true,
+   'yawara' => true,
+   'yuki' => true
   ),
   'ishikawa' => array(
-   '*' => true,
-   '!pref' => true
+   'anamizu' => true,
+   'hakui' => true,
+   'hakusan' => true,
+   'kaga' => true,
+   'kahoku' => true,
+   'kanazawa' => true,
+   'kawakita' => true,
+   'komatsu' => true,
+   'nakanoto' => true,
+   'nanao' => true,
+   'nomi' => true,
+   'nonoichi' => true,
+   'noto' => true,
+   'shika' => true,
+   'suzu' => true,
+   'tsubata' => true,
+   'tsurugi' => true,
+   'uchinada' => true,
+   'wajima' => true
   ),
   'iwate' => array(
-   '*' => true,
-   '!pref' => true
+   'fudai' => true,
+   'fujisawa' => true,
+   'hanamaki' => true,
+   'hiraizumi' => true,
+   'hirono' => true,
+   'ichinohe' => true,
+   'ichinoseki' => true,
+   'iwaizumi' => true,
+   'iwate' => true,
+   'joboji' => true,
+   'kamaishi' => true,
+   'kanegasaki' => true,
+   'karumai' => true,
+   'kawai' => true,
+   'kitakami' => true,
+   'kuji' => true,
+   'kunohe' => true,
+   'kuzumaki' => true,
+   'miyako' => true,
+   'mizusawa' => true,
+   'morioka' => true,
+   'ninohe' => true,
+   'noda' => true,
+   'ofunato' => true,
+   'oshu' => true,
+   'otsuchi' => true,
+   'rikuzentakata' => true,
+   'shiwa' => true,
+   'shizukuishi' => true,
+   'sumita' => true,
+   'takizawa' => true,
+   'tanohata' => true,
+   'tono' => true,
+   'yahaba' => true,
+   'yamada' => true
   ),
   'kagawa' => array(
-   '*' => true,
-   '!pref' => true
+   'ayagawa' => true,
+   'higashikagawa' => true,
+   'kanonji' => true,
+   'kotohira' => true,
+   'manno' => true,
+   'marugame' => true,
+   'mitoyo' => true,
+   'naoshima' => true,
+   'sanuki' => true,
+   'tadotsu' => true,
+   'takamatsu' => true,
+   'tonosho' => true,
+   'uchinomi' => true,
+   'utazu' => true,
+   'zentsuji' => true
   ),
   'kagoshima' => array(
-   '*' => true,
-   '!pref' => true
+   'akune' => true,
+   'amami' => true,
+   'hioki' => true,
+   'isa' => true,
+   'isen' => true,
+   'izumi' => true,
+   'kagoshima' => true,
+   'kanoya' => true,
+   'kawanabe' => true,
+   'kinko' => true,
+   'kouyama' => true,
+   'makurazaki' => true,
+   'matsumoto' => true,
+   'minamitane' => true,
+   'nakatane' => true,
+   'nishinoomote' => true,
+   'satsumasendai' => true,
+   'soo' => true,
+   'tarumizu' => true,
+   'yusui' => true
   ),
   'kanagawa' => array(
-   '*' => true,
-   '!pref' => true
-  ),
-  'kawasaki' => array(
-   '*' => true,
-   '!city' => true
-  ),
-  'kitakyushu' => array(
-   '*' => true,
-   '!city' => true
-  ),
-  'kobe' => array(
-   '*' => true,
-   '!city' => true
+   'aikawa' => true,
+   'atsugi' => true,
+   'ayase' => true,
+   'chigasaki' => true,
+   'ebina' => true,
+   'fujisawa' => true,
+   'hadano' => true,
+   'hakone' => true,
+   'hiratsuka' => true,
+   'isehara' => true,
+   'kaisei' => true,
+   'kamakura' => true,
+   'kiyokawa' => true,
+   'matsuda' => true,
+   'minamiashigara' => true,
+   'miura' => true,
+   'nakai' => true,
+   'ninomiya' => true,
+   'odawara' => true,
+   'oi' => true,
+   'oiso' => true,
+   'sagamihara' => true,
+   'samukawa' => true,
+   'tsukui' => true,
+   'yamakita' => true,
+   'yamato' => true,
+   'yokosuka' => true,
+   'yugawara' => true,
+   'zama' => true,
+   'zushi' => true
   ),
   'kochi' => array(
-   '*' => true,
-   '!pref' => true
+   'aki' => true,
+   'geisei' => true,
+   'hidaka' => true,
+   'higashitsuno' => true,
+   'ino' => true,
+   'kagami' => true,
+   'kami' => true,
+   'kitagawa' => true,
+   'kochi' => true,
+   'mihara' => true,
+   'motoyama' => true,
+   'muroto' => true,
+   'nahari' => true,
+   'nakamura' => true,
+   'nankoku' => true,
+   'nishitosa' => true,
+   'niyodogawa' => true,
+   'ochi' => true,
+   'okawa' => true,
+   'otoyo' => true,
+   'otsuki' => true,
+   'sakawa' => true,
+   'sukumo' => true,
+   'susaki' => true,
+   'tosa' => true,
+   'tosashimizu' => true,
+   'toyo' => true,
+   'tsuno' => true,
+   'umaji' => true,
+   'yasuda' => true,
+   'yusuhara' => true
   ),
   'kumamoto' => array(
-   '*' => true,
-   '!pref' => true
+   'amakusa' => true,
+   'arao' => true,
+   'aso' => true,
+   'choyo' => true,
+   'gyokuto' => true,
+   'hitoyoshi' => true,
+   'kamiamakusa' => true,
+   'kashima' => true,
+   'kikuchi' => true,
+   'kosa' => true,
+   'kumamoto' => true,
+   'mashiki' => true,
+   'mifune' => true,
+   'minamata' => true,
+   'minamioguni' => true,
+   'nagasu' => true,
+   'nishihara' => true,
+   'oguni' => true,
+   'ozu' => true,
+   'sumoto' => true,
+   'takamori' => true,
+   'uki' => true,
+   'uto' => true,
+   'yamaga' => true,
+   'yamato' => true,
+   'yatsushiro' => true
   ),
   'kyoto' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'ayabe' => true,
+   'fukuchiyama' => true,
+   'higashiyama' => true,
+   'ide' => true,
+   'ine' => true,
+   'joyo' => true,
+   'kameoka' => true,
+   'kamo' => true,
+   'kita' => true,
+   'kizu' => true,
+   'kumiyama' => true,
+   'kyotamba' => true,
+   'kyotanabe' => true,
+   'kyotango' => true,
+   'maizuru' => true,
+   'minami' => true,
+   'minamiyamashiro' => true,
+   'miyazu' => true,
+   'muko' => true,
+   'nagaokakyo' => true,
+   'nakagyo' => true,
+   'nantan' => true,
+   'oyamazaki' => true,
+   'sakyo' => true,
+   'seika' => true,
+   'tanabe' => true,
+   'uji' => true,
+   'ujitawara' => true,
+   'wazuka' => true,
+   'yamashina' => true,
+   'yawata' => true
   ),
   'mie' => array(
-   '*' => true,
-   '!pref' => true
+   'asahi' => true,
+   'inabe' => true,
+   'ise' => true,
+   'kameyama' => true,
+   'kawagoe' => true,
+   'kiho' => true,
+   'kisosaki' => true,
+   'kiwa' => true,
+   'komono' => true,
+   'kumano' => true,
+   'kuwana' => true,
+   'matsusaka' => true,
+   'meiwa' => true,
+   'mihama' => true,
+   'minamiise' => true,
+   'misugi' => true,
+   'miyama' => true,
+   'nabari' => true,
+   'shima' => true,
+   'suzuka' => true,
+   'tado' => true,
+   'taiki' => true,
+   'taki' => true,
+   'tamaki' => true,
+   'toba' => true,
+   'tsu' => true,
+   'udono' => true,
+   'ureshino' => true,
+   'watarai' => true,
+   'yokkaichi' => true
   ),
   'miyagi' => array(
-   '*' => true,
-   '!pref' => true
+   'furukawa' => true,
+   'higashimatsushima' => true,
+   'ishinomaki' => true,
+   'iwanuma' => true,
+   'kakuda' => true,
+   'kami' => true,
+   'kawasaki' => true,
+   'kesennuma' => true,
+   'marumori' => true,
+   'matsushima' => true,
+   'minamisanriku' => true,
+   'misato' => true,
+   'murata' => true,
+   'natori' => true,
+   'ogawara' => true,
+   'ohira' => true,
+   'onagawa' => true,
+   'osaki' => true,
+   'rifu' => true,
+   'semine' => true,
+   'shibata' => true,
+   'shichikashuku' => true,
+   'shikama' => true,
+   'shiogama' => true,
+   'shiroishi' => true,
+   'tagajo' => true,
+   'taiwa' => true,
+   'tome' => true,
+   'tomiya' => true,
+   'wakuya' => true,
+   'watari' => true,
+   'yamamoto' => true,
+   'zao' => true
   ),
   'miyazaki' => array(
-   '*' => true,
-   '!pref' => true
+   'aya' => true,
+   'ebino' => true,
+   'gokase' => true,
+   'hyuga' => true,
+   'kadogawa' => true,
+   'kawaminami' => true,
+   'kijo' => true,
+   'kitagawa' => true,
+   'kitakata' => true,
+   'kitaura' => true,
+   'kobayashi' => true,
+   'kunitomi' => true,
+   'kushima' => true,
+   'mimata' => true,
+   'miyakonojo' => true,
+   'miyazaki' => true,
+   'morotsuka' => true,
+   'nichinan' => true,
+   'nishimera' => true,
+   'nobeoka' => true,
+   'saito' => true,
+   'shiiba' => true,
+   'shintomi' => true,
+   'takaharu' => true,
+   'takanabe' => true,
+   'takazaki' => true,
+   'tsuno' => true
   ),
   'nagano' => array(
-   '*' => true,
-   '!pref' => true
+   'achi' => true,
+   'agematsu' => true,
+   'anan' => true,
+   'aoki' => true,
+   'asahi' => true,
+   'azumino' => true,
+   'chikuhoku' => true,
+   'chikuma' => true,
+   'chino' => true,
+   'fujimi' => true,
+   'hakuba' => true,
+   'hara' => true,
+   'hiraya' => true,
+   'iida' => true,
+   'iijima' => true,
+   'iiyama' => true,
+   'iizuna' => true,
+   'ikeda' => true,
+   'ikusaka' => true,
+   'ina' => true,
+   'karuizawa' => true,
+   'kawakami' => true,
+   'kiso' => true,
+   'kisofukushima' => true,
+   'kitaaiki' => true,
+   'komagane' => true,
+   'komoro' => true,
+   'matsukawa' => true,
+   'matsumoto' => true,
+   'miasa' => true,
+   'minamiaiki' => true,
+   'minamimaki' => true,
+   'minamiminowa' => true,
+   'minowa' => true,
+   'miyada' => true,
+   'miyota' => true,
+   'mochizuki' => true,
+   'nagano' => true,
+   'nagawa' => true,
+   'nagiso' => true,
+   'nakagawa' => true,
+   'nakano' => true,
+   'nozawaonsen' => true,
+   'obuse' => true,
+   'ogawa' => true,
+   'okaya' => true,
+   'omachi' => true,
+   'omi' => true,
+   'ookuwa' => true,
+   'ooshika' => true,
+   'otaki' => true,
+   'otari' => true,
+   'sakae' => true,
+   'sakaki' => true,
+   'saku' => true,
+   'sakuho' => true,
+   'shimosuwa' => true,
+   'shinanomachi' => true,
+   'shiojiri' => true,
+   'suwa' => true,
+   'suzaka' => true,
+   'takagi' => true,
+   'takamori' => true,
+   'takayama' => true,
+   'tateshina' => true,
+   'tatsuno' => true,
+   'togakushi' => true,
+   'togura' => true,
+   'tomi' => true,
+   'ueda' => true,
+   'wada' => true,
+   'yamagata' => true,
+   'yamanouchi' => true,
+   'yasaka' => true,
+   'yasuoka' => true
   ),
   'nagasaki' => array(
-   '*' => true,
-   '!pref' => true
-  ),
-  'nagoya' => array(
-   '*' => true,
-   '!city' => true
+   'chijiwa' => true,
+   'futsu' => true,
+   'goto' => true,
+   'hasami' => true,
+   'hirado' => true,
+   'iki' => true,
+   'isahaya' => true,
+   'kawatana' => true,
+   'kuchinotsu' => true,
+   'matsuura' => true,
+   'nagasaki' => true,
+   'obama' => true,
+   'omura' => true,
+   'oseto' => true,
+   'saikai' => true,
+   'sasebo' => true,
+   'seihi' => true,
+   'shimabara' => true,
+   'shinkamigoto' => true,
+   'togitsu' => true,
+   'tsushima' => true,
+   'unzen' => true
   ),
   'nara' => array(
-   '*' => true,
-   '!pref' => true
+   'ando' => true,
+   'gose' => true,
+   'heguri' => true,
+   'higashiyoshino' => true,
+   'ikaruga' => true,
+   'ikoma' => true,
+   'kamikitayama' => true,
+   'kanmaki' => true,
+   'kashiba' => true,
+   'kashihara' => true,
+   'katsuragi' => true,
+   'kawai' => true,
+   'kawakami' => true,
+   'kawanishi' => true,
+   'koryo' => true,
+   'kurotaki' => true,
+   'mitsue' => true,
+   'miyake' => true,
+   'nara' => true,
+   'nosegawa' => true,
+   'oji' => true,
+   'ouda' => true,
+   'oyodo' => true,
+   'sakurai' => true,
+   'sango' => true,
+   'shimoichi' => true,
+   'shimokitayama' => true,
+   'shinjo' => true,
+   'soni' => true,
+   'takatori' => true,
+   'tawaramoto' => true,
+   'tenkawa' => true,
+   'tenri' => true,
+   'uda' => true,
+   'yamatokoriyama' => true,
+   'yamatotakada' => true,
+   'yamazoe' => true,
+   'yoshino' => true
   ),
   'niigata' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'aga' => true,
+   'agano' => true,
+   'gosen' => true,
+   'itoigawa' => true,
+   'izumozaki' => true,
+   'joetsu' => true,
+   'kamo' => true,
+   'kariwa' => true,
+   'kashiwazaki' => true,
+   'minamiuonuma' => true,
+   'mitsuke' => true,
+   'muika' => true,
+   'murakami' => true,
+   'myoko' => true,
+   'nagaoka' => true,
+   'niigata' => true,
+   'ojiya' => true,
+   'omi' => true,
+   'sado' => true,
+   'sanjo' => true,
+   'seiro' => true,
+   'seirou' => true,
+   'sekikawa' => true,
+   'shibata' => true,
+   'tagami' => true,
+   'tainai' => true,
+   'tochio' => true,
+   'tokamachi' => true,
+   'tsubame' => true,
+   'tsunan' => true,
+   'uonuma' => true,
+   'yahiko' => true,
+   'yoita' => true,
+   'yuzawa' => true
   ),
   'oita' => array(
-   '*' => true,
-   '!pref' => true
+   'beppu' => true,
+   'bungoono' => true,
+   'bungotakada' => true,
+   'hasama' => true,
+   'hiji' => true,
+   'himeshima' => true,
+   'hita' => true,
+   'kamitsue' => true,
+   'kokonoe' => true,
+   'kuju' => true,
+   'kunisaki' => true,
+   'kusu' => true,
+   'oita' => true,
+   'saiki' => true,
+   'taketa' => true,
+   'tsukumi' => true,
+   'usa' => true,
+   'usuki' => true,
+   'yufu' => true
   ),
   'okayama' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'akaiwa' => true,
+   'asakuchi' => true,
+   'bizen' => true,
+   'hayashima' => true,
+   'ibara' => true,
+   'kagamino' => true,
+   'kasaoka' => true,
+   'kibichuo' => true,
+   'kumenan' => true,
+   'kurashiki' => true,
+   'maniwa' => true,
+   'misaki' => true,
+   'nagi' => true,
+   'niimi' => true,
+   'nishiawakura' => true,
+   'okayama' => true,
+   'satosho' => true,
+   'setouchi' => true,
+   'shinjo' => true,
+   'shoo' => true,
+   'soja' => true,
+   'takahashi' => true,
+   'tamano' => true,
+   'tsuyama' => true,
+   'wake' => true,
+   'yakage' => true
   ),
   'okinawa' => array(
-   '*' => true,
-   '!pref' => true
+   'aguni' => true,
+   'ginowan' => true,
+   'ginoza' => true,
+   'gushikami' => true,
+   'haebaru' => true,
+   'higashi' => true,
+   'hirara' => true,
+   'iheya' => true,
+   'ishigaki' => true,
+   'ishikawa' => true,
+   'itoman' => true,
+   'izena' => true,
+   'kadena' => true,
+   'kin' => true,
+   'kitadaito' => true,
+   'kitanakagusuku' => true,
+   'kumejima' => true,
+   'kunigami' => true,
+   'minamidaito' => true,
+   'motobu' => true,
+   'nago' => true,
+   'naha' => true,
+   'nakagusuku' => true,
+   'nakijin' => true,
+   'nanjo' => true,
+   'nishihara' => true,
+   'ogimi' => true,
+   'okinawa' => true,
+   'onna' => true,
+   'shimoji' => true,
+   'taketomi' => true,
+   'tarama' => true,
+   'tokashiki' => true,
+   'tomigusuku' => true,
+   'tonaki' => true,
+   'urasoe' => true,
+   'uruma' => true,
+   'yaese' => true,
+   'yomitan' => true,
+   'yonabaru' => true,
+   'yonaguni' => true,
+   'zamami' => true
   ),
   'osaka' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'abeno' => true,
+   'chihayaakasaka' => true,
+   'chuo' => true,
+   'daito' => true,
+   'fujiidera' => true,
+   'habikino' => true,
+   'hannan' => true,
+   'higashiosaka' => true,
+   'higashisumiyoshi' => true,
+   'higashiyodogawa' => true,
+   'hirakata' => true,
+   'ibaraki' => true,
+   'ikeda' => true,
+   'izumi' => true,
+   'izumiotsu' => true,
+   'izumisano' => true,
+   'kadoma' => true,
+   'kaizuka' => true,
+   'kanan' => true,
+   'kashiwara' => true,
+   'katano' => true,
+   'kawachinagano' => true,
+   'kishiwada' => true,
+   'kita' => true,
+   'kumatori' => true,
+   'matsubara' => true,
+   'minato' => true,
+   'minoh' => true,
+   'misaki' => true,
+   'moriguchi' => true,
+   'neyagawa' => true,
+   'nishi' => true,
+   'nose' => true,
+   'osakasayama' => true,
+   'sakai' => true,
+   'sayama' => true,
+   'sennan' => true,
+   'settsu' => true,
+   'shijonawate' => true,
+   'shimamoto' => true,
+   'suita' => true,
+   'tadaoka' => true,
+   'taishi' => true,
+   'tajiri' => true,
+   'takaishi' => true,
+   'takatsuki' => true,
+   'tondabayashi' => true,
+   'toyonaka' => true,
+   'toyono' => true,
+   'yao' => true
   ),
   'saga' => array(
-   '*' => true,
-   '!pref' => true
+   'ariake' => true,
+   'arita' => true,
+   'fukudomi' => true,
+   'genkai' => true,
+   'hamatama' => true,
+   'hizen' => true,
+   'imari' => true,
+   'kamimine' => true,
+   'kanzaki' => true,
+   'karatsu' => true,
+   'kashima' => true,
+   'kitagata' => true,
+   'kitahata' => true,
+   'kiyama' => true,
+   'kouhoku' => true,
+   'kyuragi' => true,
+   'nishiarita' => true,
+   'ogi' => true,
+   'omachi' => true,
+   'ouchi' => true,
+   'saga' => true,
+   'shiroishi' => true,
+   'taku' => true,
+   'tara' => true,
+   'tosu' => true,
+   'yoshinogari' => true
   ),
   'saitama' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
-  ),
-  'sapporo' => array(
-   '*' => true,
-   '!city' => true
-  ),
-  'sendai' => array(
-   '*' => true,
-   '!city' => true
+   'arakawa' => true,
+   'asaka' => true,
+   'chichibu' => true,
+   'fujimi' => true,
+   'fujimino' => true,
+   'fukaya' => true,
+   'hanno' => true,
+   'hanyu' => true,
+   'hasuda' => true,
+   'hatogaya' => true,
+   'hatoyama' => true,
+   'hidaka' => true,
+   'higashichichibu' => true,
+   'higashimatsuyama' => true,
+   'honjo' => true,
+   'ina' => true,
+   'iruma' => true,
+   'iwatsuki' => true,
+   'kamiizumi' => true,
+   'kamikawa' => true,
+   'kamisato' => true,
+   'kasukabe' => true,
+   'kawagoe' => true,
+   'kawaguchi' => true,
+   'kawajima' => true,
+   'kazo' => true,
+   'kitamoto' => true,
+   'koshigaya' => true,
+   'kounosu' => true,
+   'kuki' => true,
+   'kumagaya' => true,
+   'matsubushi' => true,
+   'minano' => true,
+   'misato' => true,
+   'miyashiro' => true,
+   'miyoshi' => true,
+   'moroyama' => true,
+   'nagatoro' => true,
+   'namegawa' => true,
+   'niiza' => true,
+   'ogano' => true,
+   'ogawa' => true,
+   'ogose' => true,
+   'okegawa' => true,
+   'omiya' => true,
+   'otaki' => true,
+   'ranzan' => true,
+   'ryokami' => true,
+   'saitama' => true,
+   'sakado' => true,
+   'satte' => true,
+   'sayama' => true,
+   'shiki' => true,
+   'shiraoka' => true,
+   'soka' => true,
+   'sugito' => true,
+   'toda' => true,
+   'tokigawa' => true,
+   'tokorozawa' => true,
+   'tsurugashima' => true,
+   'urawa' => true,
+   'warabi' => true,
+   'yashio' => true,
+   'yokoze' => true,
+   'yono' => true,
+   'yorii' => true,
+   'yoshida' => true,
+   'yoshikawa' => true,
+   'yoshimi' => true
   ),
   'shiga' => array(
-   '*' => true,
-   '!pref' => true
+   'aisho' => true,
+   'gamo' => true,
+   'higashiomi' => true,
+   'hikone' => true,
+   'koka' => true,
+   'konan' => true,
+   'kosei' => true,
+   'koto' => true,
+   'kusatsu' => true,
+   'maibara' => true,
+   'moriyama' => true,
+   'nagahama' => true,
+   'nishiazai' => true,
+   'notogawa' => true,
+   'omihachiman' => true,
+   'otsu' => true,
+   'ritto' => true,
+   'ryuoh' => true,
+   'takashima' => true,
+   'takatsuki' => true,
+   'torahime' => true,
+   'toyosato' => true,
+   'yasu' => true
   ),
   'shimane' => array(
-   '*' => true,
-   '!pref' => true
+   'akagi' => true,
+   'ama' => true,
+   'gotsu' => true,
+   'hamada' => true,
+   'higashiizumo' => true,
+   'hikawa' => true,
+   'hikimi' => true,
+   'izumo' => true,
+   'kakinoki' => true,
+   'masuda' => true,
+   'matsue' => true,
+   'misato' => true,
+   'nishinoshima' => true,
+   'ohda' => true,
+   'okinoshima' => true,
+   'okuizumo' => true,
+   'shimane' => true,
+   'tamayu' => true,
+   'tsuwano' => true,
+   'unnan' => true,
+   'yakumo' => true,
+   'yasugi' => true,
+   'yatsuka' => true
   ),
   'shizuoka' => array(
-   '*' => true,
-   '!pref' => true,
-   '!city' => true
+   'arai' => true,
+   'atami' => true,
+   'fuji' => true,
+   'fujieda' => true,
+   'fujikawa' => true,
+   'fujinomiya' => true,
+   'fukuroi' => true,
+   'gotemba' => true,
+   'haibara' => true,
+   'hamamatsu' => true,
+   'higashiizu' => true,
+   'ito' => true,
+   'iwata' => true,
+   'izu' => true,
+   'izunokuni' => true,
+   'kakegawa' => true,
+   'kannami' => true,
+   'kawanehon' => true,
+   'kawazu' => true,
+   'kikugawa' => true,
+   'kosai' => true,
+   'makinohara' => true,
+   'matsuzaki' => true,
+   'minamiizu' => true,
+   'mishima' => true,
+   'morimachi' => true,
+   'nishiizu' => true,
+   'numazu' => true,
+   'omaezaki' => true,
+   'shimada' => true,
+   'shimizu' => true,
+   'shimoda' => true,
+   'shizuoka' => true,
+   'susono' => true,
+   'yaizu' => true,
+   'yoshida' => true
   ),
   'tochigi' => array(
-   '*' => true,
-   '!pref' => true
+   'ashikaga' => true,
+   'bato' => true,
+   'haga' => true,
+   'ichikai' => true,
+   'iwafune' => true,
+   'kaminokawa' => true,
+   'kanuma' => true,
+   'karasuyama' => true,
+   'kuroiso' => true,
+   'mashiko' => true,
+   'mibu' => true,
+   'moka' => true,
+   'motegi' => true,
+   'nasu' => true,
+   'nasushiobara' => true,
+   'nikko' => true,
+   'nishikata' => true,
+   'nogi' => true,
+   'ohira' => true,
+   'ohtawara' => true,
+   'oyama' => true,
+   'sakura' => true,
+   'sano' => true,
+   'shimotsuke' => true,
+   'shioya' => true,
+   'takanezawa' => true,
+   'tochigi' => true,
+   'tsuga' => true,
+   'ujiie' => true,
+   'utsunomiya' => true,
+   'yaita' => true
   ),
   'tokushima' => array(
-   '*' => true,
-   '!pref' => true
+   'aizumi' => true,
+   'anan' => true,
+   'ichiba' => true,
+   'itano' => true,
+   'kainan' => true,
+   'komatsushima' => true,
+   'matsushige' => true,
+   'mima' => true,
+   'minami' => true,
+   'miyoshi' => true,
+   'mugi' => true,
+   'nakagawa' => true,
+   'naruto' => true,
+   'sanagochi' => true,
+   'shishikui' => true,
+   'tokushima' => true,
+   'wajiki' => true
   ),
   'tokyo' => array(
-   '*' => true,
-   '!metro' => true
+   'adachi' => true,
+   'akiruno' => true,
+   'akishima' => true,
+   'aogashima' => true,
+   'arakawa' => true,
+   'bunkyo' => true,
+   'chiyoda' => true,
+   'chofu' => true,
+   'chuo' => true,
+   'edogawa' => true,
+   'fuchu' => true,
+   'fussa' => true,
+   'hachijo' => true,
+   'hachioji' => true,
+   'hamura' => true,
+   'higashikurume' => true,
+   'higashimurayama' => true,
+   'higashiyamato' => true,
+   'hino' => true,
+   'hinode' => true,
+   'hinohara' => true,
+   'inagi' => true,
+   'itabashi' => true,
+   'katsushika' => true,
+   'kita' => true,
+   'kiyose' => true,
+   'kodaira' => true,
+   'koganei' => true,
+   'kokubunji' => true,
+   'komae' => true,
+   'koto' => true,
+   'kouzushima' => true,
+   'kunitachi' => true,
+   'machida' => true,
+   'meguro' => true,
+   'minato' => true,
+   'mitaka' => true,
+   'mizuho' => true,
+   'musashimurayama' => true,
+   'musashino' => true,
+   'nakano' => true,
+   'nerima' => true,
+   'ogasawara' => true,
+   'okutama' => true,
+   'ome' => true,
+   'oshima' => true,
+   'ota' => true,
+   'setagaya' => true,
+   'shibuya' => true,
+   'shinagawa' => true,
+   'shinjuku' => true,
+   'suginami' => true,
+   'sumida' => true,
+   'tachikawa' => true,
+   'taito' => true,
+   'tama' => true,
+   'toshima' => true
   ),
   'tottori' => array(
-   '*' => true,
-   '!pref' => true
+   'chizu' => true,
+   'hino' => true,
+   'kawahara' => true,
+   'koge' => true,
+   'kotoura' => true,
+   'misasa' => true,
+   'nanbu' => true,
+   'nichinan' => true,
+   'sakaiminato' => true,
+   'tottori' => true,
+   'wakasa' => true,
+   'yazu' => true,
+   'yonago' => true
   ),
   'toyama' => array(
-   '*' => true,
-   '!pref' => true
+   'asahi' => true,
+   'fuchu' => true,
+   'fukumitsu' => true,
+   'funahashi' => true,
+   'himi' => true,
+   'imizu' => true,
+   'inami' => true,
+   'johana' => true,
+   'kamiichi' => true,
+   'kurobe' => true,
+   'nakaniikawa' => true,
+   'namerikawa' => true,
+   'nanto' => true,
+   'nyuzen' => true,
+   'oyabe' => true,
+   'taira' => true,
+   'takaoka' => true,
+   'tateyama' => true,
+   'toga' => true,
+   'tonami' => true,
+   'toyama' => true,
+   'unazuki' => true,
+   'uozu' => true,
+   'yamada' => true
   ),
   'wakayama' => array(
-   '*' => true,
-   '!pref' => true
+   'arida' => true,
+   'aridagawa' => true,
+   'gobo' => true,
+   'hashimoto' => true,
+   'hidaka' => true,
+   'hirogawa' => true,
+   'inami' => true,
+   'iwade' => true,
+   'kainan' => true,
+   'kamitonda' => true,
+   'katsuragi' => true,
+   'kimino' => true,
+   'kinokawa' => true,
+   'kitayama' => true,
+   'koya' => true,
+   'koza' => true,
+   'kozagawa' => true,
+   'kudoyama' => true,
+   'kushimoto' => true,
+   'mihama' => true,
+   'misato' => true,
+   'nachikatsuura' => true,
+   'shingu' => true,
+   'shirahama' => true,
+   'taiji' => true,
+   'tanabe' => true,
+   'wakayama' => true,
+   'yuasa' => true,
+   'yura' => true
   ),
   'yamagata' => array(
-   '*' => true,
-   '!pref' => true
+   'asahi' => true,
+   'funagata' => true,
+   'higashine' => true,
+   'iide' => true,
+   'kahoku' => true,
+   'kaminoyama' => true,
+   'kaneyama' => true,
+   'kawanishi' => true,
+   'mamurogawa' => true,
+   'mikawa' => true,
+   'murayama' => true,
+   'nagai' => true,
+   'nakayama' => true,
+   'nanyo' => true,
+   'nishikawa' => true,
+   'obanazawa' => true,
+   'oe' => true,
+   'oguni' => true,
+   'ohkura' => true,
+   'oishida' => true,
+   'sagae' => true,
+   'sakata' => true,
+   'sakegawa' => true,
+   'shinjo' => true,
+   'shirataka' => true,
+   'shonai' => true,
+   'takahata' => true,
+   'tendo' => true,
+   'tozawa' => true,
+   'tsuruoka' => true,
+   'yamagata' => true,
+   'yamanobe' => true,
+   'yonezawa' => true,
+   'yuza' => true
   ),
   'yamaguchi' => array(
-   '*' => true,
-   '!pref' => true
+   'abu' => true,
+   'hagi' => true,
+   'hikari' => true,
+   'hofu' => true,
+   'iwakuni' => true,
+   'kudamatsu' => true,
+   'mitou' => true,
+   'nagato' => true,
+   'oshima' => true,
+   'shimonoseki' => true,
+   'shunan' => true,
+   'tabuse' => true,
+   'tokuyama' => true,
+   'toyota' => true,
+   'ube' => true,
+   'yuu' => true
   ),
   'yamanashi' => array(
+   'chuo' => true,
+   'doshi' => true,
+   'fuefuki' => true,
+   'fujikawa' => true,
+   'fujikawaguchiko' => true,
+   'fujiyoshida' => true,
+   'hayakawa' => true,
+   'hokuto' => true,
+   'ichikawamisato' => true,
+   'kai' => true,
+   'kofu' => true,
+   'koshu' => true,
+   'kosuge' => true,
+   'minami-alps' => true,
+   'minobu' => true,
+   'nakamichi' => true,
+   'nanbu' => true,
+   'narusawa' => true,
+   'nirasaki' => true,
+   'nishikatsura' => true,
+   'oshino' => true,
+   'otsuki' => true,
+   'showa' => true,
+   'tabayama' => true,
+   'tsuru' => true,
+   'uenohara' => true,
+   'yamanakako' => true,
+   'yamanashi' => true
+  ),
+  'kawasaki' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'kitakyushu' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'kobe' => array(
    '*' => true,
-   '!pref' => true
+   '!city' => true
+  ),
+  'nagoya' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'sapporo' => array(
+   '*' => true,
+   '!city' => true
+  ),
+  'sendai' => array(
+   '*' => true,
+   '!city' => true
   ),
   'yokohama' => array(
    '*' => true,
    '!city' => true
-  )
+  ),
+  'blogspot' => true
  ),
  'ke' => array(
   '*' => true
@@ -1828,7 +3464,8 @@ return array(
   'jeonbuk' => true,
   'jeonnam' => true,
   'seoul' => true,
-  'ulsan' => true
+  'ulsan' => true,
+  'blogspot' => true
  ),
  'kw' => array(
   '*' => true
@@ -1987,7 +3624,8 @@ return array(
  'mn' => array(
   'gov' => true,
   'edu' => true,
-  'org' => true
+  'org' => true,
+  'nyc' => true
  ),
  'mo' => array(
   'com' => true,
@@ -2000,11 +3638,15 @@ return array(
  'mp' => true,
  'mq' => true,
  'mr' => array(
-  'gov' => true
+  'gov' => true,
+  'blogspot' => true
  ),
  'ms' => true,
  'mt' => array(
-  '*' => true
+  'com' => true,
+  'edu' => true,
+  'net' => true,
+  'org' => true
  ),
  'mu' => array(
   'com' => true,
@@ -2599,7 +4241,8 @@ return array(
   'org' => true,
   'gob' => true,
   'edu' => true,
-  'net' => true
+  'net' => true,
+  'blogspot' => true
  ),
  'my' => array(
   'com' => true,
@@ -2611,7 +4254,8 @@ return array(
   'name' => true
  ),
  'mz' => array(
-  '*' => true
+  '*' => true,
+  '!teledata' => true
  ),
  'na' => array(
   'info' => true,
@@ -2645,11 +4289,12 @@ return array(
  ),
  'ne' => true,
  'net' => array(
+  'cloudfront' => true,
   'gb' => true,
+  'hu' => true,
   'jp' => true,
   'se' => true,
   'uk' => true,
-  'za' => true,
   'at-band-camp' => true,
   'blogdns' => true,
   'broke-it' => true,
@@ -2684,7 +4329,19 @@ return array(
   'servebbs' => true,
   'serveftp' => true,
   'thruhere' => true,
-  'webhop' => true
+  'webhop' => true,
+  'fastly' => array(
+   'ssl' => array(
+    'a' => true,
+    'b' => true,
+    'global' => true
+   ),
+   'prod' => array(
+    'a' => true,
+    'global' => true
+   )
+  ),
+  'za' => true
  ),
  'nf' => array(
   'com' => true,
@@ -2699,19 +4356,23 @@ return array(
   'store' => true
  ),
  'ng' => array(
-  'ac' => true,
   'com' => true,
   'edu' => true,
-  'gov' => true,
+  'name' => true,
   'net' => true,
-  'org' => true
+  'org' => true,
+  'sch' => true,
+  'gov' => true,
+  'mil' => true,
+  'mobi' => true
  ),
  'ni' => array(
   '*' => true
  ),
  'nl' => array(
   'bv' => true,
-  'co' => true
+  'co' => true,
+  'blogspot' => true
  ),
  'no' => array(
   'fhs' => true,
@@ -3510,7 +5171,8 @@ return array(
   'østfold' => array(
    'våler' => true
   ),
-  'co' => true
+  'co' => true,
+  'blogspot' => true
  ),
  'np' => array(
   '*' => true
@@ -3530,25 +5192,25 @@ return array(
   'shacknet' => true
  ),
  'nz' => array(
-  '*' => true
+  '*' => true,
+  'co' => array(
+   'blogspot' => true
+  )
  ),
  'om' => array(
-  '*' => true,
-  '!mediaphone' => true,
-  '!nawrastelecom' => true,
-  '!nawras' => true,
-  '!omanmobile' => true,
-  '!omanpost' => true,
-  '!omantel' => true,
-  '!rakpetroleum' => true,
-  '!siemens' => true,
-  '!songfest' => true,
-  '!statecouncil' => true
+  'co' => true,
+  'com' => true,
+  'edu' => true,
+  'gov' => true,
+  'med' => true,
+  'museum' => true,
+  'net' => true,
+  'org' => true,
+  'pro' => true
  ),
  'org' => array(
   'ae' => true,
   'us' => true,
-  'za' => true,
   'dyndns' => array(
    'go' => true,
    'home' => true
@@ -3601,7 +5263,8 @@ return array(
   'serveftp' => true,
   'servegame' => true,
   'stuff-4-sale' => true,
-  'webhop' => true
+  'webhop' => true,
+  'za' => true
  ),
  'pa' => array(
   'ac' => true,
@@ -3850,6 +5513,7 @@ return array(
   'edu' => true,
   'net' => true
  ),
+ 'post' => true,
  'pr' => array(
   'com' => true,
   'net' => true,
@@ -3891,7 +5555,8 @@ return array(
   'int' => true,
   'publ' => true,
   'com' => true,
-  'nome' => true
+  'nome' => true,
+  'blogspot' => true
  ),
  'pw' => array(
   'co' => true,
@@ -3902,7 +5567,13 @@ return array(
   'belau' => true
  ),
  'py' => array(
-  '*' => true
+  'com' => true,
+  'coop' => true,
+  'edu' => true,
+  'gov' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true
  ),
  'qa' => array(
   'com' => true,
@@ -3917,7 +5588,8 @@ return array(
  're' => array(
   'com' => true,
   'asso' => true,
-  'nom' => true
+  'nom' => true,
+  'blogspot' => true
  ),
  'ro' => array(
   'com' => true,
@@ -3930,7 +5602,8 @@ return array(
   'arts' => true,
   'firm' => true,
   'store' => true,
-  'www' => true
+  'www' => true,
+  'blogspot' => true
  ),
  'rs' => array(
   'co' => true,
@@ -4116,6 +5789,7 @@ return array(
   'org' => true,
   'edu' => true,
   'med' => true,
+  'tv' => true,
   'gov' => true,
   'info' => true
  ),
@@ -4159,7 +5833,8 @@ return array(
   'w' => true,
   'x' => true,
   'y' => true,
-  'z' => true
+  'z' => true,
+  'blogspot' => true
  ),
  'sg' => array(
   'com' => true,
@@ -4167,11 +5842,21 @@ return array(
   'org' => true,
   'gov' => true,
   'edu' => true,
-  'per' => true
+  'per' => true,
+  'blogspot' => true
+ ),
+ 'sh' => array(
+  'com' => true,
+  'net' => true,
+  'gov' => true,
+  'org' => true,
+  'mil' => true
  ),
- 'sh' => true,
  'si' => true,
- 'sk' => true,
+ 'sj' => true,
+ 'sk' => array(
+  'blogspot' => true
+ ),
  'sl' => array(
   'com' => true,
   'net' => true,
@@ -4211,7 +5896,14 @@ return array(
  ),
  'su' => true,
  'sv' => array(
-  '*' => true
+  'com' => true,
+  'edu' => true,
+  'gob' => true,
+  'org' => true,
+  'red' => true
+ ),
+ 'sx' => array(
+  'gov' => true
  ),
  'sy' => array(
   'edu' => true,
@@ -4227,7 +5919,9 @@ return array(
   'org' => true
  ),
  'tc' => true,
- 'td' => true,
+ 'td' => array(
+  'blogspot' => true
+ ),
  'tel' => true,
  'tf' => true,
  'tg' => true,
@@ -4261,7 +5955,16 @@ return array(
  'tl' => array(
   'gov' => true
  ),
- 'tm' => true,
+ 'tm' => array(
+  'com' => true,
+  'co' => true,
+  'org' => true,
+  'net' => true,
+  'nom' => true,
+  'gov' => true,
+  'mil' => true,
+  'edu' => true
+ ),
  'tn' => array(
   'com' => true,
   'ens' => true,
@@ -4292,6 +5995,7 @@ return array(
   'edu' => true,
   'mil' => true
  ),
+ 'tp' => true,
  'tr' => array(
   '*' => true,
   '!nic' => true,
@@ -4338,16 +6042,22 @@ return array(
   'club' => true,
   '網路' => true,
   '組織' => true,
-  '商業' => true
+  '商業' => true,
+  'blogspot' => true
  ),
  'tz' => array(
   'ac' => true,
   'co' => true,
   'go' => true,
+  'hotel' => true,
+  'info' => true,
+  'me' => true,
   'mil' => true,
+  'mobi' => true,
   'ne' => true,
   'or' => true,
-  'sc' => true
+  'sc' => true,
+  'tv' => true
  ),
  'ua' => array(
   'com' => true,
@@ -4357,61 +6067,87 @@ return array(
   'net' => true,
   'org' => true,
   'cherkassy' => true,
+  'cherkasy' => true,
   'chernigov' => true,
+  'chernihiv' => true,
+  'chernivtsi' => true,
   'chernovtsy' => true,
   'ck' => true,
   'cn' => true,
+  'cr' => true,
   'crimea' => true,
   'cv' => true,
   'dn' => true,
   'dnepropetrovsk' => true,
+  'dnipropetrovsk' => true,
+  'dominic' => true,
   'donetsk' => true,
   'dp' => true,
   'if' => true,
   'ivano-frankivsk' => true,
   'kh' => true,
+  'kharkiv' => true,
   'kharkov' => true,
   'kherson' => true,
   'khmelnitskiy' => true,
+  'khmelnytskyi' => true,
   'kiev' => true,
   'kirovograd' => true,
   'km' => true,
   'kr' => true,
+  'krym' => true,
   'ks' => true,
   'kv' => true,
+  'kyiv' => true,
   'lg' => true,
+  'lt' => true,
   'lugansk' => true,
   'lutsk' => true,
+  'lv' => true,
   'lviv' => true,
   'mk' => true,
+  'mykolaiv' => true,
   'nikolaev' => true,
   'od' => true,
+  'odesa' => true,
   'odessa' => true,
   'pl' => true,
   'poltava' => true,
+  'rivne' => true,
   'rovno' => true,
   'rv' => true,
+  'sb' => true,
   'sebastopol' => true,
+  'sevastopol' => true,
+  'sm' => true,
   'sumy' => true,
   'te' => true,
   'ternopil' => true,
+  'uz' => true,
   'uzhgorod' => true,
   'vinnica' => true,
+  'vinnytsia' => true,
   'vn' => true,
+  'volyn' => true,
+  'yalta' => true,
   'zaporizhzhe' => true,
-  'zp' => true,
+  'zaporizhzhia' => true,
   'zhitomir' => true,
+  'zhytomyr' => true,
+  'zp' => true,
   'zt' => true,
   'co' => true,
   'pp' => true
  ),
  'ug' => array(
   'co' => true,
+  'or' => true,
   'ac' => true,
   'sc' => true,
   'go' => true,
   'ne' => true,
-  'or' => true
+  'com' => true,
+  'org' => true
  ),
  'uk' => array(
   '*' => true,
@@ -4420,16 +6156,16 @@ return array(
   ),
   '!bl' => true,
   '!british-library' => true,
-  '!icnet' => true,
   '!jet' => true,
   '!mod' => true,
+  '!national-library-scotland' => true,
   '!nel' => true,
-  '!nhs' => true,
   '!nic' => true,
   '!nls' => true,
-  '!national-library-scotland' => true,
   '!parliament' => true,
-  '!police' => true
+  'co' => array(
+   'blogspot' => true
+  )
  ),
  'us' => array(
   'dni' => true,
@@ -4661,7 +6397,6 @@ return array(
    'lib' => true
   ),
   'sd' => array(
-   'k12' => true,
    'cc' => true,
    'lib' => true
   ),
@@ -4706,9 +6441,7 @@ return array(
    'lib' => true
   ),
   'wv' => array(
-   'k12' => true,
-   'cc' => true,
-   'lib' => true
+   'cc' => true
   ),
   'wy' => array(
    'k12' => true,
@@ -4720,11 +6453,18 @@ return array(
   'stuff-4-sale' => true
  ),
  'uy' => array(
-  '*' => true
+  'com' => true,
+  'edu' => true,
+  'gub' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true
  ),
  'uz' => array(
+  'co' => true,
   'com' => true,
-  'co' => true
+  'net' => true,
+  'org' => true
  ),
  'va' => true,
  'vc' => array(
@@ -4736,7 +6476,16 @@ return array(
   'edu' => true
  ),
  've' => array(
-  '*' => true
+  'co' => true,
+  'com' => true,
+  'e12' => true,
+  'edu' => true,
+  'gov' => true,
+  'info' => true,
+  'mil' => true,
+  'net' => true,
+  'org' => true,
+  'web' => true
  ),
  'vg' => true,
  'vi' => array(
@@ -4791,9 +6540,12 @@ return array(
  'ايران' => true,
  'الاردن' => true,
  '한국' => true,
+ 'қаз' => true,
  'ලංකා' => true,
  'இலங்கை' => true,
  'المغرب' => true,
+ 'мон' => true,
+ 'مليسيا' => true,
  'عمان' => true,
  'فلسطين' => true,
  'срб' => true,
@@ -4826,6 +6578,124 @@ return array(
  ),
  'zw' => array(
   '*' => true
- )
+ ),
+ 'онлайн' => true,
+ 'сайт' => true,
+ 'شبكة' => true,
+ '游戏' => true,
+ '企业' => true,
+ 'camera' => true,
+ 'clothing' => true,
+ 'lighting' => true,
+ 'singles' => true,
+ 'ventures' => true,
+ 'voyage' => true,
+ 'guru' => true,
+ 'holdings' => true,
+ 'equipment' => true,
+ 'bike' => true,
+ 'estate' => true,
+ 'tattoo' => true,
+ '在线' => true,
+ '中文网' => true,
+ 'land' => true,
+ 'plumbing' => true,
+ 'contractors' => true,
+ 'sexy' => true,
+ 'menu' => true,
+ '世界' => true,
+ 'uno' => true,
+ 'gallery' => true,
+ 'technology' => true,
+ '集团' => true,
+ 'reviews' => true,
+ 'guide' => true,
+ '我爱你' => true,
+ 'graphics' => true,
+ 'construction' => true,
+ 'onl' => true,
+ 'みんな' => true,
+ 'diamonds' => true,
+ 'kiwi' => true,
+ 'enterprises' => true,
+ 'today' => true,
+ 'futbol' => true,
+ 'photography' => true,
+ 'tips' => true,
+ 'directory' => true,
+ 'kitchen' => true,
+ '移动' => true,
+ 'kim' => true,
+ '삼성' => true,
+ 'monash' => true,
+ 'wed' => true,
+ 'pink' => true,
+ 'ruhr' => true,
+ 'buzz' => true,
+ 'careers' => true,
+ 'shoes' => true,
+ 'موقع' => true,
+ 'career' => true,
+ 'otsuka' => true,
+ '中信' => true,
+ 'gift' => true,
+ 'recipes' => true,
+ 'coffee' => true,
+ 'luxury' => true,
+ 'domains' => true,
+ 'photos' => true,
+ 'limo' => true,
+ 'viajes' => true,
+ 'wang' => true,
+ 'democrat' => true,
+ 'mango' => true,
+ 'cab' => true,
+ 'support' => true,
+ 'dance' => true,
+ 'nagoya' => true,
+ 'computer' => true,
+ 'wien' => true,
+ 'berlin' => true,
+ 'codes' => true,
+ 'email' => true,
+ 'بازار' => true,
+ 'repair' => true,
+ 'holiday' => true,
+ 'center' => true,
+ 'systems' => true,
+ 'wiki' => true,
+ 'ceo' => true,
+ 'international' => true,
+ 'solar' => true,
+ 'company' => true,
+ 'education' => true,
+ 'training' => true,
+ 'academy' => true,
+ 'marketing' => true,
+ 'florist' => true,
+ 'solutions' => true,
+ 'build' => true,
+ 'institute' => true,
+ 'builders' => true,
+ 'red' => true,
+ 'blue' => true,
+ 'ninja' => true,
+ 'business' => true,
+ 'gal' => true,
+ 'social' => true,
+ 'house' => true,
+ 'camp' => true,
+ 'immobilien' => true,
+ 'moda' => true,
+ 'glass' => true,
+ 'management' => true,
+ 'kaufen' => true,
+ 'farm' => true,
+ '公益' => true,
+ '政务' => true,
+ 'club' => true,
+ 'voting' => true,
+ 'TOKYO' => true,
+ 'moe' => true
 );
 ?>
\ No newline at end of file
index b44a20d..d809697 100644 (file)
@@ -90,15 +90,15 @@ class HttpRequest extends \HTTP_Request2 {
                $this->setConfig('store_body', FALSE);
                // Check if we already attached an instance of download. If so, just reuse it.
                foreach ($this->observers as $observer) {
-                       if ($observer instanceof \TYPO3\CMS\Core\Http\Observer\Download) {
-                               /** @var \TYPO3\CMS\Core\Http\Observer\Download $attached */
+                       if ($observer instanceof Observer\Download) {
+                               /** @var Observer\Download $attached */
                                $observer->setDirectory($directory);
                                $observer->setFilename($filename);
                                $isAttached = TRUE;
                        }
                }
                if (!$isAttached) {
-                       /** @var \TYPO3\CMS\Core\Http\Observer\Download $observer */
+                       /** @var Observer\Download $observer */
                        $observer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\Observer\Download::class, $directory, $filename);
                        $this->attach($observer);
                }
index bde0d7d..8f601ed 100644 (file)
@@ -67,7 +67,7 @@ class ExternalLinktype extends \TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktyp
                        'follow_redirects' => TRUE,
                        'strict_redirects' => TRUE
                );
-               /** @var $request \TYPO3\CMS\Core\Http\HttpRequest|\HTTP_Request2 */
+               /** @var $request \TYPO3\CMS\Core\Http\HttpRequest */
                $request = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\HttpRequest::class, $url, 'HEAD', $config);
                // Observe cookies
                $request->setCookieJar(TRUE);