Merge branch 'develop'
This commit is contained in:
@@ -260,6 +260,7 @@ class CDN {
|
||||
* 'cdn_enabled' => 1
|
||||
* 'name' => 'I♡HPCloud'
|
||||
* 'x-cdn-uri' => 'http://hcf937838.cdn.aw1.hpcloud.net'
|
||||
* 'x-cdn-ssl-uri' => 'https://hcf937838.cdn.aw1.hpcloud.net'
|
||||
* 'ttl' => 1234
|
||||
* ),
|
||||
* array(
|
||||
@@ -267,6 +268,7 @@ class CDN {
|
||||
* 'cdn_enabled' => 0
|
||||
* 'name' => 'HPCloud2'
|
||||
* 'x-cdn-uri' => 'http://hcf9abc38.cdn.aw1.hpcloud.net'
|
||||
* 'x-cdn-ssl-uri' => 'https://hcf937838.cdn.aw1.hpcloud.net'
|
||||
* 'ttl' => 1234
|
||||
* ),
|
||||
* );
|
||||
|
||||
@@ -236,7 +236,10 @@ class ObjectStorage {
|
||||
// This is needed b/c of a bug in SOS that sometimes
|
||||
// returns disabled containers (DEVEX-1733).
|
||||
if ($item['cdn_enabled'] == 1) {
|
||||
$buffer[$item['name']] = $item['x-cdn-uri'];
|
||||
$buffer[$item['name']] = array(
|
||||
'url' => $item['x-cdn-uri'],
|
||||
'sslUrl' => $item['x-cdn-ssl-uri'],
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->cdnContainers = $buffer;
|
||||
@@ -254,13 +257,17 @@ class ObjectStorage {
|
||||
*
|
||||
* @param string $containerName
|
||||
* The name of the container.
|
||||
* @param boolean $ssl
|
||||
* If this is TRUE (default), get the URL to the SSL CDN;
|
||||
* otherwise get the URL to the plain HTTP CDN.
|
||||
* @retval string
|
||||
* The URL to the CDN container, or NULL if no such
|
||||
* URL is found.
|
||||
*/
|
||||
public function cdnUrl($containerName) {
|
||||
public function cdnUrl($containerName, $ssl = TRUE) {
|
||||
if (!empty($this->cdnContainers[$containerName])) {
|
||||
return $this->cdnContainers[$containerName];
|
||||
$key = $ssl ? 'sslUrl' : 'url';
|
||||
return $this->cdnContainers[$containerName][$key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +346,8 @@ class ObjectStorage {
|
||||
$containerList[$cname] = Container::newFromJSON($container, $this->token(), $this->url());
|
||||
|
||||
if (!empty($this->cdnContainers[$cname])) {
|
||||
$containerList[$cname]->useCDN($this->cdnContainers[$cname]);
|
||||
$cdnList = $this->cdnContainers[$cname];
|
||||
$containerList[$cname]->useCDN($cdnList['url'], $cdnList['sslUrl']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +376,8 @@ class ObjectStorage {
|
||||
$container = Container::newFromResponse($name, $data, $this->token(), $this->url());
|
||||
|
||||
if (isset($this->cdnContainers[$name])) {
|
||||
$container->useCDN($this->cdnContainers[$name]);
|
||||
$cdnList = $this->cdnContainers[$name];
|
||||
$container->useCDN($cdnList['url'], $cdnList['sslUrl']);
|
||||
}
|
||||
|
||||
return $container;
|
||||
|
||||
@@ -95,6 +95,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
|
||||
// This is only set if CDN service is activated.
|
||||
protected $cdnUrl;
|
||||
protected $cdnSslUrl;
|
||||
|
||||
/**
|
||||
* Transform a metadata array into headers.
|
||||
@@ -335,9 +336,12 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
*
|
||||
* @param string $url
|
||||
* The URL to the CDN for this container.
|
||||
* @param string $sslUrl
|
||||
* The SSL URL to the CDN for this container.
|
||||
*/
|
||||
public function useCDN($url) {
|
||||
public function useCDN($url, $sslUrl) {
|
||||
$this->cdnUrl = $url;
|
||||
$this->cdnSslUrl = $sslUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -681,13 +685,18 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the object to load.
|
||||
* @param boolean $requireSSL
|
||||
* If this is TRUE (the default), then SSL will always be
|
||||
* used. If this is FALSE, then CDN-based fetching will
|
||||
* use non-SSL, which is faster.
|
||||
* @retval \HPCloud\Storage\ObjectStorage\RemoteObject
|
||||
* A remote object with the content already stored locally.
|
||||
*/
|
||||
public function object($name) {
|
||||
public function object($name, $requireSSL = TRUE) {
|
||||
|
||||
$url = self::objectUrl($this->url, $name);
|
||||
$cdn = self::objectUrl($this->cdnUrl, $name);
|
||||
$cdnSsl = self::objectUrl($this->cdnSslUrl, $name);
|
||||
$headers = array();
|
||||
|
||||
// Auth token.
|
||||
@@ -699,7 +708,9 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
$response = $client->doRequest($url, 'GET', $headers);
|
||||
}
|
||||
else {
|
||||
$response = $client->doRequest($cdn, 'GET', $headers);
|
||||
$from = $requireSSL ? $cdnSsl : $cdn;
|
||||
// print "Fetching object from $from\n";
|
||||
$response = $client->doRequest($from, 'GET', $headers);
|
||||
}
|
||||
|
||||
if ($response->status() != 200) {
|
||||
@@ -710,7 +721,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
$remoteObject->setContent($response->content());
|
||||
|
||||
if (!empty($this->cdnUrl)) {
|
||||
$remoteObject->useCDN($cdn);
|
||||
$remoteObject->useCDN($cdn, $cdnSsl);
|
||||
}
|
||||
|
||||
return $remoteObject;
|
||||
@@ -748,6 +759,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
public function proxyObject($name) {
|
||||
$url = self::objectUrl($this->url, $name);
|
||||
$cdn = self::objectUrl($this->cdnUrl, $name);
|
||||
$cdnSsl = self::objectUrl($this->cdnSslUrl, $name);
|
||||
$headers = array(
|
||||
'X-Auth-Token' => $this->token,
|
||||
);
|
||||
@@ -759,7 +771,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
$response = $client->doRequest($url, 'HEAD', $headers);
|
||||
}
|
||||
else {
|
||||
$response = $client->doRequest($cdn, 'HEAD', $headers);
|
||||
$response = $client->doRequest($cdnSsl, 'HEAD', $headers);
|
||||
}
|
||||
|
||||
if ($response->status() != 200) {
|
||||
@@ -771,7 +783,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
$obj = RemoteObject::newFromHeaders($name, $headers, $this->token, $url);
|
||||
|
||||
if (!empty($this->cdnUrl)) {
|
||||
$obj->useCDN($cdn);
|
||||
$obj->useCDN($cdn, $cdnSsl);
|
||||
}
|
||||
|
||||
return $obj;
|
||||
@@ -944,8 +956,8 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function cdnUrl() {
|
||||
return $this->cdnUrl;
|
||||
public function cdnUrl($ssl = TRUE) {
|
||||
return $ssl ? $this->cdnSslUrl : $this->cdnUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,6 +68,7 @@ class RemoteObject extends Object {
|
||||
protected $allHeaders;
|
||||
|
||||
protected $cdnUrl;
|
||||
protected $cdnSslUrl;
|
||||
|
||||
/**
|
||||
* Create a new RemoteObject from JSON data.
|
||||
@@ -118,8 +119,10 @@ class RemoteObject extends Object {
|
||||
* subsequent requests. If this is set, this object may use
|
||||
* CDN to make subsequent requests. It may also return the
|
||||
* CDN URL when requested.
|
||||
* @param string $cdnSslUrl
|
||||
* The URL to the SSL-protected CDN version of the object.
|
||||
*/
|
||||
public static function newFromHeaders($name, $headers, $token, $url, $cdnUrl = NULL) {
|
||||
public static function newFromHeaders($name, $headers, $token, $url, $cdnUrl = NULL, $cdnSslUrl = NULL) {
|
||||
$object = new RemoteObject($name);
|
||||
|
||||
$object->allHeaders = $headers;
|
||||
@@ -153,6 +156,7 @@ class RemoteObject extends Object {
|
||||
$object->token = $token;
|
||||
$object->url = $url;
|
||||
$object->cdnUrl = $cdnUrl;
|
||||
$object->cdnSslUrl = $cdnSslUrl;
|
||||
|
||||
return $object;
|
||||
}
|
||||
@@ -176,9 +180,12 @@ class RemoteObject extends Object {
|
||||
*
|
||||
* @param string $url
|
||||
* The URL to this object in CDN.
|
||||
* @param string $sslUrl
|
||||
* The SSL URL to this object in CDN.
|
||||
*/
|
||||
public function useCDN($url) {
|
||||
public function useCDN($url, $sslUrl) {
|
||||
$this->cdnUrl = $url;
|
||||
$this->cdnSslUrl = $sslUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,6 +203,11 @@ class RemoteObject extends Object {
|
||||
* object. See ObjectStorage::useCDN(), Container::useCDN() and
|
||||
* RemoteObject::useCDN(). (Generally, using ObjectStorage::useCDN()
|
||||
* is all you need to do.)
|
||||
* @param boolean $useSSL
|
||||
* FOR CACHED URLS ONLY, there is an option for either SSL or non-SSL
|
||||
* URLs. By default, we use SSL URLs because (a) it's safer, and
|
||||
* (b) it mirrors non-CDN behavior. This can be turned off by setting
|
||||
* $useSSL to FALSE.
|
||||
* @retval string
|
||||
* A URL to the object. The following considerations apply:
|
||||
* - If the container is public, this URL can be loaded without
|
||||
@@ -207,10 +219,10 @@ class RemoteObject extends Object {
|
||||
* - If this object has never been saved remotely, then there will be
|
||||
* no URL, and this will return NULL.
|
||||
*/
|
||||
public function url($cached = FALSE) {
|
||||
public function url($cached = FALSE, $useSSL = TRUE) {
|
||||
|
||||
if ($cached && !empty($this->cdnUrl)) {
|
||||
return $this->cdnUrl;
|
||||
return $useSSL ? $this->cdnSslUrl : $this->cdnUrl;
|
||||
}
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
@@ -248,6 +248,9 @@ use \HPCloud\Storage\ObjectStorage;
|
||||
* - The container must have CDN enabled
|
||||
* - The CDN container must be active ("cdn-enabled")
|
||||
* - Authentication info must be accessible to the stream wrapper.
|
||||
* - cdn_require_ssl: If this is set to FALSE, then CDN-based requests
|
||||
* may use plain HTTP instead of HTTPS. This will spead up CDN
|
||||
* fetches at the cost of security.
|
||||
*
|
||||
* @attention
|
||||
* ADVANCED: You can also pass an HPCloud::Storage::CDN object in use_cdn instead of
|
||||
@@ -827,14 +830,16 @@ class StreamWrapper {
|
||||
// EXPERIMENTAL:
|
||||
// If we can get the resource from CDN, we do so now. Note that we try to sidestep
|
||||
// the Container creation, which saves us an HTTP request.
|
||||
$cdnUrl = $this->store->cdnUrl($containerName);
|
||||
$cdnUrl = $this->store->cdnUrl($containerName, FALSE);
|
||||
$cdnSslUrl = $this->store->cdnUrl($containerName, TRUE);
|
||||
if (!empty($cdnUrl) && !$this->isWriting && !$this->isAppending) {
|
||||
$requireSSL = (boolean) $this->cxt('cdn_require_ssl', TRUE);
|
||||
try {
|
||||
$newUrl = $this->store->url() . '/' . $containerName;
|
||||
$token = $this->store->token();
|
||||
$this->container = new \HPCloud\Storage\ObjectStorage\Container($containerName, $newUrl, $token);
|
||||
$this->container->useCDN($cdnUrl);
|
||||
$this->obj = $this->container->object($objectName);
|
||||
$this->container->useCDN($cdnUrl, $cdnSslUrl);
|
||||
$this->obj = $this->container->object($objectName, $requireSSL);
|
||||
$this->objStream = $this->obj->stream();
|
||||
|
||||
return TRUE;
|
||||
@@ -1569,6 +1574,9 @@ class StreamWrapper {
|
||||
* When use_cdn is set to TRUE, the wrapper tries to use CDN service.
|
||||
* In such cases, we need a handle to the CDN object. This initializes
|
||||
* that handle, which can later be used to get other information.
|
||||
*
|
||||
* Also note that CDN's default behavior is to fetch over SSL CDN.
|
||||
* To disable this, set 'cdn_require_ssl' to FALSE.
|
||||
*/
|
||||
protected function initializeCDN($token, $catalog) {
|
||||
$cdn = $this->cxt('use_cdn', FALSE);
|
||||
|
||||
@@ -95,7 +95,7 @@ else {
|
||||
}
|
||||
|
||||
if (empty($token)) {
|
||||
print "Authentication seemed to succeed, but no token was return." . PHP_EOL;
|
||||
print "Authentication seemed to succeed, but no token was returned." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,20 +66,39 @@ print "***** TESTING CDN ENABLED" . PHP_EOL;
|
||||
if ($cdnData['cdn_enabled'] != 1) {
|
||||
die('Cannot test CDN: You must enable CDN on ' . $cname);
|
||||
}
|
||||
|
||||
$container = $objstore->container($cname);
|
||||
|
||||
print "***** TESTING CDN URL" . PHP_EOL;
|
||||
$cdnSsl = $objstore->cdnUrl($cname);
|
||||
$cdnPlain = $objstore->cdnUrl($cname, FALSE);
|
||||
if ($cdnSsl == $cdnPlain) {
|
||||
die(sprintf("Surprise! %s matches %s\n", $cdnSsl, $cdnPlain));
|
||||
}
|
||||
print 'SSL CDN: ' . $cdnSsl. PHP_EOL;
|
||||
print 'Plain CDN: ' . $cdnPlain . PHP_EOL;
|
||||
print 'Container CDN URL: ' . $container->cdnUrl() . PHP_EOL;
|
||||
if ($container->cdnUrl() == NULL) {
|
||||
die('No CDN URL for Container ' . $cname);
|
||||
}
|
||||
|
||||
if ($cdnSsl != $container->cdnUrl()) {
|
||||
die(sprintf("Expected SSL CDN %s to match Container CDN %s\n", $cdnSsl, $container->cdnUrl()));
|
||||
}
|
||||
|
||||
$o = new \HPCloud\Storage\ObjectStorage\Object('CDNTest.txt', 'TEST');
|
||||
|
||||
$container->save($o);
|
||||
|
||||
$copy = $container->object($o->name());
|
||||
|
||||
print "***** TESTING OBJECT CDN URLS." . PHP_EOL;
|
||||
print "Object SSL URL: " . $copy->url() . PHP_EOL;
|
||||
print "Object CDN SSL URL: " . $copy->url(TRUE) . PHP_EOL;
|
||||
print "Object CDN URL: " . $copy->url(TRUE, FALSE) . PHP_EOL;
|
||||
if ($copy->url(TRUE) == $copy->url(TRUE, FALSE)) {
|
||||
die(sprintf("Object SSL URL %s should not match non-SSL URL %s\n", $copy->url(TRUE), $copy->url(TRUE, FALSE)));
|
||||
}
|
||||
|
||||
print "***** TESTING THAT CDN WAS USED." . PHP_EOL;
|
||||
if ($copy->url() == $copy->url(TRUE)) {
|
||||
die('Object Storage not used for ' . $o->name());
|
||||
@@ -96,8 +115,31 @@ $cxt = stream_context_create(array(
|
||||
'use_cdn' => TRUE,
|
||||
),
|
||||
));
|
||||
$cxt2 = stream_context_create(array(
|
||||
'swift' => array(
|
||||
//'token' => $token,
|
||||
'tenantid' => $ini['hpcloud.identity.tenantId'],
|
||||
'account' => $ini['hpcloud.identity.account'],
|
||||
'key' => $ini['hpcloud.identity.secret'],
|
||||
'endpoint' => $ini['hpcloud.identity.url'],
|
||||
'use_cdn' => TRUE,
|
||||
'cdn_require_ssl' => FALSE,
|
||||
),
|
||||
));
|
||||
|
||||
print "***** TESTING RETURNED DATA" . PHP_EOL;
|
||||
print file_get_contents('swift://' . TEST_CONTAINER . '/CDNTest.txt', FALSE, $cxt);
|
||||
$res = array(
|
||||
'internal' => file_get_contents('swift://' . TEST_CONTAINER . '/CDNTest.txt', FALSE, $cxt),
|
||||
'internalNoSSL' => file_get_contents('swift://' . TEST_CONTAINER . '/CDNTest.txt', FALSE, $cxt2),
|
||||
'external' => file_get_contents($copy->url()),
|
||||
'externalSslCdn' => file_get_contents($copy->url(TRUE)),
|
||||
'externalCdn' => file_get_contents($copy->url(TRUE, FALSE)),
|
||||
);
|
||||
|
||||
foreach ($res as $name => $val) {
|
||||
if ($val != 'TEST') {
|
||||
die(sprintf("Facility %s failed, returning '%s' instead of TEST.", $name, $val));
|
||||
}
|
||||
}
|
||||
|
||||
print PHP_EOL . "***** All tests passed." . PHP_EOL;
|
||||
|
||||
@@ -28,7 +28,7 @@ hpcloud.identity.password =
|
||||
|
||||
; For authentication by account ID.
|
||||
hpcloud.identity.account =
|
||||
hpcloud.identity.key =
|
||||
hpcloud.identity.secret =
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Configuration Parameters ;
|
||||
|
||||
Reference in New Issue
Block a user