See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 /* 3 * Copyright 2014 Google Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** 19 * Curl based implementation of Google_IO. 20 * 21 * @author Stuart Langley <slangley@google.com> 22 */ 23 24 if (!class_exists('Google_Client')) { 25 require_once dirname(__FILE__) . '/../autoload.php'; 26 } 27 28 class Google_IO_Curl extends Google_IO_Abstract 29 { 30 // cURL hex representation of version 7.30.0 31 const NO_QUIRK_VERSION = 0x071E00; 32 33 private $options = array(); 34 35 /** @var bool $disableProxyWorkaround */ 36 private $disableProxyWorkaround; 37 38 public function __construct(Google_Client $client) 39 { 40 if (!extension_loaded('curl')) { 41 $error = 'The cURL IO handler requires the cURL extension to be enabled'; 42 $client->getLogger()->critical($error); 43 throw new Google_IO_Exception($error); 44 } 45 46 parent::__construct($client); 47 48 $this->disableProxyWorkaround = $this->client->getClassConfig( 49 'Google_IO_Curl', 50 'disable_proxy_workaround' 51 ); 52 } 53 54 /** 55 * Execute an HTTP Request 56 * 57 * @param Google_Http_Request $request the http request to be executed 58 * @return array containing response headers, body, and http code 59 * @throws Google_IO_Exception on curl or IO error 60 */ 61 public function executeRequest(Google_Http_Request $request) 62 { 63 $curl = curl_init(); 64 65 if ($request->getPostBody()) { 66 curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPostBody()); 67 } 68 69 $requestHeaders = $request->getRequestHeaders(); 70 if ($requestHeaders && is_array($requestHeaders)) { 71 $curlHeaders = array(); 72 foreach ($requestHeaders as $k => $v) { 73 $curlHeaders[] = "$k: $v"; 74 } 75 curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders); 76 } 77 curl_setopt($curl, CURLOPT_URL, $request->getUrl()); 78 79 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod()); 80 curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent()); 81 82 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); 83 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); 84 85 // The SSL version will be determined by the underlying library 86 // @see https://github.com/google/google-api-php-client/pull/644 87 //curl_setopt($curl, CURLOPT_SSLVERSION, 1); 88 89 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 90 curl_setopt($curl, CURLOPT_HEADER, true); 91 92 if ($request->canGzip()) { 93 curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate'); 94 } 95 96 $options = $this->client->getClassConfig('Google_IO_Curl', 'options'); 97 if (is_array($options)) { 98 $this->setOptions($options); 99 } 100 101 foreach ($this->options as $key => $var) { 102 curl_setopt($curl, $key, $var); 103 } 104 105 if (!isset($this->options[CURLOPT_CAINFO])) { 106 curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem'); 107 } 108 109 $this->client->getLogger()->debug( 110 'cURL request', 111 array( 112 'url' => $request->getUrl(), 113 'method' => $request->getRequestMethod(), 114 'headers' => $requestHeaders, 115 'body' => $request->getPostBody() 116 ) 117 ); 118 119 $response = curl_exec($curl); 120 if ($response === false) { 121 $error = curl_error($curl); 122 $code = curl_errno($curl); 123 $map = $this->client->getClassConfig('Google_IO_Exception', 'retry_map'); 124 125 $this->client->getLogger()->error('cURL ' . $error); 126 throw new Google_IO_Exception($error, $code, null, $map); 127 } 128 $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); 129 130 list($responseHeaders, $responseBody) = $this->parseHttpResponse($response, $headerSize); 131 $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 132 133 $this->client->getLogger()->debug( 134 'cURL response', 135 array( 136 'code' => $responseCode, 137 'headers' => $responseHeaders, 138 'body' => $responseBody, 139 ) 140 ); 141 142 return array($responseBody, $responseHeaders, $responseCode); 143 } 144 145 /** 146 * Set options that update the transport implementation's behavior. 147 * @param $options 148 */ 149 public function setOptions($options) 150 { 151 $this->options = $options + $this->options; 152 } 153 154 /** 155 * Set the maximum request time in seconds. 156 * @param $timeout in seconds 157 */ 158 public function setTimeout($timeout) 159 { 160 // Since this timeout is really for putting a bound on the time 161 // we'll set them both to the same. If you need to specify a longer 162 // CURLOPT_TIMEOUT, or a higher CONNECTTIMEOUT, the best thing to 163 // do is use the setOptions method for the values individually. 164 $this->options[CURLOPT_CONNECTTIMEOUT] = $timeout; 165 $this->options[CURLOPT_TIMEOUT] = $timeout; 166 } 167 168 /** 169 * Get the maximum request time in seconds. 170 * @return timeout in seconds 171 */ 172 public function getTimeout() 173 { 174 return $this->options[CURLOPT_TIMEOUT]; 175 } 176 177 /** 178 * Test for the presence of a cURL header processing bug 179 * 180 * {@inheritDoc} 181 * 182 * @return boolean 183 */ 184 protected function needsQuirk() 185 { 186 if ($this->disableProxyWorkaround) { 187 return false; 188 } 189 190 $ver = curl_version(); 191 $versionNum = $ver['version_number']; 192 return $versionNum < Google_IO_Curl::NO_QUIRK_VERSION; 193 } 194 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body