33 changed files with 7936 additions and 2 deletions
-
203apps/files_external/3rdparty/google-api-php-client/LICENSE
-
4apps/files_external/3rdparty/google-api-php-client/NOTICE
-
40apps/files_external/3rdparty/google-api-php-client/README
-
462apps/files_external/3rdparty/google-api-php-client/src/Google_Client.php
-
104apps/files_external/3rdparty/google-api-php-client/src/auth/Google_AssertionCredentials.php
-
36apps/files_external/3rdparty/google-api-php-client/src/auth/Google_Auth.php
-
48apps/files_external/3rdparty/google-api-php-client/src/auth/Google_AuthNone.php
-
63apps/files_external/3rdparty/google-api-php-client/src/auth/Google_LoginTicket.php
-
445apps/files_external/3rdparty/google-api-php-client/src/auth/Google_OAuth2.php
-
70apps/files_external/3rdparty/google-api-php-client/src/auth/Google_P12Signer.php
-
66apps/files_external/3rdparty/google-api-php-client/src/auth/Google_PemVerifier.php
-
30apps/files_external/3rdparty/google-api-php-client/src/auth/Google_Signer.php
-
31apps/files_external/3rdparty/google-api-php-client/src/auth/Google_Verifier.php
-
98apps/files_external/3rdparty/google-api-php-client/src/cache/Google_ApcCache.php
-
55apps/files_external/3rdparty/google-api-php-client/src/cache/Google_Cache.php
-
137apps/files_external/3rdparty/google-api-php-client/src/cache/Google_FileCache.php
-
130apps/files_external/3rdparty/google-api-php-client/src/cache/Google_MemcacheCache.php
-
81apps/files_external/3rdparty/google-api-php-client/src/config.php
-
3143apps/files_external/3rdparty/google-api-php-client/src/contrib/Google_DriveService.php
-
209apps/files_external/3rdparty/google-api-php-client/src/external/URITemplateParser.php
-
173apps/files_external/3rdparty/google-api-php-client/src/io/Google_CacheParser.php
-
278apps/files_external/3rdparty/google-api-php-client/src/io/Google_CurlIO.php
-
304apps/files_external/3rdparty/google-api-php-client/src/io/Google_HttpRequest.php
-
49apps/files_external/3rdparty/google-api-php-client/src/io/Google_IO.php
-
128apps/files_external/3rdparty/google-api-php-client/src/io/Google_REST.php
-
714apps/files_external/3rdparty/google-api-php-client/src/io/cacerts.pem
-
110apps/files_external/3rdparty/google-api-php-client/src/service/Google_BatchRequest.php
-
262apps/files_external/3rdparty/google-api-php-client/src/service/Google_MediaFileUpload.php
-
115apps/files_external/3rdparty/google-api-php-client/src/service/Google_Model.php
-
22apps/files_external/3rdparty/google-api-php-client/src/service/Google_Service.php
-
205apps/files_external/3rdparty/google-api-php-client/src/service/Google_ServiceResource.php
-
117apps/files_external/3rdparty/google-api-php-client/src/service/Google_Utils.php
-
6apps/files_external/lib/google.php
@ -0,0 +1,203 @@ |
|||
Apache License |
|||
Version 2.0, January 2004 |
|||
http://www.apache.org/licenses/ |
|||
|
|||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
|||
|
|||
1. Definitions. |
|||
|
|||
"License" shall mean the terms and conditions for use, reproduction, |
|||
and distribution as defined by Sections 1 through 9 of this document. |
|||
|
|||
"Licensor" shall mean the copyright owner or entity authorized by |
|||
the copyright owner that is granting the License. |
|||
|
|||
"Legal Entity" shall mean the union of the acting entity and all |
|||
other entities that control, are controlled by, or are under common |
|||
control with that entity. For the purposes of this definition, |
|||
"control" means (i) the power, direct or indirect, to cause the |
|||
direction or management of such entity, whether by contract or |
|||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
|||
outstanding shares, or (iii) beneficial ownership of such entity. |
|||
|
|||
"You" (or "Your") shall mean an individual or Legal Entity |
|||
exercising permissions granted by this License. |
|||
|
|||
"Source" form shall mean the preferred form for making modifications, |
|||
including but not limited to software source code, documentation |
|||
source, and configuration files. |
|||
|
|||
"Object" form shall mean any form resulting from mechanical |
|||
transformation or translation of a Source form, including but |
|||
not limited to compiled object code, generated documentation, |
|||
and conversions to other media types. |
|||
|
|||
"Work" shall mean the work of authorship, whether in Source or |
|||
Object form, made available under the License, as indicated by a |
|||
copyright notice that is included in or attached to the work |
|||
(an example is provided in the Appendix below). |
|||
|
|||
"Derivative Works" shall mean any work, whether in Source or Object |
|||
form, that is based on (or derived from) the Work and for which the |
|||
editorial revisions, annotations, elaborations, or other modifications |
|||
represent, as a whole, an original work of authorship. For the purposes |
|||
of this License, Derivative Works shall not include works that remain |
|||
separable from, or merely link (or bind by name) to the interfaces of, |
|||
the Work and Derivative Works thereof. |
|||
|
|||
"Contribution" shall mean any work of authorship, including |
|||
the original version of the Work and any modifications or additions |
|||
to that Work or Derivative Works thereof, that is intentionally |
|||
submitted to Licensor for inclusion in the Work by the copyright owner |
|||
or by an individual or Legal Entity authorized to submit on behalf of |
|||
the copyright owner. For the purposes of this definition, "submitted" |
|||
means any form of electronic, verbal, or written communication sent |
|||
to the Licensor or its representatives, including but not limited to |
|||
communication on electronic mailing lists, source code control systems, |
|||
and issue tracking systems that are managed by, or on behalf of, the |
|||
Licensor for the purpose of discussing and improving the Work, but |
|||
excluding communication that is conspicuously marked or otherwise |
|||
designated in writing by the copyright owner as "Not a Contribution." |
|||
|
|||
"Contributor" shall mean Licensor and any individual or Legal Entity |
|||
on behalf of whom a Contribution has been received by Licensor and |
|||
subsequently incorporated within the Work. |
|||
|
|||
2. Grant of Copyright License. Subject to the terms and conditions of |
|||
this License, each Contributor hereby grants to You a perpetual, |
|||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|||
copyright license to reproduce, prepare Derivative Works of, |
|||
publicly display, publicly perform, sublicense, and distribute the |
|||
Work and such Derivative Works in Source or Object form. |
|||
|
|||
3. Grant of Patent License. Subject to the terms and conditions of |
|||
this License, each Contributor hereby grants to You a perpetual, |
|||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|||
(except as stated in this section) patent license to make, have made, |
|||
use, offer to sell, sell, import, and otherwise transfer the Work, |
|||
where such license applies only to those patent claims licensable |
|||
by such Contributor that are necessarily infringed by their |
|||
Contribution(s) alone or by combination of their Contribution(s) |
|||
with the Work to which such Contribution(s) was submitted. If You |
|||
institute patent litigation against any entity (including a |
|||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
|||
or a Contribution incorporated within the Work constitutes direct |
|||
or contributory patent infringement, then any patent licenses |
|||
granted to You under this License for that Work shall terminate |
|||
as of the date such litigation is filed. |
|||
|
|||
4. Redistribution. You may reproduce and distribute copies of the |
|||
Work or Derivative Works thereof in any medium, with or without |
|||
modifications, and in Source or Object form, provided that You |
|||
meet the following conditions: |
|||
|
|||
(a) You must give any other recipients of the Work or |
|||
Derivative Works a copy of this License; and |
|||
|
|||
(b) You must cause any modified files to carry prominent notices |
|||
stating that You changed the files; and |
|||
|
|||
(c) You must retain, in the Source form of any Derivative Works |
|||
that You distribute, all copyright, patent, trademark, and |
|||
attribution notices from the Source form of the Work, |
|||
excluding those notices that do not pertain to any part of |
|||
the Derivative Works; and |
|||
|
|||
(d) If the Work includes a "NOTICE" text file as part of its |
|||
distribution, then any Derivative Works that You distribute must |
|||
include a readable copy of the attribution notices contained |
|||
within such NOTICE file, excluding those notices that do not |
|||
pertain to any part of the Derivative Works, in at least one |
|||
of the following places: within a NOTICE text file distributed |
|||
as part of the Derivative Works; within the Source form or |
|||
documentation, if provided along with the Derivative Works; or, |
|||
within a display generated by the Derivative Works, if and |
|||
wherever such third-party notices normally appear. The contents |
|||
of the NOTICE file are for informational purposes only and |
|||
do not modify the License. You may add Your own attribution |
|||
notices within Derivative Works that You distribute, alongside |
|||
or as an addendum to the NOTICE text from the Work, provided |
|||
that such additional attribution notices cannot be construed |
|||
as modifying the License. |
|||
|
|||
You may add Your own copyright statement to Your modifications and |
|||
may provide additional or different license terms and conditions |
|||
for use, reproduction, or distribution of Your modifications, or |
|||
for any such Derivative Works as a whole, provided Your use, |
|||
reproduction, and distribution of the Work otherwise complies with |
|||
the conditions stated in this License. |
|||
|
|||
5. Submission of Contributions. Unless You explicitly state otherwise, |
|||
any Contribution intentionally submitted for inclusion in the Work |
|||
by You to the Licensor shall be under the terms and conditions of |
|||
this License, without any additional terms or conditions. |
|||
Notwithstanding the above, nothing herein shall supersede or modify |
|||
the terms of any separate license agreement you may have executed |
|||
with Licensor regarding such Contributions. |
|||
|
|||
6. Trademarks. This License does not grant permission to use the trade |
|||
names, trademarks, service marks, or product names of the Licensor, |
|||
except as required for reasonable and customary use in describing the |
|||
origin of the Work and reproducing the content of the NOTICE file. |
|||
|
|||
7. Disclaimer of Warranty. Unless required by applicable law or |
|||
agreed to in writing, Licensor provides the Work (and each |
|||
Contributor provides its Contributions) on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|||
implied, including, without limitation, any warranties or conditions |
|||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
|||
PARTICULAR PURPOSE. You are solely responsible for determining the |
|||
appropriateness of using or redistributing the Work and assume any |
|||
risks associated with Your exercise of permissions under this License. |
|||
|
|||
8. Limitation of Liability. In no event and under no legal theory, |
|||
whether in tort (including negligence), contract, or otherwise, |
|||
unless required by applicable law (such as deliberate and grossly |
|||
negligent acts) or agreed to in writing, shall any Contributor be |
|||
liable to You for damages, including any direct, indirect, special, |
|||
incidental, or consequential damages of any character arising as a |
|||
result of this License or out of the use or inability to use the |
|||
Work (including but not limited to damages for loss of goodwill, |
|||
work stoppage, computer failure or malfunction, or any and all |
|||
other commercial damages or losses), even if such Contributor |
|||
has been advised of the possibility of such damages. |
|||
|
|||
9. Accepting Warranty or Additional Liability. While redistributing |
|||
the Work or Derivative Works thereof, You may choose to offer, |
|||
and charge a fee for, acceptance of support, warranty, indemnity, |
|||
or other liability obligations and/or rights consistent with this |
|||
License. However, in accepting such obligations, You may act only |
|||
on Your own behalf and on Your sole responsibility, not on behalf |
|||
of any other Contributor, and only if You agree to indemnify, |
|||
defend, and hold each Contributor harmless for any liability |
|||
incurred by, or claims asserted against, such Contributor by reason |
|||
of your accepting any such warranty or additional liability. |
|||
|
|||
END OF TERMS AND CONDITIONS |
|||
|
|||
APPENDIX: How to apply the Apache License to your work. |
|||
|
|||
To apply the Apache License to your work, attach the following |
|||
boilerplate notice, with the fields enclosed by brackets "[]" |
|||
replaced with your own identifying information. (Don't include |
|||
the brackets!) The text should be enclosed in the appropriate |
|||
comment syntax for the file format. We also recommend that a |
|||
file or class name and description of purpose be included on the |
|||
same "printed page" as the copyright notice for easier |
|||
identification within third-party archives. |
|||
|
|||
Copyright [yyyy] [name of copyright owner] |
|||
|
|||
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. |
|||
|
|||
|
|||
@ -0,0 +1,4 @@ |
|||
This product contains the following libraries: |
|||
|
|||
XRDS-Simple library from http://code.google.com/p/diso/ |
|||
Apache License 2.0 |
|||
@ -0,0 +1,40 @@ |
|||
Google APIs Client Library for PHP |
|||
===================================== |
|||
|
|||
== Description |
|||
The Google API Client Library enables you to work with Google APIs such as Google+, Drive, Tasks, or Latitude on your server. |
|||
|
|||
Requirements: |
|||
PHP 5.2.x or higher [http://www.php.net/] |
|||
PHP Curl extension [http://www.php.net/manual/en/intro.curl.php] |
|||
PHP JSON extension [http://php.net/manual/en/book.json.php] |
|||
|
|||
Project page: |
|||
http://code.google.com/p/google-api-php-client |
|||
|
|||
OAuth 2 instructions: |
|||
http://code.google.com/p/google-api-php-client/wiki/OAuth2 |
|||
|
|||
Report a defect or feature request here: |
|||
http://code.google.com/p/google-api-php-client/issues/entry |
|||
|
|||
Subscribe to project updates in your feed reader: |
|||
http://code.google.com/feeds/p/google-api-php-client/updates/basic |
|||
|
|||
Supported sample applications: |
|||
http://code.google.com/p/google-api-php-client/wiki/Samples |
|||
|
|||
== Basic Example |
|||
<?php |
|||
require_once 'path/to/src/Google_Client.php'; |
|||
require_once 'path/to/src/contrib/apiBooksService.php'; |
|||
|
|||
$client = new Google_Client(); |
|||
$service = new Google_BooksService($client); |
|||
|
|||
$optParams = array('filter' => 'free-ebooks'); |
|||
$results = $service->volumes->listVolumes('Henry David Thoreau', $optParams); |
|||
|
|||
foreach ($results['items'] as $item) { |
|||
print($item['volumeInfo']['title'] . '<br>'); |
|||
} |
|||
@ -0,0 +1,462 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
// Check for the required json and curl extensions, the Google APIs PHP Client
|
|||
// won't function without them.
|
|||
if (! function_exists('curl_init')) { |
|||
throw new Exception('Google PHP API Client requires the CURL PHP extension'); |
|||
} |
|||
|
|||
if (! function_exists('json_decode')) { |
|||
throw new Exception('Google PHP API Client requires the JSON PHP extension'); |
|||
} |
|||
|
|||
if (! function_exists('http_build_query')) { |
|||
throw new Exception('Google PHP API Client requires http_build_query()'); |
|||
} |
|||
|
|||
if (! ini_get('date.timezone') && function_exists('date_default_timezone_set')) { |
|||
date_default_timezone_set('UTC'); |
|||
} |
|||
|
|||
// hack around with the include paths a bit so the library 'just works'
|
|||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path()); |
|||
|
|||
require_once "config.php"; |
|||
// If a local configuration file is found, merge it's values with the default configuration
|
|||
if (file_exists(dirname(__FILE__) . '/local_config.php')) { |
|||
$defaultConfig = $apiConfig; |
|||
require_once (dirname(__FILE__) . '/local_config.php'); |
|||
$apiConfig = array_merge($defaultConfig, $apiConfig); |
|||
} |
|||
|
|||
// Include the top level classes, they each include their own dependencies
|
|||
require_once 'service/Google_Model.php'; |
|||
require_once 'service/Google_Service.php'; |
|||
require_once 'service/Google_ServiceResource.php'; |
|||
require_once 'auth/Google_AssertionCredentials.php'; |
|||
require_once 'auth/Google_Signer.php'; |
|||
require_once 'auth/Google_P12Signer.php'; |
|||
require_once 'service/Google_BatchRequest.php'; |
|||
require_once 'external/URITemplateParser.php'; |
|||
require_once 'auth/Google_Auth.php'; |
|||
require_once 'cache/Google_Cache.php'; |
|||
require_once 'io/Google_IO.php'; |
|||
require_once('service/Google_MediaFileUpload.php'); |
|||
|
|||
/** |
|||
* The Google API Client |
|||
* http://code.google.com/p/google-api-php-client/ |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_Client { |
|||
/** |
|||
* @static |
|||
* @var Google_Auth $auth |
|||
*/ |
|||
static $auth; |
|||
|
|||
/** |
|||
* @static |
|||
* @var Google_IO $io |
|||
*/ |
|||
static $io; |
|||
|
|||
/** |
|||
* @static |
|||
* @var Google_Cache $cache |
|||
*/ |
|||
static $cache; |
|||
|
|||
/** |
|||
* @static |
|||
* @var boolean $useBatch |
|||
*/ |
|||
static $useBatch = false; |
|||
|
|||
/** @var array $scopes */ |
|||
protected $scopes = array(); |
|||
|
|||
/** @var bool $useObjects */ |
|||
protected $useObjects = false; |
|||
|
|||
// definitions of services that are discovered.
|
|||
protected $services = array(); |
|||
|
|||
// Used to track authenticated state, can't discover services after doing authenticate()
|
|||
private $authenticated = false; |
|||
|
|||
public function __construct($config = array()) { |
|||
global $apiConfig; |
|||
$apiConfig = array_merge($apiConfig, $config); |
|||
self::$cache = new $apiConfig['cacheClass'](); |
|||
self::$auth = new $apiConfig['authClass'](); |
|||
self::$io = new $apiConfig['ioClass'](); |
|||
} |
|||
|
|||
/** |
|||
* Add a service |
|||
*/ |
|||
public function addService($service, $version = false) { |
|||
global $apiConfig; |
|||
if ($this->authenticated) { |
|||
throw new Google_Exception('Cant add services after having authenticated'); |
|||
} |
|||
$this->services[$service] = array(); |
|||
if (isset($apiConfig['services'][$service])) { |
|||
// Merge the service descriptor with the default values
|
|||
$this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]); |
|||
} |
|||
} |
|||
|
|||
public function authenticate($code = null) { |
|||
$service = $this->prepareService(); |
|||
$this->authenticated = true; |
|||
return self::$auth->authenticate($service, $code); |
|||
} |
|||
|
|||
/** |
|||
* @return array |
|||
* @visible For Testing |
|||
*/ |
|||
public function prepareService() { |
|||
$service = array(); |
|||
$scopes = array(); |
|||
if ($this->scopes) { |
|||
$scopes = $this->scopes; |
|||
} else { |
|||
foreach ($this->services as $key => $val) { |
|||
if (isset($val['scope'])) { |
|||
if (is_array($val['scope'])) { |
|||
$scopes = array_merge($val['scope'], $scopes); |
|||
} else { |
|||
$scopes[] = $val['scope']; |
|||
} |
|||
} else { |
|||
$scopes[] = 'https://www.googleapis.com/auth/' . $key; |
|||
} |
|||
unset($val['discoveryURI']); |
|||
unset($val['scope']); |
|||
$service = array_merge($service, $val); |
|||
} |
|||
} |
|||
$service['scope'] = implode(' ', $scopes); |
|||
return $service; |
|||
} |
|||
|
|||
/** |
|||
* Set the OAuth 2.0 access token using the string that resulted from calling authenticate() |
|||
* or Google_Client#getAccessToken().
|
|||
* @param string $accessToken JSON encoded string containing in the following format: |
|||
* {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer", |
|||
* "expires_in":3600, "id_token":"TOKEN", "created":1320790426} |
|||
*/ |
|||
public function setAccessToken($accessToken) { |
|||
if ($accessToken == null || 'null' == $accessToken) { |
|||
$accessToken = null; |
|||
} |
|||
self::$auth->setAccessToken($accessToken); |
|||
} |
|||
|
|||
/** |
|||
* Set the type of Auth class the client should use. |
|||
* @param string $authClassName |
|||
*/ |
|||
public function setAuthClass($authClassName) { |
|||
self::$auth = new $authClassName(); |
|||
} |
|||
|
|||
/** |
|||
* Construct the OAuth 2.0 authorization request URI. |
|||
* @return string |
|||
*/ |
|||
public function createAuthUrl() { |
|||
$service = $this->prepareService(); |
|||
return self::$auth->createAuthUrl($service['scope']); |
|||
} |
|||
|
|||
/** |
|||
* Get the OAuth 2.0 access token. |
|||
* @return string $accessToken JSON encoded string in the following format: |
|||
* {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer", |
|||
* "expires_in":3600,"id_token":"TOKEN", "created":1320790426} |
|||
*/ |
|||
public function getAccessToken() { |
|||
$token = self::$auth->getAccessToken(); |
|||
return (null == $token || 'null' == $token) ? null : $token; |
|||
} |
|||
|
|||
/** |
|||
* Returns if the access_token is expired. |
|||
* @return bool Returns True if the access_token is expired. |
|||
*/ |
|||
public function isAccessTokenExpired() { |
|||
return self::$auth->isAccessTokenExpired(); |
|||
} |
|||
|
|||
/** |
|||
* Set the developer key to use, these are obtained through the API Console. |
|||
* @see http://code.google.com/apis/console-help/#generatingdevkeys
|
|||
* @param string $developerKey |
|||
*/ |
|||
public function setDeveloperKey($developerKey) { |
|||
self::$auth->setDeveloperKey($developerKey); |
|||
} |
|||
|
|||
/** |
|||
* Set OAuth 2.0 "state" parameter to achieve per-request customization. |
|||
* @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
|
|||
* @param string $state |
|||
*/ |
|||
public function setState($state) { |
|||
self::$auth->setState($state); |
|||
} |
|||
|
|||
/** |
|||
* @param string $accessType Possible values for access_type include: |
|||
* {@code "offline"} to request offline access from the user. (This is the default value) |
|||
* {@code "online"} to request online access from the user. |
|||
*/ |
|||
public function setAccessType($accessType) { |
|||
self::$auth->setAccessType($accessType); |
|||
} |
|||
|
|||
/** |
|||
* @param string $approvalPrompt Possible values for approval_prompt include: |
|||
* {@code "force"} to force the approval UI to appear. (This is the default value) |
|||
* {@code "auto"} to request auto-approval when possible. |
|||
*/ |
|||
public function setApprovalPrompt($approvalPrompt) { |
|||
self::$auth->setApprovalPrompt($approvalPrompt); |
|||
} |
|||
|
|||
/** |
|||
* Set the application name, this is included in the User-Agent HTTP header. |
|||
* @param string $applicationName |
|||
*/ |
|||
public function setApplicationName($applicationName) { |
|||
global $apiConfig; |
|||
$apiConfig['application_name'] = $applicationName; |
|||
} |
|||
|
|||
/** |
|||
* Set the OAuth 2.0 Client ID. |
|||
* @param string $clientId |
|||
*/ |
|||
public function setClientId($clientId) { |
|||
global $apiConfig; |
|||
$apiConfig['oauth2_client_id'] = $clientId; |
|||
self::$auth->clientId = $clientId; |
|||
} |
|||
|
|||
/** |
|||
* Get the OAuth 2.0 Client ID. |
|||
*/ |
|||
public function getClientId() { |
|||
return self::$auth->clientId; |
|||
} |
|||
|
|||
/** |
|||
* Set the OAuth 2.0 Client Secret. |
|||
* @param string $clientSecret |
|||
*/ |
|||
public function setClientSecret($clientSecret) { |
|||
global $apiConfig; |
|||
$apiConfig['oauth2_client_secret'] = $clientSecret; |
|||
self::$auth->clientSecret = $clientSecret; |
|||
} |
|||
|
|||
/** |
|||
* Get the OAuth 2.0 Client Secret. |
|||
*/ |
|||
public function getClientSecret() { |
|||
return self::$auth->clientSecret; |
|||
} |
|||
|
|||
/** |
|||
* Set the OAuth 2.0 Redirect URI. |
|||
* @param string $redirectUri |
|||
*/ |
|||
public function setRedirectUri($redirectUri) { |
|||
global $apiConfig; |
|||
$apiConfig['oauth2_redirect_uri'] = $redirectUri; |
|||
self::$auth->redirectUri = $redirectUri; |
|||
} |
|||
|
|||
/** |
|||
* Get the OAuth 2.0 Redirect URI. |
|||
*/ |
|||
public function getRedirectUri() { |
|||
return self::$auth->redirectUri; |
|||
} |
|||
|
|||
/** |
|||
* Fetches a fresh OAuth 2.0 access token with the given refresh token. |
|||
* @param string $refreshToken |
|||
* @return void |
|||
*/ |
|||
public function refreshToken($refreshToken) { |
|||
self::$auth->refreshToken($refreshToken); |
|||
} |
|||
|
|||
/** |
|||
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access |
|||
* token, if a token isn't provided. |
|||
* @throws Google_AuthException |
|||
* @param string|null $token The token (access token or a refresh token) that should be revoked. |
|||
* @return boolean Returns True if the revocation was successful, otherwise False. |
|||
*/ |
|||
public function revokeToken($token = null) { |
|||
self::$auth->revokeToken($token); |
|||
} |
|||
|
|||
/** |
|||
* Verify an id_token. This method will verify the current id_token, if one |
|||
* isn't provided. |
|||
* @throws Google_AuthException |
|||
* @param string|null $token The token (id_token) that should be verified. |
|||
* @return Google_LoginTicket Returns an apiLoginTicket if the verification was |
|||
* successful. |
|||
*/ |
|||
public function verifyIdToken($token = null) { |
|||
return self::$auth->verifyIdToken($token); |
|||
} |
|||
|
|||
/** |
|||
* @param Google_AssertionCredentials $creds |
|||
* @return void |
|||
*/ |
|||
public function setAssertionCredentials(Google_AssertionCredentials $creds) { |
|||
self::$auth->setAssertionCredentials($creds); |
|||
} |
|||
|
|||
/** |
|||
* This function allows you to overrule the automatically generated scopes, |
|||
* so that you can ask for more or less permission in the auth flow |
|||
* Set this before you call authenticate() though! |
|||
* @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/moderator') |
|||
*/ |
|||
public function setScopes($scopes) { |
|||
$this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes; |
|||
} |
|||
|
|||
/** |
|||
* Returns the list of scopes set on the client |
|||
* @return array the list of scopes |
|||
* |
|||
*/ |
|||
public function getScopes() { |
|||
return $this->scopes; |
|||
} |
|||
|
|||
/** |
|||
* Declare if objects should be returned by the api service classes. |
|||
* |
|||
* @param boolean $useObjects True if objects should be returned by the service classes. |
|||
* False if associative arrays should be returned (default behavior). |
|||
* @experimental |
|||
*/ |
|||
public function setUseObjects($useObjects) { |
|||
global $apiConfig; |
|||
$apiConfig['use_objects'] = $useObjects; |
|||
} |
|||
|
|||
/** |
|||
* Declare if objects should be returned by the api service classes. |
|||
* |
|||
* @param boolean $useBatch True if the experimental batch support should |
|||
* be enabled. Defaults to False. |
|||
* @experimental |
|||
*/ |
|||
public function setUseBatch($useBatch) { |
|||
self::$useBatch = $useBatch; |
|||
} |
|||
|
|||
/** |
|||
* @static |
|||
* @return Google_Auth the implementation of apiAuth. |
|||
*/ |
|||
public static function getAuth() { |
|||
return Google_Client::$auth; |
|||
} |
|||
|
|||
/** |
|||
* @static |
|||
* @return Google_IO the implementation of apiIo. |
|||
*/ |
|||
public static function getIo() { |
|||
return Google_Client::$io; |
|||
} |
|||
|
|||
/** |
|||
* @return Google_Cache the implementation of apiCache. |
|||
*/ |
|||
public function getCache() { |
|||
return Google_Client::$cache; |
|||
} |
|||
} |
|||
|
|||
// Exceptions that the Google PHP API Library can throw
|
|||
class Google_Exception extends Exception {} |
|||
class Google_AuthException extends Google_Exception {} |
|||
class Google_CacheException extends Google_Exception {} |
|||
class Google_IOException extends Google_Exception {} |
|||
class Google_ServiceException extends Google_Exception { |
|||
/** |
|||
* Optional list of errors returned in a JSON body of an HTTP error response. |
|||
*/ |
|||
protected $errors = array(); |
|||
|
|||
/** |
|||
* Override default constructor to add ability to set $errors. |
|||
* |
|||
* @param string $message |
|||
* @param int $code |
|||
* @param Exception|null $previous |
|||
* @param [{string, string}] errors List of errors returned in an HTTP |
|||
* response. Defaults to []. |
|||
*/ |
|||
public function __construct($message, $code = 0, Exception $previous = null, |
|||
$errors = array()) { |
|||
if(version_compare(PHP_VERSION, '5.3.0') >= 0) { |
|||
parent::__construct($message, $code, $previous); |
|||
} else { |
|||
parent::__construct($message, $code); |
|||
} |
|||
|
|||
$this->errors = $errors; |
|||
} |
|||
|
|||
/** |
|||
* An example of the possible errors returned. |
|||
* |
|||
* { |
|||
* "domain": "global", |
|||
* "reason": "authError", |
|||
* "message": "Invalid Credentials", |
|||
* "locationType": "header", |
|||
* "location": "Authorization", |
|||
* } |
|||
* |
|||
* @return [{string, string}] List of errors return in an HTTP response or []. |
|||
*/ |
|||
public function getErrors() { |
|||
return $this->errors; |
|||
} |
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* Credentials object used for OAuth 2.0 Signed JWT assertion grants. |
|||
* |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_AssertionCredentials { |
|||
const MAX_TOKEN_LIFETIME_SECS = 3600; |
|||
|
|||
public $serviceAccountName; |
|||
public $scopes; |
|||
public $privateKey; |
|||
public $privateKeyPassword; |
|||
public $assertionType; |
|||
public $sub; |
|||
/** |
|||
* @deprecated |
|||
* @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06 |
|||
*/ |
|||
public $prn; |
|||
|
|||
/** |
|||
* @param $serviceAccountName |
|||
* @param $scopes array List of scopes |
|||
* @param $privateKey |
|||
* @param string $privateKeyPassword |
|||
* @param string $assertionType |
|||
* @param bool|string $sub The email address of the user for which the |
|||
* application is requesting delegated access. |
|||
* |
|||
*/ |
|||
public function __construct( |
|||
$serviceAccountName, |
|||
$scopes, |
|||
$privateKey, |
|||
$privateKeyPassword = 'notasecret', |
|||
$assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer', |
|||
$sub = false) { |
|||
$this->serviceAccountName = $serviceAccountName; |
|||
$this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes); |
|||
$this->privateKey = $privateKey; |
|||
$this->privateKeyPassword = $privateKeyPassword; |
|||
$this->assertionType = $assertionType; |
|||
$this->sub = $sub; |
|||
$this->prn = $sub; |
|||
} |
|||
|
|||
public function generateAssertion() { |
|||
$now = time(); |
|||
|
|||
$jwtParams = array( |
|||
'aud' => Google_OAuth2::OAUTH2_TOKEN_URI, |
|||
'scope' => $this->scopes, |
|||
'iat' => $now, |
|||
'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS, |
|||
'iss' => $this->serviceAccountName, |
|||
); |
|||
|
|||
if ($this->sub !== false) { |
|||
$jwtParams['sub'] = $this->sub; |
|||
} else if ($this->prn !== false) { |
|||
$jwtParams['prn'] = $this->prn; |
|||
} |
|||
|
|||
return $this->makeSignedJwt($jwtParams); |
|||
} |
|||
|
|||
/** |
|||
* Creates a signed JWT. |
|||
* @param array $payload |
|||
* @return string The signed JWT. |
|||
*/ |
|||
private function makeSignedJwt($payload) { |
|||
$header = array('typ' => 'JWT', 'alg' => 'RS256'); |
|||
|
|||
$segments = array( |
|||
Google_Utils::urlSafeB64Encode(json_encode($header)), |
|||
Google_Utils::urlSafeB64Encode(json_encode($payload)) |
|||
); |
|||
|
|||
$signingInput = implode('.', $segments); |
|||
$signer = new Google_P12Signer($this->privateKey, $this->privateKeyPassword); |
|||
$signature = $signer->sign($signingInput); |
|||
$segments[] = Google_Utils::urlSafeB64Encode($signature); |
|||
|
|||
return implode(".", $segments); |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
require_once "Google_AuthNone.php"; |
|||
require_once "Google_OAuth2.php"; |
|||
|
|||
/** |
|||
* Abstract class for the Authentication in the API client |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* |
|||
*/ |
|||
abstract class Google_Auth { |
|||
abstract public function authenticate($service); |
|||
abstract public function sign(Google_HttpRequest $request); |
|||
abstract public function createAuthUrl($scope); |
|||
|
|||
abstract public function getAccessToken(); |
|||
abstract public function setAccessToken($accessToken); |
|||
abstract public function setDeveloperKey($developerKey); |
|||
abstract public function refreshToken($refreshToken); |
|||
abstract public function revokeToken(); |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* Do-nothing authentication implementation, use this if you want to make un-authenticated calls |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_AuthNone extends Google_Auth { |
|||
public $key = null; |
|||
|
|||
public function __construct() { |
|||
global $apiConfig; |
|||
if (!empty($apiConfig['developer_key'])) { |
|||
$this->setDeveloperKey($apiConfig['developer_key']); |
|||
} |
|||
} |
|||
|
|||
public function setDeveloperKey($key) {$this->key = $key;} |
|||
public function authenticate($service) {/*noop*/} |
|||
public function setAccessToken($accessToken) {/* noop*/} |
|||
public function getAccessToken() {return null;} |
|||
public function createAuthUrl($scope) {return null;} |
|||
public function refreshToken($refreshToken) {/* noop*/} |
|||
public function revokeToken() {/* noop*/} |
|||
|
|||
public function sign(Google_HttpRequest $request) { |
|||
if ($this->key) { |
|||
$request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&') |
|||
. 'key='.urlencode($this->key)); |
|||
} |
|||
return $request; |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Class to hold information about an authenticated login. |
|||
* |
|||
* @author Brian Eaton <beaton@google.com> |
|||
*/ |
|||
class Google_LoginTicket { |
|||
const USER_ATTR = "id"; |
|||
|
|||
// Information from id token envelope.
|
|||
private $envelope; |
|||
|
|||
// Information from id token payload.
|
|||
private $payload; |
|||
|
|||
/** |
|||
* Creates a user based on the supplied token. |
|||
* |
|||
* @param string $envelope Header from a verified authentication token. |
|||
* @param string $payload Information from a verified authentication token. |
|||
*/ |
|||
public function __construct($envelope, $payload) { |
|||
$this->envelope = $envelope; |
|||
$this->payload = $payload; |
|||
} |
|||
|
|||
/** |
|||
* Returns the numeric identifier for the user. |
|||
* @throws Google_AuthException |
|||
* @return |
|||
*/ |
|||
public function getUserId() { |
|||
if (array_key_exists(self::USER_ATTR, $this->payload)) { |
|||
return $this->payload[self::USER_ATTR]; |
|||
} |
|||
throw new Google_AuthException("No user_id in token"); |
|||
} |
|||
|
|||
/** |
|||
* Returns attributes from the login ticket. This can contain |
|||
* various information about the user session. |
|||
* @return array |
|||
*/ |
|||
public function getAttributes() { |
|||
return array("envelope" => $this->envelope, "payload" => $this->payload); |
|||
} |
|||
} |
|||
@ -0,0 +1,445 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2008 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. |
|||
*/ |
|||
|
|||
require_once "Google_Verifier.php"; |
|||
require_once "Google_LoginTicket.php"; |
|||
require_once "service/Google_Utils.php"; |
|||
|
|||
/** |
|||
* Authentication class that deals with the OAuth 2 web-server authentication flow |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* @author Chirag Shah <chirags@google.com> |
|||
* |
|||
*/ |
|||
class Google_OAuth2 extends Google_Auth { |
|||
public $clientId; |
|||
public $clientSecret; |
|||
public $developerKey; |
|||
public $token; |
|||
public $redirectUri; |
|||
public $state; |
|||
public $accessType = 'offline'; |
|||
public $approvalPrompt = 'force'; |
|||
|
|||
/** @var Google_AssertionCredentials $assertionCredentials */ |
|||
public $assertionCredentials; |
|||
|
|||
const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke'; |
|||
const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token'; |
|||
const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth'; |
|||
const OAUTH2_FEDERATED_SIGNON_CERTS_URL = 'https://www.googleapis.com/oauth2/v1/certs'; |
|||
const CLOCK_SKEW_SECS = 300; // five minutes in seconds
|
|||
const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
|
|||
const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
|
|||
|
|||
/** |
|||
* Instantiates the class, but does not initiate the login flow, leaving it |
|||
* to the discretion of the caller (which is done by calling authenticate()). |
|||
*/ |
|||
public function __construct() { |
|||
global $apiConfig; |
|||
|
|||
if (! empty($apiConfig['developer_key'])) { |
|||
$this->developerKey = $apiConfig['developer_key']; |
|||
} |
|||
|
|||
if (! empty($apiConfig['oauth2_client_id'])) { |
|||
$this->clientId = $apiConfig['oauth2_client_id']; |
|||
} |
|||
|
|||
if (! empty($apiConfig['oauth2_client_secret'])) { |
|||
$this->clientSecret = $apiConfig['oauth2_client_secret']; |
|||
} |
|||
|
|||
if (! empty($apiConfig['oauth2_redirect_uri'])) { |
|||
$this->redirectUri = $apiConfig['oauth2_redirect_uri']; |
|||
} |
|||
|
|||
if (! empty($apiConfig['oauth2_access_type'])) { |
|||
$this->accessType = $apiConfig['oauth2_access_type']; |
|||
} |
|||
|
|||
if (! empty($apiConfig['oauth2_approval_prompt'])) { |
|||
$this->approvalPrompt = $apiConfig['oauth2_approval_prompt']; |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @param $service |
|||
* @param string|null $code |
|||
* @throws Google_AuthException |
|||
* @return string |
|||
*/ |
|||
public function authenticate($service, $code = null) { |
|||
if (!$code && isset($_GET['code'])) { |
|||
$code = $_GET['code']; |
|||
} |
|||
|
|||
if ($code) { |
|||
// We got here from the redirect from a successful authorization grant, fetch the access token
|
|||
$request = Google_Client::$io->makeRequest(new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array( |
|||
'code' => $code, |
|||
'grant_type' => 'authorization_code', |
|||
'redirect_uri' => $this->redirectUri, |
|||
'client_id' => $this->clientId, |
|||
'client_secret' => $this->clientSecret |
|||
))); |
|||
|
|||
if ($request->getResponseHttpCode() == 200) { |
|||
$this->setAccessToken($request->getResponseBody()); |
|||
$this->token['created'] = time(); |
|||
return $this->getAccessToken(); |
|||
} else { |
|||
$response = $request->getResponseBody(); |
|||
$decodedResponse = json_decode($response, true); |
|||
if ($decodedResponse != null && $decodedResponse['error']) { |
|||
$response = $decodedResponse['error']; |
|||
} |
|||
throw new Google_AuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode()); |
|||
} |
|||
} |
|||
|
|||
$authUrl = $this->createAuthUrl($service['scope']); |
|||
header('Location: ' . $authUrl); |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* Create a URL to obtain user authorization. |
|||
* The authorization endpoint allows the user to first |
|||
* authenticate, and then grant/deny the access request. |
|||
* @param string $scope The scope is expressed as a list of space-delimited strings. |
|||
* @return string |
|||
*/ |
|||
public function createAuthUrl($scope) { |
|||
$params = array( |
|||
'response_type=code', |
|||
'redirect_uri=' . urlencode($this->redirectUri), |
|||
'client_id=' . urlencode($this->clientId), |
|||
'scope=' . urlencode($scope), |
|||
'access_type=' . urlencode($this->accessType), |
|||
'approval_prompt=' . urlencode($this->approvalPrompt), |
|||
); |
|||
|
|||
if (isset($this->state)) { |
|||
$params[] = 'state=' . urlencode($this->state); |
|||
} |
|||
$params = implode('&', $params); |
|||
return self::OAUTH2_AUTH_URL . "?$params"; |
|||
} |
|||
|
|||
/** |
|||
* @param string $token |
|||
* @throws Google_AuthException |
|||
*/ |
|||
public function setAccessToken($token) { |
|||
$token = json_decode($token, true); |
|||
if ($token == null) { |
|||
throw new Google_AuthException('Could not json decode the token'); |
|||
} |
|||
if (! isset($token['access_token'])) { |
|||
throw new Google_AuthException("Invalid token format"); |
|||
} |
|||
$this->token = $token; |
|||
} |
|||
|
|||
public function getAccessToken() { |
|||
return json_encode($this->token); |
|||
} |
|||
|
|||
public function setDeveloperKey($developerKey) { |
|||
$this->developerKey = $developerKey; |
|||
} |
|||
|
|||
public function setState($state) { |
|||
$this->state = $state; |
|||
} |
|||
|
|||
public function setAccessType($accessType) { |
|||
$this->accessType = $accessType; |
|||
} |
|||
|
|||
public function setApprovalPrompt($approvalPrompt) { |
|||
$this->approvalPrompt = $approvalPrompt; |
|||
} |
|||
|
|||
public function setAssertionCredentials(Google_AssertionCredentials $creds) { |
|||
$this->assertionCredentials = $creds; |
|||
} |
|||
|
|||
/** |
|||
* Include an accessToken in a given apiHttpRequest. |
|||
* @param Google_HttpRequest $request |
|||
* @return Google_HttpRequest |
|||
* @throws Google_AuthException |
|||
*/ |
|||
public function sign(Google_HttpRequest $request) { |
|||
// add the developer key to the request before signing it
|
|||
if ($this->developerKey) { |
|||
$requestUrl = $request->getUrl(); |
|||
$requestUrl .= (strpos($request->getUrl(), '?') === false) ? '?' : '&'; |
|||
$requestUrl .= 'key=' . urlencode($this->developerKey); |
|||
$request->setUrl($requestUrl); |
|||
} |
|||
|
|||
// Cannot sign the request without an OAuth access token.
|
|||
if (null == $this->token && null == $this->assertionCredentials) { |
|||
return $request; |
|||
} |
|||
|
|||
// Check if the token is set to expire in the next 30 seconds
|
|||
// (or has already expired).
|
|||
if ($this->isAccessTokenExpired()) { |
|||
if ($this->assertionCredentials) { |
|||
$this->refreshTokenWithAssertion(); |
|||
} else { |
|||
if (! array_key_exists('refresh_token', $this->token)) { |
|||
throw new Google_AuthException("The OAuth 2.0 access token has expired, " |
|||
. "and a refresh token is not available. Refresh tokens are not " |
|||
. "returned for responses that were auto-approved."); |
|||
} |
|||
$this->refreshToken($this->token['refresh_token']); |
|||
} |
|||
} |
|||
|
|||
// Add the OAuth2 header to the request
|
|||
$request->setRequestHeaders( |
|||
array('Authorization' => 'Bearer ' . $this->token['access_token']) |
|||
); |
|||
|
|||
return $request; |
|||
} |
|||
|
|||
/** |
|||
* Fetches a fresh access token with the given refresh token. |
|||
* @param string $refreshToken |
|||
* @return void |
|||
*/ |
|||
public function refreshToken($refreshToken) { |
|||
$this->refreshTokenRequest(array( |
|||
'client_id' => $this->clientId, |
|||
'client_secret' => $this->clientSecret, |
|||
'refresh_token' => $refreshToken, |
|||
'grant_type' => 'refresh_token' |
|||
)); |
|||
} |
|||
|
|||
/** |
|||
* Fetches a fresh access token with a given assertion token. |
|||
* @param Google_AssertionCredentials $assertionCredentials optional. |
|||
* @return void |
|||
*/ |
|||
public function refreshTokenWithAssertion($assertionCredentials = null) { |
|||
if (!$assertionCredentials) { |
|||
$assertionCredentials = $this->assertionCredentials; |
|||
} |
|||
|
|||
$this->refreshTokenRequest(array( |
|||
'grant_type' => 'assertion', |
|||
'assertion_type' => $assertionCredentials->assertionType, |
|||
'assertion' => $assertionCredentials->generateAssertion(), |
|||
)); |
|||
} |
|||
|
|||
private function refreshTokenRequest($params) { |
|||
$http = new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params); |
|||
$request = Google_Client::$io->makeRequest($http); |
|||
|
|||
$code = $request->getResponseHttpCode(); |
|||
$body = $request->getResponseBody(); |
|||
if (200 == $code) { |
|||
$token = json_decode($body, true); |
|||
if ($token == null) { |
|||
throw new Google_AuthException("Could not json decode the access token"); |
|||
} |
|||
|
|||
if (! isset($token['access_token']) || ! isset($token['expires_in'])) { |
|||
throw new Google_AuthException("Invalid token format"); |
|||
} |
|||
|
|||
$this->token['access_token'] = $token['access_token']; |
|||
$this->token['expires_in'] = $token['expires_in']; |
|||
$this->token['created'] = time(); |
|||
} else { |
|||
throw new Google_AuthException("Error refreshing the OAuth2 token, message: '$body'", $code); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access |
|||
* token, if a token isn't provided. |
|||
* @throws Google_AuthException |
|||
* @param string|null $token The token (access token or a refresh token) that should be revoked. |
|||
* @return boolean Returns True if the revocation was successful, otherwise False. |
|||
*/ |
|||
public function revokeToken($token = null) { |
|||
if (!$token) { |
|||
$token = $this->token['access_token']; |
|||
} |
|||
$request = new Google_HttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token"); |
|||
$response = Google_Client::$io->makeRequest($request); |
|||
$code = $response->getResponseHttpCode(); |
|||
if ($code == 200) { |
|||
$this->token = null; |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* Returns if the access_token is expired. |
|||
* @return bool Returns True if the access_token is expired. |
|||
*/ |
|||
public function isAccessTokenExpired() { |
|||
if (null == $this->token) { |
|||
return true; |
|||
} |
|||
|
|||
// If the token is set to expire in the next 30 seconds.
|
|||
$expired = ($this->token['created'] |
|||
+ ($this->token['expires_in'] - 30)) < time(); |
|||
|
|||
return $expired; |
|||
} |
|||
|
|||
// Gets federated sign-on certificates to use for verifying identity tokens.
|
|||
// Returns certs as array structure, where keys are key ids, and values
|
|||
// are PEM encoded certificates.
|
|||
private function getFederatedSignOnCerts() { |
|||
// This relies on makeRequest caching certificate responses.
|
|||
$request = Google_Client::$io->makeRequest(new Google_HttpRequest( |
|||
self::OAUTH2_FEDERATED_SIGNON_CERTS_URL)); |
|||
if ($request->getResponseHttpCode() == 200) { |
|||
$certs = json_decode($request->getResponseBody(), true); |
|||
if ($certs) { |
|||
return $certs; |
|||
} |
|||
} |
|||
throw new Google_AuthException( |
|||
"Failed to retrieve verification certificates: '" . |
|||
$request->getResponseBody() . "'.", |
|||
$request->getResponseHttpCode()); |
|||
} |
|||
|
|||
/** |
|||
* Verifies an id token and returns the authenticated apiLoginTicket. |
|||
* Throws an exception if the id token is not valid. |
|||
* The audience parameter can be used to control which id tokens are |
|||
* accepted. By default, the id token must have been issued to this OAuth2 client. |
|||
* |
|||
* @param $id_token |
|||
* @param $audience |
|||
* @return Google_LoginTicket |
|||
*/ |
|||
public function verifyIdToken($id_token = null, $audience = null) { |
|||
if (!$id_token) { |
|||
$id_token = $this->token['id_token']; |
|||
} |
|||
|
|||
$certs = $this->getFederatedSignonCerts(); |
|||
if (!$audience) { |
|||
$audience = $this->clientId; |
|||
} |
|||
return $this->verifySignedJwtWithCerts($id_token, $certs, $audience); |
|||
} |
|||
|
|||
// Verifies the id token, returns the verified token contents.
|
|||
// Visible for testing.
|
|||
function verifySignedJwtWithCerts($jwt, $certs, $required_audience) { |
|||
$segments = explode(".", $jwt); |
|||
if (count($segments) != 3) { |
|||
throw new Google_AuthException("Wrong number of segments in token: $jwt"); |
|||
} |
|||
$signed = $segments[0] . "." . $segments[1]; |
|||
$signature = Google_Utils::urlSafeB64Decode($segments[2]); |
|||
|
|||
// Parse envelope.
|
|||
$envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true); |
|||
if (!$envelope) { |
|||
throw new Google_AuthException("Can't parse token envelope: " . $segments[0]); |
|||
} |
|||
|
|||
// Parse token
|
|||
$json_body = Google_Utils::urlSafeB64Decode($segments[1]); |
|||
$payload = json_decode($json_body, true); |
|||
if (!$payload) { |
|||
throw new Google_AuthException("Can't parse token payload: " . $segments[1]); |
|||
} |
|||
|
|||
// Check signature
|
|||
$verified = false; |
|||
foreach ($certs as $keyName => $pem) { |
|||
$public_key = new Google_PemVerifier($pem); |
|||
if ($public_key->verify($signed, $signature)) { |
|||
$verified = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (!$verified) { |
|||
throw new Google_AuthException("Invalid token signature: $jwt"); |
|||
} |
|||
|
|||
// Check issued-at timestamp
|
|||
$iat = 0; |
|||
if (array_key_exists("iat", $payload)) { |
|||
$iat = $payload["iat"]; |
|||
} |
|||
if (!$iat) { |
|||
throw new Google_AuthException("No issue time in token: $json_body"); |
|||
} |
|||
$earliest = $iat - self::CLOCK_SKEW_SECS; |
|||
|
|||
// Check expiration timestamp
|
|||
$now = time(); |
|||
$exp = 0; |
|||
if (array_key_exists("exp", $payload)) { |
|||
$exp = $payload["exp"]; |
|||
} |
|||
if (!$exp) { |
|||
throw new Google_AuthException("No expiration time in token: $json_body"); |
|||
} |
|||
if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) { |
|||
throw new Google_AuthException( |
|||
"Expiration time too far in future: $json_body"); |
|||
} |
|||
|
|||
$latest = $exp + self::CLOCK_SKEW_SECS; |
|||
if ($now < $earliest) { |
|||
throw new Google_AuthException( |
|||
"Token used too early, $now < $earliest: $json_body"); |
|||
} |
|||
if ($now > $latest) { |
|||
throw new Google_AuthException( |
|||
"Token used too late, $now > $latest: $json_body"); |
|||
} |
|||
|
|||
// TODO(beaton): check issuer field?
|
|||
|
|||
// Check audience
|
|||
$aud = $payload["aud"]; |
|||
if ($aud != $required_audience) { |
|||
throw new Google_AuthException("Wrong recipient, $aud != $required_audience: $json_body"); |
|||
} |
|||
|
|||
// All good.
|
|||
return new Google_LoginTicket($envelope, $payload); |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Signs data. |
|||
* |
|||
* Only used for testing. |
|||
* |
|||
* @author Brian Eaton <beaton@google.com> |
|||
*/ |
|||
class Google_P12Signer extends Google_Signer { |
|||
// OpenSSL private key resource
|
|||
private $privateKey; |
|||
|
|||
// Creates a new signer from a .p12 file.
|
|||
function __construct($p12, $password) { |
|||
if (!function_exists('openssl_x509_read')) { |
|||
throw new Exception( |
|||
'The Google PHP API library needs the openssl PHP extension'); |
|||
} |
|||
|
|||
// This throws on error
|
|||
$certs = array(); |
|||
if (!openssl_pkcs12_read($p12, $certs, $password)) { |
|||
throw new Google_AuthException("Unable to parse the p12 file. " . |
|||
"Is this a .p12 file? Is the password correct? OpenSSL error: " . |
|||
openssl_error_string()); |
|||
} |
|||
// TODO(beaton): is this part of the contract for the openssl_pkcs12_read
|
|||
// method? What happens if there are multiple private keys? Do we care?
|
|||
if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) { |
|||
throw new Google_AuthException("No private key found in p12 file."); |
|||
} |
|||
$this->privateKey = openssl_pkey_get_private($certs["pkey"]); |
|||
if (!$this->privateKey) { |
|||
throw new Google_AuthException("Unable to load private key in "); |
|||
} |
|||
} |
|||
|
|||
function __destruct() { |
|||
if ($this->privateKey) { |
|||
openssl_pkey_free($this->privateKey); |
|||
} |
|||
} |
|||
|
|||
function sign($data) { |
|||
if(version_compare(PHP_VERSION, '5.3.0') < 0) { |
|||
throw new Google_AuthException( |
|||
"PHP 5.3.0 or higher is required to use service accounts."); |
|||
} |
|||
if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) { |
|||
throw new Google_AuthException("Unable to sign data"); |
|||
} |
|||
return $signature; |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Verifies signatures using PEM encoded certificates. |
|||
* |
|||
* @author Brian Eaton <beaton@google.com> |
|||
*/ |
|||
class Google_PemVerifier extends Google_Verifier { |
|||
private $publicKey; |
|||
|
|||
/** |
|||
* Constructs a verifier from the supplied PEM-encoded certificate. |
|||
* |
|||
* $pem: a PEM encoded certificate (not a file). |
|||
* @param $pem |
|||
* @throws Google_AuthException |
|||
* @throws Google_Exception |
|||
*/ |
|||
function __construct($pem) { |
|||
if (!function_exists('openssl_x509_read')) { |
|||
throw new Google_Exception('Google API PHP client needs the openssl PHP extension'); |
|||
} |
|||
$this->publicKey = openssl_x509_read($pem); |
|||
if (!$this->publicKey) { |
|||
throw new Google_AuthException("Unable to parse PEM: $pem"); |
|||
} |
|||
} |
|||
|
|||
function __destruct() { |
|||
if ($this->publicKey) { |
|||
openssl_x509_free($this->publicKey); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Verifies the signature on data. |
|||
* |
|||
* Returns true if the signature is valid, false otherwise. |
|||
* @param $data |
|||
* @param $signature |
|||
* @throws Google_AuthException |
|||
* @return bool |
|||
*/ |
|||
function verify($data, $signature) { |
|||
$status = openssl_verify($data, $signature, $this->publicKey, "sha256"); |
|||
if ($status === -1) { |
|||
throw new Google_AuthException('Signature verification error: ' . openssl_error_string()); |
|||
} |
|||
return $status === 1; |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
require_once "Google_P12Signer.php"; |
|||
|
|||
/** |
|||
* Signs data. |
|||
* |
|||
* @author Brian Eaton <beaton@google.com> |
|||
*/ |
|||
abstract class Google_Signer { |
|||
/** |
|||
* Signs data, returns the signature as binary data. |
|||
*/ |
|||
abstract public function sign($data); |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
require_once "Google_PemVerifier.php"; |
|||
|
|||
/** |
|||
* Verifies signatures. |
|||
* |
|||
* @author Brian Eaton <beaton@google.com> |
|||
*/ |
|||
abstract class Google_Verifier { |
|||
/** |
|||
* Checks a signature, returns true if the signature is correct, |
|||
* false otherwise. |
|||
*/ |
|||
abstract public function verify($data, $signature); |
|||
} |
|||
@ -0,0 +1,98 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* A persistent storage class based on the APC cache, which is not |
|||
* really very persistent, as soon as you restart your web server |
|||
* the storage will be wiped, however for debugging and/or speed |
|||
* it can be useful, kinda, and cache is a lot cheaper then storage. |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
*/ |
|||
class googleApcCache extends Google_Cache { |
|||
|
|||
public function __construct() { |
|||
if (! function_exists('apc_add')) { |
|||
throw new Google_CacheException("Apc functions not available"); |
|||
} |
|||
} |
|||
|
|||
private function isLocked($key) { |
|||
if ((@apc_fetch($key . '.lock')) === false) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
private function createLock($key) { |
|||
// the interesting thing is that this could fail if the lock was created in the meantime..
|
|||
// but we'll ignore that out of convenience
|
|||
@apc_add($key . '.lock', '', 5); |
|||
} |
|||
|
|||
private function removeLock($key) { |
|||
// suppress all warnings, if some other process removed it that's ok too
|
|||
@apc_delete($key . '.lock'); |
|||
} |
|||
|
|||
private function waitForLock($key) { |
|||
// 20 x 250 = 5 seconds
|
|||
$tries = 20; |
|||
$cnt = 0; |
|||
do { |
|||
// 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
|
|||
usleep(250); |
|||
$cnt ++; |
|||
} while ($cnt <= $tries && $this->isLocked($key)); |
|||
if ($this->isLocked($key)) { |
|||
// 5 seconds passed, assume the owning process died off and remove it
|
|||
$this->removeLock($key); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function get($key, $expiration = false) { |
|||
|
|||
if (($ret = @apc_fetch($key)) === false) { |
|||
return false; |
|||
} |
|||
if (!$expiration || (time() - $ret['time'] > $expiration)) { |
|||
$this->delete($key); |
|||
return false; |
|||
} |
|||
return unserialize($ret['data']); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function set($key, $value) { |
|||
if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) { |
|||
throw new Google_CacheException("Couldn't store data"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
* @param String $key |
|||
*/ |
|||
public function delete($key) { |
|||
@apc_delete($key); |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2008 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. |
|||
*/ |
|||
|
|||
require_once "Google_FileCache.php"; |
|||
require_once "Google_MemcacheCache.php"; |
|||
|
|||
/** |
|||
* Abstract storage class |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
*/ |
|||
abstract class Google_Cache { |
|||
|
|||
/** |
|||
* Retrieves the data for the given key, or false if they |
|||
* key is unknown or expired |
|||
* |
|||
* @param String $key The key who's data to retrieve |
|||
* @param boolean|int $expiration Expiration time in seconds |
|||
* |
|||
*/ |
|||
abstract function get($key, $expiration = false); |
|||
|
|||
/** |
|||
* Store the key => $value set. The $value is serialized |
|||
* by this function so can be of any type |
|||
* |
|||
* @param string $key Key of the data |
|||
* @param string $value data |
|||
*/ |
|||
abstract function set($key, $value); |
|||
|
|||
/** |
|||
* Removes the key/data pair for the given $key |
|||
* |
|||
* @param String $key |
|||
*/ |
|||
abstract function delete($key); |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,137 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2008 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. |
|||
*/ |
|||
|
|||
/* |
|||
* This class implements a basic on disk storage. While that does |
|||
* work quite well it's not the most elegant and scalable solution. |
|||
* It will also get you into a heap of trouble when you try to run |
|||
* this in a clustered environment. In those cases please use the |
|||
* MySql back-end |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
*/ |
|||
class Google_FileCache extends Google_Cache { |
|||
private $path; |
|||
|
|||
public function __construct() { |
|||
global $apiConfig; |
|||
$this->path = $apiConfig['ioFileCache_directory']; |
|||
} |
|||
|
|||
private function isLocked($storageFile) { |
|||
// our lock file convention is simple: /the/file/path.lock
|
|||
return file_exists($storageFile . '.lock'); |
|||
} |
|||
|
|||
private function createLock($storageFile) { |
|||
$storageDir = dirname($storageFile); |
|||
if (! is_dir($storageDir)) { |
|||
// @codeCoverageIgnoreStart
|
|||
if (! @mkdir($storageDir, 0755, true)) { |
|||
// make sure the failure isn't because of a concurrency issue
|
|||
if (! is_dir($storageDir)) { |
|||
throw new Google_CacheException("Could not create storage directory: $storageDir"); |
|||
} |
|||
} |
|||
// @codeCoverageIgnoreEnd
|
|||
} |
|||
@touch($storageFile . '.lock'); |
|||
} |
|||
|
|||
private function removeLock($storageFile) { |
|||
// suppress all warnings, if some other process removed it that's ok too
|
|||
@unlink($storageFile . '.lock'); |
|||
} |
|||
|
|||
private function waitForLock($storageFile) { |
|||
// 20 x 250 = 5 seconds
|
|||
$tries = 20; |
|||
$cnt = 0; |
|||
do { |
|||
// make sure PHP picks up on file changes. This is an expensive action but really can't be avoided
|
|||
clearstatcache(); |
|||
// 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
|
|||
usleep(250); |
|||
$cnt ++; |
|||
} while ($cnt <= $tries && $this->isLocked($storageFile)); |
|||
if ($this->isLocked($storageFile)) { |
|||
// 5 seconds passed, assume the owning process died off and remove it
|
|||
$this->removeLock($storageFile); |
|||
} |
|||
} |
|||
|
|||
private function getCacheDir($hash) { |
|||
// use the first 2 characters of the hash as a directory prefix
|
|||
// this should prevent slowdowns due to huge directory listings
|
|||
// and thus give some basic amount of scalability
|
|||
return $this->path . '/' . substr($hash, 0, 2); |
|||
} |
|||
|
|||
private function getCacheFile($hash) { |
|||
return $this->getCacheDir($hash) . '/' . $hash; |
|||
} |
|||
|
|||
public function get($key, $expiration = false) { |
|||
$storageFile = $this->getCacheFile(md5($key)); |
|||
// See if this storage file is locked, if so we wait up to 5 seconds for the lock owning process to
|
|||
// complete it's work. If the lock is not released within that time frame, it's cleaned up.
|
|||
// This should give us a fair amount of 'Cache Stampeding' protection
|
|||
if ($this->isLocked($storageFile)) { |
|||
$this->waitForLock($storageFile); |
|||
} |
|||
if (file_exists($storageFile) && is_readable($storageFile)) { |
|||
$now = time(); |
|||
if (! $expiration || (($mtime = @filemtime($storageFile)) !== false && ($now - $mtime) < $expiration)) { |
|||
if (($data = @file_get_contents($storageFile)) !== false) { |
|||
$data = unserialize($data); |
|||
return $data; |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public function set($key, $value) { |
|||
$storageDir = $this->getCacheDir(md5($key)); |
|||
$storageFile = $this->getCacheFile(md5($key)); |
|||
if ($this->isLocked($storageFile)) { |
|||
// some other process is writing to this file too, wait until it's done to prevent hiccups
|
|||
$this->waitForLock($storageFile); |
|||
} |
|||
if (! is_dir($storageDir)) { |
|||
if (! @mkdir($storageDir, 0755, true)) { |
|||
throw new Google_CacheException("Could not create storage directory: $storageDir"); |
|||
} |
|||
} |
|||
// we serialize the whole request object, since we don't only want the
|
|||
// responseContent but also the postBody used, headers, size, etc
|
|||
$data = serialize($value); |
|||
$this->createLock($storageFile); |
|||
if (! @file_put_contents($storageFile, $data)) { |
|||
$this->removeLock($storageFile); |
|||
throw new Google_CacheException("Could not store data in the file"); |
|||
} |
|||
$this->removeLock($storageFile); |
|||
} |
|||
|
|||
public function delete($key) { |
|||
$file = $this->getCacheFile(md5($key)); |
|||
if (! @unlink($file)) { |
|||
throw new Google_CacheException("Cache file could not be deleted"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2008 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. |
|||
*/ |
|||
|
|||
/** |
|||
* A persistent storage class based on the memcache, which is not |
|||
* really very persistent, as soon as you restart your memcache daemon |
|||
* the storage will be wiped, however for debugging and/or speed |
|||
* it can be useful, kinda, and cache is a lot cheaper then storage. |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
*/ |
|||
class Google_MemcacheCache extends Google_Cache { |
|||
private $connection = false; |
|||
|
|||
public function __construct() { |
|||
global $apiConfig; |
|||
if (! function_exists('memcache_connect')) { |
|||
throw new Google_CacheException("Memcache functions not available"); |
|||
} |
|||
$this->host = $apiConfig['ioMemCacheCache_host']; |
|||
$this->port = $apiConfig['ioMemCacheCache_port']; |
|||
if (empty($this->host) || empty($this->port)) { |
|||
throw new Google_CacheException("You need to supply a valid memcache host and port"); |
|||
} |
|||
} |
|||
|
|||
private function isLocked($key) { |
|||
$this->check(); |
|||
if ((@memcache_get($this->connection, $key . '.lock')) === false) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
private function createLock($key) { |
|||
$this->check(); |
|||
// the interesting thing is that this could fail if the lock was created in the meantime..
|
|||
// but we'll ignore that out of convenience
|
|||
@memcache_add($this->connection, $key . '.lock', '', 0, 5); |
|||
} |
|||
|
|||
private function removeLock($key) { |
|||
$this->check(); |
|||
// suppress all warnings, if some other process removed it that's ok too
|
|||
@memcache_delete($this->connection, $key . '.lock'); |
|||
} |
|||
|
|||
private function waitForLock($key) { |
|||
$this->check(); |
|||
// 20 x 250 = 5 seconds
|
|||
$tries = 20; |
|||
$cnt = 0; |
|||
do { |
|||
// 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
|
|||
usleep(250); |
|||
$cnt ++; |
|||
} while ($cnt <= $tries && $this->isLocked($key)); |
|||
if ($this->isLocked($key)) { |
|||
// 5 seconds passed, assume the owning process died off and remove it
|
|||
$this->removeLock($key); |
|||
} |
|||
} |
|||
|
|||
// I prefer lazy initialization since the cache isn't used every request
|
|||
// so this potentially saves a lot of overhead
|
|||
private function connect() { |
|||
if (! $this->connection = @memcache_pconnect($this->host, $this->port)) { |
|||
throw new Google_CacheException("Couldn't connect to memcache server"); |
|||
} |
|||
} |
|||
|
|||
private function check() { |
|||
if (! $this->connection) { |
|||
$this->connect(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function get($key, $expiration = false) { |
|||
$this->check(); |
|||
if (($ret = @memcache_get($this->connection, $key)) === false) { |
|||
return false; |
|||
} |
|||
if (! $expiration || (time() - $ret['time'] > $expiration)) { |
|||
$this->delete($key); |
|||
return false; |
|||
} |
|||
return $ret['data']; |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
* @param string $key |
|||
* @param string $value |
|||
* @throws Google_CacheException |
|||
*/ |
|||
public function set($key, $value) { |
|||
$this->check(); |
|||
// we store it with the cache_time default expiration so objects will at least get cleaned eventually.
|
|||
if (@memcache_set($this->connection, $key, array('time' => time(), |
|||
'data' => $value), false) == false) { |
|||
throw new Google_CacheException("Couldn't store data in cache"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
* @param String $key |
|||
*/ |
|||
public function delete($key) { |
|||
$this->check(); |
|||
@memcache_delete($this->connection, $key); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
global $apiConfig; |
|||
$apiConfig = array( |
|||
// True if objects should be returned by the service classes.
|
|||
// False if associative arrays should be returned (default behavior).
|
|||
'use_objects' => false, |
|||
|
|||
// The application_name is included in the User-Agent HTTP header.
|
|||
'application_name' => '', |
|||
|
|||
// OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
|
|||
'oauth2_client_id' => '', |
|||
'oauth2_client_secret' => '', |
|||
'oauth2_redirect_uri' => '', |
|||
|
|||
// The developer key, you get this at https://code.google.com/apis/console
|
|||
'developer_key' => '', |
|||
|
|||
// Site name to show in the Google's OAuth 1 authentication screen.
|
|||
'site_name' => 'www.example.org', |
|||
|
|||
// Which Authentication, Storage and HTTP IO classes to use.
|
|||
'authClass' => 'Google_OAuth2', |
|||
'ioClass' => 'Google_CurlIO', |
|||
'cacheClass' => 'Google_FileCache', |
|||
|
|||
// Don't change these unless you're working against a special development or testing environment.
|
|||
'basePath' => 'https://www.googleapis.com', |
|||
|
|||
// IO Class dependent configuration, you only have to configure the values
|
|||
// for the class that was configured as the ioClass above
|
|||
'ioFileCache_directory' => |
|||
(function_exists('sys_get_temp_dir') ? |
|||
sys_get_temp_dir() . '/Google_Client' : |
|||
'/tmp/Google_Client'), |
|||
|
|||
// Definition of service specific values like scopes, oauth token URLs, etc
|
|||
'services' => array( |
|||
'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'), |
|||
'calendar' => array( |
|||
'scope' => array( |
|||
"https://www.googleapis.com/auth/calendar", |
|||
"https://www.googleapis.com/auth/calendar.readonly", |
|||
) |
|||
), |
|||
'books' => array('scope' => 'https://www.googleapis.com/auth/books'), |
|||
'latitude' => array( |
|||
'scope' => array( |
|||
'https://www.googleapis.com/auth/latitude.all.best', |
|||
'https://www.googleapis.com/auth/latitude.all.city', |
|||
) |
|||
), |
|||
'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'), |
|||
'oauth2' => array( |
|||
'scope' => array( |
|||
'https://www.googleapis.com/auth/userinfo.profile', |
|||
'https://www.googleapis.com/auth/userinfo.email', |
|||
) |
|||
), |
|||
'plus' => array('scope' => 'https://www.googleapis.com/auth/plus.login'), |
|||
'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'), |
|||
'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'), |
|||
'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener') |
|||
) |
|||
); |
|||
3143
apps/files_external/3rdparty/google-api-php-client/src/contrib/Google_DriveService.php
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,209 @@ |
|||
<?php |
|||
/* |
|||
Copyright (c) 2010 Kevin M Burns Jr, http://kevburnsjr.com/ |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining |
|||
a copy of this software and associated documentation files (the |
|||
"Software"), to deal in the Software without restriction, including |
|||
without limitation the rights to use, copy, modify, merge, publish, |
|||
distribute, sublicense, and/or sell copies of the Software, and to |
|||
permit persons to whom the Software is furnished to do so, subject to |
|||
the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be |
|||
included in all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|||
*/ |
|||
|
|||
/** |
|||
* A URI Template Parser which is used by the apiREST class to resolve the REST requests |
|||
* Blogpost: http://lab.kevburnsjr.com/php-uri-template-parser |
|||
* Source: http://github.com/KevBurnsJr/php-uri-template-parser |
|||
*/ |
|||
class URI_Template_Parser { |
|||
|
|||
public static $operators = array('+', ';', '?', '/', '.'); |
|||
public static $reserved_operators = array('|', '!', '@'); |
|||
public static $explode_modifiers = array('+', '*'); |
|||
public static $partial_modifiers = array(':', '^'); |
|||
|
|||
public static $gen_delims = array(':', '/', '?', '#', '[', ']', '@'); |
|||
public static $gen_delims_pct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40'); |
|||
public static $sub_delims = array('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '='); |
|||
public static $sub_delims_pct = array('%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D'); |
|||
public static $reserved; |
|||
public static $reserved_pct; |
|||
|
|||
public function __construct($template) { |
|||
self::$reserved = array_merge(self::$gen_delims, self::$sub_delims); |
|||
self::$reserved_pct = array_merge(self::$gen_delims_pct, self::$sub_delims_pct); |
|||
$this->template = $template; |
|||
} |
|||
|
|||
public function expand($data) { |
|||
// Modification to make this a bit more performant (since gettype is very slow)
|
|||
if (! is_array($data)) { |
|||
$data = (array)$data; |
|||
} |
|||
/* |
|||
// Original code, which uses a slow gettype() statement, kept in place for if the assumption that is_array always works here is incorrect
|
|||
switch (gettype($data)) { |
|||
case "boolean": |
|||
case "integer": |
|||
case "double": |
|||
case "string": |
|||
case "object": |
|||
$data = (array)$data; |
|||
break; |
|||
} |
|||
*/ |
|||
|
|||
// Resolve template vars
|
|||
preg_match_all('/\{([^\}]*)\}/', $this->template, $em); |
|||
|
|||
foreach ($em[1] as $i => $bare_expression) { |
|||
preg_match('/^([\+\;\?\/\.]{1})?(.*)$/', $bare_expression, $lm); |
|||
$exp = new StdClass(); |
|||
$exp->expression = $em[0][$i]; |
|||
$exp->operator = $lm[1]; |
|||
$exp->variable_list = $lm[2]; |
|||
$exp->varspecs = explode(',', $exp->variable_list); |
|||
$exp->vars = array(); |
|||
foreach ($exp->varspecs as $varspec) { |
|||
preg_match('/^([a-zA-Z0-9_]+)([\*\+]{1})?([\:\^][0-9-]+)?(\=[^,]+)?$/', $varspec, $vm); |
|||
$var = new StdClass(); |
|||
$var->name = $vm[1]; |
|||
$var->modifier = isset($vm[2]) && $vm[2] ? $vm[2] : null; |
|||
$var->modifier = isset($vm[3]) && $vm[3] ? $vm[3] : $var->modifier; |
|||
$var->default = isset($vm[4]) ? substr($vm[4], 1) : null; |
|||
$exp->vars[] = $var; |
|||
} |
|||
|
|||
// Add processing flags
|
|||
$exp->reserved = false; |
|||
$exp->prefix = ''; |
|||
$exp->delimiter = ','; |
|||
switch ($exp->operator) { |
|||
case '+': |
|||
$exp->reserved = 'true'; |
|||
break; |
|||
case ';': |
|||
$exp->prefix = ';'; |
|||
$exp->delimiter = ';'; |
|||
break; |
|||
case '?': |
|||
$exp->prefix = '?'; |
|||
$exp->delimiter = '&'; |
|||
break; |
|||
case '/': |
|||
$exp->prefix = '/'; |
|||
$exp->delimiter = '/'; |
|||
break; |
|||
case '.': |
|||
$exp->prefix = '.'; |
|||
$exp->delimiter = '.'; |
|||
break; |
|||
} |
|||
$expressions[] = $exp; |
|||
} |
|||
|
|||
// Expansion
|
|||
$this->expansion = $this->template; |
|||
|
|||
foreach ($expressions as $exp) { |
|||
$part = $exp->prefix; |
|||
$exp->one_var_defined = false; |
|||
foreach ($exp->vars as $var) { |
|||
$val = ''; |
|||
if ($exp->one_var_defined && isset($data[$var->name])) { |
|||
$part .= $exp->delimiter; |
|||
} |
|||
// Variable present
|
|||
if (isset($data[$var->name])) { |
|||
$exp->one_var_defined = true; |
|||
$var->data = $data[$var->name]; |
|||
|
|||
$val = self::val_from_var($var, $exp); |
|||
|
|||
// Variable missing
|
|||
} else { |
|||
if ($var->default) { |
|||
$exp->one_var_defined = true; |
|||
$val = $var->default; |
|||
} |
|||
} |
|||
$part .= $val; |
|||
} |
|||
if (! $exp->one_var_defined) $part = ''; |
|||
$this->expansion = str_replace($exp->expression, $part, $this->expansion); |
|||
} |
|||
|
|||
return $this->expansion; |
|||
} |
|||
|
|||
private function val_from_var($var, $exp) { |
|||
$val = ''; |
|||
if (is_array($var->data)) { |
|||
$i = 0; |
|||
if ($exp->operator == '?' && ! $var->modifier) { |
|||
$val .= $var->name . '='; |
|||
} |
|||
foreach ($var->data as $k => $v) { |
|||
$del = $var->modifier ? $exp->delimiter : ','; |
|||
$ek = rawurlencode($k); |
|||
$ev = rawurlencode($v); |
|||
|
|||
// Array
|
|||
if ($k !== $i) { |
|||
if ($var->modifier == '+') { |
|||
$val .= $var->name . '.'; |
|||
} |
|||
if ($exp->operator == '?' && $var->modifier || $exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+') { |
|||
$val .= $ek . '='; |
|||
} else { |
|||
$val .= $ek . $del; |
|||
} |
|||
|
|||
// List
|
|||
} else { |
|||
if ($var->modifier == '+') { |
|||
if ($exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+' || $exp->operator == '?' && $var->modifier == '+') { |
|||
$val .= $var->name . '='; |
|||
} else { |
|||
$val .= $var->name . '.'; |
|||
} |
|||
} |
|||
} |
|||
$val .= $ev . $del; |
|||
$i ++; |
|||
} |
|||
$val = trim($val, $del); |
|||
|
|||
// Strings, numbers, etc.
|
|||
} else { |
|||
if ($exp->operator == '?') { |
|||
$val = $var->name . (isset($var->data) ? '=' : ''); |
|||
} else if ($exp->operator == ';') { |
|||
$val = $var->name . ($var->data ? '=' : ''); |
|||
} |
|||
$val .= rawurlencode($var->data); |
|||
if ($exp->operator == '+') { |
|||
$val = str_replace(self::$reserved_pct, self::$reserved, $val); |
|||
} |
|||
} |
|||
return $val; |
|||
} |
|||
|
|||
public function match($uri) {} |
|||
|
|||
public function __toString() { |
|||
return $this->template; |
|||
} |
|||
} |
|||
@ -0,0 +1,173 @@ |
|||
<?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. |
|||
*/ |
|||
/** |
|||
* Implement the caching directives specified in rfc2616. This |
|||
* implementation is guided by the guidance offered in rfc2616-sec13. |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_CacheParser { |
|||
public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD'); |
|||
public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301'); |
|||
|
|||
private function __construct() {} |
|||
|
|||
/** |
|||
* Check if an HTTP request can be cached by a private local cache. |
|||
* |
|||
* @static |
|||
* @param Google_HttpRequest $resp |
|||
* @return bool True if the request is cacheable. |
|||
* False if the request is uncacheable. |
|||
*/ |
|||
public static function isRequestCacheable (Google_HttpRequest $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_HttpRequest $resp |
|||
* @return bool True if the response is cacheable. |
|||
* False if the response is un-cacheable. |
|||
*/ |
|||
public static function isResponseCacheable (Google_HttpRequest $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_HttpRequest $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_HttpRequest $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) { |
|||
$parsedDate = time(); |
|||
} |
|||
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_HttpRequest $response |
|||
* @return bool True if the entry is expired, else return false. |
|||
*/ |
|||
public static function mustRevalidate(Google_HttpRequest $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); |
|||
} |
|||
} |
|||
@ -0,0 +1,278 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* Curl based implementation of apiIO. |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
|
|||
require_once 'Google_CacheParser.php'; |
|||
|
|||
class Google_CurlIO implements Google_IO { |
|||
const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n"; |
|||
const FORM_URLENCODED = 'application/x-www-form-urlencoded'; |
|||
|
|||
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null); |
|||
private static $HOP_BY_HOP = array( |
|||
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', |
|||
'te', 'trailers', 'transfer-encoding', 'upgrade'); |
|||
|
|||
private $curlParams = array ( |
|||
CURLOPT_RETURNTRANSFER => true, |
|||
CURLOPT_FOLLOWLOCATION => 0, |
|||
CURLOPT_FAILONERROR => false, |
|||
CURLOPT_SSL_VERIFYPEER => true, |
|||
CURLOPT_HEADER => true, |
|||
CURLOPT_VERBOSE => false, |
|||
); |
|||
|
|||
/** |
|||
* Perform an authenticated / signed apiHttpRequest. |
|||
* This function takes the apiHttpRequest, calls apiAuth->sign on it |
|||
* (which can modify the request in what ever way fits the auth mechanism) |
|||
* and then calls apiCurlIO::makeRequest on the signed request |
|||
* |
|||
* @param Google_HttpRequest $request |
|||
* @return Google_HttpRequest The resulting HTTP response including the |
|||
* responseHttpCode, responseHeaders and responseBody. |
|||
*/ |
|||
public function authenticatedRequest(Google_HttpRequest $request) { |
|||
$request = Google_Client::$auth->sign($request); |
|||
return $this->makeRequest($request); |
|||
} |
|||
|
|||
/** |
|||
* Execute a apiHttpRequest |
|||
* |
|||
* @param Google_HttpRequest $request the http request to be executed |
|||
* @return Google_HttpRequest http request with the response http code, response |
|||
* headers and response body filled in |
|||
* @throws Google_IOException on curl or IO error |
|||
*/ |
|||
public function makeRequest(Google_HttpRequest $request) { |
|||
// First, check to see if we have a valid cached version.
|
|||
$cached = $this->getCachedRequest($request); |
|||
if ($cached !== false) { |
|||
if (Google_CacheParser::mustRevalidate($cached)) { |
|||
$addHeaders = array(); |
|||
if ($cached->getResponseHeader('etag')) { |
|||
// [13.3.4] If an entity tag has been provided by the origin server,
|
|||
// we must use that entity tag in any cache-conditional request.
|
|||
$addHeaders['If-None-Match'] = $cached->getResponseHeader('etag'); |
|||
} elseif ($cached->getResponseHeader('date')) { |
|||
$addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date'); |
|||
} |
|||
|
|||
$request->setRequestHeaders($addHeaders); |
|||
} else { |
|||
// No need to revalidate the request, return it directly
|
|||
return $cached; |
|||
} |
|||
} |
|||
|
|||
if (array_key_exists($request->getRequestMethod(), |
|||
self::$ENTITY_HTTP_METHODS)) { |
|||
$request = $this->processEntityRequest($request); |
|||
} |
|||
|
|||
$ch = curl_init(); |
|||
curl_setopt_array($ch, $this->curlParams); |
|||
curl_setopt($ch, CURLOPT_URL, $request->getUrl()); |
|||
if ($request->getPostBody()) { |
|||
curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody()); |
|||
} |
|||
|
|||
$requestHeaders = $request->getRequestHeaders(); |
|||
if ($requestHeaders && is_array($requestHeaders)) { |
|||
$parsed = array(); |
|||
foreach ($requestHeaders as $k => $v) { |
|||
$parsed[] = "$k: $v"; |
|||
} |
|||
curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed); |
|||
} |
|||
|
|||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod()); |
|||
curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent()); |
|||
$respData = curl_exec($ch); |
|||
|
|||
// Retry if certificates are missing.
|
|||
if (curl_errno($ch) == CURLE_SSL_CACERT) { |
|||
error_log('SSL certificate problem, verify that the CA cert is OK.' |
|||
. ' Retrying with the CA cert bundle from google-api-php-client.'); |
|||
curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem'); |
|||
$respData = curl_exec($ch); |
|||
} |
|||
|
|||
$respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); |
|||
$respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); |
|||
$curlErrorNum = curl_errno($ch); |
|||
$curlError = curl_error($ch); |
|||
curl_close($ch); |
|||
if ($curlErrorNum != CURLE_OK) { |
|||
throw new Google_IOException("HTTP Error: ($respHttpCode) $curlError"); |
|||
} |
|||
|
|||
// Parse out the raw response into usable bits
|
|||
list($responseHeaders, $responseBody) = |
|||
self::parseHttpResponse($respData, $respHeaderSize); |
|||
|
|||
if ($respHttpCode == 304 && $cached) { |
|||
// If the server responded NOT_MODIFIED, return the cached request.
|
|||
if (isset($responseHeaders['connection'])) { |
|||
$hopByHop = array_merge( |
|||
self::$HOP_BY_HOP, |
|||
explode(',', $responseHeaders['connection']) |
|||
); |
|||
|
|||
$endToEnd = array(); |
|||
foreach($hopByHop as $key) { |
|||
if (isset($responseHeaders[$key])) { |
|||
$endToEnd[$key] = $responseHeaders[$key]; |
|||
} |
|||
} |
|||
$cached->setResponseHeaders($endToEnd); |
|||
} |
|||
return $cached; |
|||
} |
|||
|
|||
// Fill in the apiHttpRequest with the response values
|
|||
$request->setResponseHttpCode($respHttpCode); |
|||
$request->setResponseHeaders($responseHeaders); |
|||
$request->setResponseBody($responseBody); |
|||
// Store the request in cache (the function checks to see if the request
|
|||
// can actually be cached)
|
|||
$this->setCachedRequest($request); |
|||
// And finally return it
|
|||
return $request; |
|||
} |
|||
|
|||
/** |
|||
* @visible for testing. |
|||
* Cache the response to an HTTP request if it is cacheable. |
|||
* @param Google_HttpRequest $request |
|||
* @return bool Returns true if the insertion was successful. |
|||
* Otherwise, return false. |
|||
*/ |
|||
public function setCachedRequest(Google_HttpRequest $request) { |
|||
// Determine if the request is cacheable.
|
|||
if (Google_CacheParser::isResponseCacheable($request)) { |
|||
Google_Client::$cache->set($request->getCacheKey(), $request); |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* @visible for testing. |
|||
* @param Google_HttpRequest $request |
|||
* @return Google_HttpRequest|bool Returns the cached object or |
|||
* false if the operation was unsuccessful. |
|||
*/ |
|||
public function getCachedRequest(Google_HttpRequest $request) { |
|||
if (false == Google_CacheParser::isRequestCacheable($request)) { |
|||
false; |
|||
} |
|||
|
|||
return Google_Client::$cache->get($request->getCacheKey()); |
|||
} |
|||
|
|||
/** |
|||
* @param $respData |
|||
* @param $headerSize |
|||
* @return array |
|||
*/ |
|||
public static function parseHttpResponse($respData, $headerSize) { |
|||
if (stripos($respData, self::CONNECTION_ESTABLISHED) !== false) { |
|||
$respData = str_ireplace(self::CONNECTION_ESTABLISHED, '', $respData); |
|||
} |
|||
|
|||
if ($headerSize) { |
|||
$responseBody = substr($respData, $headerSize); |
|||
$responseHeaders = substr($respData, 0, $headerSize); |
|||
} else { |
|||
list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2); |
|||
} |
|||
|
|||
$responseHeaders = self::parseResponseHeaders($responseHeaders); |
|||
return array($responseHeaders, $responseBody); |
|||
} |
|||
|
|||
public static function parseResponseHeaders($rawHeaders) { |
|||
$responseHeaders = array(); |
|||
|
|||
$responseHeaderLines = explode("\r\n", $rawHeaders); |
|||
foreach ($responseHeaderLines as $headerLine) { |
|||
if ($headerLine && strpos($headerLine, ':') !== false) { |
|||
list($header, $value) = explode(': ', $headerLine, 2); |
|||
$header = strtolower($header); |
|||
if (isset($responseHeaders[$header])) { |
|||
$responseHeaders[$header] .= "\n" . $value; |
|||
} else { |
|||
$responseHeaders[$header] = $value; |
|||
} |
|||
} |
|||
} |
|||
return $responseHeaders; |
|||
} |
|||
|
|||
/** |
|||
* @visible for testing |
|||
* Process an http request that contains an enclosed entity. |
|||
* @param Google_HttpRequest $request |
|||
* @return Google_HttpRequest Processed request with the enclosed entity. |
|||
*/ |
|||
public function processEntityRequest(Google_HttpRequest $request) { |
|||
$postBody = $request->getPostBody(); |
|||
$contentType = $request->getRequestHeader("content-type"); |
|||
|
|||
// Set the default content-type as application/x-www-form-urlencoded.
|
|||
if (false == $contentType) { |
|||
$contentType = self::FORM_URLENCODED; |
|||
$request->setRequestHeaders(array('content-type' => $contentType)); |
|||
} |
|||
|
|||
// Force the payload to match the content-type asserted in the header.
|
|||
if ($contentType == self::FORM_URLENCODED && is_array($postBody)) { |
|||
$postBody = http_build_query($postBody, '', '&'); |
|||
$request->setPostBody($postBody); |
|||
} |
|||
|
|||
// Make sure the content-length header is set.
|
|||
if (!$postBody || is_string($postBody)) { |
|||
$postsLength = strlen($postBody); |
|||
$request->setRequestHeaders(array('content-length' => $postsLength)); |
|||
} |
|||
|
|||
return $request; |
|||
} |
|||
|
|||
/** |
|||
* Set options that update cURL's default behavior. |
|||
* The list of accepted options are: |
|||
* {@link http://php.net/manual/en/function.curl-setopt.php] |
|||
* |
|||
* @param array $optCurlParams Multiple options used by a cURL session. |
|||
*/ |
|||
public function setOptions($optCurlParams) { |
|||
foreach ($optCurlParams as $key => $val) { |
|||
$this->curlParams[$key] = $val; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,304 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* HTTP Request to be executed by apiIO 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_HttpRequest { |
|||
const USER_AGENT_SUFFIX = "google-api-php-client/0.6.0"; |
|||
private $batchHeaders = array( |
|||
'Content-Type' => 'application/http', |
|||
'Content-Transfer-Encoding' => 'binary', |
|||
'MIME-Version' => '1.0', |
|||
'Content-Length' => '' |
|||
); |
|||
|
|||
protected $url; |
|||
protected $requestMethod; |
|||
protected $requestHeaders; |
|||
protected $postBody; |
|||
protected $userAgent; |
|||
|
|||
protected $responseHttpCode; |
|||
protected $responseHeaders; |
|||
protected $responseBody; |
|||
|
|||
public $accessKey; |
|||
|
|||
public function __construct($url, $method = 'GET', $headers = array(), $postBody = null) { |
|||
$this->setUrl($url); |
|||
$this->setRequestMethod($method); |
|||
$this->setRequestHeaders($headers); |
|||
$this->setPostBody($postBody); |
|||
|
|||
global $apiConfig; |
|||
if (empty($apiConfig['application_name'])) { |
|||
$this->userAgent = self::USER_AGENT_SUFFIX; |
|||
} else { |
|||
$this->userAgent = $apiConfig['application_name'] . " " . self::USER_AGENT_SUFFIX; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 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. |
|||
* @see http://oauth.net/core/1.0a/#anchor13
|
|||
*/ |
|||
public function getBaseUrl() { |
|||
if ($pos = strpos($this->url, '?')) { |
|||
return substr($this->url, 0, $pos); |
|||
} |
|||
return $this->url; |
|||
} |
|||
|
|||
/** |
|||
* 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() { |
|||
if ($pos = strpos($this->url, '?')) { |
|||
$queryStr = substr($this->url, $pos + 1); |
|||
$params = array(); |
|||
parse_str($queryStr, $params); |
|||
return $params; |
|||
} |
|||
return array(); |
|||
} |
|||
|
|||
/** |
|||
* @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; |
|||
} |
|||
|
|||
/** |
|||
* @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->url; |
|||
} |
|||
|
|||
/** |
|||
* @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') { |
|||
$this->url = $url; |
|||
} else { |
|||
// Force the path become relative.
|
|||
if (substr($url, 0, 1) !== '/') { |
|||
$url = '/' . $url; |
|||
} |
|||
global $apiConfig; |
|||
$this->url = $apiConfig['basePath'] . $url; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @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; |
|||
} |
|||
|
|||
/** |
|||
* @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 = ''; |
|||
foreach($this->batchHeaders as $key => $val) { |
|||
$str .= $key . ': ' . $val . "\n"; |
|||
} |
|||
|
|||
$str .= "Content-ID: $id\n"; |
|||
$str .= "\n"; |
|||
|
|||
$path = parse_url($this->getUrl(), PHP_URL_PATH); |
|||
$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(); |
|||
} |
|||
|
|||
return $str; |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
require_once 'io/Google_HttpRequest.php'; |
|||
require_once 'io/Google_CurlIO.php'; |
|||
require_once 'io/Google_REST.php'; |
|||
|
|||
/** |
|||
* Abstract IO class |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
*/ |
|||
interface Google_IO { |
|||
/** |
|||
* An utility function that first calls $this->auth->sign($request) and then executes makeRequest() |
|||
* on that signed request. Used for when a request should be authenticated |
|||
* @param Google_HttpRequest $request |
|||
* @return Google_HttpRequest $request |
|||
*/ |
|||
public function authenticatedRequest(Google_HttpRequest $request); |
|||
|
|||
/** |
|||
* Executes a apIHttpRequest and returns the resulting populated httpRequest |
|||
* @param Google_HttpRequest $request |
|||
* @return Google_HttpRequest $request |
|||
*/ |
|||
public function makeRequest(Google_HttpRequest $request); |
|||
|
|||
/** |
|||
* Set options that update the transport implementation's behavior. |
|||
* @param $options |
|||
*/ |
|||
public function setOptions($options); |
|||
|
|||
} |
|||
@ -0,0 +1,128 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* This class implements the RESTful transport of apiServiceRequest()'s |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_REST { |
|||
/** |
|||
* Executes a apiServiceRequest using a RESTful call by transforming it into |
|||
* an apiHttpRequest, and executed via apiIO::authenticatedRequest(). |
|||
* |
|||
* @param Google_HttpRequest $req |
|||
* @return array decoded result |
|||
* @throws Google_ServiceException on server side error (ie: not authenticated, |
|||
* invalid or malformed post body, invalid url) |
|||
*/ |
|||
static public function execute(Google_HttpRequest $req) { |
|||
$httpRequest = Google_Client::$io->makeRequest($req); |
|||
$decodedResponse = self::decodeHttpResponse($httpRequest); |
|||
$ret = isset($decodedResponse['data']) |
|||
? $decodedResponse['data'] : $decodedResponse; |
|||
return $ret; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Decode an HTTP Response. |
|||
* @static |
|||
* @throws Google_ServiceException |
|||
* @param Google_HttpRequest $response The http response to be decoded. |
|||
* @return mixed|null |
|||
*/ |
|||
public static function decodeHttpResponse($response) { |
|||
$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 ($decoded != null && 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"; |
|||
} |
|||
|
|||
throw new Google_ServiceException($err, $code, null, $decoded['error']['errors']); |
|||
} |
|||
|
|||
// Only attempt to decode the response, if the response code wasn't (204) 'no content'
|
|||
if ($code != '204') { |
|||
$decoded = json_decode($body, true); |
|||
if ($decoded === null || $decoded === "") { |
|||
throw new Google_ServiceException("Invalid json in service response: $body"); |
|||
} |
|||
} |
|||
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 |
|||
*/ |
|||
static function createRequestUri($servicePath, $restPath, $params) { |
|||
$requestUrl = $servicePath . $restPath; |
|||
$uriTemplateVars = array(); |
|||
$queryVars = array(); |
|||
foreach ($params as $paramName => $paramSpec) { |
|||
// Discovery v1.0 puts the canonical location under the 'location' field.
|
|||
if (! isset($paramSpec['location'])) { |
|||
$paramSpec['location'] = $paramSpec['restParameterType']; |
|||
} |
|||
|
|||
if ($paramSpec['type'] == 'boolean') { |
|||
$paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false'; |
|||
} |
|||
if ($paramSpec['location'] == 'path') { |
|||
$uriTemplateVars[$paramName] = $paramSpec['value']; |
|||
} else { |
|||
if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) { |
|||
foreach ($paramSpec['value'] as $value) { |
|||
$queryVars[] = $paramName . '=' . rawurlencode($value); |
|||
} |
|||
} else { |
|||
$queryVars[] = $paramName . '=' . rawurlencode($paramSpec['value']); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (count($uriTemplateVars)) { |
|||
$uriTemplateParser = new URI_Template_Parser($requestUrl); |
|||
$requestUrl = $uriTemplateParser->expand($uriTemplateVars); |
|||
} |
|||
//FIXME work around for the the uri template lib which url encodes
|
|||
// the @'s & confuses our servers.
|
|||
$requestUrl = str_replace('%40', '@', $requestUrl); |
|||
|
|||
if (count($queryVars)) { |
|||
$requestUrl .= '?' . implode($queryVars, '&'); |
|||
} |
|||
|
|||
return $requestUrl; |
|||
} |
|||
} |
|||
@ -0,0 +1,714 @@ |
|||
# Certifcate Authority certificates for validating SSL connections. |
|||
# |
|||
# This file contains PEM format certificates generated from |
|||
# http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt |
|||
# |
|||
# ***** BEGIN LICENSE BLOCK ***** |
|||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
|||
# |
|||
# The contents of this file are subject to the Mozilla Public License Version |
|||
# 1.1 (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.mozilla.org/MPL/ |
|||
# |
|||
# Software distributed under the License is distributed on an "AS IS" basis, |
|||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
|||
# for the specific language governing rights and limitations under the |
|||
# License. |
|||
# |
|||
# The Original Code is the Netscape security libraries. |
|||
# |
|||
# The Initial Developer of the Original Code is |
|||
# Netscape Communications Corporation. |
|||
# Portions created by the Initial Developer are Copyright (C) 1994-2000 |
|||
# the Initial Developer. All Rights Reserved. |
|||
# |
|||
# Contributor(s): |
|||
# |
|||
# Alternatively, the contents of this file may be used under the terms of |
|||
# either the GNU General Public License Version 2 or later (the "GPL"), or |
|||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|||
# in which case the provisions of the GPL or the LGPL are applicable instead |
|||
# of those above. If you wish to allow use of your version of this file only |
|||
# under the terms of either the GPL or the LGPL, and not to allow others to |
|||
# use your version of this file under the terms of the MPL, indicate your |
|||
# decision by deleting the provisions above and replace them with the notice |
|||
# and other provisions required by the GPL or the LGPL. If you do not delete |
|||
# the provisions above, a recipient may use your version of this file under |
|||
# the terms of any one of the MPL, the GPL or the LGPL. |
|||
# |
|||
# ***** END LICENSE BLOCK ***** |
|||
|
|||
Verisign/RSA Secure Server CA |
|||
============================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG |
|||
A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD |
|||
VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0 |
|||
MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV |
|||
BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy |
|||
dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ |
|||
ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII |
|||
0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI |
|||
uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI |
|||
hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3 |
|||
YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc |
|||
1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Thawte Personal Basic CA |
|||
======================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx |
|||
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD |
|||
VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT |
|||
ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj |
|||
IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X |
|||
DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw |
|||
EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE |
|||
ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy |
|||
dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD |
|||
QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN |
|||
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53 |
|||
dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK |
|||
wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7 |
|||
G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF |
|||
AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7 |
|||
c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P |
|||
9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Thawte Personal Premium CA |
|||
========================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx |
|||
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD |
|||
VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT |
|||
ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p |
|||
dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv |
|||
bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa |
|||
QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY |
|||
BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u |
|||
IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl |
|||
bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu |
|||
Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs |
|||
Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI |
|||
Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD |
|||
ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG |
|||
SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH |
|||
b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh |
|||
KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ |
|||
-----END CERTIFICATE----- |
|||
|
|||
Thawte Personal Freemail CA |
|||
=========================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx |
|||
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD |
|||
VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT |
|||
ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt |
|||
YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu |
|||
Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT |
|||
AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa |
|||
MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp |
|||
b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG |
|||
cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh |
|||
d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY |
|||
DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E |
|||
rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq |
|||
uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN |
|||
BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP |
|||
MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa |
|||
/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei |
|||
gQ== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Thawte Server CA |
|||
================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx |
|||
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD |
|||
VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv |
|||
biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm |
|||
MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx |
|||
MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT |
|||
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 |
|||
dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl |
|||
cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 |
|||
DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD |
|||
gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 |
|||
yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX |
|||
L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj |
|||
EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG |
|||
7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e |
|||
QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ |
|||
qdq5snUb9kLy78fyGPmJvKP/iiMucEc= |
|||
-----END CERTIFICATE----- |
|||
|
|||
Thawte Premium Server CA |
|||
======================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx |
|||
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD |
|||
VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv |
|||
biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy |
|||
dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t |
|||
MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB |
|||
MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG |
|||
A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp |
|||
b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl |
|||
cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv |
|||
bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE |
|||
VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ |
|||
ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR |
|||
uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG |
|||
9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI |
|||
hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM |
|||
pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Equifax Secure CA |
|||
================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV |
|||
UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy |
|||
dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 |
|||
MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx |
|||
dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B |
|||
AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f |
|||
BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A |
|||
cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC |
|||
AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ |
|||
MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm |
|||
aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw |
|||
ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj |
|||
IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF |
|||
MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA |
|||
A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y |
|||
7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh |
|||
1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 1 Public Primary Certification Authority |
|||
======================================================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ |
|||
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh |
|||
c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05 |
|||
NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD |
|||
VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp |
|||
bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB |
|||
jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N |
|||
H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR |
|||
4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN |
|||
BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo |
|||
EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5 |
|||
FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx |
|||
lA== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 2 Public Primary Certification Authority |
|||
======================================================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG |
|||
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz |
|||
cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 |
|||
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV |
|||
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt |
|||
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN |
|||
ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh |
|||
YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7 |
|||
FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G |
|||
CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg |
|||
J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc |
|||
r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 3 Public Primary Certification Authority |
|||
======================================================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG |
|||
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz |
|||
cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 |
|||
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV |
|||
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt |
|||
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN |
|||
ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE |
|||
BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is |
|||
I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G |
|||
CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do |
|||
lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc |
|||
AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 1 Public Primary Certification Authority - G2 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ |
|||
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh |
|||
c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy |
|||
MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp |
|||
emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X |
|||
DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw |
|||
FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg |
|||
UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo |
|||
YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 |
|||
MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB |
|||
AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK |
|||
VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm |
|||
Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID |
|||
AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J |
|||
h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul |
|||
uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68 |
|||
DzFc6PLZ |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 2 Public Primary Certification Authority - G2 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw |
|||
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns |
|||
YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH |
|||
MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y |
|||
aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe |
|||
Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX |
|||
MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj |
|||
IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx |
|||
KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s |
|||
eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B |
|||
AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM |
|||
HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw |
|||
DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC |
|||
AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji |
|||
nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX |
|||
rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn |
|||
jBJ7xUS0rg== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 3 Public Primary Certification Authority - G2 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ |
|||
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh |
|||
c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy |
|||
MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp |
|||
emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X |
|||
DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw |
|||
FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg |
|||
UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo |
|||
YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 |
|||
MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB |
|||
AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 |
|||
pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 |
|||
13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID |
|||
AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk |
|||
U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i |
|||
F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY |
|||
oJ2daZH9 |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 4 Public Primary Certification Authority - G2 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ |
|||
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh |
|||
c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy |
|||
MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp |
|||
emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X |
|||
DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw |
|||
FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg |
|||
UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo |
|||
YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 |
|||
MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB |
|||
AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM |
|||
HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK |
|||
qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID |
|||
AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj |
|||
cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y |
|||
cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP |
|||
T8qAkbYp |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 1 Public Primary Certification Authority - G3 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw |
|||
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl |
|||
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu |
|||
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT |
|||
aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp |
|||
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD |
|||
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT |
|||
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ |
|||
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu |
|||
IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg |
|||
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 |
|||
nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO |
|||
8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV |
|||
ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb |
|||
PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 |
|||
6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr |
|||
n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a |
|||
qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 |
|||
wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 |
|||
ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs |
|||
pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 |
|||
E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 2 Public Primary Certification Authority - G3 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ |
|||
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy |
|||
aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s |
|||
IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp |
|||
Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 |
|||
eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV |
|||
BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp |
|||
Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu |
|||
Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g |
|||
Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt |
|||
IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU |
|||
J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO |
|||
JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY |
|||
wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o |
|||
koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN |
|||
qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E |
|||
Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe |
|||
xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u |
|||
7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU |
|||
sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI |
|||
sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP |
|||
cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 3 Public Primary Certification Authority - G3 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw |
|||
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl |
|||
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu |
|||
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT |
|||
aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp |
|||
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD |
|||
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT |
|||
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ |
|||
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu |
|||
IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg |
|||
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b |
|||
N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t |
|||
KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu |
|||
kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm |
|||
CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ |
|||
Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu |
|||
imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te |
|||
2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe |
|||
DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC |
|||
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p |
|||
F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt |
|||
TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Verisign Class 4 Public Primary Certification Authority - G3 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw |
|||
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl |
|||
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu |
|||
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT |
|||
aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp |
|||
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD |
|||
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT |
|||
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ |
|||
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu |
|||
IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg |
|||
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 |
|||
GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ |
|||
+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd |
|||
U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm |
|||
NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY |
|||
ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ |
|||
ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 |
|||
CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq |
|||
g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm |
|||
fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c |
|||
2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ |
|||
bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Equifax Secure Global eBusiness CA |
|||
================================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc |
|||
MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT |
|||
ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw |
|||
MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj |
|||
dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l |
|||
c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC |
|||
UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc |
|||
58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ |
|||
o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH |
|||
MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr |
|||
aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA |
|||
A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA |
|||
Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv |
|||
8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV |
|||
-----END CERTIFICATE----- |
|||
|
|||
Equifax Secure eBusiness CA 1 |
|||
============================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc |
|||
MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT |
|||
ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw |
|||
MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j |
|||
LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ |
|||
KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo |
|||
RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu |
|||
WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw |
|||
Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD |
|||
AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK |
|||
eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM |
|||
zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ |
|||
WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN |
|||
/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== |
|||
-----END CERTIFICATE----- |
|||
|
|||
Equifax Secure eBusiness CA 2 |
|||
============================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV |
|||
UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj |
|||
dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 |
|||
NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD |
|||
VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B |
|||
AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G |
|||
vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ |
|||
BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C |
|||
AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX |
|||
MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl |
|||
IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw |
|||
NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq |
|||
y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF |
|||
MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA |
|||
A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy |
|||
0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 |
|||
E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN |
|||
-----END CERTIFICATE----- |
|||
|
|||
Thawte Time Stamping CA |
|||
======================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx |
|||
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN |
|||
BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd |
|||
BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN |
|||
MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g |
|||
Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG |
|||
A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l |
|||
c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT |
|||
6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa |
|||
Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL |
|||
8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB |
|||
Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC |
|||
9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ |
|||
pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ |
|||
CayJSdM= |
|||
-----END CERTIFICATE----- |
|||
|
|||
thawte Primary Root CA |
|||
====================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB |
|||
qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf |
|||
Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw |
|||
MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV |
|||
BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw |
|||
NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j |
|||
LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG |
|||
A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl |
|||
IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG |
|||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs |
|||
W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta |
|||
3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk |
|||
6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 |
|||
Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J |
|||
NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA |
|||
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP |
|||
r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU |
|||
DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz |
|||
YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX |
|||
xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 |
|||
/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ |
|||
LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 |
|||
jVaMaA== |
|||
-----END CERTIFICATE----- |
|||
|
|||
VeriSign Class 3 Public Primary Certification Authority - G5 |
|||
============================================================ |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB |
|||
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL |
|||
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp |
|||
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW |
|||
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 |
|||
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL |
|||
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW |
|||
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln |
|||
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp |
|||
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y |
|||
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 |
|||
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex |
|||
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz |
|||
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG |
|||
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ |
|||
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ |
|||
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E |
|||
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH |
|||
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy |
|||
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv |
|||
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE |
|||
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y |
|||
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK |
|||
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ |
|||
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N |
|||
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq |
|||
-----END CERTIFICATE----- |
|||
|
|||
Entrust.net Secure Server Certification Authority |
|||
================================================= |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC |
|||
VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u |
|||
ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc |
|||
KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u |
|||
ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 |
|||
MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE |
|||
ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j |
|||
b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF |
|||
bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg |
|||
U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA |
|||
A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ |
|||
I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 |
|||
wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC |
|||
AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb |
|||
oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 |
|||
BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p |
|||
dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk |
|||
MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp |
|||
b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu |
|||
dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 |
|||
MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi |
|||
E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa |
|||
MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI |
|||
hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN |
|||
95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd |
|||
2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= |
|||
-----END CERTIFICATE----- |
|||
|
|||
Go Daddy Certification Authority Root Certificate Bundle |
|||
======================================================== |
|||
|
|||
-----BEGIN CERTIFICATE----- |
|||
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx |
|||
ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g |
|||
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw |
|||
MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH |
|||
QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j |
|||
b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j |
|||
b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj |
|||
YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN |
|||
AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H |
|||
KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm |
|||
VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR |
|||
SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT |
|||
cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ |
|||
6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu |
|||
MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS |
|||
kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB |
|||
BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f |
|||
BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv |
|||
c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH |
|||
AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO |
|||
BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG |
|||
OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU |
|||
A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o |
|||
0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX |
|||
RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH |
|||
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV |
|||
U+4= |
|||
-----END CERTIFICATE----- |
|||
-----BEGIN CERTIFICATE----- |
|||
MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh |
|||
bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu |
|||
Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g |
|||
QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe |
|||
BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX |
|||
DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE |
|||
YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0 |
|||
aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC |
|||
ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv |
|||
2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q |
|||
N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO |
|||
r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN |
|||
f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH |
|||
U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU |
|||
TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb |
|||
VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg |
|||
SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv |
|||
biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg |
|||
MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw |
|||
AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv |
|||
ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu |
|||
Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd |
|||
IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv |
|||
bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1 |
|||
QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O |
|||
WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf |
|||
SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw== |
|||
-----END CERTIFICATE----- |
|||
-----BEGIN CERTIFICATE----- |
|||
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 |
|||
IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz |
|||
BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y |
|||
aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG |
|||
9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy |
|||
NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y |
|||
azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs |
|||
YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw |
|||
Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl |
|||
cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY |
|||
dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 |
|||
WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS |
|||
v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v |
|||
UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu |
|||
IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC |
|||
W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd |
|||
-----END CERTIFICATE----- |
|||
|
|||
@ -0,0 +1,110 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_BatchRequest { |
|||
/** @var string Multipart Boundary. */ |
|||
private $boundary; |
|||
|
|||
/** @var array service requests to be executed. */ |
|||
private $requests = array(); |
|||
|
|||
public function __construct($boundary = false) { |
|||
$boundary = (false == $boundary) ? mt_rand() : $boundary; |
|||
$this->boundary = str_replace('"', '', $boundary); |
|||
} |
|||
|
|||
public function add(Google_HttpRequest $request, $key = false) { |
|||
if (false == $key) { |
|||
$key = mt_rand(); |
|||
} |
|||
|
|||
$this->requests[$key] = $request; |
|||
} |
|||
|
|||
public function execute() { |
|||
$body = ''; |
|||
|
|||
/** @var Google_HttpRequest $req */ |
|||
foreach($this->requests as $key => $req) { |
|||
$body .= "--{$this->boundary}\n"; |
|||
$body .= $req->toBatchString($key) . "\n"; |
|||
} |
|||
|
|||
$body = rtrim($body); |
|||
$body .= "\n--{$this->boundary}--"; |
|||
|
|||
global $apiConfig; |
|||
$url = $apiConfig['basePath'] . '/batch'; |
|||
$httpRequest = new Google_HttpRequest($url, 'POST'); |
|||
$httpRequest->setRequestHeaders(array( |
|||
'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary)); |
|||
|
|||
$httpRequest->setPostBody($body); |
|||
$response = Google_Client::$io->makeRequest($httpRequest); |
|||
|
|||
$response = $this->parseResponse($response); |
|||
return $response; |
|||
} |
|||
|
|||
public function parseResponse(Google_HttpRequest $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 = Google_CurlIO::parseResponseHeaders($metaHeaders); |
|||
|
|||
$status = substr($part, 0, strpos($part, "\n")); |
|||
$status = explode(" ", $status); |
|||
$status = $status[1]; |
|||
|
|||
list($partHeaders, $partBody) = Google_CurlIO::parseHttpResponse($part, false); |
|||
$response = new Google_HttpRequest(""); |
|||
$response->setResponseHttpCode($status); |
|||
$response->setResponseHeaders($partHeaders); |
|||
$response->setResponseBody($partBody); |
|||
$response = Google_REST::decodeHttpResponse($response); |
|||
|
|||
// Need content id.
|
|||
$responses[$metaHeaders['content-id']] = $response; |
|||
} |
|||
} |
|||
|
|||
return $responses; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
@ -0,0 +1,262 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* @author Chirag Shah <chirags@google.com> |
|||
* |
|||
*/ |
|||
class Google_MediaFileUpload { |
|||
const UPLOAD_MEDIA_TYPE = 'media'; |
|||
const UPLOAD_MULTIPART_TYPE = 'multipart'; |
|||
const UPLOAD_RESUMABLE_TYPE = 'resumable'; |
|||
|
|||
/** @var string $mimeType */ |
|||
public $mimeType; |
|||
|
|||
/** @var string $data */ |
|||
public $data; |
|||
|
|||
/** @var bool $resumable */ |
|||
public $resumable; |
|||
|
|||
/** @var int $chunkSize */ |
|||
public $chunkSize; |
|||
|
|||
/** @var int $size */ |
|||
public $size; |
|||
|
|||
/** @var string $resumeUri */ |
|||
public $resumeUri; |
|||
|
|||
/** @var int $progress */ |
|||
public $progress; |
|||
|
|||
/** |
|||
* @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($mimeType, $data, $resumable=false, $chunkSize=false) { |
|||
$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; |
|||
} |
|||
|
|||
public function setFileSize($size) { |
|||
$this->size = $size; |
|||
} |
|||
|
|||
/** |
|||
* @static |
|||
* @param $meta |
|||
* @param $params |
|||
* @return array|bool |
|||
*/ |
|||
public static function process($meta, &$params) { |
|||
$payload = array(); |
|||
$meta = is_string($meta) ? json_decode($meta, true) : $meta; |
|||
$uploadType = self::getUploadType($meta, $payload, $params); |
|||
if (!$uploadType) { |
|||
// Process as a normal API request.
|
|||
return false; |
|||
} |
|||
|
|||
// Process as a media upload request.
|
|||
$params['uploadType'] = array( |
|||
'type' => 'string', |
|||
'location' => 'query', |
|||
'value' => $uploadType, |
|||
); |
|||
|
|||
$mimeType = isset($params['mimeType']) |
|||
? $params['mimeType']['value'] |
|||
: false; |
|||
unset($params['mimeType']); |
|||
|
|||
if (!$mimeType) { |
|||
$mimeType = $payload['content-type']; |
|||
} |
|||
|
|||
if (isset($params['file'])) { |
|||
// This is a standard file upload with curl.
|
|||
$file = $params['file']['value']; |
|||
unset($params['file']); |
|||
return self::processFileUpload($file, $mimeType); |
|||
} |
|||
|
|||
$data = isset($params['data']) |
|||
? $params['data']['value'] |
|||
: false; |
|||
unset($params['data']); |
|||
|
|||
if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) { |
|||
$payload['content-type'] = $mimeType; |
|||
$payload['postBody'] = is_string($meta) ? $meta : json_encode($meta); |
|||
|
|||
} elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) { |
|||
// This is a simple media upload.
|
|||
$payload['content-type'] = $mimeType; |
|||
$payload['postBody'] = $data; |
|||
} |
|||
|
|||
elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) { |
|||
// This is a multipart/related upload.
|
|||
$boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand(); |
|||
$boundary = str_replace('"', '', $boundary); |
|||
$payload['content-type'] = '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($data) . "\r\n"; |
|||
$related .= "--$boundary--"; |
|||
$payload['postBody'] = $related; |
|||
} |
|||
|
|||
return $payload; |
|||
} |
|||
|
|||
/** |
|||
* Prepares a standard file upload via cURL. |
|||
* @param $file |
|||
* @param $mime |
|||
* @return array Includes the processed file name. |
|||
* @visible For testing. |
|||
*/ |
|||
public static function processFileUpload($file, $mime) { |
|||
if (!$file) return array(); |
|||
if (substr($file, 0, 1) != '@') { |
|||
$file = '@' . $file; |
|||
} |
|||
|
|||
// This is a standard file upload with curl.
|
|||
$params = array('postBody' => array('file' => $file)); |
|||
if ($mime) { |
|||
$params['content-type'] = $mime; |
|||
} |
|||
|
|||
return $params; |
|||
} |
|||
|
|||
/** |
|||
* Valid upload types: |
|||
* - resumable (UPLOAD_RESUMABLE_TYPE) |
|||
* - media (UPLOAD_MEDIA_TYPE) |
|||
* - multipart (UPLOAD_MULTIPART_TYPE) |
|||
* - none (false) |
|||
* @param $meta |
|||
* @param $payload |
|||
* @param $params |
|||
* @return bool|string |
|||
*/ |
|||
public static function getUploadType($meta, &$payload, &$params) { |
|||
if (isset($params['mediaUpload']) |
|||
&& get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') { |
|||
$upload = $params['mediaUpload']['value']; |
|||
unset($params['mediaUpload']); |
|||
$payload['content-type'] = $upload->mimeType; |
|||
if (isset($upload->resumable) && $upload->resumable) { |
|||
return self::UPLOAD_RESUMABLE_TYPE; |
|||
} |
|||
} |
|||
|
|||
// Allow the developer to override the upload type.
|
|||
if (isset($params['uploadType'])) { |
|||
return $params['uploadType']['value']; |
|||
} |
|||
|
|||
$data = isset($params['data']['value']) |
|||
? $params['data']['value'] : false; |
|||
|
|||
if (false == $data && false == isset($params['file'])) { |
|||
// No upload data available.
|
|||
return false; |
|||
} |
|||
|
|||
if (isset($params['file'])) { |
|||
return self::UPLOAD_MEDIA_TYPE; |
|||
} |
|||
|
|||
if (false == $meta) { |
|||
return self::UPLOAD_MEDIA_TYPE; |
|||
} |
|||
|
|||
return self::UPLOAD_MULTIPART_TYPE; |
|||
} |
|||
|
|||
|
|||
public function nextChunk(Google_HttpRequest $req, $chunk=false) { |
|||
if (false == $this->resumeUri) { |
|||
$this->resumeUri = $this->getResumeUri($req); |
|||
} |
|||
|
|||
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' => $req->getRequestHeader('content-type'), |
|||
'content-length' => $this->chunkSize, |
|||
'expect' => '', |
|||
); |
|||
|
|||
$httpRequest = new Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk); |
|||
$response = Google_Client::$io->authenticatedRequest($httpRequest); |
|||
$code = $response->getResponseHttpCode(); |
|||
if (308 == $code) { |
|||
$range = explode('-', $response->getResponseHeader('range')); |
|||
$this->progress = $range[1] + 1; |
|||
return false; |
|||
} else { |
|||
return Google_REST::decodeHttpResponse($response); |
|||
} |
|||
} |
|||
|
|||
private function getResumeUri(Google_HttpRequest $httpRequest) { |
|||
$result = null; |
|||
$body = $httpRequest->getPostBody(); |
|||
if ($body) { |
|||
$httpRequest->setRequestHeaders(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' => '', |
|||
)); |
|||
} |
|||
|
|||
$response = Google_Client::$io->makeRequest($httpRequest); |
|||
$location = $response->getResponseHeader('location'); |
|||
$code = $response->getResponseHttpCode(); |
|||
if (200 == $code && true == $location) { |
|||
return $location; |
|||
} |
|||
throw new Google_Exception("Failed to start the resumable upload"); |
|||
} |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
/** |
|||
* This class defines attributes, valid values, and usage which is generated from |
|||
* a given json schema. http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
|
|||
* |
|||
* @author Chirag Shah <chirags@google.com> |
|||
* |
|||
*/ |
|||
class Google_Model { |
|||
public function __construct( /* polymorphic */ ) { |
|||
if (func_num_args() == 1 && is_array(func_get_arg(0))) { |
|||
// Initialize the model with the array's contents.
|
|||
$array = func_get_arg(0); |
|||
$this->mapTypes($array); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Initialize this object's properties from an array. |
|||
* |
|||
* @param array $array Used to seed this object's properties. |
|||
* @return void |
|||
*/ |
|||
protected function mapTypes($array) { |
|||
foreach ($array as $key => $val) { |
|||
$this->$key = $val; |
|||
|
|||
$keyTypeName = "__$key" . 'Type'; |
|||
$keyDataType = "__$key" . 'DataType'; |
|||
if ($this->useObjects() && property_exists($this, $keyTypeName)) { |
|||
if ($this->isAssociativeArray($val)) { |
|||
if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) { |
|||
foreach($val as $arrayKey => $arrayItem) { |
|||
$val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem); |
|||
} |
|||
$this->$key = $val; |
|||
} else { |
|||
$this->$key = $this->createObjectFromName($keyTypeName, $val); |
|||
} |
|||
} else if (is_array($val)) { |
|||
$arrayObject = array(); |
|||
foreach ($val as $arrayIndex => $arrayItem) { |
|||
$arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem); |
|||
} |
|||
$this->$key = $arrayObject; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Returns true only if the array is associative. |
|||
* @param array $array |
|||
* @return bool True if the array is associative. |
|||
*/ |
|||
protected function isAssociativeArray($array) { |
|||
if (!is_array($array)) { |
|||
return false; |
|||
} |
|||
$keys = array_keys($array); |
|||
foreach($keys as $key) { |
|||
if (is_string($key)) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* Given a variable name, discover its type. |
|||
* |
|||
* @param $name |
|||
* @param $item |
|||
* @return object The object from the item. |
|||
*/ |
|||
private function createObjectFromName($name, $item) { |
|||
$type = $this->$name; |
|||
return new $type($item); |
|||
} |
|||
|
|||
protected function useObjects() { |
|||
global $apiConfig; |
|||
return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']); |
|||
} |
|||
|
|||
/** |
|||
* Verify if $obj is an array. |
|||
* @throws Google_Exception Thrown if $obj isn't an array. |
|||
* @param array $obj Items that should be validated. |
|||
* @param string $type Array items should be of this type. |
|||
* @param string $method Method expecting an array as an argument. |
|||
*/ |
|||
public function assertIsArray($obj, $type, $method) { |
|||
if ($obj && !is_array($obj)) { |
|||
throw new Google_Exception("Incorrect parameter type passed to $method(), expected an" |
|||
. " array containing items of type $type."); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
class Google_Service { |
|||
public $version; |
|||
public $servicePath; |
|||
public $resource; |
|||
} |
|||
@ -0,0 +1,205 @@ |
|||
<?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. |
|||
*/ |
|||
|
|||
/** |
|||
* Implements the actual methods/resources of the discovered Google API using magic function
|
|||
* calling overloading (__call()), which on call will see if the method name (plus.activities.list) |
|||
* is available in this service, and if so construct an apiHttpRequest representing it. |
|||
* |
|||
* @author Chris Chabot <chabotc@google.com> |
|||
* @author Chirag Shah <chirags@google.com> |
|||
* |
|||
*/ |
|||
class Google_ServiceResource { |
|||
// Valid query parameters that work, but don't appear in discovery.
|
|||
private $stackParameters = array( |
|||
'alt' => array('type' => 'string', 'location' => 'query'), |
|||
'boundary' => array('type' => 'string', 'location' => 'query'), |
|||
'fields' => array('type' => 'string', 'location' => 'query'), |
|||
'trace' => array('type' => 'string', 'location' => 'query'), |
|||
'userIp' => array('type' => 'string', 'location' => 'query'), |
|||
'userip' => array('type' => 'string', 'location' => 'query'), |
|||
'quotaUser' => array('type' => 'string', 'location' => 'query'), |
|||
'file' => array('type' => 'complex', 'location' => 'body'), |
|||
'data' => array('type' => 'string', 'location' => 'body'), |
|||
'mimeType' => array('type' => 'string', 'location' => 'header'), |
|||
'uploadType' => array('type' => 'string', 'location' => 'query'), |
|||
'mediaUpload' => array('type' => 'complex', 'location' => 'query'), |
|||
); |
|||
|
|||
/** @var Google_Service $service */ |
|||
private $service; |
|||
|
|||
/** @var string $serviceName */ |
|||
private $serviceName; |
|||
|
|||
/** @var string $resourceName */ |
|||
private $resourceName; |
|||
|
|||
/** @var array $methods */ |
|||
private $methods; |
|||
|
|||
public function __construct($service, $serviceName, $resourceName, $resource) { |
|||
$this->service = $service; |
|||
$this->serviceName = $serviceName; |
|||
$this->resourceName = $resourceName; |
|||
$this->methods = isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource); |
|||
} |
|||
|
|||
/** |
|||
* @param $name |
|||
* @param $arguments |
|||
* @return Google_HttpRequest|array |
|||
* @throws Google_Exception |
|||
*/ |
|||
public function __call($name, $arguments) { |
|||
if (! isset($this->methods[$name])) { |
|||
throw new Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()"); |
|||
} |
|||
$method = $this->methods[$name]; |
|||
$parameters = $arguments[0]; |
|||
|
|||
// postBody is a special case since it's not defined in the discovery document as parameter, but we abuse the param entry for storing it
|
|||
$postBody = null; |
|||
if (isset($parameters['postBody'])) { |
|||
if (is_object($parameters['postBody'])) { |
|||
$this->stripNull($parameters['postBody']); |
|||
} |
|||
|
|||
// Some APIs require the postBody to be set under the data key.
|
|||
if (is_array($parameters['postBody']) && 'latitude' == $this->serviceName) { |
|||
if (!isset($parameters['postBody']['data'])) { |
|||
$rawBody = $parameters['postBody']; |
|||
unset($parameters['postBody']); |
|||
$parameters['postBody']['data'] = $rawBody; |
|||
} |
|||
} |
|||
|
|||
$postBody = is_array($parameters['postBody']) || is_object($parameters['postBody']) |
|||
? json_encode($parameters['postBody']) |
|||
: $parameters['postBody']; |
|||
unset($parameters['postBody']); |
|||
|
|||
if (isset($parameters['optParams'])) { |
|||
$optParams = $parameters['optParams']; |
|||
unset($parameters['optParams']); |
|||
$parameters = array_merge($parameters, $optParams); |
|||
} |
|||
} |
|||
|
|||
if (!isset($method['parameters'])) { |
|||
$method['parameters'] = array(); |
|||
} |
|||
|
|||
$method['parameters'] = array_merge($method['parameters'], $this->stackParameters); |
|||
foreach ($parameters as $key => $val) { |
|||
if ($key != 'postBody' && ! isset($method['parameters'][$key])) { |
|||
throw new Google_Exception("($name) unknown parameter: '$key'"); |
|||
} |
|||
} |
|||
if (isset($method['parameters'])) { |
|||
foreach ($method['parameters'] as $paramName => $paramSpec) { |
|||
if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) { |
|||
throw new Google_Exception("($name) missing required param: '$paramName'"); |
|||
} |
|||
if (isset($parameters[$paramName])) { |
|||
$value = $parameters[$paramName]; |
|||
$parameters[$paramName] = $paramSpec; |
|||
$parameters[$paramName]['value'] = $value; |
|||
unset($parameters[$paramName]['required']); |
|||
} else { |
|||
unset($parameters[$paramName]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Discovery v1.0 puts the canonical method id under the 'id' field.
|
|||
if (! isset($method['id'])) { |
|||
$method['id'] = $method['rpcMethod']; |
|||
} |
|||
|
|||
// Discovery v1.0 puts the canonical path under the 'path' field.
|
|||
if (! isset($method['path'])) { |
|||
$method['path'] = $method['restPath']; |
|||
} |
|||
|
|||
$servicePath = $this->service->servicePath; |
|||
|
|||
// Process Media Request
|
|||
$contentType = false; |
|||
if (isset($method['mediaUpload'])) { |
|||
$media = Google_MediaFileUpload::process($postBody, $parameters); |
|||
if ($media) { |
|||
$contentType = isset($media['content-type']) ? $media['content-type']: null; |
|||
$postBody = isset($media['postBody']) ? $media['postBody'] : null; |
|||
$servicePath = $method['mediaUpload']['protocols']['simple']['path']; |
|||
$method['path'] = ''; |
|||
} |
|||
} |
|||
|
|||
$url = Google_REST::createRequestUri($servicePath, $method['path'], $parameters); |
|||
$httpRequest = new Google_HttpRequest($url, $method['httpMethod'], null, $postBody); |
|||
if ($postBody) { |
|||
$contentTypeHeader = array(); |
|||
if (isset($contentType) && $contentType) { |
|||
$contentTypeHeader['content-type'] = $contentType; |
|||
} else { |
|||
$contentTypeHeader['content-type'] = 'application/json; charset=UTF-8'; |
|||
$contentTypeHeader['content-length'] = Google_Utils::getStrLen($postBody); |
|||
} |
|||
$httpRequest->setRequestHeaders($contentTypeHeader); |
|||
} |
|||
|
|||
$httpRequest = Google_Client::$auth->sign($httpRequest); |
|||
if (Google_Client::$useBatch) { |
|||
return $httpRequest; |
|||
} |
|||
|
|||
// Terminate immediately if this is a resumable request.
|
|||
if (isset($parameters['uploadType']['value']) |
|||
&& Google_MediaFileUpload::UPLOAD_RESUMABLE_TYPE == $parameters['uploadType']['value']) { |
|||
$contentTypeHeader = array(); |
|||
if (isset($contentType) && $contentType) { |
|||
$contentTypeHeader['content-type'] = $contentType; |
|||
} |
|||
$httpRequest->setRequestHeaders($contentTypeHeader); |
|||
if ($postBody) { |
|||
$httpRequest->setPostBody($postBody); |
|||
} |
|||
return $httpRequest; |
|||
} |
|||
|
|||
return Google_REST::execute($httpRequest); |
|||
} |
|||
|
|||
public function useObjects() { |
|||
global $apiConfig; |
|||
return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']); |
|||
} |
|||
|
|||
protected function stripNull(&$o) { |
|||
$o = (array) $o; |
|||
foreach ($o as $k => $v) { |
|||
if ($v === null || strstr($k, "\0*\0__")) { |
|||
unset($o[$k]); |
|||
} |
|||
elseif (is_object($v) || is_array($v)) { |
|||
$this->stripNull($o[$k]); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,117 @@ |
|||
<?php |
|||
/* |
|||
* Copyright 2011 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Collection of static utility methods used for convenience across |
|||
* the client library. |
|||
* |
|||
* @author Chirag Shah <chirags@google.com> |
|||
*/ |
|||
class Google_Utils { |
|||
public static function urlSafeB64Encode($data) { |
|||
$b64 = base64_encode($data); |
|||
$b64 = str_replace(array('+', '/', '\r', '\n', '='), |
|||
array('-', '_'), |
|||
$b64); |
|||
return $b64; |
|||
} |
|||
|
|||
public static function urlSafeB64Decode($b64) { |
|||
$b64 = str_replace(array('-', '_'), |
|||
array('+', '/'), |
|||
$b64); |
|||
return base64_decode($b64); |
|||
} |
|||
|
|||
/** |
|||
* Misc function used to count the number of bytes in a post body, in the world of multi-byte chars |
|||
* and the unpredictability of strlen/mb_strlen/sizeof, this is the only way to do that in a sane |
|||
* manner at the moment. |
|||
* |
|||
* This algorithm was originally developed for the |
|||
* Solar Framework by Paul M. Jones |
|||
* |
|||
* @link http://solarphp.com/ |
|||
* @link http://svn.solarphp.com/core/trunk/Solar/Json.php |
|||
* @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php |
|||
* @param string $str |
|||
* @return int The number of bytes in a string. |
|||
*/ |
|||
static public function getStrLen($str) { |
|||
$strlenVar = strlen($str); |
|||
$d = $ret = 0; |
|||
for ($count = 0; $count < $strlenVar; ++ $count) { |
|||
$ordinalValue = ord($str{$ret}); |
|||
switch (true) { |
|||
case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)): |
|||
// characters U-00000000 - U-0000007F (same as ASCII)
|
|||
$ret ++; |
|||
break; |
|||
|
|||
case (($ordinalValue & 0xE0) == 0xC0): |
|||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
|||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
|||
$ret += 2; |
|||
break; |
|||
|
|||
case (($ordinalValue & 0xF0) == 0xE0): |
|||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
|||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
|||
$ret += 3; |
|||
break; |
|||
|
|||
case (($ordinalValue & 0xF8) == 0xF0): |
|||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
|||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
|||
$ret += 4; |
|||
break; |
|||
|
|||
case (($ordinalValue & 0xFC) == 0xF8): |
|||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
|||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
|||
$ret += 5; |
|||
break; |
|||
|
|||
case (($ordinalValue & 0xFE) == 0xFC): |
|||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
|||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
|||
$ret += 6; |
|||
break; |
|||
default: |
|||
$ret ++; |
|||
} |
|||
} |
|||
return $ret; |
|||
} |
|||
|
|||
/** |
|||
* Normalize all keys in an array to lower-case. |
|||
* @param array $arr |
|||
* @return array Normalized array. |
|||
*/ |
|||
public static function normalize($arr) { |
|||
if (!is_array($arr)) { |
|||
return array(); |
|||
} |
|||
|
|||
$normalized = array(); |
|||
foreach ($arr as $key => $val) { |
|||
$normalized[strtolower($key)] = $val; |
|||
} |
|||
return $normalized; |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue