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 / Google / Http / Request.php

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

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