PluginProbe
InfiniteWP Client / trunk
InfiniteWP Client vtrunk
1.13.10 1.13.7 trunk 0.1.4 0.1.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.11.0 1.11.1 1.12.1 1.12.3 All 92 releases
iwp-client / lib / Google2 / Http / Request.php

Request.php in InfiniteWP Client trunk, at lib/Google2/Http/Request.php

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