public function testGzipSupport() { $url = 'http://localhost:8080/foo/bar?foo=a&foo=b&wowee=oh+my'; $request = new Google_Http_Request($url); $request->enableGzip(); $this->assertStringEndsWith(Google_Http_Request::GZIP_UA, $request->getUserAgent()); $this->assertArrayHasKey('accept-encoding', $request->getRequestHeaders()); $this->assertTrue($request->canGzip()); $request->disableGzip(); $this->assertStringEndsNotWith(Google_Http_Request::GZIP_UA, $request->getUserAgent()); $this->assertArrayNotHasKey('accept-encoding', $request->getRequestHeaders()); $this->assertFalse($request->canGzip()); }
/** * 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(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}"; } if (isset($this->options[CURLOPT_HTTPHEADER])) { if (is_array($this->options[CURLOPT_HTTPHEADER])) { foreach ($this->options[CURLOPT_HTTPHEADER] as $optionHeader) { $curlHeaders[] = $optionHeader; } } unset($this->options[CURLOPT_HTTPHEADER]); } 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 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_HttpRequest $request the http request to be executed * @return Google_HttpRequest http request with the response http code, * response headers and response body filled in * @throws Google_IO_Exception on curl or IO error */ public function executeRequest(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; } // 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) { throw new Google_IO_Exception(sprintf("HTTP Error: Unable to connect: '%s'", $this->trappedErrorString), $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) { throw new Google_IO_Exception(sprintf("HTTP Error: Unable to connect: '%s'", $respHttpCode), $respHttpCode); } $responseHeaders = $this->getHttpResponseHeaders($http_response_header); return array($response_data, $responseHeaders, $respHttpCode); }
/** * Execute an HTTP Request * * @param Google_HttpRequest $request the http request to be executed * * @return Google_HttpRequest http request with the response http code, * response headers and response body filled in * @throws Google_IO_Exception on curl or IO error */ public function executeRequest(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; } // Not entirely happy about this, but supressing the warning from the // fopen seems like the best situation here - we can't do anything // useful with it, and failure to connect is a legitimate run // time situation. @($fh = fopen($url, 'r', false, $context)); $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) { throw new Google_IO_Exception(sprintf("HTTP Error: Unable to connect: '%s'", $respHttpCode), $respHttpCode); } $responseHeaders = $this->getHttpResponseHeaders($http_response_header); return array($response_data, $responseHeaders, $respHttpCode); }
/** * Execute an HTTP Request * * @param Google_HttpRequest $request the http request to be executed * @return Google_HttpRequest http request with the response http code, * response headers and response body filled in * @throws Google_IO_Exception on curl or IO error */ public function executeRequest(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_CUSTOMREQUEST, $request->getRequestMethod()); curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent()); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_URL, $request->getUrl()); if ($request->canGzip()) { curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate'); } 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'); } $response = curl_exec($curl); if ($response === false) { throw new Google_IO_Exception(curl_error($curl)); } $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $responseBody = substr($response, $headerSize); $responseHeaderString = substr($response, 0, $headerSize); $responseHeaders = $this->getHttpResponseHeaders($responseHeaderString); $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 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(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(); # UpdraftPlus patch // if (!array_key_exists("cafile", $requestSslContext)) { // $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem'; // } $url = $request->getUrl(); if (preg_match('#^https?://([^/]+)/#', $url, $umatches)) { $cname = $umatches[1]; } else { $cname = false; } # UpdraftPlus patch // Added if (empty($this->options['disable_verify_peer'])) { $requestSslContext['verify_peer'] = true; if (version_compare(PHP_VERSION, '5.6.0', '>=')) { if (!empty($cname)) { $requestSslContext['peer_name'] = $cname; } } else { if (!empty($cname)) { $requestSslContext['CN_match'] = $cname; $retry_on_fail = true; } } } else { $requestSslContext['allow_self_signed'] = true; } if (!empty($this->options['cafile'])) { $requestSslContext['cafile'] = $this->options['cafile']; } $options = array("http" => array_merge(self::$DEFAULT_HTTP_CONTEXT, $requestHttpContext), "ssl" => array_merge($requestSslContext)); $context = stream_context_create($options); # UpdraftPlus patch // $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); # UpdraftPLus patch if (!$fh && isset($retry_on_fail) && !empty($cname) && 'www.googleapis.com' == $cname) { // Reset $this->trappedErrorNumber = null; $this->trappedErrorString = null; global $updraftplus; $updraftplus->log("Using Stream, and fopen failed; retrying different CN match to try to overcome"); // www.googleapis.com does not match the cert now being presented - *.storage.googleapis.com; presumably, PHP's stream handler isn't handling alternative names properly. Rather than turn off all verification, let's retry with a new name to match. $options['ssl']['CN_match'] = 'www.storage.googleapis.com'; $context = stream_context_create($options); $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 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 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); }
/** * Execute an API request. * * This is a copy/paste from the parent class that uses Moodle's implementation * of curl. Portions have been removed or altered. * * @param Google_Http_Request $request the http request to be executed * @return Google_Http_Request http request with the response http code, response * headers and response body filled in * @throws Google_IO_Exception on curl or IO error */ public function executeRequest(Google_Http_Request $request) { $curl = new curl(); if ($request->getPostBody()) { $curl->setopt(array('CURLOPT_POSTFIELDS' => $request->getPostBody())); } $requestHeaders = $request->getRequestHeaders(); if ($requestHeaders && is_array($requestHeaders)) { $curlHeaders = array(); foreach ($requestHeaders as $k => $v) { $curlHeaders[] = "{$k}: {$v}"; } $curl->setopt(array('CURLOPT_HTTPHEADER' => $curlHeaders)); } $curl->setopt(array('CURLOPT_URL' => $request->getUrl())); $curl->setopt(array('CURLOPT_CUSTOMREQUEST' => $request->getRequestMethod())); $curl->setopt(array('CURLOPT_USERAGENT' => $request->getUserAgent())); $curl->setopt(array('CURLOPT_FOLLOWLOCATION' => false)); $curl->setopt(array('CURLOPT_SSL_VERIFYPEER' => true)); $curl->setopt(array('CURLOPT_RETURNTRANSFER' => true)); $curl->setopt(array('CURLOPT_HEADER' => true)); if ($request->canGzip()) { $curl->setopt(array('CURLOPT_ENCODING' => 'gzip,deflate')); } $curl->setopt($this->options); $respdata = $this->do_request($curl, $request); $infos = $curl->get_info(); $respheadersize = $infos['header_size']; $resphttpcode = (int) $infos['http_code']; $curlerrornum = $curl->get_errno(); $curlerror = $curl->error; if ($respdata != CURLE_OK) { throw new Google_IO_Exception($curlerror); } list($responseHeaders, $responseBody) = $this->parseHttpResponse($respdata, $respheadersize); return array($responseBody, $responseHeaders, $resphttpcode); }