���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home3/cpr76684/public_html/Http.tar
���ѧ٧ѧ�
Request.php 0000644 00000027414 15152171264 0006721 0 ustar 00 <?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. */ if (!class_exists('Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } /** * HTTP Request to be executed by IO classes. Upon execution, the * responseHttpCode, responseHeaders and responseBody will be filled in. * * @author Chris Chabot <chabotc@google.com> * @author Chirag Shah <chirags@google.com> * */ class Google_Http_Request { const GZIP_UA = " (gzip)"; private $batchHeaders = array( 'Content-Type' => 'application/http', 'Content-Transfer-Encoding' => 'binary', 'MIME-Version' => '1.0', ); protected $queryParams; protected $requestMethod; protected $requestHeaders; protected $baseComponent = null; protected $path; protected $postBody; protected $userAgent; protected $canGzip = null; protected $responseHttpCode; protected $responseHeaders; protected $responseBody; protected $expectedClass; protected $expectedRaw = false; public $accessKey; public function __construct( $url, $method = 'GET', $headers = array(), $postBody = null ) { $this->setUrl($url); $this->setRequestMethod($method); $this->setRequestHeaders($headers); $this->setPostBody($postBody); } /** * Misc function that returns the base url component of the $url * used by the OAuth signing class to calculate the base string * @return string The base url component of the $url. */ public function getBaseComponent() { return $this->baseComponent; } /** * Set the base URL that path and query parameters will be added to. * @param $baseComponent string */ public function setBaseComponent($baseComponent) { $this->baseComponent = rtrim($baseComponent, '/'); } /** * Enable support for gzipped responses with this request. */ public function enableGzip() { $this->setRequestHeaders(array("Accept-Encoding" => "gzip")); $this->canGzip = true; $this->setUserAgent($this->userAgent); } /** * Disable support for gzip responses with this request. */ public function disableGzip() { if ( isset($this->requestHeaders['accept-encoding']) && $this->requestHeaders['accept-encoding'] == "gzip" ) { unset($this->requestHeaders['accept-encoding']); } $this->canGzip = false; $this->userAgent = str_replace(self::GZIP_UA, "", $this->userAgent); } /** * Can this request accept a gzip response? * @return bool */ public function canGzip() { return $this->canGzip; } /** * Misc function that returns an array of the query parameters of the current * url used by the OAuth signing class to calculate the signature * @return array Query parameters in the query string. */ public function getQueryParams() { return $this->queryParams; } /** * Set a new query parameter. * @param $key - string to set, does not need to be URL encoded * @param $value - string to set, does not need to be URL encoded */ public function setQueryParam($key, $value) { $this->queryParams[$key] = $value; } /** * @return string HTTP Response Code. */ public function getResponseHttpCode() { return (int) $this->responseHttpCode; } /** * @param int $responseHttpCode HTTP Response Code. */ public function setResponseHttpCode($responseHttpCode) { $this->responseHttpCode = $responseHttpCode; } /** * @return $responseHeaders (array) HTTP Response Headers. */ public function getResponseHeaders() { return $this->responseHeaders; } /** * @return string HTTP Response Body */ public function getResponseBody() { return $this->responseBody; } /** * Set the class the response to this request should expect. * * @param $class string the class name */ public function setExpectedClass($class) { $this->expectedClass = $class; } /** * Retrieve the expected class the response should expect. * @return string class name */ public function getExpectedClass() { return $this->expectedClass; } /** * Enable expected raw response */ public function enableExpectedRaw() { $this->expectedRaw = true; } /** * Disable expected raw response */ public function disableExpectedRaw() { $this->expectedRaw = false; } /** * Expected raw response or not. * @return boolean expected raw response */ public function getExpectedRaw() { return $this->expectedRaw; } /** * @param array $headers The HTTP response headers * to be normalized. */ public function setResponseHeaders($headers) { $headers = Google_Utils::normalize($headers); if ($this->responseHeaders) { $headers = array_merge($this->responseHeaders, $headers); } $this->responseHeaders = $headers; } /** * @param string $key * @return array|boolean Returns the requested HTTP header or * false if unavailable. */ public function getResponseHeader($key) { return isset($this->responseHeaders[$key]) ? $this->responseHeaders[$key] : false; } /** * @param string $responseBody The HTTP response body. */ public function setResponseBody($responseBody) { $this->responseBody = $responseBody; } /** * @return string $url The request URL. */ public function getUrl() { return $this->baseComponent . $this->path . (count($this->queryParams) ? "?" . $this->buildQuery($this->queryParams) : ''); } /** * @return string $method HTTP Request Method. */ public function getRequestMethod() { return $this->requestMethod; } /** * @return array $headers HTTP Request Headers. */ public function getRequestHeaders() { return $this->requestHeaders; } /** * @param string $key * @return array|boolean Returns the requested HTTP header or * false if unavailable. */ public function getRequestHeader($key) { return isset($this->requestHeaders[$key]) ? $this->requestHeaders[$key] : false; } /** * @return string $postBody HTTP Request Body. */ public function getPostBody() { return $this->postBody; } /** * @param string $url the url to set */ public function setUrl($url) { if (substr($url, 0, 4) != 'http') { // Force the path become relative. if (substr($url, 0, 1) !== '/') { $url = '/' . $url; } } $parts = parse_url($url); if (isset($parts['host'])) { $this->baseComponent = sprintf( "%s%s%s", isset($parts['scheme']) ? $parts['scheme'] . "://" : '', isset($parts['host']) ? $parts['host'] : '', isset($parts['port']) ? ":" . $parts['port'] : '' ); } $this->path = isset($parts['path']) ? $parts['path'] : ''; $this->queryParams = array(); if (isset($parts['query'])) { $this->queryParams = $this->parseQuery($parts['query']); } } /** * @param string $method Set he HTTP Method and normalize * it to upper-case, as required by HTTP. * */ public function setRequestMethod($method) { $this->requestMethod = strtoupper($method); } /** * @param array $headers The HTTP request headers * to be set and normalized. */ public function setRequestHeaders($headers) { $headers = Google_Utils::normalize($headers); if ($this->requestHeaders) { $headers = array_merge($this->requestHeaders, $headers); } $this->requestHeaders = $headers; } /** * @param string $postBody the postBody to set */ public function setPostBody($postBody) { $this->postBody = $postBody; } /** * Set the User-Agent Header. * @param string $userAgent The User-Agent. */ public function setUserAgent($userAgent) { $this->userAgent = $userAgent; if ($this->canGzip) { $this->userAgent = $userAgent . self::GZIP_UA; } } /** * @return string The User-Agent. */ public function getUserAgent() { return $this->userAgent; } /** * Returns a cache key depending on if this was an OAuth signed request * in which case it will use the non-signed url and access key to make this * cache key unique per authenticated user, else use the plain request url * @return string The md5 hash of the request cache key. */ public function getCacheKey() { $key = $this->getUrl(); if (isset($this->accessKey)) { $key .= $this->accessKey; } if (isset($this->requestHeaders['authorization'])) { $key .= $this->requestHeaders['authorization']; } return md5($key); } public function getParsedCacheControl() { $parsed = array(); $rawCacheControl = $this->getResponseHeader('cache-control'); if ($rawCacheControl) { $rawCacheControl = str_replace(', ', '&', $rawCacheControl); parse_str($rawCacheControl, $parsed); } return $parsed; } /** * @param string $id * @return string A string representation of the HTTP Request. */ public function toBatchString($id) { $str = ''; $path = parse_url($this->getUrl(), PHP_URL_PATH) . "?" . http_build_query($this->queryParams); $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n"; foreach ($this->getRequestHeaders() as $key => $val) { $str .= $key . ': ' . $val . "\n"; } if ($this->getPostBody()) { $str .= "\n"; $str .= $this->getPostBody(); } $headers = ''; foreach ($this->batchHeaders as $key => $val) { $headers .= $key . ': ' . $val . "\n"; } $headers .= "Content-ID: $id\n"; $str = $headers . "\n" . $str; return $str; } /** * Our own version of parse_str that allows for multiple variables * with the same name. * @param $string - the query string to parse */ private function parseQuery($string) { $return = array(); $parts = explode("&", $string); foreach ($parts as $part) { list($key, $value) = explode('=', $part, 2); $value = urldecode($value); if (isset($return[$key])) { if (!is_array($return[$key])) { $return[$key] = array($return[$key]); } $return[$key][] = $value; } else { $return[$key] = $value; } } return $return; } /** * A version of build query that allows for multiple * duplicate keys. * @param $parts array of key value pairs */ private function buildQuery($parts) { $return = array(); foreach ($parts as $key => $value) { if (is_array($value)) { foreach ($value as $v) { $return[] = urlencode($key) . "=" . urlencode($v); } } else { $return[] = urlencode($key) . "=" . urlencode($value); } } return implode('&', $return); } /** * If we're POSTing and have no body to send, we can send the query * parameters in there, which avoids length issues with longer query * params. */ public function maybeMoveParametersToBody() { if ($this->getRequestMethod() == "POST" && empty($this->postBody)) { $this->setRequestHeaders( array( "content-type" => "application/x-www-form-urlencoded; charset=UTF-8" ) ); $this->setPostBody($this->buildQuery($this->queryParams)); $this->queryParams = array(); } } } Batch.php 0000644 00000010527 15152171264 0006307 0 ustar 00 <?php /* * Copyright 2012 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. */ if (!class_exists('Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } /** * Class to handle batched requests to the Google API service. */ class Google_Http_Batch { /** @var string Multipart Boundary. */ private $boundary; /** @var array service requests to be executed. */ private $requests = array(); /** @var Google_Client */ private $client; private $expected_classes = array(); private $root_url; private $batch_path; public function __construct(Google_Client $client, $boundary = false, $rootUrl = '', $batchPath = '') { $this->client = $client; $this->root_url = rtrim($rootUrl ? $rootUrl : $this->client->getBasePath(), '/'); $this->batch_path = $batchPath ? $batchPath : 'batch'; $this->expected_classes = array(); $boundary = (false == $boundary) ? mt_rand() : $boundary; $this->boundary = str_replace('"', '', $boundary); } public function add(Google_Http_Request $request, $key = false) { if (false == $key) { $key = mt_rand(); } $this->requests[$key] = $request; } public function execute() { $body = ''; /** @var Google_Http_Request $req */ foreach ($this->requests as $key => $req) { $body .= "--{$this->boundary}\n"; $body .= $req->toBatchString($key) . "\n\n"; $this->expected_classes["response-" . $key] = $req->getExpectedClass(); } $body .= "--{$this->boundary}--"; $url = $this->root_url . '/' . $this->batch_path; $httpRequest = new Google_Http_Request($url, 'POST'); $httpRequest->setRequestHeaders( array('Content-Type' => 'multipart/mixed; boundary=' . $this->boundary) ); $httpRequest->setPostBody($body); $response = $this->client->getIo()->makeRequest($httpRequest); return $this->parseResponse($response); } public function parseResponse(Google_Http_Request $response) { $contentType = $response->getResponseHeader('content-type'); $contentType = explode(';', $contentType); $boundary = false; foreach ($contentType as $part) { $part = (explode('=', $part, 2)); if (isset($part[0]) && 'boundary' == trim($part[0])) { $boundary = $part[1]; } } $body = $response->getResponseBody(); if ($body) { $body = str_replace("--$boundary--", "--$boundary", $body); $parts = explode("--$boundary", $body); $responses = array(); foreach ($parts as $part) { $part = trim($part); if (!empty($part)) { list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2); $metaHeaders = $this->client->getIo()->getHttpResponseHeaders($metaHeaders); $status = substr($part, 0, strpos($part, "\n")); $status = explode(" ", $status); $status = $status[1]; list($partHeaders, $partBody) = $this->client->getIo()->ParseHttpResponse($part, false); $response = new Google_Http_Request(""); $response->setResponseHttpCode($status); $response->setResponseHeaders($partHeaders); $response->setResponseBody($partBody); // Need content id. $key = $metaHeaders['content-id']; if (isset($this->expected_classes[$key]) && strlen($this->expected_classes[$key]) > 0) { $class = $this->expected_classes[$key]; $response->setExpectedClass($class); } try { $response = Google_Http_REST::decodeHttpResponse($response, $this->client); $responses[$key] = $response; } catch (Google_Service_Exception $e) { // Store the exception as the response, so successful responses // can be processed. $responses[$key] = $e; } } } return $responses; } return null; } } REST.php 0000644 00000013132 15152171264 0006036 0 ustar 00 <?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. */ if (!class_exists('Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } /** * This class implements the RESTful transport of apiServiceRequest()'s */ class Google_Http_REST { /** * Executes a Google_Http_Request and (if applicable) automatically retries * when errors occur. * * @param Google_Client $client * @param Google_Http_Request $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(Google_Client $client, Google_Http_Request $req) { $runner = new Google_Task_Runner( $client, sprintf('%s %s', $req->getRequestMethod(), $req->getUrl()), array(get_class(), 'doExecute'), array($client, $req) ); return $runner->run(); } /** * Executes a Google_Http_Request * * @param Google_Client $client * @param Google_Http_Request $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 doExecute(Google_Client $client, Google_Http_Request $req) { $httpRequest = $client->getIo()->makeRequest($req); $httpRequest->setExpectedClass($req->getExpectedClass()); return self::decodeHttpResponse($httpRequest, $client); } /** * Decode an HTTP Response. * @static * @throws Google_Service_Exception * @param Google_Http_Request $response The http response to be decoded. * @param Google_Client $client * @return mixed|null */ public static function decodeHttpResponse($response, Google_Client $client = null) { $code = $response->getResponseHttpCode(); $body = $response->getResponseBody(); $decoded = null; if ((intVal($code)) >= 300) { $decoded = json_decode($body, true); $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl(); if (isset($decoded['error']) && isset($decoded['error']['message']) && isset($decoded['error']['code'])) { // if we're getting a json encoded error definition, use that instead of the raw response // body for improved readability $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}"; } else { $err .= ": ($code) $body"; } $errors = null; // Specific check for APIs which don't return error details, such as Blogger. if (isset($decoded['error']) && isset($decoded['error']['errors'])) { $errors = $decoded['error']['errors']; } $map = null; if ($client) { $client->getLogger()->error( $err, array('code' => $code, 'errors' => $errors) ); $map = $client->getClassConfig( 'Google_Service_Exception', 'retry_map' ); } throw new Google_Service_Exception($err, $code, null, $errors, $map); } // Only attempt to decode the response, if the response code wasn't (204) 'no content' if ($code != '204') { if ($response->getExpectedRaw()) { return $body; } $decoded = json_decode($body, true); if ($decoded === null || $decoded === "") { $error = "Invalid json in service response: $body"; if ($client) { $client->getLogger()->error($error); } throw new Google_Service_Exception($error); } if ($response->getExpectedClass()) { $class = $response->getExpectedClass(); $decoded = new $class($decoded); } } return $decoded; } /** * Parse/expand request parameters and create a fully qualified * request uri. * @static * @param string $servicePath * @param string $restPath * @param array $params * @return string $requestUrl */ public static function createRequestUri($servicePath, $restPath, $params) { $requestUrl = $servicePath . $restPath; $uriTemplateVars = array(); $queryVars = array(); foreach ($params as $paramName => $paramSpec) { if ($paramSpec['type'] == 'boolean') { $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false'; } if ($paramSpec['location'] == 'path') { $uriTemplateVars[$paramName] = $paramSpec['value']; } else if ($paramSpec['location'] == 'query') { if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) { foreach ($paramSpec['value'] as $value) { $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($value)); } } else { $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($paramSpec['value'])); } } } if (count($uriTemplateVars)) { $uriTemplateParser = new Google_Utils_URITemplate(); $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars); } if (count($queryVars)) { $requestUrl .= '?' . implode('&', $queryVars); } return $requestUrl; } } CacheParser.php 0000644 00000014045 15152171264 0007445 0 ustar 00 <?php /* * Copyright 2012 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. */ if (!class_exists('Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } /** * Implement the caching directives specified in rfc2616. This * implementation is guided by the guidance offered in rfc2616-sec13. */ class Google_Http_CacheParser { public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD'); public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301'); /** * Check if an HTTP request can be cached by a private local cache. * * @static * @param Google_Http_Request $resp * @return bool True if the request is cacheable. * False if the request is uncacheable. */ public static function isRequestCacheable(Google_Http_Request $resp) { $method = $resp->getRequestMethod(); if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) { return false; } // Don't cache authorized requests/responses. // [rfc2616-14.8] When a shared cache receives a request containing an // Authorization field, it MUST NOT return the corresponding response // as a reply to any other request... if ($resp->getRequestHeader("authorization")) { return false; } return true; } /** * Check if an HTTP response can be cached by a private local cache. * * @static * @param Google_Http_Request $resp * @return bool True if the response is cacheable. * False if the response is un-cacheable. */ public static function isResponseCacheable(Google_Http_Request $resp) { // First, check if the HTTP request was cacheable before inspecting the // HTTP response. if (false == self::isRequestCacheable($resp)) { return false; } $code = $resp->getResponseHttpCode(); if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) { return false; } // The resource is uncacheable if the resource is already expired and // the resource doesn't have an ETag for revalidation. $etag = $resp->getResponseHeader("etag"); if (self::isExpired($resp) && $etag == false) { return false; } // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT // store any part of either this response or the request that elicited it. $cacheControl = $resp->getParsedCacheControl(); if (isset($cacheControl['no-store'])) { return false; } // Pragma: no-cache is an http request directive, but is occasionally // used as a response header incorrectly. $pragma = $resp->getResponseHeader('pragma'); if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) { return false; } // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that // a cache cannot determine from the request headers of a subsequent request // whether this response is the appropriate representation." // Given this, we deem responses with the Vary header as uncacheable. $vary = $resp->getResponseHeader('vary'); if ($vary) { return false; } return true; } /** * @static * @param Google_Http_Request $resp * @return bool True if the HTTP response is considered to be expired. * False if it is considered to be fresh. */ public static function isExpired(Google_Http_Request $resp) { // HTTP/1.1 clients and caches MUST treat other invalid date formats, // especially including the value “0”, as in the past. $parsedExpires = false; $responseHeaders = $resp->getResponseHeaders(); if (isset($responseHeaders['expires'])) { $rawExpires = $responseHeaders['expires']; // Check for a malformed expires header first. if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) { return true; } // See if we can parse the expires header. $parsedExpires = strtotime($rawExpires); if (false == $parsedExpires || $parsedExpires <= 0) { return true; } } // Calculate the freshness of an http response. $freshnessLifetime = false; $cacheControl = $resp->getParsedCacheControl(); if (isset($cacheControl['max-age'])) { $freshnessLifetime = $cacheControl['max-age']; } $rawDate = $resp->getResponseHeader('date'); $parsedDate = strtotime($rawDate); if (empty($rawDate) || false == $parsedDate) { // We can't default this to now, as that means future cache reads // will always pass with the logic below, so we will require a // date be injected if not supplied. throw new Google_Exception("All cacheable requests must have creation dates."); } if (false == $freshnessLifetime && isset($responseHeaders['expires'])) { $freshnessLifetime = $parsedExpires - $parsedDate; } if (false == $freshnessLifetime) { return true; } // Calculate the age of an http response. $age = max(0, time() - $parsedDate); if (isset($responseHeaders['age'])) { $age = max($age, strtotime($responseHeaders['age'])); } return $freshnessLifetime <= $age; } /** * Determine if a cache entry should be revalidated with by the origin. * * @param Google_Http_Request $response * @return bool True if the entry is expired, else return false. */ public static function mustRevalidate(Google_Http_Request $response) { // [13.3] When a cache has a stale entry that it would like to use as a // response to a client's request, it first has to check with the origin // server to see if its cached entry is still usable. return self::isExpired($response); } } MediaFileUpload.php 0000644 00000022162 15152171264 0010250 0 ustar 00 <?php /** * Copyright 2012 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. */ if (!class_exists('Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } /** * Manage large file uploads, which may be media but can be any type * of sizable data. */ class Google_Http_MediaFileUpload { const UPLOAD_MEDIA_TYPE = 'media'; const UPLOAD_MULTIPART_TYPE = 'multipart'; const UPLOAD_RESUMABLE_TYPE = 'resumable'; /** @var string $mimeType */ private $mimeType; /** @var string $data */ private $data; /** @var bool $resumable */ private $resumable; /** @var int $chunkSize */ private $chunkSize; /** @var int $size */ private $size; /** @var string $resumeUri */ private $resumeUri; /** @var int $progress */ private $progress; /** @var Google_Client */ private $client; /** @var Google_Http_Request */ private $request; /** @var string */ private $boundary; /** * Result code from last HTTP call * @var int */ private $httpResultCode; /** * @param $mimeType string * @param $data string The bytes you want to upload. * @param $resumable bool * @param bool $chunkSize File will be uploaded in chunks of this many bytes. * only used if resumable=True */ public function __construct( Google_Client $client, Google_Http_Request $request, $mimeType, $data, $resumable = false, $chunkSize = false, $boundary = false ) { $this->client = $client; $this->request = $request; $this->mimeType = $mimeType; $this->data = $data; $this->size = strlen($this->data); $this->resumable = $resumable; if (!$chunkSize) { $chunkSize = 256 * 1024; } $this->chunkSize = $chunkSize; $this->progress = 0; $this->boundary = $boundary; // Process Media Request $this->process(); } /** * Set the size of the file that is being uploaded. * @param $size - int file size in bytes */ public function setFileSize($size) { $this->size = $size; } /** * Return the progress on the upload * @return int progress in bytes uploaded. */ public function getProgress() { return $this->progress; } /** * Return the HTTP result code from the last call made. * @return int code */ public function getHttpResultCode() { return $this->httpResultCode; } /** * Sends a PUT-Request to google drive and parses the response, * setting the appropiate variables from the response() * * @param Google_Http_Request $httpRequest the Reuqest which will be send * * @return false|mixed false when the upload is unfinished or the decoded http response * */ private function makePutRequest(Google_Http_Request $httpRequest) { if ($this->client->getClassConfig("Google_Http_Request", "enable_gzip_for_uploads")) { $httpRequest->enableGzip(); } else { $httpRequest->disableGzip(); } $response = $this->client->getIo()->makeRequest($httpRequest); $response->setExpectedClass($this->request->getExpectedClass()); $code = $response->getResponseHttpCode(); $this->httpResultCode = $code; if (308 == $code) { // Track the amount uploaded. $range = explode('-', $response->getResponseHeader('range')); $this->progress = $range[1] + 1; // Allow for changing upload URLs. $location = $response->getResponseHeader('location'); if ($location) { $this->resumeUri = $location; } // No problems, but upload not complete. return false; } else { return Google_Http_REST::decodeHttpResponse($response, $this->client); } } /** * Send the next part of the file to upload. * @param [$chunk] the next set of bytes to send. If false will used $data passed * at construct time. */ public function nextChunk($chunk = false) { if (false == $this->resumeUri) { $this->resumeUri = $this->fetchResumeUri(); } if (false == $chunk) { $chunk = substr($this->data, $this->progress, $this->chunkSize); } $lastBytePos = $this->progress + strlen($chunk) - 1; $headers = array( 'content-range' => "bytes $this->progress-$lastBytePos/$this->size", 'content-type' => $this->request->getRequestHeader('content-type'), 'content-length' => $this->chunkSize, 'expect' => '', ); $httpRequest = new Google_Http_Request( $this->resumeUri, 'PUT', $headers, $chunk ); return $this->makePutRequest($httpRequest); } /** * Resume a previously unfinished upload * @param $resumeUri the resume-URI of the unfinished, resumable upload. */ public function resume($resumeUri) { $this->resumeUri = $resumeUri; $headers = array( 'content-range' => "bytes */$this->size", 'content-length' => 0, ); $httpRequest = new Google_Http_Request( $this->resumeUri, 'PUT', $headers ); return $this->makePutRequest($httpRequest); } /** * @return array|bool * @visible for testing */ private function process() { $postBody = false; $contentType = false; $meta = $this->request->getPostBody(); $meta = is_string($meta) ? json_decode($meta, true) : $meta; $uploadType = $this->getUploadType($meta); $this->request->setQueryParam('uploadType', $uploadType); $this->transformToUploadUrl(); $mimeType = $this->mimeType ? $this->mimeType : $this->request->getRequestHeader('content-type'); if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) { $contentType = $mimeType; $postBody = is_string($meta) ? $meta : json_encode($meta); } else if (self::UPLOAD_MEDIA_TYPE == $uploadType) { $contentType = $mimeType; $postBody = $this->data; } else if (self::UPLOAD_MULTIPART_TYPE == $uploadType) { // This is a multipart/related upload. $boundary = $this->boundary ? $this->boundary : mt_rand(); $boundary = str_replace('"', '', $boundary); $contentType = 'multipart/related; boundary=' . $boundary; $related = "--$boundary\r\n"; $related .= "Content-Type: application/json; charset=UTF-8\r\n"; $related .= "\r\n" . json_encode($meta) . "\r\n"; $related .= "--$boundary\r\n"; $related .= "Content-Type: $mimeType\r\n"; $related .= "Content-Transfer-Encoding: base64\r\n"; $related .= "\r\n" . base64_encode($this->data) . "\r\n"; $related .= "--$boundary--"; $postBody = $related; } $this->request->setPostBody($postBody); if (isset($contentType) && $contentType) { $contentTypeHeader['content-type'] = $contentType; $this->request->setRequestHeaders($contentTypeHeader); } } private function transformToUploadUrl() { $base = $this->request->getBaseComponent(); $this->request->setBaseComponent($base . '/upload'); } /** * Valid upload types: * - resumable (UPLOAD_RESUMABLE_TYPE) * - media (UPLOAD_MEDIA_TYPE) * - multipart (UPLOAD_MULTIPART_TYPE) * @param $meta * @return string * @visible for testing */ public function getUploadType($meta) { if ($this->resumable) { return self::UPLOAD_RESUMABLE_TYPE; } if (false == $meta && $this->data) { return self::UPLOAD_MEDIA_TYPE; } return self::UPLOAD_MULTIPART_TYPE; } public function getResumeUri() { return ( $this->resumeUri !== null ? $this->resumeUri : $this->fetchResumeUri() ); } private function fetchResumeUri() { $result = null; $body = $this->request->getPostBody(); if ($body) { $headers = array( 'content-type' => 'application/json; charset=UTF-8', 'content-length' => Google_Utils::getStrLen($body), 'x-upload-content-type' => $this->mimeType, 'x-upload-content-length' => $this->size, 'expect' => '', ); $this->request->setRequestHeaders($headers); } $response = $this->client->getIo()->makeRequest($this->request); $location = $response->getResponseHeader('location'); $code = $response->getResponseHttpCode(); if (200 == $code && true == $location) { return $location; } $message = $code; $body = @json_decode($response->getResponseBody()); if (!empty($body->error->errors) ) { $message .= ': '; foreach ($body->error->errors as $error) { $message .= "{$error->domain}, {$error->message};"; } $message = rtrim($message, ';'); } $error = "Failed to start the resumable upload (HTTP {$message})"; $this->client->getLogger()->error($error); throw new Google_Exception($error); } public function setChunkSize($chunkSize) { $this->chunkSize = $chunkSize; } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0.02 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