PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/wordpress-seo/vendor/yoast/api-libs/google/io/Google_CurlIO.php

https://gitlab.com/ngochuynh1991/cuacuon
PHP | 196 lines | 113 code | 21 blank | 62 comment | 21 complexity | b02d7b9832ea0a3c69d172d264b64d93 MD5 | raw file
  1. <?php
  2. /*
  3. * Copyright 2010 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. * Curl based implementation of apiIO.
  19. *
  20. * @author Chris Chabot <chabotc@google.com>
  21. * @author Chirag Shah <chirags@google.com>
  22. */
  23. class Yoast_Google_CurlIO extends Yoast_Google_IO {
  24. private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
  25. private static $HOP_BY_HOP = array(
  26. 'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
  27. 'te', 'trailers', 'transfer-encoding', 'upgrade');
  28. private $curlParams = array (
  29. CURLOPT_RETURNTRANSFER => true,
  30. CURLOPT_FOLLOWLOCATION => 0,
  31. CURLOPT_FAILONERROR => false,
  32. CURLOPT_SSL_VERIFYPEER => true,
  33. CURLOPT_HEADER => true,
  34. CURLOPT_VERBOSE => false,
  35. );
  36. /**
  37. * Check for cURL availability.
  38. */
  39. public function __construct() {
  40. if (! function_exists('curl_init')) {
  41. throw new Exception(
  42. 'Google CurlIO client requires the CURL PHP extension');
  43. }
  44. }
  45. /**
  46. * Perform an authenticated / signed apiHttpRequest.
  47. * This function takes the apiHttpRequest, calls apiAuth->sign on it
  48. * (which can modify the request in what ever way fits the auth mechanism)
  49. * and then calls apiCurlIO::makeRequest on the signed request
  50. *
  51. * @param Yoast_Google_HttpRequest $request
  52. * @return Yoast_Google_HttpRequest The resulting HTTP response including the
  53. * responseHttpCode, responseHeaders and responseBody.
  54. */
  55. public function authenticatedRequest(Yoast_Google_HttpRequest $request) {
  56. $request = Yoast_Google_Client::$auth->sign($request);
  57. return $this->makeRequest($request);
  58. }
  59. /**
  60. * Execute a apiHttpRequest
  61. *
  62. * @param Yoast_Google_HttpRequest $request the http request to be executed
  63. * @return Yoast_Google_HttpRequest http request with the response http code, response
  64. * headers and response body filled in
  65. * @throws Yoast_Google_IOException on curl or IO error
  66. */
  67. public function makeRequest(Yoast_Google_HttpRequest $request) {
  68. // First, check to see if we have a valid cached version.
  69. $cached = $this->getCachedRequest($request);
  70. if ($cached !== false) {
  71. if (!$this->checkMustRevaliadateCachedRequest($cached, $request)) {
  72. return $cached;
  73. }
  74. }
  75. if (array_key_exists($request->getRequestMethod(),
  76. self::$ENTITY_HTTP_METHODS)) {
  77. $request = $this->processEntityRequest($request);
  78. }
  79. $ch = curl_init();
  80. curl_setopt_array($ch, $this->curlParams);
  81. curl_setopt($ch, CURLOPT_URL, $request->getUrl());
  82. if ($request->getPostBody()) {
  83. curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody());
  84. }
  85. $requestHeaders = $request->getRequestHeaders();
  86. if ($requestHeaders && is_array($requestHeaders)) {
  87. $parsed = array();
  88. foreach ($requestHeaders as $k => $v) {
  89. $parsed[] = "$k: $v";
  90. }
  91. curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed);
  92. }
  93. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
  94. curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent());
  95. $respData = curl_exec($ch);
  96. // Retry if certificates are missing.
  97. if (curl_errno($ch) == CURLE_SSL_CACERT) {
  98. error_log('SSL certificate problem, verify that the CA cert is OK.'
  99. . ' Retrying with the CA cert bundle from google-api-php-client.');
  100. curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
  101. $respData = curl_exec($ch);
  102. }
  103. $respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  104. $respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
  105. $curlErrorNum = curl_errno($ch);
  106. $curlError = curl_error($ch);
  107. curl_close($ch);
  108. if ($curlErrorNum != CURLE_OK) {
  109. throw new Yoast_Google_IOException("HTTP Error: ($respHttpCode) $curlError");
  110. }
  111. // Parse out the raw response into usable bits
  112. list($responseHeaders, $responseBody) =
  113. self::parseHttpResponse($respData, $respHeaderSize);
  114. if ($respHttpCode == 304 && $cached) {
  115. // If the server responded NOT_MODIFIED, return the cached request.
  116. $this->updateCachedRequest($cached, $responseHeaders);
  117. return $cached;
  118. }
  119. // Fill in the apiHttpRequest with the response values
  120. $request->setResponseHttpCode($respHttpCode);
  121. $request->setResponseHeaders($responseHeaders);
  122. $request->setResponseBody($responseBody);
  123. // Store the request in cache (the function checks to see if the request
  124. // can actually be cached)
  125. $this->setCachedRequest($request);
  126. // And finally return it
  127. return $request;
  128. }
  129. /**
  130. * Set options that update cURL's default behavior.
  131. * The list of accepted options are:
  132. * {@link http://php.net/manual/en/function.curl-setopt.php]
  133. *
  134. * @param array $optCurlParams Multiple options used by a cURL session.
  135. */
  136. public function setOptions($optCurlParams) {
  137. foreach ($optCurlParams as $key => $val) {
  138. $this->curlParams[$key] = $val;
  139. }
  140. }
  141. /**
  142. * @param $respData
  143. * @param $headerSize
  144. * @return array
  145. */
  146. public static function parseHttpResponse($respData, $headerSize) {
  147. if (stripos($respData, parent::CONNECTION_ESTABLISHED) !== false) {
  148. $respData = str_ireplace(parent::CONNECTION_ESTABLISHED, '', $respData);
  149. }
  150. if ($headerSize) {
  151. $responseBody = substr($respData, $headerSize);
  152. $responseHeaders = substr($respData, 0, $headerSize);
  153. } else {
  154. list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2);
  155. }
  156. $responseHeaders = self::parseResponseHeaders($responseHeaders);
  157. return array($responseHeaders, $responseBody);
  158. }
  159. public static function parseResponseHeaders($rawHeaders) {
  160. $responseHeaders = array();
  161. $responseHeaderLines = explode("\r\n", $rawHeaders);
  162. foreach ($responseHeaderLines as $headerLine) {
  163. if ($headerLine && strpos($headerLine, ':') !== false) {
  164. list($header, $value) = explode(': ', $headerLine, 2);
  165. $header = strtolower($header);
  166. if (isset($responseHeaders[$header])) {
  167. $responseHeaders[$header] .= "\n" . $value;
  168. } else {
  169. $responseHeaders[$header] = $value;
  170. }
  171. }
  172. }
  173. return $responseHeaders;
  174. }
  175. }