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