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