Source for file Storage.php
Documentation is available at Storage.php
* Copyright (c) 2009 - 2011, RealDolmen
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of RealDolmen nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @package Microsoft_WindowsAzure
* @copyright Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
* @license http://phpazure.codeplex.com/license
* @version $Id: Storage.php 61044 2011-04-19 10:21:34Z unknown $
* @see Microsoft_AutoLoader
require_once dirname(__FILE__ ) . '/../AutoLoader.php';
* @package Microsoft_WindowsAzure
* @copyright Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
* @license http://phpazure.codeplex.com/license
* Development storage URLS
const URL_DEV_BLOB = "127.0.0.1:10000";
const URL_DEV_QUEUE = "127.0.0.1:10001";
const URL_DEV_TABLE = "127.0.0.1:10002";
const URL_CLOUD_BLOB = "blob.core.windows.net";
const URL_CLOUD_QUEUE = "queue.core.windows.net";
const URL_CLOUD_TABLE = "table.core.windows.net";
const RESOURCE_UNKNOWN = "unknown";
const RESOURCE_CONTAINER = "c";
const RESOURCE_BLOB = "b";
const RESOURCE_TABLE = "t";
const RESOURCE_ENTITY = "e";
const RESOURCE_QUEUE = "q";
const PREFIX_PROPERTIES = "x-ms-prop-";
const PREFIX_METADATA = "x-ms-meta-";
const PREFIX_STORAGE_HEADER = "x-ms-";
* Account name for Windows Azure
* Account key for Windows Azure
* Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
* @var Microsoft_WindowsAzure_Credentials_CredentialsAbstract
* Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract instance
* @var Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
* Microsoft_Http_Client channel used for communication with REST services
* @var Microsoft_Http_Client
* Creates a new Microsoft_WindowsAzure_Storage instance
* @param string $host Storage host name
* @param string $accountName Account name for Windows Azure
* @param string $accountKey Account key for Windows Azure
* @param boolean $usePathStyleUri Use path-style URI's
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
$host = self::URL_DEV_BLOB,
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
$usePathStyleUri = false,
Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null
&& ($this->_host == self::URL_DEV_BLOB
|| $this->_host == self::URL_DEV_QUEUE
|| $this->_host == self::URL_DEV_TABLE)
// Setup default Microsoft_Http_Client channel
'adapter' => 'Microsoft_Http_Client_Adapter_Proxy'
// Set cURL options if cURL is used afterwards
$options['curloptions'] = array(
CURLOPT_FOLLOWLOCATION => true,
* Set the HTTP client channel to use
* @param Microsoft_Http_Client_Adapter_Interface|string$adapterInstance Adapter instance or adapter class name.
* Retrieve HTTP client channel
* @return Microsoft_Http_Client_Adapter_Interface
* Set retry policy to use when making requests
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
public function setRetryPolicy(Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
* @param boolean $useProxy Use proxy?
* @param string $proxyUrl Proxy URL
* @param int $proxyPort Proxy port
* @param string $proxyCredentials Proxy credentials
public function setProxy($useProxy = false, $proxyUrl = '', $proxyPort = 80, $proxyCredentials = '')
'proxy_user' => $credentials[0],
'proxy_pass' => $credentials[1],
* Returns the Windows Azure account name
* Get base URL for creating requests
* Set Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
* @param Microsoft_WindowsAzure_Credentials_CredentialsAbstract $credentials Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance to use for request signing.
public function setCredentials(Microsoft_WindowsAzure_Credentials_CredentialsAbstract $credentials)
* Get Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
* @return Microsoft_WindowsAzure_Credentials_CredentialsAbstract
* Perform request using Microsoft_Http_Client channel
* @param string $path Path
* @param string $queryString Query string
* @param string $httpVerb HTTP verb the request will use
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param mixed $rawData Optional RAW HTTP data to be sent over the wire
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return Microsoft_Http_Response
$httpVerb = Microsoft_Http_Client::GET,
$forTableStorage = false,
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
if (strpos($path, '/') !== 0) {
// Ensure cUrl will also work correctly:
// - disable Content-Type if required
// - disable Expect: 100 Continue
if (!isset ($headers["Content-Type"])) {
$headers["Content-Type"] = '';
$path = self::urlencode($path);
$queryString = self::urlencode($queryString);
// Generate URL and sign request
->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission, $rawData);
* Parse result from Microsoft_Http_Response
* @param Microsoft_Http_Response $response Response from HTTP call
* @throws Microsoft_WindowsAzure_Exception
protected function _parseResponse(Microsoft_Http_Response $response = null)
$namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true));
// Register all namespace prefixes
foreach ($namespaces as $prefix => $ns) {
$xml->registerXPathNamespace($prefix, $ns);
* Generate metadata headers
* @return HTTP headers containing metadata
foreach ($metadata as $key => $value) {
if (strpos($value, "\r") !== false || strpos($value, "\n") !== false) {
if (!self::isValidMetadataName($key)) {
throw new Microsoft_WindowsAzure_Exception('Metadata name does not adhere to metadata naming conventions. See http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx for more information.');
$headers["x-ms-meta-" . strtolower($key)] = $value;
* @param array $headers HTTP headers containing metadata
foreach ($headers as $key => $value) {
* @param SimpleXMLElement $parentElement Element containing the Metadata element.
if (!is_null($element) && isset ($element->Metadata) && !is_null($element->Metadata)) {
* Generate ISO 8601 compliant date string in UTC time zone
public function isoDate($timestamp = null)
* @param string $value Value to encode
* @return string Encoded value
* Is valid metadata name?
* @param string $metadataName Metadata name
if (preg_match("/^[a-zA-Z0-9_@][a-zA-Z0-9_]*$/", $metadataName) === 0) {
if ($metadataName == '') {
* Builds a query string from an array of elements
* @param array Array of elements
* @return string Assembled query string
return count($queryString) > 0 ? '?' . implode('&', $queryString) : '';
|