Blame | Last modification | View Log | RSS feed
<?php/** Copyright 2010 Google Inc.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/use Google\Auth\HttpHandler\HttpHandlerFactory;use GuzzleHttp\ClientInterface;use GuzzleHttp\Exception\RequestException;use GuzzleHttp\Psr7\Response;use Psr\Http\Message\RequestInterface;use Psr\Http\Message\ResponseInterface;/*** This class implements the RESTful transport of apiServiceRequest()'s*/class Google_Http_REST{/*** Executes a Psr\Http\Message\RequestInterface and (if applicable) automatically retries* when errors occur.** @param Google_Client $client* @param Psr\Http\Message\RequestInterface $req* @return array decoded result* @throws Google_Service_Exception on server side error (ie: not authenticated,* invalid or malformed post body, invalid url)*/public static function execute(ClientInterface $client,RequestInterface $request,$expectedClass = null,$config = array(),$retryMap = null) {$runner = new Google_Task_Runner($config,sprintf('%s %s', $request->getMethod(), (string) $request->getUri()),array(get_class(), 'doExecute'),array($client, $request, $expectedClass));if (null !== $retryMap) {$runner->setRetryMap($retryMap);}return $runner->run();}/*** Executes a Psr\Http\Message\RequestInterface** @param Google_Client $client* @param Psr\Http\Message\RequestInterface $request* @return array decoded result* @throws Google_Service_Exception on server side error (ie: not authenticated,* invalid or malformed post body, invalid url)*/public static function doExecute(ClientInterface $client, RequestInterface $request, $expectedClass = null){try {$httpHandler = HttpHandlerFactory::build($client);$response = $httpHandler($request);} catch (RequestException $e) {// if Guzzle throws an exception, catch it and handle the responseif (!$e->hasResponse()) {throw $e;}$response = $e->getResponse();// specific checking for Guzzle 5: convert to PSR7 responseif ($response instanceof \GuzzleHttp\Message\ResponseInterface) {$response = new Response($response->getStatusCode(),$response->getHeaders() ?: [],$response->getBody(),$response->getProtocolVersion(),$response->getReasonPhrase());}}return self::decodeHttpResponse($response, $request, $expectedClass);}/*** Decode an HTTP Response.* @static* @throws Google_Service_Exception* @param Psr\Http\Message\RequestInterface $response The http response to be decoded.* @param Psr\Http\Message\ResponseInterface $response* @return mixed|null*/public static function decodeHttpResponse(ResponseInterface $response,RequestInterface $request = null,$expectedClass = null) {$code = $response->getStatusCode();// retry strategyif (intVal($code) >= 400) {// if we errored out, it should be safe to grab the response body$body = (string) $response->getBody();// Check if we received errors, and add those to the Exception for conveniencethrow new Google_Service_Exception($body, $code, null, self::getResponseErrors($body));}// Ensure we only pull the entire body into memory if the request is not// of media type$body = self::decodeBody($response, $request);if ($expectedClass = self::determineExpectedClass($expectedClass, $request)) {$json = json_decode($body, true);return new $expectedClass($json);}return $response;}private static function decodeBody(ResponseInterface $response, RequestInterface $request = null){if (self::isAltMedia($request)) {// don't decode the body, it's probably a really long stringreturn '';}return (string) $response->getBody();}private static function determineExpectedClass($expectedClass, RequestInterface $request = null){// "false" is used to explicitly prevent an expected class from being returnedif (false === $expectedClass) {return null;}// if we don't have a request, we just use what's passed inif (null === $request) {return $expectedClass;}// return what we have in the request header if one was not suppliedreturn $expectedClass ?: $request->getHeaderLine('X-Php-Expected-Class');}private static function getResponseErrors($body){$json = json_decode($body, true);if (isset($json['error']['errors'])) {return $json['error']['errors'];}return null;}private static function isAltMedia(RequestInterface $request = null){if ($request && $qs = $request->getUri()->getQuery()) {parse_str($qs, $query);if (isset($query['alt']) && $query['alt'] == 'media') {return true;}}return false;}}