source: vendor/google/apiclient/src/Http/REST.php@ f9c482b

Last change on this file since f9c482b was f9c482b, checked in by Vlado 222039 <vlado.popovski@…>, 7 days ago

Upload new project files

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[f9c482b]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
18namespace Google\Http;
19
20use Google\Auth\HttpHandler\HttpHandlerFactory;
21use Google\Service\Exception as GoogleServiceException;
22use Google\Task\Runner;
23use GuzzleHttp\ClientInterface;
24use GuzzleHttp\Exception\RequestException;
25use GuzzleHttp\Psr7\Response;
26use Psr\Http\Message\RequestInterface;
27use Psr\Http\Message\ResponseInterface;
28
29/**
30 * This class implements the RESTful transport of apiServiceRequest()'s
31 */
32class 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 // specific checking for Guzzle 5: convert to PSR7 response
93 if (
94 interface_exists('\GuzzleHttp\Message\ResponseInterface')
95 && $response instanceof \GuzzleHttp\Message\ResponseInterface
96 ) {
97 $response = new Response(
98 $response->getStatusCode(),
99 $response->getHeaders() ?: [],
100 $response->getBody(),
101 $response->getProtocolVersion(),
102 $response->getReasonPhrase()
103 );
104 }
105 }
106
107 return self::decodeHttpResponse($response, $request, $expectedClass);
108 }
109
110 /**
111 * Decode an HTTP Response.
112 * @static
113 *
114 * @template T
115 * @param RequestInterface $response The http response to be decoded.
116 * @param ResponseInterface $response
117 * @param class-string<T>|false|null $expectedClass
118 * @return mixed|T|null
119 * @throws \Google\Service\Exception
120 */
121 public static function decodeHttpResponse(
122 ResponseInterface $response,
123 ?RequestInterface $request = null,
124 $expectedClass = null
125 ) {
126 $code = $response->getStatusCode();
127
128 // retry strategy
129 if (intVal($code) >= 400) {
130 // if we errored out, it should be safe to grab the response body
131 $body = (string)$response->getBody();
132
133 // Check if we received errors, and add those to the Exception for convenience
134 throw new GoogleServiceException($body, $code, null, self::getResponseErrors($body));
135 }
136
137 // Ensure we only pull the entire body into memory if the request is not
138 // of media type
139 $body = self::decodeBody($response, $request);
140
141 if ($expectedClass = self::determineExpectedClass($expectedClass, $request)) {
142 $json = json_decode($body, true);
143
144 return new $expectedClass($json);
145 }
146
147 return $response;
148 }
149
150 private static function decodeBody(ResponseInterface $response, ?RequestInterface $request = null)
151 {
152 if (self::isAltMedia($request)) {
153 // don't decode the body, it's probably a really long string
154 return '';
155 }
156
157 return (string)$response->getBody();
158 }
159
160 private static function determineExpectedClass($expectedClass, ?RequestInterface $request = null)
161 {
162 // "false" is used to explicitly prevent an expected class from being returned
163 if (false === $expectedClass) {
164 return null;
165 }
166
167 // if we don't have a request, we just use what's passed in
168 if (null === $request) {
169 return $expectedClass;
170 }
171
172 // return what we have in the request header if one was not supplied
173 return $expectedClass ?: $request->getHeaderLine('X-Php-Expected-Class');
174 }
175
176 private static function getResponseErrors($body)
177 {
178 $json = json_decode($body, true);
179
180 if (isset($json['error']['errors'])) {
181 return $json['error']['errors'];
182 }
183
184 return null;
185 }
186
187 private static function isAltMedia(?RequestInterface $request = null)
188 {
189 if ($request && $qs = $request->getUri()->getQuery()) {
190 parse_str($qs, $query);
191 if (isset($query['alt']) && $query['alt'] == 'media') {
192 return true;
193 }
194 }
195
196 return false;
197 }
198}
Note: See TracBrowser for help on using the repository browser.