]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - extlib/HTTP/Request2/Adapter/Socket.php
Updating external libraries for net access
[quix0rs-gnu-social.git] / extlib / HTTP / Request2 / Adapter / Socket.php
index 05cc4c715bb6b8f83adc502694d49dd3ae5337ef..fb2940a2ee352a8c46125f1b3eb086f66e7d80c6 100644 (file)
@@ -6,7 +6,7 @@
  *\r
  * LICENSE:\r
  *\r
- * Copyright (c) 2008-2011, Alexey Borzov <avb@php.net>\r
+ * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>\r
  * All rights reserved.\r
  *\r
  * Redistribution and use in source and binary forms, with or without\r
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
  *\r
- * @category   HTTP\r
- * @package    HTTP_Request2\r
- * @author     Alexey Borzov <avb@php.net>\r
- * @license    http://opensource.org/licenses/bsd-license.php New BSD License\r
- * @version    SVN: $Id: Socket.php 309921 2011-04-03 16:43:02Z avb $\r
- * @link       http://pear.php.net/package/HTTP_Request2\r
+ * @category HTTP\r
+ * @package  HTTP_Request2\r
+ * @author   Alexey Borzov <avb@php.net>\r
+ * @license  http://opensource.org/licenses/bsd-license.php New BSD License\r
+ * @version  SVN: $Id: Socket.php 324953 2012-04-08 07:24:12Z avb $\r
+ * @link     http://pear.php.net/package/HTTP_Request2\r
  */\r
 \r
-/**\r
- * Base class for HTTP_Request2 adapters\r
- */\r
+/** Base class for HTTP_Request2 adapters */\r
 require_once 'HTTP/Request2/Adapter.php';\r
 \r
