Merge branch 'develop'

This commit is contained in:
Matt Butcher
2012-05-04 18:00:10 -05:00
8 changed files with 109 additions and 24 deletions

View File

@@ -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
* ),
* );

View File

@@ -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;

View File

@@ -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;
}
/**

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -28,7 +28,7 @@ hpcloud.identity.password =
; For authentication by account ID.
hpcloud.identity.account =
hpcloud.identity.key =
hpcloud.identity.secret =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Configuration Parameters ;