PluginProbe
WP-Stateless – Google Cloud Storage / trunk
WP-Stateless – Google Cloud Storage vtrunk
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
wp-stateless / lib / Google / src / Http / REST.php

REST.php in WP-Stateless – Google Cloud Storage trunk, at lib/Google/src/Http/REST.php

186 lines 5.7 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 namespace Google\Http;
19
20 use Google\Auth\HttpHandler\HttpHandlerFactory;
21 use Google\Service\Exception as GoogleServiceException;
22 use Google\Task\Runner;
23 use GuzzleHttp\ClientInterface;
24 use GuzzleHttp\Exception\RequestException;
25 use GuzzleHttp\Psr7\Response;
26 use Psr\Http\Message\RequestInterface;
27 use Psr\Http\Message\ResponseInterface;
28
29 /**
30 * This class implements the RESTful transport of apiServiceRequest()'s
31 */
32 class REST
33 {
34 /**
35 * Executes a Psr\Http\Message\RequestInterface and (if applicable) automatically retries
36 * when errors occur.
37 *
38 * @template T
39 * @param ClientInterface $client
40 * @param RequestInterface $request
41 * @param class-string<T>|false|null $expectedClass
42 * @param array $config
43 * @param array $retryMap
44 * @return mixed|T|null
45 * @throws \Google\Service\Exception on server side error (ie: not authenticated,
46 * invalid or malformed post body, invalid url)
47 */
48 public static function execute(
49 ClientInterface $client,
50 RequestInterface $request,
51 $expectedClass = null,
52 $config = [],
53 $retryMap = null
54 ) {
55 $runner = new Runner(
56 $config,
57 sprintf('%s %s', $request->getMethod(), (string)$request->getUri()),
58 [self::class, 'doExecute'],
59 [$client, $request, $expectedClass]
60 );
61
62 if (null !== $retryMap) {
63 $runner->setRetryMap($retryMap);
64 }
65
66 return $runner->run();
67 }
68
69 /**
70 * Executes a Psr\Http\Message\RequestInterface
71 *
72 * @template T
73 * @param ClientInterface $client
74 * @param RequestInterface $request
75 * @param class-string<T>|false|null $expectedClass
76 * @return mixed|T|null
77 * @throws \Google\Service\Exception on server side error (ie: not authenticated,
78 * invalid or malformed post body, invalid url)
79 */
80 public static function doExecute(ClientInterface $client, RequestInterface $request, $expectedClass = null)
81 {
82 try {
83 $httpHandler = HttpHandlerFactory::build($client);
84 $response = $httpHandler($request);
85 } catch (RequestException $e) {
86 // if Guzzle throws an exception, catch it and handle the response
87 if (!$e->hasResponse()) {
88 throw $e;
89 }
90
91 $response = $e->getResponse();
92 }
93
94 return self::decodeHttpResponse($response, $request, $expectedClass);
95 }
96
97 /**
98 * Decode an HTTP Response.
99 * @static
100 *
101 * @template T
102 * @param RequestInterface $response The http response to be decoded.
103 * @param ResponseInterface $response
104 * @param class-string<T>|false|null $expectedClass
105 * @return mixed|T|null
106 * @throws \Google\Service\Exception
107 */
108 public static function decodeHttpResponse(
109 ResponseInterface $response,
110 ?RequestInterface $request = null,
111 $expectedClass = null
112 ) {
113 $code = $response->getStatusCode();
114
115 // retry strategy
116 if (intVal($code) >= 400) {
117 // if we errored out, it should be safe to grab the response body
118 $body = (string)$response->getBody();
119
120 // Check if we received errors, and add those to the Exception for convenience
121 throw new GoogleServiceException($body, $code, null, self::getResponseErrors($body));
122 }
123
124 // Ensure we only pull the entire body into memory if the request is not
125 // of media type
126 $body = self::decodeBody($response, $request);
127
128 if ($expectedClass = self::determineExpectedClass($expectedClass, $request)) {
129 $json = json_decode($body, true);
130
131 return new $expectedClass($json);
132 }
133
134 return $response;
135 }
136
137 private static function decodeBody(ResponseInterface $response, ?RequestInterface $request = null)
138 {
139 if (self::isAltMedia($request)) {
140 // don't decode the body, it's probably a really long string
141 return '';
142 }
143
144 return (string)$response->getBody();
145 }
146
147 private static function determineExpectedClass($expectedClass, ?RequestInterface $request = null)
148 {
149 // "false" is used to explicitly prevent an expected class from being returned
150 if (false === $expectedClass) {
151 return null;
152 }
153
154 // if we don't have a request, we just use what's passed in
155 if (null === $request) {
156 return $expectedClass;
157 }
158
159 // return what we have in the request header if one was not supplied
160 return $expectedClass ?: $request->getHeaderLine('X-Php-Expected-Class');
161 }
162
163 private static function getResponseErrors($body)
164 {
165 $json = json_decode($body, true);
166
167 if (isset($json['error']['errors'])) {
168 return $json['error']['errors'];
169 }
170
171 return null;
172 }
173
174 private static function isAltMedia(?RequestInterface $request = null)
175 {
176 if ($request && $qs = $request->getUri()->getQuery()) {
177 parse_str($qs, $query);
178 if (isset($query['alt']) && $query['alt'] == 'media') {
179 return true;
180 }
181 }
182
183 return false;
184 }
185 }
186