/**
  * Execute an HTTP Request
  *
  * @param Google_Http_Request $request the http request to be executed
  * @return array containing response headers, body, and http code
  * @throws Google_IO_Exception on curl or IO error
  */
 public function executeRequest(App_Google_Http_Request $request)
 {
     $curl = curl_init();
     if ($request->getPostBody()) {
         curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPostBody());
     }
     $requestHeaders = $request->getRequestHeaders();
     if ($requestHeaders && is_array($requestHeaders)) {
         $curlHeaders = array();
         foreach ($requestHeaders as $k => $v) {
             $curlHeaders[] = "{$k}: {$v}";
         }
         curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders);
     }
     curl_setopt($curl, CURLOPT_URL, $request->getUrl());
     curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
     curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent());
     curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
     // 1 is CURL_SSLVERSION_TLSv1, which is not always defined in PHP.
     curl_setopt($curl, CURLOPT_SSLVERSION, 1);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($curl, CURLOPT_HEADER, true);
     if ($request->canGzip()) {
         curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
     }
     $options = $this->client->getClassConfig('Google_IO_Curl', 'options');
     if (is_array($options)) {
         $this->setOptions($options);
     }
     foreach ($this->options as $key => $var) {
         curl_setopt($curl, $key, $var);
     }
     if (!isset($this->options[CURLOPT_CAINFO])) {
         curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
     }
     $this->client->getLogger()->debug('cURL request', array('url' => $request->getUrl(), 'method' => $request->getRequestMethod(), 'headers' => $requestHeaders, 'body' => $request->getPostBody()));
     $response = curl_exec($curl);
     if ($response === false) {
         $error = curl_error($curl);
         $code = curl_errno($curl);
         $map = $this->client->getClassConfig('Google_IO_Exception', 'retry_map');
         $this->client->getLogger()->error('cURL ' . $error);
         throw new App_Google_IO_Exception($error, $code, null, $map);
     }
     $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
     list($responseHeaders, $responseBody) = $this->parseHttpResponse($response, $headerSize);
     $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
     $this->client->getLogger()->debug('cURL response', array('code' => $responseCode, 'headers' => $responseHeaders, 'body' => $responseBody));
     return array($responseBody, $responseHeaders, $responseCode);
 }
 /**
  * Execute an HTTP Request
  *
  * @param Google_Http_Request $request the http request to be executed
  * @return array containing response headers, body, and http code
  * @throws Google_IO_Exception on curl or IO error
  */
 public function executeRequest(App_Google_Http_Request $request)
 {
     $default_options = stream_context_get_options(stream_context_get_default());
     $requestHttpContext = array_key_exists('http', $default_options) ? $default_options['http'] : array();
     if ($request->getPostBody()) {
         $requestHttpContext["content"] = $request->getPostBody();
     }
     $requestHeaders = $request->getRequestHeaders();
     if ($requestHeaders && is_array($requestHeaders)) {
         $headers = "";
         foreach ($requestHeaders as $k => $v) {
             $headers .= "{$k}: {$v}\r\n";
         }
         $requestHttpContext["header"] = $headers;
     }
     $requestHttpContext["method"] = $request->getRequestMethod();
     $requestHttpContext["user_agent"] = $request->getUserAgent();
     $requestSslContext = array_key_exists('ssl', $default_options) ? $default_options['ssl'] : array();
     if (!array_key_exists("cafile", $requestSslContext)) {
         $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem';
     }
     $options = array("http" => array_merge(self::$DEFAULT_HTTP_CONTEXT, $requestHttpContext), "ssl" => array_merge(self::$DEFAULT_SSL_CONTEXT, $requestSslContext));
     $context = stream_context_create($options);
     $url = $request->getUrl();
     if ($request->canGzip()) {
         $url = self::ZLIB . $url;
     }
     $this->client->getLogger()->debug('Stream request', array('url' => $url, 'method' => $request->getRequestMethod(), 'headers' => $requestHeaders, 'body' => $request->getPostBody()));
     // We are trapping any thrown errors in this method only and
     // throwing an exception.
     $this->trappedErrorNumber = null;
     $this->trappedErrorString = null;
     // START - error trap.
     set_error_handler(array($this, 'trapError'));
     $fh = fopen($url, 'r', false, $context);
     restore_error_handler();
     // END - error trap.
     if ($this->trappedErrorNumber) {
         $error = sprintf("HTTP Error: Unable to connect: '%s'", $this->trappedErrorString);
         $this->client->getLogger()->error('Stream ' . $error);
         throw new App_Google_IO_Exception($error, $this->trappedErrorNumber);
     }
     $response_data = false;
     $respHttpCode = self::UNKNOWN_CODE;
     if ($fh) {
         if (isset($this->options[self::TIMEOUT])) {
             stream_set_timeout($fh, $this->options[self::TIMEOUT]);
         }
         $response_data = stream_get_contents($fh);
         fclose($fh);
         $respHttpCode = $this->getHttpResponseCode($http_response_header);
     }
     if (false === $response_data) {
         $error = sprintf("HTTP Error: Unable to connect: '%s'", $respHttpCode);
         $this->client->getLogger()->error('Stream ' . $error);
         throw new App_Google_IO_Exception($error, $respHttpCode);
     }
     $responseHeaders = $this->getHttpResponseHeaders($http_response_header);
     $this->client->getLogger()->debug('Stream response', array('code' => $respHttpCode, 'headers' => $responseHeaders, 'body' => $response_data));
     return array($response_data, $responseHeaders, $respHttpCode);
 }