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 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 if (!class_exists('Google_Client')) { 19 require_once dirname(__FILE__) . '/../autoload.php'; 20 } 21 22 /** 23 * HTTP Request to be executed by IO classes. Upon execution, the 24 * responseHttpCode, responseHeaders and responseBody will be filled in. 25 * 26 * @author Chris Chabot <chabotc@google.com> 27 * @author Chirag Shah <chirags@google.com> 28 * 29 */ 30 #[AllowDynamicProperties] 31 class Google_Http_Request 32 { 33 const GZIP_UA = " (gzip)"; 34 35 private $batchHeaders = array( 36 'Content-Type' => 'application/http', 37 'Content-Transfer-Encoding' => 'binary', 38 'MIME-Version' => '1.0', 39 ); 40 41 protected $queryParams; 42 protected $requestMethod; 43 protected $requestHeaders; 44 protected $baseComponent = null; 45 protected $path; 46 protected $postBody; 47 protected $userAgent; 48 protected $canGzip = null; 49 50 protected $responseHttpCode; 51 protected $responseHeaders; 52 protected $responseBody; 53 54 protected $expectedClass; 55 protected $expectedRaw = false; 56 57 public $accessKey; 58 59 public function __construct( 60 $url, 61 $method = 'GET', 62 $headers = array(), 63 $postBody = null 64 ) { 65 $this->setUrl($url); 66 $this->setRequestMethod($method); 67 $this->setRequestHeaders($headers); 68 $this->setPostBody($postBody); 69 } 70 71 /** 72 * Misc function that returns the base url component of the $url 73 * used by the OAuth signing class to calculate the base string 74 * @return string The base url component of the $url. 75 */ 76 public function getBaseComponent() 77 { 78 return $this->baseComponent; 79 } 80 81 /** 82 * Set the base URL that path and query parameters will be added to. 83 * @param $baseComponent string 84 */ 85 public function setBaseComponent($baseComponent) 86 { 87 $this->baseComponent = rtrim($baseComponent, '/'); 88 } 89 90 /** 91 * Enable support for gzipped responses with this request. 92 */ 93 public function enableGzip() 94 { 95 $this->setRequestHeaders(array("Accept-Encoding" => "gzip")); 96 $this->canGzip = true; 97 $this->setUserAgent($this->userAgent); 98 } 99 100 /** 101 * Disable support for gzip responses with this request. 102 */ 103 public function disableGzip() 104 { 105 if ( 106 isset($this->requestHeaders['accept-encoding']) && 107 $this->requestHeaders['accept-encoding'] == "gzip" 108 ) { 109 unset($this->requestHeaders['accept-encoding']); 110 } 111 $this->canGzip = false; 112 $this->userAgent = str_replace(self::GZIP_UA, "", $this->userAgent); 113 } 114 115 /** 116 * Can this request accept a gzip response? 117 * @return bool 118 */ 119 public function canGzip() 120 { 121 return $this->canGzip; 122 } 123 124 /** 125 * Misc function that returns an array of the query parameters of the current 126 * url used by the OAuth signing class to calculate the signature 127 * @return array Query parameters in the query string. 128 */ 129 public function getQueryParams() 130 { 131 return $this->queryParams; 132 } 133 134 /** 135 * Set a new query parameter. 136 * @param $key - string to set, does not need to be URL encoded 137 * @param $value - string to set, does not need to be URL encoded 138 */ 139 public function setQueryParam($key, $value) 140 { 141 $this->queryParams[$key] = $value; 142 } 143 144 /** 145 * @return string HTTP Response Code. 146 */ 147 public function getResponseHttpCode() 148 { 149 return (int) $this->responseHttpCode; 150 } 151 152 /** 153 * @param int $responseHttpCode HTTP Response Code. 154 */ 155 public function setResponseHttpCode($responseHttpCode) 156 { 157 $this->responseHttpCode = $responseHttpCode; 158 } 159 160 /** 161 * @return $responseHeaders (array) HTTP Response Headers. 162 */ 163 public function getResponseHeaders() 164 { 165 return $this->responseHeaders; 166 } 167 168 /** 169 * @return string HTTP Response Body 170 */ 171 public function getResponseBody() 172 { 173 return $this->responseBody; 174 } 175 176 /** 177 * Set the class the response to this request should expect. 178 * 179 * @param $class string the class name 180 */ 181 public function setExpectedClass($class) 182 { 183 $this->expectedClass = $class; 184 } 185 186 /** 187 * Retrieve the expected class the response should expect. 188 * @return string class name 189 */ 190 public function getExpectedClass() 191 { 192 return $this->expectedClass; 193 } 194 195 /** 196 * Enable expected raw response 197 */ 198 public function enableExpectedRaw() 199 { 200 $this->expectedRaw = true; 201 } 202 203 /** 204 * Disable expected raw response 205 */ 206 public function disableExpectedRaw() 207 { 208 $this->expectedRaw = false; 209 } 210 211 /** 212 * Expected raw response or not. 213 * @return boolean expected raw response 214 */ 215 public function getExpectedRaw() 216 { 217 return $this->expectedRaw; 218 } 219 220 /** 221 * @param array $headers The HTTP response headers 222 * to be normalized. 223 */ 224 public function setResponseHeaders($headers) 225 { 226 $headers = Google_Utils::normalize($headers); 227 if ($this->responseHeaders) { 228 $headers = array_merge($this->responseHeaders, $headers); 229 } 230 231 $this->responseHeaders = $headers; 232 } 233 234 /** 235 * @param string $key 236 * @return array|boolean Returns the requested HTTP header or 237 * false if unavailable. 238 */ 239 public function getResponseHeader($key) 240 { 241 return isset($this->responseHeaders[$key]) 242 ? $this->responseHeaders[$key] 243 : false; 244 } 245 246 /** 247 * @param string $responseBody The HTTP response body. 248 */ 249 public function setResponseBody($responseBody) 250 { 251 $this->responseBody = $responseBody; 252 } 253 254 /** 255 * @return string $url The request URL. 256 */ 257 public function getUrl() 258 { 259 return $this->baseComponent . $this->path . 260 (count($this->queryParams) ? 261 "?" . $this->buildQuery($this->queryParams) : 262 ''); 263 } 264 265 /** 266 * @return string $method HTTP Request Method. 267 */ 268 public function getRequestMethod() 269 { 270 return $this->requestMethod; 271 } 272 273 /** 274 * @return array $headers HTTP Request Headers. 275 */ 276 public function getRequestHeaders() 277 { 278 return $this->requestHeaders; 279 } 280 281 /** 282 * @param string $key 283 * @return array|boolean Returns the requested HTTP header or 284 * false if unavailable. 285 */ 286 public function getRequestHeader($key) 287 { 288 return isset($this->requestHeaders[$key]) 289 ? $this->requestHeaders[$key] 290 : false; 291 } 292 293 /** 294 * @return string $postBody HTTP Request Body. 295 */ 296 public function getPostBody() 297 { 298 return $this->postBody; 299 } 300 301 /** 302 * @param string $url the url to set 303 */ 304 public function setUrl($url) 305 { 306 if (substr($url, 0, 4) != 'http') { 307 // Force the path become relative. 308 if (substr($url, 0, 1) !== '/') { 309 $url = '/' . $url; 310 } 311 } 312 $parts = parse_url($url); 313 if (isset($parts['host'])) { 314 $this->baseComponent = sprintf( 315 "%s%s%s", 316 isset($parts['scheme']) ? $parts['scheme'] . "://" : '', 317 isset($parts['host']) ? $parts['host'] : '', 318 isset($parts['port']) ? ":" . $parts['port'] : '' 319 ); 320 } 321 $this->path = isset($parts['path']) ? $parts['path'] : ''; 322 $this->queryParams = array(); 323 if (isset($parts['query'])) { 324 $this->queryParams = $this->parseQuery($parts['query']); 325 } 326 } 327 328 /** 329 * @param string $method Set he HTTP Method and normalize 330 * it to upper-case, as required by HTTP. 331 * 332 */ 333 public function setRequestMethod($method) 334 { 335 $this->requestMethod = strtoupper($method); 336 } 337 338 /** 339 * @param array $headers The HTTP request headers 340 * to be set and normalized. 341 */ 342 public function setRequestHeaders($headers) 343 { 344 $headers = Google_Utils::normalize($headers); 345 if ($this->requestHeaders) { 346 $headers = array_merge($this->requestHeaders, $headers); 347 } 348 $this->requestHeaders = $headers; 349 } 350 351 /** 352 * @param string $postBody the postBody to set 353 */ 354 public function setPostBody($postBody) 355 { 356 $this->postBody = $postBody; 357 } 358 359 /** 360 * Set the User-Agent Header. 361 * @param string $userAgent The User-Agent. 362 */ 363 public function setUserAgent($userAgent) 364 { 365 $this->userAgent = $userAgent; 366 if ($this->canGzip) { 367 $this->userAgent = $userAgent . self::GZIP_UA; 368 } 369 } 370 371 /** 372 * @return string The User-Agent. 373 */ 374 public function getUserAgent() 375 { 376 return $this->userAgent; 377 } 378 379 /** 380 * Returns a cache key depending on if this was an OAuth signed request 381 * in which case it will use the non-signed url and access key to make this 382 * cache key unique per authenticated user, else use the plain request url 383 * @return string The md5 hash of the request cache key. 384 */ 385 public function getCacheKey() 386 { 387 $key = $this->getUrl(); 388 389 if (isset($this->accessKey)) { 390 $key .= $this->accessKey; 391 } 392 393 if (isset($this->requestHeaders['authorization'])) { 394 $key .= $this->requestHeaders['authorization']; 395 } 396 397 return md5($key); 398 } 399 400 public function getParsedCacheControl() 401 { 402 $parsed = array(); 403 $rawCacheControl = $this->getResponseHeader('cache-control'); 404 if ($rawCacheControl) { 405 $rawCacheControl = str_replace(', ', '&', $rawCacheControl); 406 parse_str($rawCacheControl, $parsed); 407 } 408 409 return $parsed; 410 } 411 412 /** 413 * @param string $id 414 * @return string A string representation of the HTTP Request. 415 */ 416 public function toBatchString($id) 417 { 418 $str = ''; 419 $path = parse_url($this->getUrl(), PHP_URL_PATH) . "?" . 420 http_build_query($this->queryParams); 421 $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n"; 422 423 foreach ($this->getRequestHeaders() as $key => $val) { 424 $str .= $key . ': ' . $val . "\n"; 425 } 426 427 if ($this->getPostBody()) { 428 $str .= "\n"; 429 $str .= $this->getPostBody(); 430 } 431 432 $headers = ''; 433 foreach ($this->batchHeaders as $key => $val) { 434 $headers .= $key . ': ' . $val . "\n"; 435 } 436 437 $headers .= "Content-ID: $id\n"; 438 $str = $headers . "\n" . $str; 439 440 return $str; 441 } 442 443 /** 444 * Our own version of parse_str that allows for multiple variables 445 * with the same name. 446 * @param $string - the query string to parse 447 */ 448 private function parseQuery($string) 449 { 450 $return = array(); 451 $parts = explode("&", $string); 452 foreach ($parts as $part) { 453 list($key, $value) = explode('=', $part, 2); 454 $value = urldecode($value); 455 if (isset($return[$key])) { 456 if (!is_array($return[$key])) { 457 $return[$key] = array($return[$key]); 458 } 459 $return[$key][] = $value; 460 } else { 461 $return[$key] = $value; 462 } 463 } 464 return $return; 465 } 466 467 /** 468 * A version of build query that allows for multiple 469 * duplicate keys. 470 * @param $parts array of key value pairs 471 */ 472 private function buildQuery($parts) 473 { 474 $return = array(); 475 foreach ($parts as $key => $value) { 476 if (is_array($value)) { 477 foreach ($value as $v) { 478 $return[] = urlencode($key) . "=" . urlencode($v); 479 } 480 } else { 481 $return[] = urlencode($key) . "=" . urlencode($value); 482 } 483 } 484 return implode('&', $return); 485 } 486 487 /** 488 * If we're POSTing and have no body to send, we can send the query 489 * parameters in there, which avoids length issues with longer query 490 * params. 491 */ 492 public function maybeMoveParametersToBody() 493 { 494 if ($this->getRequestMethod() == "POST" && empty($this->postBody)) { 495 $this->setRequestHeaders( 496 array( 497 "content-type" => 498 "application/x-www-form-urlencoded; charset=UTF-8" 499 ) 500 ); 501 $this->setPostBody($this->buildQuery($this->queryParams)); 502 $this->queryParams = array(); 503 } 504 } 505 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body