PluginProbe
Gmail SMTP / trunk
Gmail SMTP vtrunk
1.2.3.21 1.2.3.20 trunk 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.9 1.2.0 1.2.3.14 1.2.3.15 1.2.3.16 1.2.3.18 1.2.3.5
gmail-smtp / google-api-php-client / src / Http / REST.php

REST.php in Gmail SMTP trunk, at google-api-php-client/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