Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 #[AllowDynamicProperties] 29 class Google_IO_Curl extends Google_IO_Abstract 30 { 31 // cURL hex representation of version 7.30.0 32 const NO_QUIRK_VERSION = 0x071E00; 33 34 private $options = array(); 35 36 /** @var bool $disableProxyWorkaround */ 37 private $disableProxyWorkaround; 38 39 public function __construct(Google_Client $client) 40 { 41 if (!extension_loaded('curl')) { 42 $error = 'The cURL IO handler requires the cURL extension to be enabled'; 43 $client->getLogger()->critical($error); 44 throw new Google_IO_Exception($error); 45 } 46 47 parent::__construct($client); 48 49 $this->disableProxyWorkaround = $this->client->getClassConfig( 50 'Google_IO_Curl', 51 'disable_proxy_workaround' 52 ); 53 } 54 55 /** 56 * Execute an HTTP Request 57 * 58 * @param Google_Http_Request $request the http request to be executed 59 * @return array containing response headers, body, and http code 60 * @throws Google_IO_Exception on curl or IO error 61 */ 62 public function executeRequest(Google_Http_Request $request) 63 { 64 $curl = curl_init(); 65 66 if ($request->getPostBody()) { 67 curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPostBody()); 68 } 69 70 $requestHeaders = $request->getRequestHeaders(); 71 if ($requestHeaders && is_array($requestHeaders)) { 72 $curlHeaders = array(); 73 foreach ($requestHeaders as $k => $v) { 74 $curlHeaders[] = "$k: $v"; 75 } 76 curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders); 77 } 78 curl_setopt($curl, CURLOPT_URL, $request->getUrl()); 79 80 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod()); 81 curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent()); 82 83 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); 84 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); 85 86 // The SSL version will be determined by the underlying library 87 // @see https://github.com/google/google-api-php-client/pull/644 88 //curl_setopt($curl, CURLOPT_SSLVERSION, 1); 89 90 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 91 curl_setopt($curl, CURLOPT_HEADER, true); 92 93 if ($request->canGzip()) { 94 curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate'); 95 } 96 97 $options = $this->client->getClassConfig('Google_IO_Curl', 'options'); 98 if (is_array($options)) { 99 $this->setOptions($options); 100 } 101 102 foreach ($this->options as $key => $var) { 103 curl_setopt($curl, $key, $var); 104 } 105 106 if (!isset($this->options[CURLOPT_CAINFO])) { 107 curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem'); 108 } 109 110 $this->client->getLogger()->debug( 111 'cURL request', 112 array( 113 'url' => $request->getUrl(), 114 'method' => $request->getRequestMethod(), 115 'headers' => $requestHeaders, 116 'body' => $request->getPostBody() 117 ) 118 ); 119 120 $response = curl_exec($curl); 121 if ($response === false) { 122 $error = curl_error($curl); 123 $code = curl_errno($curl); 124 $map = $this->client->getClassConfig('Google_IO_Exception', 'retry_map'); 125 126 $this->client->getLogger()->error('cURL ' . $error); 127 throw new Google_IO_Exception($error, $code, null, $map); 128 } 129 $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); 130 131 list($responseHeaders, $responseBody) = $this->parseHttpResponse($response, $headerSize); 132 $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 133 134 $this->client->getLogger()->debug( 135 'cURL response', 136 array( 137 'code' => $responseCode, 138 'headers' => $responseHeaders, 139 'body' => $responseBody, 140 ) 141 ); 142 143 return array($responseBody, $responseHeaders, $responseCode); 144 } 145 146 /** 147 * Set options that update the transport implementation's behavior. 148 * @param $options 149 */ 150 public function setOptions($options) 151 { 152 $this->options = $options + $this->options; 153 } 154 155 /** 156 * Set the maximum request time in seconds. 157 * @param $timeout in seconds 158 */ 159 public function setTimeout($timeout) 160 { 161 // Since this timeout is really for putting a bound on the time 162 // we'll set them both to the same. If you need to specify a longer 163 // CURLOPT_TIMEOUT, or a higher CONNECTTIMEOUT, the best thing to 164 // do is use the setOptions method for the values individually. 165 $this->options[CURLOPT_CONNECTTIMEOUT] = $timeout; 166 $this->options[CURLOPT_TIMEOUT] = $timeout; 167 } 168 169 /** 170 * Get the maximum request time in seconds. 171 * @return timeout in seconds 172 */ 173 public function getTimeout() 174 { 175 return $this->options[CURLOPT_TIMEOUT]; 176 } 177 178 /** 179 * Test for the presence of a cURL header processing bug 180 * 181 * {@inheritDoc} 182 * 183 * @return boolean 184 */ 185 protected function needsQuirk() 186 { 187 if ($this->disableProxyWorkaround) { 188 return false; 189 } 190 191 $ver = curl_version(); 192 $versionNum = $ver['version_number']; 193 return $versionNum < Google_IO_Curl::NO_QUIRK_VERSION; 194 } 195 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body