* This is the PHP Cloud Files API.
* # Authenticate to Cloud Files. The default is to automatically try
* # to re-authenticate if an authentication token expires.
* # NOTE: Some versions of cURL include an outdated certificate authority (CA)
* # file. This API ships with a newer version obtained directly from
* # cURL's web site (http://curl.haxx.se). To use the newer CA bundle,
* # call the CF_Authentication instance's 'ssl_use_cabundle()' method.
* $auth = new CF_Authentication($username, $api_key);
* # $auth->ssl_use_cabundle(); # bypass cURL's old CA bundle
* # Establish a connection to the storage system
* # NOTE: Some versions of cURL include an outdated certificate authority (CA)
* # file. This API ships with a newer version obtained directly from
* # cURL's web site (http://curl.haxx.se). To use the newer CA bundle,
* # call the CF_Connection instance's 'ssl_use_cabundle()' method.
* $conn = new CF_Connection($auth);
* # $conn->ssl_use_cabundle(); # bypass cURL's old CA bundle
* # Create a remote Container and storage Object
* $images = $conn->create_container("photos");
* $bday = $images->create_object("first_birthday.jpg");
* # Upload content from a local file by streaming it. Note that we use
* # a "float" for the file size to overcome PHP's 32-bit integer limit for
* $fname = "/home/user/photos/birthdays/birthday1.jpg"; # filename to upload
* $size = (float) sprintf("%u", filesize($fname));
* $fp = open($fname, "r");
* $bday->write($fp, $size);
* # Or... use a convenience function instead
* $bday->load_from_filename("/home/user/photos/birthdays/birthday1.jpg");
* # Now, publish the "photos" container to serve the images by CDN.
* # Use the "$uri" value to put in your web pages or send the link in an
* $uri = $images->make_public();
* # Or... print out the Object's public URI
* print $bday->public_uri();
* See the included tests directory for additional sample code.
* Requres PHP 5.x (for Exceptions and OO syntax) and PHP's cURL module.
* It uses the supporting "cloudfiles_http.php" module for HTTP(s) support and
* allows for connection re-use and streaming of content into/out of Cloud Files
* See COPYING for license information.
* @author Eric "EJ" Johnson <ej@racklabs.com>
* @copyright Copyright (c) 2008, Rackspace US, Inc.
* @package php-cloudfiles
require_once(UPDRAFTPLUS_DIR."/includes/cloudfiles/cloudfiles_exceptions.php");
require_once(UPDRAFTPLUS_DIR."/includes/cloudfiles/cloudfiles_http.php");
@define("DEFAULT_CF_API_VERSION", 1);
@define("MAX_CONTAINER_NAME_LEN", 256);
@define("MAX_OBJECT_NAME_LEN", 1024);
@define("MAX_OBJECT_SIZE", 5*1024*1024*1024+1);
@define("US_AUTHURL", "https://auth.api.rackspacecloud.com");
@define("UK_AUTHURL", "https://lon.auth.api.rackspacecloud.com");
* Class for handling Cloud Files Authentication, call it's {@link authenticate()}
* method to obtain authorized service urls and an authentication token.
* # Create the authentication instance
* $auth = new CF_Authentication("username", "api_key");
* # NOTE: For UK Customers please specify your AuthURL Manually
* # There is a Predfined constant to use EX:
* # $auth = new CF_Authentication("username, "api_key", NULL, UK_AUTHURL);
* # Using the UK_AUTHURL keyword will force the api to use the UK AuthUrl.
* # rather then the US one. The NULL Is passed for legacy purposes and must
* # be passed to function correctly.
* # NOTE: Some versions of cURL include an outdated certificate authority (CA)
* # file. This API ships with a newer version obtained directly from
* # cURL's web site (http://curl.haxx.se). To use the newer CA bundle,
* # call the CF_Authentication instance's 'ssl_use_cabundle()' method.
* # $auth->ssl_use_cabundle(); # bypass cURL's old CA bundle
* # Perform authentication request
* @package php-cloudfiles
class UpdraftPlus_CF_Authentication
* Instance variables that are set after successful authentication
* Class constructor (PHP 5 syntax)
* @param string $username Mosso username
* @param string $api_key Mosso API Access Key
* @param string $account <i>Account name</i>
* @param string $auth_host <i>Authentication service URI</i>
function __construct($username=NULL, $api_key=NULL, $account=NULL, $auth_host=US_AUTHURL)
$this->username = $username;
$this->api_key = $api_key;
$this->account_name = $account;
$this->auth_host = $auth_host;
$this->storage_url = NULL;
$this->auth_token = NULL;
$this->cfs_http = new UpdraftPlus_CF_Http(DEFAULT_CF_API_VERSION);
* Use the Certificate Authority bundle included with this API
* Most versions of PHP with cURL support include an outdated Certificate
* Authority (CA) bundle (the file that lists all valid certificate
* signing authorities). The SSL certificates used by the Cloud Files
* storage system are perfectly valid but have been created/signed by
* a CA not listed in these outdated cURL distributions.
* As a work-around, we've included an updated CA bundle obtained
* directly from cURL's web site (http://curl.haxx.se). You can direct
* the API to use this CA bundle by calling this method prior to making
* any remote calls. The best place to use this method is right after
* the CF_Authentication instance has been instantiated.
* You can specify your own CA bundle by passing in the full pathname
* to the bundle. You can use the included CA bundle by leaving the
* @param string $path Specify path to CA bundle (default to included)
function ssl_use_cabundle($path=NULL)
$this->cfs_http->ssl_use_cabundle($path);
* Attempt to validate Username/API Access Key
* Attempts to validate credentials with the authentication service. It
* either returns <kbd>True</kbd> or throws an Exception. Accepts a single
* (optional) argument for the storage system API version.
* # Create the authentication instance
* $auth = new CF_Authentication("username", "api_key");
* # Perform authentication request
* @param string $version API version for Auth service (optional)
* @return boolean <kbd>True</kbd> if successfully authenticated
* @throws AuthenticationException invalid credentials
* @throws InvalidResponseException invalid response
function authenticate($version=DEFAULT_CF_API_VERSION)
list($status,$reason,$surl,$curl,$atoken) =
$this->cfs_http->authenticate($this->username, $this->api_key,
$this->account_name, $this->auth_host);
throw new AuthenticationException("Invalid username or access key.");
if ($status < 200 || $status > 299) {
throw new InvalidResponseException(
"Unexpected response (".$status."): ".$reason);
if (!($surl || $curl) || !$atoken) {
throw new InvalidResponseException(
"Expected headers missing from auth service.");
$this->storage_url = $surl;
$this->auth_token = $atoken;
* Use Cached Token and Storage URL's rather then grabbing from the Auth System
* #Create an Auth instance
* $auth = new CF_Authentication();
* #Pass Cached URL's and Token as Args
* $auth->load_cached_credentials("auth_token", "storage_url", "cdn_management_url");
* @param string $auth_token A Cloud Files Auth Token (Required)
* @param string $storage_url The Cloud Files Storage URL (Required)
* @param string $cdnm_url CDN Management URL (Required)
* @return boolean <kbd>True</kbd> if successful
* @throws SyntaxException If any of the Required Arguments are missing
function load_cached_credentials($auth_token, $storage_url, $cdnm_url)
if(!$storage_url || !$cdnm_url)
throw new SyntaxException("Missing Required Interface URL's!");
throw new SyntaxException("Missing Auth Token!");
$this->storage_url = $storage_url;
$this->cdnm_url = $cdnm_url;
$this->auth_token = $auth_token;
* Grab Cloud Files info to be Cached for later use with the load_cached_credentials method.
* #Create an Auth instance
* $auth = new CF_Authentication("UserName","API_Key");
* $array = $auth->export_credentials();
* @return array of url's and an auth token.
function export_credentials()
$arr['storage_url'] = $this->storage_url;
$arr['cdnm_url'] = $this->cdnm_url;
$arr['auth_token'] = $this->auth_token;
* Make sure the CF_Authentication instance has authenticated.
* Ensures that the instance variables necessary to communicate with
* Cloud Files have been set from a previous authenticate() call.
* @return boolean <kbd>True</kbd> if successfully authenticated
if (!($this->storage_url || $this->cdnm_url) || !$this->auth_token) {
* Toggle debugging - set cURL verbose flag
$this->cfs_http->setDebug($bool);
* Class for establishing connections to the Cloud Files storage system.
* Connection instances are used to communicate with the storage system at
* the account level; listing and deleting Containers and returning Container
* # Create the authentication instance
* $auth = new CF_Authentication("username", "api_key");
* # Perform authentication request
* # Create a connection to the storage/cdn system(s) and pass in the
* # validated CF_Authentication instance.
* $conn = new CF_Connection($auth);
* # NOTE: Some versions of cURL include an outdated certificate authority (CA)
* # file. This API ships with a newer version obtained directly from
* # cURL's web site (http://curl.haxx.se). To use the newer CA bundle,
* # call the CF_Authentication instance's 'ssl_use_cabundle()' method.
* # $conn->ssl_use_cabundle(); # bypass cURL's old CA bundle
* @package php-cloudfiles
class UpdraftPlus_CF_Connection
* Pass in a previously authenticated CF_Authentication instance.
* # Create the authentication instance
* $auth = new CF_Authentication("username", "api_key");
* # Perform authentication request
* # Create a connection to the storage/cdn system(s) and pass in the
* # validated CF_Authentication instance.
* $conn = new CF_Connection($auth);
* # If you are connecting via Rackspace servers and have access
* # to the servicenet network you can set the $servicenet to True
* $conn = new CF_Connection($auth, $servicenet=True);
* If the environement variable RACKSPACE_SERVICENET is defined it will
* force to connect via the servicenet.
* @param obj $cfs_auth previously authenticated CF_Authentication instance
* @param boolean $servicenet enable/disable access via Rackspace servicenet.
* @throws AuthenticationException not authenticated
function __construct($cfs_auth, $servicenet=False)
if (isset($_ENV['RACKSPACE_SERVICENET']))
$this->cfs_http = new UpdraftPlus_CF_Http(DEFAULT_CF_API_VERSION);
$this->cfs_auth = $cfs_auth;
if (!$this->cfs_auth->authenticated()) {
$e = "Need to pass in a previously authenticated ";
$e .= "CF_Authentication instance.";
throw new AuthenticationException($e);
$this->cfs_http->setCFAuth($this->cfs_auth, $servicenet=$servicenet);
* Toggle debugging of instance and back-end HTTP module
* @param boolean $bool enable/disable cURL debugging
$this->dbug = (boolean) $bool;
$this->cfs_http->setDebug($this->dbug);
* Will close all current cUrl active connections.
$this->cfs_http->close();
* Cloud Files account information
* Return an array of two floats (since PHP only supports 32-bit integers);
* number of containers on the account and total bytes used for the account.
* # ... authentication code excluded (see previous examples) ...
* $conn = new CF_Connection($auth);
* list($quantity, $bytes) = $conn->get_info();
* print "Number of containers: " . $quantity . "\n";
* print "Bytes stored in container: " . $bytes . "\n";
* @return array (number of containers, total bytes stored)
* @throws InvalidResponseException unexpected response
list($status, $reason, $container_count, $total_bytes) =
$this->cfs_http->head_account();
#if ($status == 401 && $this->_re_auth()) {
# return $this->get_info();
if ($status < 200 || $status > 299) {
throw new InvalidResponseException(
"Invalid response (".$status."): ".$this->cfs_http->get_error());
return array($container_count, $total_bytes);
* Given a Container name, return a Container instance, creating a new
* remote Container if it does not exit.
* # ... authentication code excluded (see previous examples) ...
* $conn = new CF_Connection($auth);
* $images = $conn->create_container("my photos");
* @param string $container_name container name
* @throws SyntaxException invalid name
* @throws InvalidResponseException unexpected response
function create_container($container_name=NULL)
if ($container_name != "0" and !isset($container_name))
throw new SyntaxException("Container name not set.");
if (!isset($container_name) or $container_name == "")
throw new SyntaxException("Container name not set.");
if (strpos($container_name, "/") !== False) {
$r = "Container name '".$container_name;
$r .= "' cannot contain a '/' character.";
throw new SyntaxException($r);
if (strlen($container_name) > MAX_CONTAINER_NAME_LEN) {
throw new SyntaxException(sprintf(
"Container name exeeds %d bytes.",
MAX_CONTAINER_NAME_LEN));
$return_code = $this->cfs_http->create_container($container_name);
throw new InvalidResponseException("Invalid response ("
. $return_code. "): " . $this->cfs_http->get_error());