/**
  * Send a HTTP request to a URI using fsockopen().
  *
  * Does not support non-blocking mode.
  *
  * @param string $url  URI resource.
  * @param array  $r    Optional. Override the defaults.
  *
  * @return array 'headers', 'body', 'cookies' and 'response' keys.
  */
 protected function _doExecute($url, $r)
 {
     $iError = null;
     // Store error number
     $strError = null;
     // Store error string
     $arrURL = parse_url($url);
     $fsockopen_host = $arrURL['host'];
     $secure_transport = false;
     if (!isset($arrURL['port'])) {
         if (($arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https') && extension_loaded('openssl')) {
             $fsockopen_host = "ssl://{$fsockopen_host}";
             $arrURL['port'] = 443;
             $secure_transport = true;
         } else {
             $arrURL['port'] = 80;
         }
     }
     //fsockopen has issues with 'localhost' with IPv6 with certain versions of PHP, It attempts to connect to ::1,
     // which fails when the server is not set up for it. For compatibility, always connect to the IPv4 address.
     if ('localhost' == strtolower($fsockopen_host)) {
         $fsockopen_host = '127.0.0.1';
     }
     // There are issues with the HTTPS and SSL protocols that cause errors that can be safely
     // ignored and should be ignored.
     if (true === $secure_transport) {
         $error_reporting = error_reporting(0);
     }
     $handle = @fsockopen($fsockopen_host, $arrURL['port'], $iError, $strError, $r[org_tubepress_impl_http_HttpClientChain::ARGS_TIMEOUT]);
     if (false === $handle) {
         throw new Exception($iError . ': ' . $strError);
     }
     $timeout = (int) floor($r['timeout']);
     $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000;
     stream_set_timeout($handle, $timeout, $utimeout);
     $requestPath = $arrURL['path'] . (isset($arrURL['query']) ? '?' . $arrURL['query'] : '');
     if (empty($requestPath)) {
         $requestPath .= '/';
     }
     $strHeaders = strtoupper($r[org_tubepress_impl_http_HttpClientChain::ARGS_METHOD]) . ' ' . $requestPath . ' HTTP/' . $r[org_tubepress_impl_http_HttpClientChain::ARGS_HTTP_VERSION] . "\r\n";
     $strHeaders .= 'Host: ' . $arrURL['host'] . "\r\n";
     if (isset($r[org_tubepress_impl_http_HttpClientChain::ARGS_USER_AGENT])) {
         $strHeaders .= org_tubepress_api_http_HttpClient::HTTP_HEADER_USER_AGENT . ': ' . $r[org_tubepress_impl_http_HttpClientChain::ARGS_USER_AGENT] . "\r\n";
     }
     if (is_array($r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS])) {
         foreach ((array) $r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS] as $header => $headerValue) {
             $strHeaders .= $header . ': ' . $headerValue . "\r\n";
         }
     } else {
         $strHeaders .= $r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS];
     }
     $strHeaders .= "\r\n";
     if (!is_null($r[org_tubepress_impl_http_HttpClientChain::ARGS_BODY])) {
         $strHeaders .= $r[org_tubepress_impl_http_HttpClientChain::ARGS_BODY];
     }
     fwrite($handle, $strHeaders);
     $strResponse = '';
     while (!feof($handle)) {
         $strResponse .= fread($handle, 4096);
     }
     fclose($handle);
     if (true === $secure_transport) {
         error_reporting($error_reporting);
     }
     $process = self::_breakRawStringResponseIntoHeaderAndBody($strResponse);
     $arrHeaders = self::_getProcessedHeaders($process['headers']);
     // If location is found, then assume redirect and redirect to location.
     if (isset($arrHeaders['headers']['location'])) {
         if ($this->_canRedirect()) {
             return $this->_doExecute($arrHeaders['headers']['location'], $r);
         } else {
             throw new Exception('Too many redirects.');
         }
     }
     // If the body was chunk encoded, then decode it.
     if (!empty($process['body']) && isset($arrHeaders['headers']['transfer-encoding']) && 'chunked' == $arrHeaders['headers']['transfer-encoding']) {
         $process['body'] = org_tubepress_impl_http_clientimpl_Encoding::chunkTransferDecode($process['body']);
     }
     if (true === $r[org_tubepress_impl_http_HttpClientChain::ARGS_DECOMPRESS] && true === org_tubepress_impl_http_clientimpl_Encoding::shouldDecode($arrHeaders['headers'])) {
         $process['body'] = org_tubepress_impl_http_clientimpl_Encoding::decompress($process['body']);
     }
     return array('headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies']);
 }
 /**
  * Send a HTTP request to a URI using fopen().
  *
  * This transport does not support sending of headers and body, therefore should not be used in
  * the instances, where there is a body and headers.
  *
  * @param string $url  URI resource.
  * @param array  $args Optional. Override the defaults.
  *
  * @return array 'headers', 'body', 'cookies' and 'response' keys.
  */
 protected function _doExecute($url, $r)
 {
     $arrURL = parse_url($url);
     if ('http' != $arrURL['scheme'] && 'https' != $arrURL['scheme']) {
         $url = str_replace($arrURL['scheme'], 'http', $url);
     }
     $initialUserAgent = ini_get(self::INI_USER_AGENT);
     if (!empty($r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS]) && is_array($r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS])) {
         $user_agent_extra_headers = '';
         foreach ($r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS] as $header => $value) {
             $user_agent_extra_headers .= "\r\n{$header}: {$value}";
         }
         @ini_set(self::INI_USER_AGENT, $r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS] . $user_agent_extra_headers);
     } else {
         @ini_set(self::INI_USER_AGENT, $r[org_tubepress_impl_http_HttpClientChain::ARGS_HEADERS]);
     }
     $handle = @fopen($url, 'r');
     if (!$handle) {
         throw new Exception(sprintf('Could not open handle for fopen() to %s'), $url);
     }
     $timeout = (int) floor($r[org_tubepress_impl_http_HttpClientChain::ARGS_TIMEOUT]);
     $utimeout = $timeout == $r[org_tubepress_impl_http_HttpClientChain::ARGS_TIMEOUT] ? 0 : 1000000 * $r['timeout'] % 1000000;
     stream_set_timeout($handle, $timeout, $utimeout);
     $strResponse = '';
     while (!feof($handle)) {
         $strResponse .= fread($handle, 4096);
     }
     if (function_exists('stream_get_meta_data')) {
         $meta = stream_get_meta_data($handle);
         $theHeaders = $meta['wrapper_data'];
         if (isset($meta['wrapper_data']['headers'])) {
             $theHeaders = $meta['wrapper_data']['headers'];
         }
     } else {
         //$http_response_header is a PHP reserved variable which is set in the current-scope when using the HTTP Wrapper
         //see http://php.oregonstate.edu/manual/en/reserved.variables.httpresponseheader.php
         $theHeaders = $http_response_header;
     }
     fclose($handle);
     @ini_set(self::INI_USER_AGENT, $initialUserAgent);
     //Clean up any extra headers added
     $processedHeaders = self::_getProcessedHeaders($theHeaders);
     if (!empty($strResponse) && isset($processedHeaders['headers']['transfer-encoding']) && 'chunked' == $processedHeaders['headers']['transfer-encoding']) {
         $strResponse = org_tubepress_impl_http_clientimpl_Encoding::chunkTransferDecode($strResponse);
     }
     if (true === $r['decompress'] && true === org_tubepress_impl_http_clientimpl_Encoding::shouldDecode($processedHeaders['headers'])) {
         $strResponse = org_tubepress_impl_http_clientimpl_Encoding::decompress($strResponse);
     }
     return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies']);
 }