+/** Socket wrapper class */\r
+require_once 'HTTP/Request2/SocketWrapper.php';\r
+\r
 /**\r
  * Socket-based adapter for HTTP_Request2\r
  *\r
  * This adapter uses only PHP sockets and will work on almost any PHP\r
  * environment. Code is based on original HTTP_Request PEAR package.\r
  *\r
- * @category    HTTP\r
- * @package     HTTP_Request2\r
- * @author      Alexey Borzov <avb@php.net>\r
- * @version     Release: 2.0.0RC1\r
+ * @category HTTP\r
+ * @package  HTTP_Request2\r
+ * @author   Alexey Borzov <avb@php.net>\r
+ * @license  http://opensource.org/licenses/bsd-license.php New BSD License\r
+ * @version  Release: 2.1.1\r
+ * @link     http://pear.php.net/package/HTTP_Request2\r
  */\r
 class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter\r
 {\r
-   /**\r
-    * Regular expression for 'token' rule from RFC 2616\r
-    */\r
+    /**\r
+     * Regular expression for 'token' rule from RFC 2616\r
+     */\r
     const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+';\r
 \r
-   /**\r
-    * Regular expression for 'quoted-string' rule from RFC 2616\r
-    */\r
+    /**\r
+     * Regular expression for 'quoted-string' rule from RFC 2616\r
+     */\r
     const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"';\r
 \r
-   /**\r
-    * Connected sockets, needed for Keep-Alive support\r
-    * @var  array\r
-    * @see  connect()\r
-    */\r
+    /**\r
+     * Connected sockets, needed for Keep-Alive support\r
+     * @var  array\r
+     * @see  connect()\r
+     */\r
     protected static $sockets = array();\r
 \r
-   /**\r
-    * Data for digest authentication scheme\r
-    *\r
-    * The keys for the array are URL prefixes.\r
-    *\r
-    * The values are associative arrays with data (realm, nonce, nonce-count,\r
-    * opaque...) needed for digest authentication. Stored here to prevent making\r
-    * duplicate requests to digest-protected resources after we have already\r
-    * received the challenge.\r
-    *\r
-    * @var  array\r
-    */\r
+    /**\r
+     * Data for digest authentication scheme\r
+     *\r
+     * The keys for the array are URL prefixes.\r
+     *\r
+     * The values are associative arrays with data (realm, nonce, nonce-count,\r
+     * opaque...) needed for digest authentication. Stored here to prevent making\r
+     * duplicate requests to digest-protected resources after we have already\r
+     * received the challenge.\r
+     *\r
+     * @var  array\r
+     */\r
     protected static $challenges = array();\r
 \r
-   /**\r
-    * Connected socket\r
-    * @var  resource\r
-    * @see  connect()\r
-    */\r
+    /**\r
+     * Connected socket\r
+     * @var  HTTP_Request2_SocketWrapper\r
+     * @see  connect()\r
+     */\r
     protected $socket;\r
 \r
-   /**\r
-    * Challenge used for server digest authentication\r
-    * @var  array\r
-    */\r
+    /**\r
+     * Challenge used for server digest authentication\r
+     * @var  array\r
+     */\r
     protected $serverChallenge;\r
 \r
-   /**\r
-    * Challenge used for proxy digest authentication\r
-    * @var  array\r
-    */\r
+    /**\r
+     * Challenge used for proxy digest authentication\r
+     * @var  array\r
+     */\r
     protected $proxyChallenge;\r
 \r
-   /**\r
-    * Sum of start time and global timeout, exception will be thrown if request continues past this time\r
-    * @var  integer\r
-    */\r
-    protected $deadline = null;\r
-\r
-   /**\r
-    * Remaining length of the current chunk, when reading chunked response\r
-    * @var  integer\r
-    * @see  readChunked()\r
-    */\r
+    /**\r
+     * Remaining length of the current chunk, when reading chunked response\r
+     * @var  integer\r
+     * @see  readChunked()\r
+     */\r
     protected $chunkLength = 0;\r
 \r
-   /**\r
-    * Remaining amount of redirections to follow\r
-    *\r
-    * Starts at 'max_redirects' configuration parameter and is reduced on each\r
-    * subsequent redirect. An Exception will be thrown once it reaches zero.\r
-    *\r
-    * @var  integer\r
-    */\r
+    /**\r
+     * Remaining amount of redirections to follow\r
+     *\r
+     * Starts at 'max_redirects' configuration parameter and is reduced on each\r
+     * subsequent redirect. An Exception will be thrown once it reaches zero.\r
+     *\r
+     * @var  integer\r
+     */\r
     protected $redirectCountdown = null;\r
 \r
-   /**\r
-    * Sends request to the remote server and returns its response\r
-    *\r
-    * @param    HTTP_Request2\r
-    * @return   HTTP_Request2_Response\r
-    * @throws   HTTP_Request2_Exception\r
-    */\r
+    /**\r
+     * Sends request to the remote server and returns its response\r
+     *\r
+     * @param HTTP_Request2 $request HTTP request message\r
+     *\r
+     * @return   HTTP_Request2_Response\r
+     * @throws   HTTP_Request2_Exception\r
+     */\r
     public function sendRequest(HTTP_Request2 $request)\r
     {\r
         $this->request = $request;\r
 \r
-        // Use global request timeout if given, see feature requests #5735, #8964\r
-        if ($timeout = $request->getConfig('timeout')) {\r
-            $this->deadline = time() + $timeout;\r
-        } else {\r
-            $this->deadline = null;\r
-        }\r
-\r
         try {\r
             $keepAlive = $this->connect();\r
             $headers   = $this->prepareHeaders();\r
-            if (false === @fwrite($this->socket, $headers, strlen($headers))) {\r
-                throw new HTTP_Request2_MessageException('Error writing request');\r
-            }\r
+            $this->socket->write($headers);\r
             // provide request headers to the observer, see request #7633\r
             $this->request->setLastEvent('sentHeaders', $headers);\r
             $this->writeBody();\r
 \r
-            if ($this->deadline && time() > $this->deadline) {\r
-                throw new HTTP_Request2_MessageException(\r
-                    'Request timed out after ' .\r
-                    $request->getConfig('timeout') . ' second(s)',\r
-                    HTTP_Request2_Exception::TIMEOUT\r
-                );\r
-            }\r
-\r
             $response = $this->readResponse();\r
 \r
             if ($jar = $request->getCookieJar()) {\r
@@ -210,12 +191,12 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         }\r
     }\r
 \r
-   /**\r
-    * Connects to the remote server\r
-    *\r
-    * @return   bool    whether the connection can be persistent\r
-    * @throws   HTTP_Request2_Exception\r
-    */\r
+    /**\r
+     * Connects to the remote server\r
+     *\r
+     * @return   bool    whether the connection can be persistent\r
+     * @throws   HTTP_Request2_Exception\r
+     */\r
     protected function connect()\r
     {\r
         $secure  = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https');\r
@@ -226,21 +207,29 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             $reqPort = $secure? 443: 80;\r
         }\r
 \r
-        if ($host = $this->request->getConfig('proxy_host')) {\r
+        $httpProxy = $socksProxy = false;\r
+        if (!($host = $this->request->getConfig('proxy_host'))) {\r
+            $host = $reqHost;\r
+            $port = $reqPort;\r
+        } else {\r
             if (!($port = $this->request->getConfig('proxy_port'))) {\r
                 throw new HTTP_Request2_LogicException(\r
                     'Proxy port not provided',\r
                     HTTP_Request2_Exception::MISSING_VALUE\r
                 );\r
             }\r
-            $proxy = true;\r
-        } else {\r
-            $host  = $reqHost;\r
-            $port  = $reqPort;\r
-            $proxy = false;\r
+            if ('http' == ($type = $this->request->getConfig('proxy_type'))) {\r
+                $httpProxy = true;\r
+            } elseif ('socks5' == $type) {\r
+                $socksProxy = true;\r
+            } else {\r
+                throw new HTTP_Request2_NotImplementedException(\r
+                    "Proxy type '{$type}' is not supported"\r
+                );\r
+            }\r
         }\r
 \r
-        if ($tunnel && !$proxy) {\r
+        if ($tunnel && !$httpProxy) {\r
             throw new HTTP_Request2_LogicException(\r
                 "Trying to perform CONNECT request without proxy",\r
                 HTTP_Request2_Exception::MISSING_VALUE\r
@@ -255,8 +244,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
 \r
         // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive\r
         // connection token to a proxy server...\r
-        if ($proxy && !$secure &&\r
-            !empty($headers['connection']) && 'Keep-Alive' == $headers['connection']\r
+        if ($httpProxy && !$secure && !empty($headers['connection'])\r
+            && 'Keep-Alive' == $headers['connection']\r
         ) {\r
             $this->request->setHeader('connection');\r
         }\r
@@ -265,7 +254,6 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
                       empty($headers['connection'])) ||\r
                      (!empty($headers['connection']) &&\r
                       'Keep-Alive' == $headers['connection']);\r
-        $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host;\r
 \r
         $options = array();\r
         if ($secure || $tunnel) {\r
@@ -283,76 +271,81 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             ksort($options);\r
         }\r
 \r
+        // Use global request timeout if given, see feature requests #5735, #8964\r
+        if ($timeout = $this->request->getConfig('timeout')) {\r
+            $deadline = time() + $timeout;\r
+        } else {\r
+            $deadline = null;\r
+        }\r
+\r
         // Changing SSL context options after connection is established does *not*\r
         // work, we need a new connection if options change\r
-        $remote    = $host . ':' . $port;\r
-        $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') .\r
-                     (empty($options)? '': ':' . serialize($options));\r
+        $remote    = ((!$secure || $httpProxy || $socksProxy)? 'tcp://': 'ssl://')\r
+                     . $host . ':' . $port;\r
+        $socketKey = $remote . (\r
+                        ($secure && $httpProxy || $socksProxy)\r
+                        ? "->{$reqHost}:{$reqPort}" : ''\r
+                     ) . (empty($options)? '': ':' . serialize($options));\r
         unset($this->socket);\r
 \r
         // We use persistent connections and have a connected socket?\r
         // Ensure that the socket is still connected, see bug #16149\r
-        if ($keepAlive && !empty(self::$sockets[$socketKey]) &&\r
-            !feof(self::$sockets[$socketKey])\r
+        if ($keepAlive && !empty(self::$sockets[$socketKey])\r
+            && !self::$sockets[$socketKey]->eof()\r
         ) {\r
             $this->socket =& self::$sockets[$socketKey];\r
 \r
-        } elseif ($secure && $proxy && !$tunnel) {\r
-            $this->establishTunnel();\r
-            $this->request->setLastEvent(\r
-                'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}"\r
-            );\r
-            self::$sockets[$socketKey] =& $this->socket;\r
-\r
         } else {\r
-            // Set SSL context options if doing HTTPS request or creating a tunnel\r
-            $context = stream_context_create();\r
-            foreach ($options as $name => $value) {\r
-                if (!stream_context_set_option($context, 'ssl', $name, $value)) {\r
-                    throw new HTTP_Request2_LogicException(\r
-                        "Error setting SSL context option '{$name}'"\r
-                    );\r
+            if ($socksProxy) {\r
+                require_once 'HTTP/Request2/SOCKS5.php';\r
+\r
+                $this->socket = new HTTP_Request2_SOCKS5(\r
+                    $remote, $this->request->getConfig('connect_timeout'),\r
+                    $options, $this->request->getConfig('proxy_user'),\r
+                    $this->request->getConfig('proxy_password')\r
+                );\r
+                // handle request timeouts ASAP\r
+                $this->socket->setDeadline($deadline, $this->request->getConfig('timeout'));\r
+                $this->socket->connect($reqHost, $reqPort);\r
+                if (!$secure) {\r
+                    $conninfo = "tcp://{$reqHost}:{$reqPort} via {$remote}";\r
+                } else {\r
+                    $this->socket->enableCrypto();\r
+                    $conninfo = "ssl://{$reqHost}:{$reqPort} via {$remote}";\r
                 }\r
-            }\r
-            $track = @ini_set('track_errors', 1);\r
-            $this->socket = @stream_socket_client(\r
-                $remote, $errno, $errstr,\r
-                $this->request->getConfig('connect_timeout'),\r
-                STREAM_CLIENT_CONNECT, $context\r
-            );\r
-            if (!$this->socket) {\r
-                $e = new HTTP_Request2_ConnectionException(\r
-                    "Unable to connect to {$remote}. Error: "\r
-                     . (empty($errstr)? $php_errormsg: $errstr), 0, $errno\r
+\r
+            } elseif ($secure && $httpProxy && !$tunnel) {\r
+                $this->establishTunnel();\r
+                $conninfo = "ssl://{$reqHost}:{$reqPort} via {$remote}";\r
+\r
+            } else {\r
+                $this->socket = new HTTP_Request2_SocketWrapper(\r
+                    $remote, $this->request->getConfig('connect_timeout'), $options\r
                 );\r
             }\r
-            @ini_set('track_errors', $track);\r
-            if (isset($e)) {\r
-                throw $e;\r
-            }\r
-            $this->request->setLastEvent('connect', $remote);\r
+            $this->request->setLastEvent('connect', empty($conninfo)? $remote: $conninfo);\r
             self::$sockets[$socketKey] =& $this->socket;\r
         }\r
+        $this->socket->setDeadline($deadline, $this->request->getConfig('timeout'));\r
         return $keepAlive;\r
     }\r
 \r
-   /**\r
-    * Establishes a tunnel to a secure remote server via HTTP CONNECT request\r
-    *\r
-    * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP\r
-    * sees that we are connected to a proxy server (duh!) rather than the server\r
-    * that presents its certificate.\r
-    *\r
-    * @link     http://tools.ietf.org/html/rfc2817#section-5.2\r
-    * @throws   HTTP_Request2_Exception\r
-    */\r
+    /**\r
+     * Establishes a tunnel to a secure remote server via HTTP CONNECT request\r
+     *\r
+     * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP\r
+     * sees that we are connected to a proxy server (duh!) rather than the server\r
+     * that presents its certificate.\r
+     *\r
+     * @link     http://tools.ietf.org/html/rfc2817#section-5.2\r
+     * @throws   HTTP_Request2_Exception\r
+     */\r
     protected function establishTunnel()\r
     {\r
         $donor   = new self;\r
         $connect = new HTTP_Request2(\r
             $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT,\r
-            array_merge($this->request->getConfig(),\r
-                        array('adapter' => $donor))\r
+            array_merge($this->request->getConfig(), array('adapter' => $donor))\r
         );\r
         $response = $connect->send();\r
         // Need any successful (2XX) response\r
@@ -363,37 +356,23 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             );\r
         }\r
         $this->socket = $donor->socket;\r
-\r
-        $modes = array(\r
-            STREAM_CRYPTO_METHOD_TLS_CLIENT,\r
-            STREAM_CRYPTO_METHOD_SSLv3_CLIENT,\r
-            STREAM_CRYPTO_METHOD_SSLv23_CLIENT,\r
-            STREAM_CRYPTO_METHOD_SSLv2_CLIENT\r
-        );\r
-\r
-        foreach ($modes as $mode) {\r
-            if (stream_socket_enable_crypto($this->socket, true, $mode)) {\r
-                return;\r
-            }\r
-        }\r
-        throw new HTTP_Request2_ConnectionException(\r
-            'Failed to enable secure connection when connecting through proxy'\r
-        );\r
+        $this->socket->enableCrypto();\r
     }\r
 \r
-   /**\r
-    * Checks whether current connection may be reused or should be closed\r
-    *\r
-    * @param    boolean                 whether connection could be persistent\r
-    *                                   in the first place\r
-    * @param    HTTP_Request2_Response  response object to check\r
-    * @return   boolean\r
-    */\r
+    /**\r
+     * Checks whether current connection may be reused or should be closed\r
+     *\r
+     * @param boolean                $requestKeepAlive whether connection could\r
+     *                               be persistent in the first place\r
+     * @param HTTP_Request2_Response $response         response object to check\r
+     *\r
+     * @return   boolean\r
+     */\r
     protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response)\r
     {\r
         // Do not close socket on successful CONNECT request\r
-        if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&\r
-            200 <= $response->getStatus() && 300 > $response->getStatus()\r
+        if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod()\r
+            && 200 <= $response->getStatus() && 300 > $response->getStatus()\r
         ) {\r
             return true;\r
         }\r
@@ -409,40 +388,40 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $requestKeepAlive && $lengthKnown && $persistent;\r
     }\r
 \r
-   /**\r
-    * Disconnects from the remote server\r
-    */\r
+    /**\r
+     * Disconnects from the remote server\r
+     */\r
     protected function disconnect()\r
     {\r
-        if (is_resource($this->socket)) {\r
-            fclose($this->socket);\r
+        if (!empty($this->socket)) {\r
             $this->socket = null;\r
             $this->request->setLastEvent('disconnect');\r
         }\r
     }\r
 \r
-   /**\r
-    * Handles HTTP redirection\r
-    *\r
-    * This method will throw an Exception if redirect to a non-HTTP(S) location\r
-    * is attempted, also if number of redirects performed already is equal to\r
-    * 'max_redirects' configuration parameter.\r
-    *\r
-    * @param    HTTP_Request2               Original request\r
-    * @param    HTTP_Request2_Response      Response containing redirect\r
-    * @return   HTTP_Request2_Response      Response from a new location\r
-    * @throws   HTTP_Request2_Exception\r
-    */\r
-    protected function handleRedirect(HTTP_Request2 $request,\r
-                                      HTTP_Request2_Response $response)\r
-    {\r
+    /**\r
+     * Handles HTTP redirection\r
+     *\r
+     * This method will throw an Exception if redirect to a non-HTTP(S) location\r
+     * is attempted, also if number of redirects performed already is equal to\r
+     * 'max_redirects' configuration parameter.\r
+     *\r
+     * @param HTTP_Request2          $request  Original request\r
+     * @param HTTP_Request2_Response $response Response containing redirect\r
+     *\r
+     * @return   HTTP_Request2_Response      Response from a new location\r
+     * @throws   HTTP_Request2_Exception\r
+     */\r
+    protected function handleRedirect(\r
+        HTTP_Request2 $request, HTTP_Request2_Response $response\r
+    ) {\r
         if (is_null($this->redirectCountdown)) {\r
             $this->redirectCountdown = $request->getConfig('max_redirects');\r
         }\r
         if (0 == $this->redirectCountdown) {\r
             $this->redirectCountdown = null;\r
             // Copying cURL behaviour\r
-            throw new HTTP_Request2_MessageException (\r
+            throw new HTTP_Request2_MessageException(\r
                 'Maximum (' . $request->getConfig('max_redirects') . ') redirects followed',\r
                 HTTP_Request2_Exception::TOO_MANY_REDIRECTS\r
             );\r
@@ -468,8 +447,9 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         }\r
         $redirect = clone $request;\r
         $redirect->setUrl($redirectUrl);\r
-        if (303 == $response->getStatus() || (!$request->getConfig('strict_redirects')\r
-             && in_array($response->getStatus(), array(301, 302)))\r
+        if (303 == $response->getStatus()\r
+            || (!$request->getConfig('strict_redirects')\r
+                && in_array($response->getStatus(), array(301, 302)))\r
         ) {\r
             $redirect->setMethod(HTTP_Request2::METHOD_GET);\r
             $redirect->setBody('');\r
@@ -481,23 +461,24 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $this->sendRequest($redirect);\r
     }\r
 \r
-   /**\r
-    * Checks whether another request should be performed with server digest auth\r
-    *\r
-    * Several conditions should be satisfied for it to return true:\r
-    *   - response status should be 401\r
-    *   - auth credentials should be set in the request object\r
-    *   - response should contain WWW-Authenticate header with digest challenge\r
-    *   - there is either no challenge stored for this URL or new challenge\r
-    *     contains stale=true parameter (in other case we probably just failed\r
-    *     due to invalid username / password)\r
-    *\r
-    * The method stores challenge values in $challenges static property\r
-    *\r
-    * @param    HTTP_Request2_Response  response to check\r
-    * @return   boolean whether another request should be performed\r
-    * @throws   HTTP_Request2_Exception in case of unsupported challenge parameters\r
-    */\r
+    /**\r
+     * Checks whether another request should be performed with server digest auth\r
+     *\r
+     * Several conditions should be satisfied for it to return true:\r
+     *   - response status should be 401\r
+     *   - auth credentials should be set in the request object\r
+     *   - response should contain WWW-Authenticate header with digest challenge\r
+     *   - there is either no challenge stored for this URL or new challenge\r
+     *     contains stale=true parameter (in other case we probably just failed\r
+     *     due to invalid username / password)\r
+     *\r
+     * The method stores challenge values in $challenges static property\r
+     *\r
+     * @param HTTP_Request2_Response $response response to check\r
+     *\r
+     * @return   boolean whether another request should be performed\r
+     * @throws   HTTP_Request2_Exception in case of unsupported challenge parameters\r
+     */\r
     protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)\r
     {\r
         // no sense repeating a request if we don't have credentials\r
@@ -512,8 +493,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         $scheme = $url->getScheme();\r
         $host   = $scheme . '://' . $url->getHost();\r
         if ($port = $url->getPort()) {\r
-            if ((0 == strcasecmp($scheme, 'http') && 80 != $port) ||\r
-                (0 == strcasecmp($scheme, 'https') && 443 != $port)\r
+            if ((0 == strcasecmp($scheme, 'http') && 80 != $port)\r
+                || (0 == strcasecmp($scheme, 'https') && 443 != $port)\r
             ) {\r
                 $host .= ':' . $port;\r
             }\r
@@ -534,8 +515,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
 \r
         $ret = true;\r
         foreach ($prefixes as $prefix) {\r
-            if (!empty(self::$challenges[$prefix]) &&\r
-                (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))\r
+            if (!empty(self::$challenges[$prefix])\r
+                && (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))\r
             ) {\r
                 // probably credentials are invalid\r
                 $ret = false;\r
@@ -545,23 +526,24 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $ret;\r
     }\r
 \r
-   /**\r
-    * Checks whether another request should be performed with proxy digest auth\r
-    *\r
-    * Several conditions should be satisfied for it to return true:\r
-    *   - response status should be 407\r
-    *   - proxy auth credentials should be set in the request object\r
-    *   - response should contain Proxy-Authenticate header with digest challenge\r
-    *   - there is either no challenge stored for this proxy or new challenge\r
-    *     contains stale=true parameter (in other case we probably just failed\r
-    *     due to invalid username / password)\r
-    *\r
-    * The method stores challenge values in $challenges static property\r
-    *\r
-    * @param    HTTP_Request2_Response  response to check\r
-    * @return   boolean whether another request should be performed\r
-    * @throws   HTTP_Request2_Exception in case of unsupported challenge parameters\r
-    */\r
+    /**\r
+     * Checks whether another request should be performed with proxy digest auth\r
+     *\r
+     * Several conditions should be satisfied for it to return true:\r
+     *   - response status should be 407\r
+     *   - proxy auth credentials should be set in the request object\r
+     *   - response should contain Proxy-Authenticate header with digest challenge\r
+     *   - there is either no challenge stored for this proxy or new challenge\r
+     *     contains stale=true parameter (in other case we probably just failed\r
+     *     due to invalid username / password)\r
+     *\r
+     * The method stores challenge values in $challenges static property\r
+     *\r
+     * @param HTTP_Request2_Response $response response to check\r
+     *\r
+     * @return   boolean whether another request should be performed\r
+     * @throws   HTTP_Request2_Exception in case of unsupported challenge parameters\r
+     */\r
     protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response)\r
     {\r
         if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) {\r
@@ -574,8 +556,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         $key = 'proxy://' . $this->request->getConfig('proxy_host') .\r
                ':' . $this->request->getConfig('proxy_port');\r
 \r
-        if (!empty(self::$challenges[$key]) &&\r
-            (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))\r
+        if (!empty(self::$challenges[$key])\r
+            && (empty($challenge['stale']) || strcasecmp('true', $challenge['stale']))\r
         ) {\r
             $ret = false;\r
         } else {\r
@@ -585,34 +567,35 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $ret;\r
     }\r
 \r
-   /**\r
-    * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value\r
-    *\r
-    * There is a problem with implementation of RFC 2617: several of the parameters\r
-    * are defined as quoted-string there and thus may contain backslash escaped\r
-    * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as\r
-    * just value of quoted-string X without surrounding quotes, it doesn't speak\r
-    * about removing backslash escaping.\r
-    *\r
-    * Now realm parameter is user-defined and human-readable, strange things\r
-    * happen when it contains quotes:\r
-    *   - Apache allows quotes in realm, but apparently uses realm value without\r
-    *     backslashes for digest computation\r
-    *   - Squid allows (manually escaped) quotes there, but it is impossible to\r
-    *     authorize with either escaped or unescaped quotes used in digest,\r
-    *     probably it can't parse the response (?)\r
-    *   - Both IE and Firefox display realm value with backslashes in\r
-    *     the password popup and apparently use the same value for digest\r
-    *\r
-    * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in\r
-    * quoted-string handling, unfortunately that means failure to authorize\r
-    * sometimes\r
-    *\r
-    * @param    string  value of WWW-Authenticate or Proxy-Authenticate header\r
-    * @return   mixed   associative array with challenge parameters, false if\r
-    *                   no challenge is present in header value\r
-    * @throws   HTTP_Request2_NotImplementedException in case of unsupported challenge parameters\r
-    */\r
+    /**\r
+     * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value\r
+     *\r
+     * There is a problem with implementation of RFC 2617: several of the parameters\r
+     * are defined as quoted-string there and thus may contain backslash escaped\r
+     * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as\r
+     * just value of quoted-string X without surrounding quotes, it doesn't speak\r
+     * about removing backslash escaping.\r
+     *\r
+     * Now realm parameter is user-defined and human-readable, strange things\r
+     * happen when it contains quotes:\r
+     *   - Apache allows quotes in realm, but apparently uses realm value without\r
+     *     backslashes for digest computation\r
+     *   - Squid allows (manually escaped) quotes there, but it is impossible to\r
+     *     authorize with either escaped or unescaped quotes used in digest,\r
+     *     probably it can't parse the response (?)\r
+     *   - Both IE and Firefox display realm value with backslashes in\r
+     *     the password popup and apparently use the same value for digest\r
+     *\r
+     * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in\r
+     * quoted-string handling, unfortunately that means failure to authorize\r
+     * sometimes\r
+     *\r
+     * @param string $headerValue value of WWW-Authenticate or Proxy-Authenticate header\r
+     *\r
+     * @return   mixed   associative array with challenge parameters, false if\r
+     *                   no challenge is present in header value\r
+     * @throws   HTTP_Request2_NotImplementedException in case of unsupported challenge parameters\r
+     */\r
     protected function parseDigestChallenge($headerValue)\r
     {\r
         $authParam   = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .\r
@@ -637,8 +620,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             }\r
         }\r
         // we only support qop=auth\r
-        if (!empty($paramsAry['qop']) &&\r
-            !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))\r
+        if (!empty($paramsAry['qop'])\r
+            && !in_array('auth', array_map('trim', explode(',', $paramsAry['qop'])))\r
         ) {\r
             throw new HTTP_Request2_NotImplementedException(\r
                 "Only 'auth' qop is currently supported in digest authentication, " .\r
@@ -656,13 +639,14 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $paramsAry;\r
     }\r
 \r
-   /**\r
-    * Parses [Proxy-]Authentication-Info header value and updates challenge\r
-    *\r
-    * @param    array   challenge to update\r
-    * @param    string  value of [Proxy-]Authentication-Info header\r
-    * @todo     validate server rspauth response\r
-    */\r
+    /**\r
+     * Parses [Proxy-]Authentication-Info header value and updates challenge\r
+     *\r
+     * @param array  &$challenge  challenge to update\r
+     * @param string $headerValue value of [Proxy-]Authentication-Info header\r
+     *\r
+     * @todo     validate server rspauth response\r
+     */\r
     protected function updateChallenge(&$challenge, $headerValue)\r
     {\r
         $authParam   = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' .\r
@@ -684,20 +668,21 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         }\r
     }\r
 \r
-   /**\r
-    * Creates a value for [Proxy-]Authorization header when using digest authentication\r
-    *\r
-    * @param    string  user name\r
-    * @param    string  password\r
-    * @param    string  request URL\r
-    * @param    array   digest challenge parameters\r
-    * @return   string  value of [Proxy-]Authorization request header\r
-    * @link     http://tools.ietf.org/html/rfc2617#section-3.2.2\r
-    */\r
+    /**\r
+     * Creates a value for [Proxy-]Authorization header when using digest authentication\r
+     *\r
+     * @param string $user       user name\r
+     * @param string $password   password\r
+     * @param string $url        request URL\r
+     * @param array  &$challenge digest challenge parameters\r
+     *\r
+     * @return   string  value of [Proxy-]Authorization request header\r
+     * @link     http://tools.ietf.org/html/rfc2617#section-3.2.2\r
+     */\r
     protected function createDigestResponse($user, $password, $url, &$challenge)\r
     {\r
-        if (false !== ($q = strpos($url, '?')) &&\r
-            $this->request->getConfig('digest_compat_ie')\r
+        if (false !== ($q = strpos($url, '?'))\r
+            && $this->request->getConfig('digest_compat_ie')\r
         ) {\r
             $url = substr($url, 0, $q);\r
         }\r
@@ -713,8 +698,10 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
                 $challenge['nc'] = 1;\r
             }\r
             $nc     = sprintf('%08x', $challenge['nc']++);\r
-            $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .\r
-                          $challenge['cnonce'] . ':auth:' . $a2);\r
+            $digest = md5(\r
+                $a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .\r
+                $challenge['cnonce'] . ':auth:' . $a2\r
+            );\r
         }\r
         return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' .\r
                'realm="' . $challenge['realm'] . '", ' .\r
@@ -729,102 +716,106 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
                 '');\r
     }\r
 \r
-   /**\r
-    * Adds 'Authorization' header (if needed) to request headers array\r
-    *\r
-    * @param    array   request headers\r
-    * @param    string  request host (needed for digest authentication)\r
-    * @param    string  request URL (needed for digest authentication)\r
-    * @throws   HTTP_Request2_NotImplementedException\r
-    */\r
+    /**\r
+     * Adds 'Authorization' header (if needed) to request headers array\r
+     *\r
+     * @param array  &$headers    request headers\r
+     * @param string $requestHost request host (needed for digest authentication)\r
+     * @param string $requestUrl  request URL (needed for digest authentication)\r
+     *\r
+     * @throws   HTTP_Request2_NotImplementedException\r
+     */\r
     protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)\r
     {\r
         if (!($auth = $this->request->getAuth())) {\r
             return;\r
         }\r
         switch ($auth['scheme']) {\r
-            case HTTP_Request2::AUTH_BASIC:\r
-                $headers['authorization'] =\r
-                    'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']);\r
-                break;\r
-\r
-            case HTTP_Request2::AUTH_DIGEST:\r
-                unset($this->serverChallenge);\r
-                $fullUrl = ('/' == $requestUrl[0])?\r
-                           $this->request->getUrl()->getScheme() . '://' .\r
-                            $requestHost . $requestUrl:\r
-                           $requestUrl;\r
-                foreach (array_keys(self::$challenges) as $key) {\r
-                    if ($key == substr($fullUrl, 0, strlen($key))) {\r
-                        $headers['authorization'] = $this->createDigestResponse(\r
-                            $auth['user'], $auth['password'],\r
-                            $requestUrl, self::$challenges[$key]\r
-                        );\r
-                        $this->serverChallenge =& self::$challenges[$key];\r
-                        break;\r
-                    }\r
+        case HTTP_Request2::AUTH_BASIC:\r
+            $headers['authorization'] = 'Basic ' . base64_encode(\r
+                $auth['user'] . ':' . $auth['password']\r
+            );\r
+            break;\r
+\r
+        case HTTP_Request2::AUTH_DIGEST:\r
+            unset($this->serverChallenge);\r
+            $fullUrl = ('/' == $requestUrl[0])?\r
+                       $this->request->getUrl()->getScheme() . '://' .\r
+                        $requestHost . $requestUrl:\r
+                       $requestUrl;\r
+            foreach (array_keys(self::$challenges) as $key) {\r
+                if ($key == substr($fullUrl, 0, strlen($key))) {\r
+                    $headers['authorization'] = $this->createDigestResponse(\r
+                        $auth['user'], $auth['password'],\r
+                        $requestUrl, self::$challenges[$key]\r
+                    );\r
+                    $this->serverChallenge =& self::$challenges[$key];\r
+                    break;\r
                 }\r
-                break;\r
+            }\r
+            break;\r
 \r
-            default:\r
-                throw new HTTP_Request2_NotImplementedException(\r
-                    "Unknown HTTP authentication scheme '{$auth['scheme']}'"\r
-                );\r
+        default:\r
+            throw new HTTP_Request2_NotImplementedException(\r
+                "Unknown HTTP authentication scheme '{$auth['scheme']}'"\r
+            );\r
         }\r
     }\r
 \r
-   /**\r
-    * Adds 'Proxy-Authorization' header (if needed) to request headers array\r
-    *\r
-    * @param    array   request headers\r
-    * @param    string  request URL (needed for digest authentication)\r
-    * @throws   HTTP_Request2_NotImplementedException\r
-    */\r
+    /**\r
+     * Adds 'Proxy-Authorization' header (if needed) to request headers array\r
+     *\r
+     * @param array  &$headers   request headers\r
+     * @param string $requestUrl request URL (needed for digest authentication)\r
+     *\r
+     * @throws   HTTP_Request2_NotImplementedException\r
+     */\r
     protected function addProxyAuthorizationHeader(&$headers, $requestUrl)\r
     {\r
-        if (!$this->request->getConfig('proxy_host') ||\r
-            !($user = $this->request->getConfig('proxy_user')) ||\r
-            (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) &&\r
-             HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())\r
+        if (!$this->request->getConfig('proxy_host')\r
+            || !($user = $this->request->getConfig('proxy_user'))\r
+            || (0 == strcasecmp('https', $this->request->getUrl()->getScheme())\r
+                && HTTP_Request2::METHOD_CONNECT != $this->request->getMethod())\r
         ) {\r
             return;\r
         }\r
 \r
         $password = $this->request->getConfig('proxy_password');\r
         switch ($this->request->getConfig('proxy_auth_scheme')) {\r
-            case HTTP_Request2::AUTH_BASIC:\r
-                $headers['proxy-authorization'] =\r
-                    'Basic ' . base64_encode($user . ':' . $password);\r
-                break;\r
-\r
-            case HTTP_Request2::AUTH_DIGEST:\r
-                unset($this->proxyChallenge);\r
-                $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .\r
-                            ':' . $this->request->getConfig('proxy_port');\r
-                if (!empty(self::$challenges[$proxyUrl])) {\r
-                    $headers['proxy-authorization'] = $this->createDigestResponse(\r
-                        $user, $password,\r
-                        $requestUrl, self::$challenges[$proxyUrl]\r
-                    );\r
-                    $this->proxyChallenge =& self::$challenges[$proxyUrl];\r
-                }\r
-                break;\r
-\r
-            default:\r
-                throw new HTTP_Request2_NotImplementedException(\r
-                    "Unknown HTTP authentication scheme '" .\r
-                    $this->request->getConfig('proxy_auth_scheme') . "'"\r
+        case HTTP_Request2::AUTH_BASIC:\r
+            $headers['proxy-authorization'] = 'Basic ' . base64_encode(\r
+                $user . ':' . $password\r
+            );\r
+            break;\r
+\r
+        case HTTP_Request2::AUTH_DIGEST:\r
+            unset($this->proxyChallenge);\r
+            $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') .\r
+                        ':' . $this->request->getConfig('proxy_port');\r
+            if (!empty(self::$challenges[$proxyUrl])) {\r
+                $headers['proxy-authorization'] = $this->createDigestResponse(\r
+                    $user, $password,\r
+                    $requestUrl, self::$challenges[$proxyUrl]\r
                 );\r
+                $this->proxyChallenge =& self::$challenges[$proxyUrl];\r
+            }\r
+            break;\r
+\r
+        default:\r
+            throw new HTTP_Request2_NotImplementedException(\r
+                "Unknown HTTP authentication scheme '" .\r
+                $this->request->getConfig('proxy_auth_scheme') . "'"\r
+            );\r
         }\r
     }\r
 \r
 \r
-   /**\r
-    * Creates the string with the Request-Line and request headers\r
-    *\r
-    * @return   string\r
-    * @throws   HTTP_Request2_Exception\r
-    */\r
+    /**\r
+     * Creates the string with the Request-Line and request headers\r
+     *\r
+     * @return   string\r
+     * @throws   HTTP_Request2_Exception\r
+     */\r
     protected function prepareHeaders()\r
     {\r
         $headers = $this->request->getHeaders();\r
@@ -845,8 +836,9 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             $requestUrl = $host;\r
 \r
         } else {\r
-            if (!$this->request->getConfig('proxy_host') ||\r
-                0 == strcasecmp($url->getScheme(), 'https')\r
+            if (!$this->request->getConfig('proxy_host')\r
+                || 'http' != $this->request->getConfig('proxy_type')\r
+                || 0 == strcasecmp($url->getScheme(), 'https')\r
             ) {\r
                 $requestUrl = '';\r
             } else {\r
@@ -857,8 +849,8 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);\r
         }\r
 \r
-        if ('1.1' == $this->request->getConfig('protocol_version') &&\r
-            extension_loaded('zlib') && !isset($headers['accept-encoding'])\r
+        if ('1.1' == $this->request->getConfig('protocol_version')\r
+            && extension_loaded('zlib') && !isset($headers['accept-encoding'])\r
         ) {\r
             $headers['accept-encoding'] = 'gzip, deflate';\r
         }\r
@@ -881,15 +873,15 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $headersStr . "\r\n";\r
     }\r
 \r
-   /**\r
-    * Sends the request body\r
-    *\r
-    * @throws   HTTP_Request2_MessageException\r
-    */\r
+    /**\r
+     * Sends the request body\r
+     *\r
+     * @throws   HTTP_Request2_MessageException\r
+     */\r
     protected function writeBody()\r
     {\r
-        if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||\r
-            0 == $this->contentLength\r
+        if (in_array($this->request->getMethod(), self::$bodyDisallowed)\r
+            || 0 == $this->contentLength\r
         ) {\r
             return;\r
         }\r
@@ -904,9 +896,7 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             } else {\r
                 $str = $this->requestBody->read($bufferSize);\r
             }\r
-            if (false === @fwrite($this->socket, $str, strlen($str))) {\r
-                throw new HTTP_Request2_MessageException('Error writing request');\r
-            }\r
+            $this->socket->write($str);\r
             // Provide the length of written string to the observer, request #7630\r
             $this->request->setLastEvent('sentBodyPart', strlen($str));\r
             $position += strlen($str);\r
@@ -914,22 +904,22 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         $this->request->setLastEvent('sentBody', $this->contentLength);\r
     }\r
 \r
-   /**\r
-    * Reads the remote server's response\r
-    *\r
-    * @return   HTTP_Request2_Response\r
-    * @throws   HTTP_Request2_Exception\r
-    */\r
+    /**\r
+     * Reads the remote server's response\r
+     *\r
+     * @return   HTTP_Request2_Response\r
+     * @throws   HTTP_Request2_Exception\r
+     */\r
     protected function readResponse()\r
     {\r
         $bufferSize = $this->request->getConfig('buffer_size');\r
 \r
         do {\r
             $response = new HTTP_Request2_Response(\r
-                $this->readLine($bufferSize), true, $this->request->getUrl()\r
+                $this->socket->readLine($bufferSize), true, $this->request->getUrl()\r
             );\r
             do {\r
-                $headerLine = $this->readLine($bufferSize);\r
+                $headerLine = $this->socket->readLine($bufferSize);\r
                 $response->parseHeaderLine($headerLine);\r
             } while ('' != $headerLine);\r
         } while (in_array($response->getStatus(), array(100, 101)));\r
@@ -937,10 +927,10 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         $this->request->setLastEvent('receivedHeaders', $response);\r
 \r
         // No body possible in such responses\r
-        if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() ||\r
-            (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() &&\r
-             200 <= $response->getStatus() && 300 > $response->getStatus()) ||\r
-            in_array($response->getStatus(), array(204, 304))\r
+        if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod()\r
+            || (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod()\r
+                && 200 <= $response->getStatus() && 300 > $response->getStatus())\r
+            || in_array($response->getStatus(), array(204, 304))\r
         ) {\r
             return $response;\r
         }\r
@@ -956,16 +946,16 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
             $toRead = ($chunked || null === $length)? null: $length;\r
             $this->chunkLength = 0;\r
 \r
-            while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) {\r
+            while (!$this->socket->eof() && (is_null($toRead) || 0 < $toRead)) {\r
                 if ($chunked) {\r
                     $data = $this->readChunked($bufferSize);\r
                 } elseif (is_null($toRead)) {\r
-                    $data = $this->fread($bufferSize);\r
+                    $data = $this->socket->read($bufferSize);\r
                 } else {\r
-                    $data    = $this->fread(min($toRead, $bufferSize));\r
+                    $data    = $this->socket->read(min($toRead, $bufferSize));\r
                     $toRead -= strlen($data);\r
                 }\r
-                if ('' == $data && (!$this->chunkLength || feof($this->socket))) {\r
+                if ('' == $data && (!$this->chunkLength || $this->socket->eof())) {\r
                     break;\r
                 }\r
 \r
@@ -987,77 +977,19 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
         return $response;\r
     }\r
 \r
-   /**\r
-    * Reads until either the end of the socket or a newline, whichever comes first\r
-    *\r
-    * Strips the trailing newline from the returned data, handles global\r
-    * request timeout. Method idea borrowed from Net_Socket PEAR package.\r
-    *\r
-    * @param    int     buffer size to use for reading\r
-    * @return   Available data up to the newline (not including newline)\r
-    * @throws   HTTP_Request2_MessageException     In case of timeout\r
-    */\r
-    protected function readLine($bufferSize)\r
-    {\r
-        $line = '';\r
-        while (!feof($this->socket)) {\r
-            if ($this->deadline) {\r
-                stream_set_timeout($this->socket, max($this->deadline - time(), 1));\r
-            }\r
-            $line .= @fgets($this->socket, $bufferSize);\r
-            $info  = stream_get_meta_data($this->socket);\r
-            if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {\r
-                $reason = $this->deadline\r
-                          ? 'after ' . $this->request->getConfig('timeout') . ' second(s)'\r
-                          : 'due to default_socket_timeout php.ini setting';\r
-                throw new HTTP_Request2_MessageException(\r
-                    "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT\r
-                );\r
-            }\r
-            if (substr($line, -1) == "\n") {\r
-                return rtrim($line, "\r\n");\r
-            }\r
-        }\r
-        return $line;\r
-    }\r
-\r
-   /**\r
-    * Wrapper around fread(), handles global request timeout\r
-    *\r
-    * @param    int     Reads up to this number of bytes\r
-    * @return   Data read from socket\r
-    * @throws   HTTP_Request2_MessageException     In case of timeout\r
-    */\r
-    protected function fread($length)\r
-    {\r
-        if ($this->deadline) {\r
-            stream_set_timeout($this->socket, max($this->deadline - time(), 1));\r
-        }\r
-        $data = fread($this->socket, $length);\r
-        $info = stream_get_meta_data($this->socket);\r
-        if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {\r
-            $reason = $this->deadline\r
-                      ? 'after ' . $this->request->getConfig('timeout') . ' second(s)'\r
-                      : 'due to default_socket_timeout php.ini setting';\r
-            throw new HTTP_Request2_MessageException(\r
-                "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT\r
-            );\r
-        }\r
-        return $data;\r
-    }\r
-\r
-   /**\r
-    * Reads a part of response body encoded with chunked Transfer-Encoding\r
-    *\r
-    * @param    int     buffer size to use for reading\r
-    * @return   string\r
-    * @throws   HTTP_Request2_MessageException\r
-    */\r
+    /**\r
+     * Reads a part of response body encoded with chunked Transfer-Encoding\r
+     *\r
+     * @param int $bufferSize buffer size to use for reading\r
+     *\r
+     * @return   string\r
+     * @throws   HTTP_Request2_MessageException\r
+     */\r
     protected function readChunked($bufferSize)\r
     {\r
         // at start of the next chunk?\r
         if (0 == $this->chunkLength) {\r
-            $line = $this->readLine($bufferSize);\r
+            $line = $this->socket->readLine($bufferSize);\r
             if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) {\r
                 throw new HTTP_Request2_MessageException(\r
                     "Cannot decode chunked response, invalid chunk length '{$line}'",\r
@@ -1067,15 +999,15 @@ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter
                 $this->chunkLength = hexdec($matches[1]);\r
                 // Chunk with zero length indicates the end\r
                 if (0 == $this->chunkLength) {\r
-                    $this->readLine($bufferSize);\r
+                    $this->socket->readLine($bufferSize);\r
                     return '';\r
                 }\r
             }\r
         }\r
-        $data = $this->fread(min($this->chunkLength, $bufferSize));\r
+        $data = $this->socket->read(min($this->chunkLength, $bufferSize));\r
         $this->chunkLength -= strlen($data);\r
         if (0 == $this->chunkLength) {\r
-            $this->readLine($bufferSize); // Trailing CRLF\r
+            $this->socket->readLine($bufferSize); // Trailing CRLF\r
         }\r
         return $data;\r
     }\r