Вход Регистрация
Файл: library/Zend/Service/WindowsAzure/Storage/Blob.php
Строк: 4189
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Service_WindowsAzure
 * @subpackage Storage
 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://todo     name_todo
 * @version    $Id: Blob.php 23167 2010-10-19 17:53:31Z mabe $
 */

/**
 * @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract_SharedKey
 */
require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php';

/**
 * @see Zend_Service_WindowsAzure_Credentials_SharedAccessSignature
 */
require_once 'Zend/Service/WindowsAzure/Credentials/SharedAccessSignature.php';

/**
 * @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
 */
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';

/**
 * @see Zend_Http_Client
 */
require_once 'Zend/Http/Client.php';

/**
 * @see Zend_Http_Response
 */
require_once 'Zend/Http/Response.php';

/**
 * @see Zend_Service_WindowsAzure_Storage
 */
require_once 'Zend/Service/WindowsAzure/Storage.php';

/**
 * @see Zend_Service_WindowsAzure_Storage_BlobContainer
 */
require_once 'Zend/Service/WindowsAzure/Storage/BlobContainer.php';

/**
 * @see Zend_Service_WindowsAzure_Storage_BlobInstance
 */
require_once 'Zend/Service/WindowsAzure/Storage/BlobInstance.php';

/**
 * @see Zend_Service_WindowsAzure_Storage_PageRegionInstance
 */
require_once 'Zend/Service/WindowsAzure/Storage/PageRegionInstance.php';

/**
 * @see Zend_Service_WindowsAzure_Storage_LeaseInstance
 */
require_once 'Zend/Service/WindowsAzure/Storage/LeaseInstance.php';

/**
 * @see Zend_Service_WindowsAzure_Storage_SignedIdentifier
 */
require_once 'Zend/Service/WindowsAzure/Storage/SignedIdentifier.php';

/**
 * @see Zend_Service_WindowsAzure_Exception
 */
require_once 'Zend/Service/WindowsAzure/Exception.php';


/**
 * @category   Zend
 * @package    Zend_Service_WindowsAzure
 * @subpackage Storage
 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Service_WindowsAzure_Storage_Blob extends Zend_Service_WindowsAzure_Storage
{
    
/**
     * ACL - Private access
     */
    
const ACL_PRIVATE null;

    
/**
     * ACL - Public access (read all blobs)
     *
     * @deprecated Use ACL_PUBLIC_CONTAINER or ACL_PUBLIC_BLOB instead.
     */
    
const ACL_PUBLIC 'container';
    
    
/**
     * ACL - Blob Public access (read all blobs)
     */
    
const ACL_PUBLIC_BLOB 'blob';

    
/**
     * ACL - Container Public access (enumerate and read all blobs)
     */
    
const ACL_PUBLIC_CONTAINER 'container';

    
/**
     * Blob lease constants
     */
    
const LEASE_ACQUIRE 'acquire';
    const 
LEASE_RENEW   'renew';
    const 
LEASE_RELEASE 'release';
    const 
LEASE_BREAK   'break';

    
/**
     * Maximal blob size (in bytes)
     */
    
const MAX_BLOB_SIZE 67108864;

    
/**
     * Maximal blob transfer size (in bytes)
     */
    
const MAX_BLOB_TRANSFER_SIZE 4194304;

    
/**
     * Blob types
     */
    
const BLOBTYPE_BLOCK 'BlockBlob';
    const 
BLOBTYPE_PAGE  'PageBlob';

    
/**
     * Put page write options
     */
    
const PAGE_WRITE_UPDATE 'update';
    const 
PAGE_WRITE_CLEAR  'clear';

    
/**
     * Stream wrapper clients
     *
     * @var array
     */
    
protected static $_wrapperClients = array();

    
/**
     * SharedAccessSignature credentials
     *
     * @var Zend_Service_WindowsAzure_Credentials_SharedAccessSignature
     */
    
private $_sharedAccessSignatureCredentials null;

    
/**
     * Creates a new Zend_Service_WindowsAzure_Storage_Blob 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 Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
     */
    
public function __construct($host Zend_Service_WindowsAzure_Storage::URL_DEV_BLOB$accountName Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT$accountKey Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY$usePathStyleUri falseZend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy null)
    {
        
parent::__construct($host$accountName$accountKey$usePathStyleUri$retryPolicy);

        
// API version
        
$this->_apiVersion '2009-09-19';

        
// SharedAccessSignature credentials
        
$this->_sharedAccessSignatureCredentials = new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature($accountName$accountKey$usePathStyleUri);
    }

    
/**
     * Check if a blob exists
     *
     * @param string $containerName Container name
     * @param string $blobName      Blob name
     * @param string $snapshotId    Snapshot identifier
     * @return boolean
     */
    
public function blobExists($containerName ''$blobName ''$snapshotId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }

        
// Get blob instance
        
try {
            
$this->getBlobInstance($containerName$blobName$snapshotId);
        } catch (
Zend_Service_WindowsAzure_Exception $e) {
            return 
false;
        }

        return 
true;
    }

    
/**
     * Check if a container exists
     *
     * @param string $containerName Container name
     * @return boolean
     */
    
public function containerExists($containerName '')
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
            
        
// List containers
        
$containers $this->listContainers($containerName1);
        foreach (
$containers as $container) {
            if (
$container->Name == $containerName) {
                return 
true;
            }
        }

        return 
false;
    }

    
/**
     * Create container
     *
     * @param string $containerName Container name
     * @param array  $metadata      Key/value pairs of meta data
     * @return object Container properties
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function createContainer($containerName ''$metadata = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (!
is_array($metadata)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
        }
            
        
// Create metadata headers
        
$headers = array();
        
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

        
// Perform request
        
$response $this->_performRequest($containerName'?restype=container'Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            return new 
Zend_Service_WindowsAzure_Storage_BlobContainer(
            
$containerName,
            
$response->getHeader('Etag'),
            
$response->getHeader('Last-modified'),
            
$metadata
            
);
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get container ACL
     *
     * @param string $containerName Container name
     * @param bool   $signedIdentifiers Display only private/blob/container or display signed identifiers?
     * @return string Acl, to be compared with Zend_Service_WindowsAzure_Storage_Blob::ACL_*
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getContainerAcl($containerName ''$signedIdentifiers false)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }

        
// Perform request
        
$response $this->_performRequest($containerName'?restype=container&comp=acl'Zend_Http_Client::GET, array(), falsenullZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
        if (
$response->isSuccessful()) {
            if (
$signedIdentifiers == false)  {
                
// Only private/blob/container
                
$accessType $response->getHeader(Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER 'blob-public-access');
                if (
strtolower($accessType) == 'true') {
                    
$accessType self::ACL_PUBLIC_CONTAINER;
                }
                return 
$accessType;
            } else {
                
// Parse result
                
$result $this->_parseResponse($response);
                if (!
$result) {
                    return array();
                }

                
$entries null;
                if (
$result->SignedIdentifier) {
                    if (
count($result->SignedIdentifier) > 1) {
                        
$entries $result->SignedIdentifier;
                    } else {
                        
$entries = array($result->SignedIdentifier);
                    }
                }

                
// Return value
                
$returnValue = array();
                foreach (
$entries as $entry) {
                    
$returnValue[] = new Zend_Service_WindowsAzure_Storage_SignedIdentifier(
                    
$entry->Id,
                    
$entry->AccessPolicy $entry->AccessPolicy->Start $entry->AccessPolicy->Start '' '',
                    
$entry->AccessPolicy $entry->AccessPolicy->Expiry $entry->AccessPolicy->Expiry '' '',
                    
$entry->AccessPolicy $entry->AccessPolicy->Permission $entry->AccessPolicy->Permission '' ''
                    
);
                }

                
// Return
                
return $returnValue;
            }
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Set container ACL
     *
     * @param string $containerName Container name
     * @param bool $acl Zend_Service_WindowsAzure_Storage_Blob::ACL_*
     * @param array $signedIdentifiers Signed identifiers
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function setContainerAcl($containerName ''$acl self::ACL_PRIVATE$signedIdentifiers = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }

        
// Headers
        
$headers = array();

        
// Acl specified?
        
if ($acl != self::ACL_PRIVATE && $acl !== null && $acl != '') {
            
$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER 'blob-public-access'] = $acl;
        }

        
// Policies
        
$policies null;
        if (
is_array($signedIdentifiers) && count($signedIdentifiers) > 0) {
            
$policies  '';
            
$policies .= '<?xml version="1.0" encoding="utf-8"?>' "rn";
            
$policies .= '<SignedIdentifiers>' "rn";
            foreach (
$signedIdentifiers as $signedIdentifier) {
                
$policies .= '  <SignedIdentifier>' "rn";
                
$policies .= '    <Id>' $signedIdentifier->Id '</Id>' "rn";
                
$policies .= '    <AccessPolicy>' "rn";
                if (
$signedIdentifier->Start != '')
                
$policies .= '      <Start>' $signedIdentifier->Start '</Start>' "rn";
                if (
$signedIdentifier->Expiry != '')
                
$policies .= '      <Expiry>' $signedIdentifier->Expiry '</Expiry>' "rn";
                if (
$signedIdentifier->Permissions != '')
                
$policies .= '      <Permission>' $signedIdentifier->Permissions '</Permission>' "rn";
                
$policies .= '    </AccessPolicy>' "rn";
                
$policies .= '  </SignedIdentifier>' "rn";
            }
            
$policies .= '</SignedIdentifiers>' "rn";
        }

        
// Perform request
        
$response $this->_performRequest($containerName'?restype=container&comp=acl'Zend_Http_Client::PUT$headersfalse$policiesZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get container
     *
     * @param string $containerName  Container name
     * @return Zend_Service_WindowsAzure_Storage_BlobContainer
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getContainer($containerName '')
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }

        
// Perform request
        
$response $this->_performRequest($containerName'?restype=container'Zend_Http_Client::GET, array(), falsenullZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
        if (
$response->isSuccessful()) {
            
// Parse metadata
            
$metadata $this->_parseMetadataHeaders($response->getHeaders());

            
// Return container
            
return new Zend_Service_WindowsAzure_Storage_BlobContainer(
            
$containerName,
            
$response->getHeader('Etag'),
            
$response->getHeader('Last-modified'),
            
$metadata
            
);
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get container metadata
     *
     * @param string $containerName  Container name
     * @return array Key/value pairs of meta data
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getContainerMetadata($containerName '')
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }

        return 
$this->getContainer($containerName)->Metadata;
    }

    
/**
     * Set container metadata
     *
     * Calling the Set Container Metadata operation overwrites all existing metadata that is associated with the container. It's not possible to modify an individual name/value pair.
     *
     * @param string $containerName      Container name
     * @param array  $metadata           Key/value pairs of meta data
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function setContainerMetadata($containerName ''$metadata = array(), $additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (!
is_array($metadata)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
        }
        if (
count($metadata) == 0) {
            return;
        }

        
// Create metadata headers
        
$headers = array();
        
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Perform request
        
$response $this->_performRequest($containerName'?restype=container&comp=metadata'Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Delete container
     *
     * @param string $containerName      Container name
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function deleteContainer($containerName ''$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
            
        
// Additional headers?
        
$headers = array();
        foreach (
$additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Perform request
        
$response $this->_performRequest($containerName'?restype=container'Zend_Http_Client::DELETE$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * List containers
     *
     * @param string $prefix     Optional. Filters the results to return only containers whose name begins with the specified prefix.
     * @param int    $maxResults Optional. Specifies the maximum number of containers to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000)
     * @param string $marker     Optional string value that identifies the portion of the list to be returned with the next list operation.
     * @param string $include    Optional. Include this parameter to specify that the container's metadata be returned as part of the response body. (allowed values: '', 'metadata')
     * @param int    $currentResultCount Current result count (internal use)
     * @return array
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function listContainers($prefix null$maxResults null$marker null$include null$currentResultCount 0)
    {
        
// Build query string
        
$queryString = array('comp=list');
        if (
$prefix !== null) {
            
$queryString[] = 'prefix=' $prefix;
        }
        if (
$maxResults !== null) {
            
$queryString[] = 'maxresults=' $maxResults;
        }
        if (
$marker !== null) {
            
$queryString[] = 'marker=' $marker;
        }
        if (
$include !== null) {
            
$queryString[] = 'include=' $include;
        }
        
$queryString self::createQueryStringFromArray($queryString);
         
        
// Perform request
        
$response $this->_performRequest(''$queryStringZend_Http_Client::GET, array(), falsenullZend_Service_WindowsAzure_Storage::RESOURCE_CONTAINERZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST);
        if (
$response->isSuccessful()) {
            
$xmlContainers $this->_parseResponse($response)->Containers->Container;
            
$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;

            
$containers = array();
            if (
$xmlContainers !== null) {
                for (
$i 0$i count($xmlContainers); $i++) {
                    
$containers[] = new Zend_Service_WindowsAzure_Storage_BlobContainer(
                    (string)
$xmlContainers[$i]->Name,
                    (string)
$xmlContainers[$i]->Etag,
                    (string)
$xmlContainers[$i]->LastModified,
                    
$this->_parseMetadataElement($xmlContainers[$i])
                    );
                }
            }
            
$currentResultCount $currentResultCount count($containers);
            if (
$maxResults !== null && $currentResultCount $maxResults) {
                if (
$xmlMarker !== null && $xmlMarker != '') {
                    
$containers array_merge($containers$this->listContainers($prefix$maxResults$xmlMarker$include$currentResultCount));
                }
            }
            if (
$maxResults !== null && count($containers) > $maxResults) {
                
$containers array_slice($containers0$maxResults);
            }
             
            return 
$containers;
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Put blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $localFileName      Local file name to be uploaded
     * @param array  $metadata           Key/value pairs of meta data
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @return object Partial blob properties
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function putBlob($containerName ''$blobName ''$localFileName ''$metadata = array(), $leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$localFileName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
        }
        if (!
file_exists($localFileName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Local file not found.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
            
        
// Check file size
        
if (filesize($localFileName) >= self::MAX_BLOB_SIZE) {
            return 
$this->putLargeBlob($containerName$blobName$localFileName$metadata$leaseId);
        }

        
// Put the data to Windows Azure Storage
        
return $this->putBlobData($containerName$blobNamefile_get_contents($localFileName), $metadata$leaseId$additionalHeaders);
    }

    
/**
     * Put blob data
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param mixed  $data               Data to store
     * @param array  $metadata           Key/value pairs of meta data
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @return object Partial blob properties
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function putBlobData($containerName ''$blobName ''$data ''$metadata = array(), $leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Create metadata headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
        
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Specify blob type
        
$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER 'blob-type'] = self::BLOBTYPE_BLOCK;

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName''Zend_Http_Client::PUT$headersfalse$dataZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            return new 
Zend_Service_WindowsAzure_Storage_BlobInstance(
            
$containerName,
            
$blobName,
            
null,
            
$response->getHeader('Etag'),
            
$response->getHeader('Last-modified'),
            
$this->getBaseUrl() . '/' $containerName '/' $blobName,
            
strlen($data),
                
'',
                
'',
                
'',
            
false,
            
$metadata
            
);
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Put large blob (> 64 MB)
     *
     * @param string $containerName Container name
     * @param string $blobName Blob name
     * @param string $localFileName Local file name to be uploaded
     * @param array  $metadata      Key/value pairs of meta data
     * @param string $leaseId       Lease identifier
     * @return object Partial blob properties
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function putLargeBlob($containerName ''$blobName ''$localFileName ''$metadata = array(), $leaseId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$localFileName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
        }
        if (!
file_exists($localFileName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Local file not found.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
            
        
// Check file size
        
if (filesize($localFileName) < self::MAX_BLOB_SIZE) {
            return 
$this->putBlob($containerName$blobName$localFileName$metadata);
        }
            
        
// Determine number of parts
        
$numberOfParts ceilfilesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE );

        
// Generate block id's
        
$blockIdentifiers = array();
        for (
$i 0$i $numberOfParts$i++) {
            
$blockIdentifiers[] = $this->_generateBlockId($i);
        }

        
// Open file
        
$fp fopen($localFileName'r');
        if (
$fp === false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Could not open local file.');
        }
            
        
// Upload parts
        
for ($i 0$i $numberOfParts$i++) {
            
// Seek position in file
            
fseek($fp$i self::MAX_BLOB_TRANSFER_SIZE);
                
            
// Read contents
            
$fileContents fread($fpself::MAX_BLOB_TRANSFER_SIZE);
                
            
// Put block
            
$this->putBlock($containerName$blobName$blockIdentifiers[$i], $fileContents$leaseId);
                
            
// Dispose file contents
            
$fileContents null;
            unset(
$fileContents);
        }

        
// Close file
        
fclose($fp);

        
// Put block list
        
$this->putBlockList($containerName$blobName$blockIdentifiers$metadata$leaseId);

        
// Return information of the blob
        
return $this->getBlobInstance($containerName$blobNamenull$leaseId);
    }
        
    
/**
     * Put large blob block
     *
     * @param string $containerName Container name
     * @param string $blobName      Blob name
     * @param string $identifier    Block ID
     * @param array  $contents      Contents of the block
     * @param string $leaseId       Lease identifier
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function putBlock($containerName ''$blobName ''$identifier ''$contents ''$leaseId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$identifier === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Block identifier is not specified.');
        }
        if (
strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) {
            throw new 
Zend_Service_WindowsAzure_Exception('Block size is too big.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
            
        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Upload
        
$response $this->_performRequest($resourceName'?comp=block&blockid=' base64_encode($identifier), Zend_Http_Client::PUT$headersfalse$contentsZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Put block list
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param array $blockList           Array of block identifiers
     * @param array  $metadata           Key/value pairs of meta data
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function putBlockList($containerName ''$blobName ''$blockList = array(), $metadata = array(), $leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
count($blockList) == 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('Block list does not contain any elements.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Generate block list
        
$blocks '';
        foreach (
$blockList as $block) {
            
$blocks .= '  <Latest>' base64_encode($block) . '</Latest>' "n";
        }

        
// Generate block list request
        
$fileContents utf8_encode(implode("n", array(
            
'<?xml version="1.0" encoding="utf-8"?>',
            
'<BlockList>',
        
$blocks,
            
'</BlockList>'
            
)));

            
// Create metadata headers
            
$headers = array();
            if (
$leaseId !== null) {
                
$headers['x-ms-lease-id'] = $leaseId;
            }
            
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

            
// Additional headers?
            
foreach ($additionalHeaders as $key => $value) {
                
$headers[$key] = $value;
            }

            
// Resource name
            
$resourceName self::createResourceName($containerName $blobName);

            
// Perform request
            
$response $this->_performRequest($resourceName'?comp=blocklist'Zend_Http_Client::PUT$headersfalse$fileContentsZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
            if (!
$response->isSuccessful()) {
                throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
            }
    }

    
/**
     * Get block list
     *
     * @param string $containerName Container name
     * @param string $blobName      Blob name
     * @param string $snapshotId    Snapshot identifier
     * @param string $leaseId       Lease identifier
     * @param integer $type         Type of block list to retrieve. 0 = all, 1 = committed, 2 = uncommitted
     * @return array
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getBlockList($containerName ''$blobName ''$snapshotId null$leaseId null$type 0)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$type || $type 2) {
            throw new 
Zend_Service_WindowsAzure_Exception('Invalid type of block list to retrieve.');
        }

        
// Set $blockListType
        
$blockListType 'all';
        if (
$type == 1) {
            
$blockListType 'committed';
        }
        if (
$type == 2) {
            
$blockListType 'uncommitted';
        }

        
// Headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }

        
// Build query string
        
$queryString = array('comp=blocklist''blocklisttype=' $blockListType);
        if (
$snapshotId !== null) {
            
$queryString[] = 'snapshot=' $snapshotId;
        }
        
$queryString self::createQueryStringFromArray($queryString);

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);
            
        
// Perform request
        
$response $this->_performRequest($resourceName$queryStringZend_Http_Client::GET$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
        if (
$response->isSuccessful()) {
            
// Parse response
            
$blockList $this->_parseResponse($response);

            
// Create return value
            
$returnValue = array();
            if (
$blockList->CommittedBlocks) {
                foreach (
$blockList->CommittedBlocks->Block as $block) {
                    
$returnValue['CommittedBlocks'][] = (object)array(
                        
'Name' => (string)$block->Name,
                        
'Size' => (string)$block->Size
                    
);
                }
            }
            if (
$blockList->UncommittedBlocks)  {
                foreach (
$blockList->UncommittedBlocks->Block as $block) {
                    
$returnValue['UncommittedBlocks'][] = (object)array(
                        
'Name' => (string)$block->Name,
                        
'Size' => (string)$block->Size
                    
);
                }
            }

            return 
$returnValue;
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Create page blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param int    $size               Size of the page blob in bytes
     * @param array  $metadata           Key/value pairs of meta data
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @return object Partial blob properties
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function createPageBlob($containerName ''$blobName ''$size 0$metadata = array(), $leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
        if (
$size <= 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('Page blob size must be specified.');
        }

        
// Create metadata headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
        
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Specify blob type & blob length
        
$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER 'blob-type'] = self::BLOBTYPE_PAGE;
        
$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER 'blob-content-length'] = $size;
        
$headers['Content-Length'] = 0;

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName''Zend_Http_Client::PUT$headersfalse''Zend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            return new 
Zend_Service_WindowsAzure_Storage_BlobInstance(
            
$containerName,
            
$blobName,
            
null,
            
$response->getHeader('Etag'),
            
$response->getHeader('Last-modified'),
            
$this->getBaseUrl() . '/' $containerName '/' $blobName,
            
$size,
                
'',
                
'',
                
'',
            
false,
            
$metadata
            
);
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Put page in page blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param int    $startByteOffset    Start byte offset
     * @param int    $endByteOffset      End byte offset
     * @param mixed  $contents             Page contents
     * @param string $writeMethod        Write method (Zend_Service_WindowsAzure_Storage_Blob::PAGE_WRITE_*)
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function putPage($containerName ''$blobName ''$startByteOffset 0$endByteOffset 0$contents ''$writeMethod self::PAGE_WRITE_UPDATE$leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
        if (
$startByteOffset 512 != 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
        }
        if ((
$endByteOffset 1) % 512 != 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
        }

        
// Determine size
        
$size strlen($contents);
        if (
$size >= self::MAX_BLOB_TRANSFER_SIZE) {
            throw new 
Zend_Service_WindowsAzure_Exception('Page blob size must not be larger than ' self::MAX_BLOB_TRANSFER_SIZE ' bytes.');
        }

        
// Create metadata headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Specify range
        
$headers['Range'] = 'bytes=' $startByteOffset '-' $endByteOffset;

        
// Write method
        
$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER 'page-write'] = $writeMethod;

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName'?comp=page'Zend_Http_Client::PUT$headersfalse$contentsZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Put page in page blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param int    $startByteOffset    Start byte offset
     * @param int    $endByteOffset      End byte offset
     * @param string $leaseId            Lease identifier
     * @return array Array of page ranges
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getPageRegions($containerName ''$blobName ''$startByteOffset 0$endByteOffset 0$leaseId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
        if (
$startByteOffset 512 != 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
        }
        if (
$endByteOffset && ($endByteOffset 1) % 512 != 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
        }

        
// Create metadata headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }

        
// Specify range?
        
if ($endByteOffset 0) {
            
$headers['Range'] = 'bytes=' $startByteOffset '-' $endByteOffset;
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName'?comp=pagelist'Zend_Http_Client::GET$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            
$result $this->_parseResponse($response);
            
$xmlRanges null;
            if (
count($result->PageRange) > 1) {
                
$xmlRanges $result->PageRange;
            } else {
                
$xmlRanges = array($result->PageRange);
            }

            
$ranges = array();
            for (
$i 0$i count($xmlRanges); $i++) {
                
$ranges[] = new Zend_Service_WindowsAzure_Storage_PageRegionInstance(
                (int)
$xmlRanges[$i]->Start,
                (int)
$xmlRanges[$i]->End
                
);
            }
             
            return 
$ranges;
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }
        
    
/**
     * Copy blob
     *
     * @param string $sourceContainerName       Source container name
     * @param string $sourceBlobName            Source blob name
     * @param string $destinationContainerName  Destination container name
     * @param string $destinationBlobName       Destination blob name
     * @param array  $metadata                  Key/value pairs of meta data
     * @param string $sourceSnapshotId          Source snapshot identifier
     * @param string $destinationLeaseId        Destination lease identifier
     * @param array  $additionalHeaders         Additional headers. See http://msdn.microsoft.com/en-us/library/dd894037.aspx for more information.
     * @return object Partial blob properties
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function copyBlob($sourceContainerName ''$sourceBlobName ''$destinationContainerName ''$destinationBlobName ''$metadata = array(), $sourceSnapshotId null$destinationLeaseId null$additionalHeaders = array())
    {
        if (
$sourceContainerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Source container name is not specified.');
        }
        if (!
self::isValidContainerName($sourceContainerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Source container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$sourceBlobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Source blob name is not specified.');
        }
        if (
$destinationContainerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Destination container name is not specified.');
        }
        if (!
self::isValidContainerName($destinationContainerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Destination container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$destinationBlobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Destination blob name is not specified.');
        }
        if (
$sourceContainerName === '$root' && strpos($sourceBlobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
        if (
$destinationContainerName === '$root' && strpos($destinationBlobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Create metadata headers
        
$headers = array();
        if (
$destinationLeaseId !== null) {
            
$headers['x-ms-lease-id'] = $destinationLeaseId;
        }
        
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Resource names
        
$sourceResourceName self::createResourceName($sourceContainerName$sourceBlobName);
        if (
$sourceSnapshotId !== null) {
            
$sourceResourceName .= '?snapshot=' $sourceSnapshotId;
        }
        
$destinationResourceName self::createResourceName($destinationContainerName$destinationBlobName);

        
// Set source blob
        
$headers["x-ms-copy-source"] = '/' $this->_accountName '/' $sourceResourceName;

        
// Perform request
        
$response $this->_performRequest($destinationResourceName''Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            return new 
Zend_Service_WindowsAzure_Storage_BlobInstance(
            
$destinationContainerName,
            
$destinationBlobName,
            
null,
            
$response->getHeader('Etag'),
            
$response->getHeader('Last-modified'),
            
$this->getBaseUrl() . '/' $destinationContainerName '/' $destinationBlobName,
            
0,
                
'',
                
'',
                
'',
            
false,
            
$metadata
            
);
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $localFileName      Local file name to store downloaded blob
     * @param string $snapshotId         Snapshot identifier
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getBlob($containerName ''$blobName ''$localFileName ''$snapshotId null$leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$localFileName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
        }

        
// Fetch data
        
file_put_contents($localFileName$this->getBlobData($containerName$blobName$snapshotId$leaseId$additionalHeaders));
    }

    
/**
     * Get blob data
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $snapshotId         Snapshot identifier
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @return mixed Blob contents
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getBlobData($containerName ''$blobName ''$snapshotId null$leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }

        
// Build query string
        
$queryString = array();
        if (
$snapshotId !== null) {
            
$queryString[] = 'snapshot=' $snapshotId;
        }
        
$queryString self::createQueryStringFromArray($queryString);

        
// Additional headers?
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
        foreach (
$additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName$queryStringZend_Http_Client::GET$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
        if (
$response->isSuccessful()) {
            return 
$response->getBody();
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get blob instance
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $snapshotId         Snapshot identifier
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @return Zend_Service_WindowsAzure_Storage_BlobInstance
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getBlobInstance($containerName ''$blobName ''$snapshotId null$leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Build query string
        
$queryString = array();
        if (
$snapshotId !== null) {
            
$queryString[] = 'snapshot=' $snapshotId;
        }
        
$queryString self::createQueryStringFromArray($queryString);
         
        
// Additional headers?
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
        foreach (
$additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName$queryStringZend_Http_Client::HEAD$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
        if (
$response->isSuccessful()) {
            
// Parse metadata
            
$metadata $this->_parseMetadataHeaders($response->getHeaders());

            
// Return blob
            
return new Zend_Service_WindowsAzure_Storage_BlobInstance(
            
$containerName,
            
$blobName,
            
$snapshotId,
            
$response->getHeader('Etag'),
            
$response->getHeader('Last-modified'),
            
$this->getBaseUrl() . '/' $containerName '/' $blobName,
            
$response->getHeader('Content-Length'),
            
$response->getHeader('Content-Type'),
            
$response->getHeader('Content-Encoding'),
            
$response->getHeader('Content-Language'),
            
$response->getHeader('Cache-Control'),
            
$response->getHeader('x-ms-blob-type'),
            
$response->getHeader('x-ms-lease-status'),
            
false,
            
$metadata
            
);
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get blob metadata
     *
     * @param string $containerName  Container name
     * @param string $blobName       Blob name
     * @param string $snapshotId     Snapshot identifier
     * @param string $leaseId        Lease identifier
     * @return array Key/value pairs of meta data
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getBlobMetadata($containerName ''$blobName ''$snapshotId null$leaseId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        return 
$this->getBlobInstance($containerName$blobName$snapshotId$leaseId)->Metadata;
    }

    
/**
     * Set blob metadata
     *
     * Calling the Set Blob Metadata operation overwrites all existing metadata that is associated with the blob. It's not possible to modify an individual name/value pair.
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param array  $metadata           Key/value pairs of meta data
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function setBlobMetadata($containerName ''$blobName ''$metadata = array(), $leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
        if (
count($metadata) == 0) {
            return;
        }

        
// Create metadata headers
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
        
$headers array_merge($headers$this->_generateMetadataHeaders($metadata));

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Perform request
        
$response $this->_performRequest($containerName '/' $blobName'?comp=metadata'Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Set blob properties
     *
     * All available properties are listed at http://msdn.microsoft.com/en-us/library/ee691966.aspx and should be provided in the $additionalHeaders parameter.
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function setBlobProperties($containerName ''$blobName ''$leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }
        if (
count($additionalHeaders) == 0) {
            throw new 
Zend_Service_WindowsAzure_Exception('No additional headers are specified.');
        }

        
// Create headers
        
$headers = array();

        
// Lease set?
        
if ($leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }

        
// Additional headers?
        
foreach ($additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Perform request
        
$response $this->_performRequest($containerName '/' $blobName'?comp=properties'Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Get blob properties
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $snapshotId         Snapshot identifier
     * @param string $leaseId            Lease identifier
     * @return Zend_Service_WindowsAzure_Storage_BlobInstance
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function getBlobProperties($containerName ''$blobName ''$snapshotId null$leaseId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        return 
$this->getBlobInstance($containerName$blobName$snapshotId$leaseId);
    }

    
/**
     * Delete blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $snapshotId         Snapshot identifier
     * @param string $leaseId            Lease identifier
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function deleteBlob($containerName ''$blobName ''$snapshotId null$leaseId null$additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Build query string
        
$queryString = array();
        if (
$snapshotId !== null) {
            
$queryString[] = 'snapshot=' $snapshotId;
        }
        
$queryString self::createQueryStringFromArray($queryString);
            
        
// Additional headers?
        
$headers = array();
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }
        foreach (
$additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName$queryStringZend_Http_Client::DELETE$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (!
$response->isSuccessful()) {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Snapshot blob
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param array  $metadata           Key/value pairs of meta data
     * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
     * @return string Date/Time value representing the snapshot identifier.
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function snapshotBlob($containerName ''$blobName ''$metadata = array(), $additionalHeaders = array())
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Additional headers?
        
$headers = array();
        foreach (
$additionalHeaders as $key => $value) {
            
$headers[$key] = $value;
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName'?comp=snapshot'Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            return 
$response->getHeader('x-ms-snapshot');
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Lease blob - See (http://msdn.microsoft.com/en-us/library/ee691972.aspx)
     *
     * @param string $containerName      Container name
     * @param string $blobName           Blob name
     * @param string $leaseAction        Lease action (Zend_Service_WindowsAzure_Storage_Blob::LEASE_*)
     * @param string $leaseId            Lease identifier, required to renew the lease or to release the lease.
     * @return Zend_Service_WindowsAzure_Storage_LeaseInstance Lease instance
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function leaseBlob($containerName ''$blobName ''$leaseAction self::LEASE_ACQUIRE$leaseId null)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
        if (
$blobName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
        }
        if (
$containerName === '$root' && strpos($blobName'/') !== false) {
            throw new 
Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
        }

        
// Additional headers?
        
$headers = array();
        
$headers['x-ms-lease-action'] = strtolower($leaseAction);
        if (
$leaseId !== null) {
            
$headers['x-ms-lease-id'] = $leaseId;
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Perform request
        
$response $this->_performRequest($resourceName'?comp=lease'Zend_Http_Client::PUT$headersfalsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
        if (
$response->isSuccessful()) {
            return new 
Zend_Service_WindowsAzure_Storage_LeaseInstance(
            
$containerName,
            
$blobName,
            
$response->getHeader('x-ms-lease-id'),
            
$response->getHeader('x-ms-lease-time'));
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * List blobs
     *
     * @param string $containerName Container name
     * @param string $prefix     Optional. Filters the results to return only blobs whose name begins with the specified prefix.
     * @param string $delimiter  Optional. Delimiter, i.e. '/', for specifying folder hierarchy
     * @param int    $maxResults Optional. Specifies the maximum number of blobs to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000)
     * @param string $marker     Optional string value that identifies the portion of the list to be returned with the next list operation.
     * @param string $include    Optional. Specifies that the response should include one or more of the following subsets: '', 'metadata', 'snapshots', 'uncommittedblobs'). Multiple values can be added separated with a comma (,)
     * @param int    $currentResultCount Current result count (internal use)
     * @return array
     * @throws Zend_Service_WindowsAzure_Exception
     */
    
public function listBlobs($containerName ''$prefix ''$delimiter ''$maxResults null$marker null$include null$currentResultCount 0)
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }
            
        
// Build query string
        
$queryString = array('restype=container''comp=list');
        if (
$prefix !== null) {
            
$queryString[] = 'prefix=' $prefix;
        }
        if (
$delimiter !== '') {
            
$queryString[] = 'delimiter=' $delimiter;
        }
        if (
$maxResults !== null) {
            
$queryString[] = 'maxresults=' $maxResults;
        }
        if (
$marker !== null) {
            
$queryString[] = 'marker=' $marker;
        }
        if (
$include !== null) {
            
$queryString[] = 'include=' $include;
        }
        
$queryString self::createQueryStringFromArray($queryString);

        
// Perform request
        
$response $this->_performRequest($containerName$queryStringZend_Http_Client::GET, array(), falsenullZend_Service_WindowsAzure_Storage::RESOURCE_BLOBZend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST);
        if (
$response->isSuccessful()) {
            
// Return value
            
$blobs = array();

            
// Blobs
            
$xmlBlobs $this->_parseResponse($response)->Blobs->Blob;
            if (
$xmlBlobs !== null) {
                for (
$i 0$i count($xmlBlobs); $i++) {
                    
$properties = (array)$xmlBlobs[$i]->Properties;
                        
                    
$blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance(
                    
$containerName,
                    (string)
$xmlBlobs[$i]->Name,
                    (string)
$xmlBlobs[$i]->Snapshot,
                    (string)
$properties['Etag'],
                    (string)
$properties['Last-Modified'],
                    (string)
$xmlBlobs[$i]->Url,
                    (string)
$properties['Content-Length'],
                    (string)
$properties['Content-Type'],
                    (string)
$properties['Content-Encoding'],
                    (string)
$properties['Content-Language'],
                    (string)
$properties['Cache-Control'],
                    (string)
$properties['BlobType'],
                    (string)
$properties['LeaseStatus'],
                    
false,
                    
$this->_parseMetadataElement($xmlBlobs[$i])
                    );
                }
            }
                
            
// Blob prefixes (folders)
            
$xmlBlobs $this->_parseResponse($response)->Blobs->BlobPrefix;
                
            if (
$xmlBlobs !== null) {
                for (
$i 0$i count($xmlBlobs); $i++) {
                    
$blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance(
                    
$containerName,
                    (string)
$xmlBlobs[$i]->Name,
                    
null,
                        
'',
                        
'',
                        
'',
                    
0,
                        
'',
                        
'',
                        
'',
                        
'',
                        
'',
                        
'',
                    
true,
                    
$this->_parseMetadataElement($xmlBlobs[$i])
                    );
                }
            }
                
            
// More blobs?
            
$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
            
$currentResultCount $currentResultCount count($blobs);
            if (
$maxResults !== null && $currentResultCount $maxResults) {
                if (
$xmlMarker !== null && $xmlMarker != '') {
                    
$blobs array_merge($blobs$this->listBlobs($containerName$prefix$delimiter$maxResults$marker$include$currentResultCount));
                }
            }
            if (
$maxResults !== null && count($blobs) > $maxResults) {
                
$blobs array_slice($blobs0$maxResults);
            }
                
            return 
$blobs;
        } else {
            throw new 
Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response'Resource could not be accessed.'));
        }
    }

    
/**
     * Generate shared access URL
     *
     * @param string $containerName  Container name
     * @param string $blobName       Blob name
     * @param string $resource       Signed resource - container (c) - blob (b)
     * @param string $permissions    Signed permissions - read (r), write (w), delete (d) and list (l)
     * @param string $start          The time at which the Shared Access Signature becomes valid.
     * @param string $expiry         The time at which the Shared Access Signature becomes invalid.
     * @param string $identifier     Signed identifier
     * @return string
     */
    
public function generateSharedAccessUrl($containerName ''$blobName ''$resource 'b'$permissions 'r'$start ''$expiry ''$identifier '')
    {
        if (
$containerName === '') {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name is not specified.');
        }
        if (!
self::isValidContainerName($containerName)) {
            throw new 
Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
        }

        
// Resource name
        
$resourceName self::createResourceName($containerName $blobName);

        
// Generate URL
        
return $this->getBaseUrl() . '/' $resourceName '?' .
        
$this->_sharedAccessSignatureCredentials->createSignedQueryString(
        
$resourceName,
                
'',
        
$resource,
        
$permissions,
        
$start,
        
$expiry,
        
$identifier);
    }

    
/**
     * Register this object as stream wrapper client
     *
     * @param  string $name Protocol name
     * @return Zend_Service_WindowsAzure_Storage_Blob
     */
    
public function registerAsClient($name)
    {
        
self::$_wrapperClients[$name] = $this;
        return 
$this;
    }

    
/**
     * Unregister this object as stream wrapper client
     *
     * @param  string $name Protocol name
     * @return Zend_Service_WindowsAzure_Storage_Blob
     */
    
public function unregisterAsClient($name)
    {
        unset(
self::$_wrapperClients[$name]);
        return 
$this;
    }

    
/**
     * Get wrapper client for stream type
     *
     * @param  string $name Protocol name
     * @return Zend_Service_WindowsAzure_Storage_Blob
     */
    
public static function getWrapperClient($name)
    {
        return 
self::$_wrapperClients[$name];
    }

    
/**
     * Register this object as stream wrapper
     *
     * @param  string $name Protocol name
     */
    
public function registerStreamWrapper($name 'azure')
    {
        
/**
         * @see Zend_Service_WindowsAzure_Storage_Blob_Stream
         */
        
require_once 'Zend/Service/WindowsAzure/Storage/Blob/Stream.php';

        
stream_register_wrapper($name'Zend_Service_WindowsAzure_Storage_Blob_Stream');
        
$this->registerAsClient($name);
    }

    
/**
     * Unregister this object as stream wrapper
     *
     * @param  string $name Protocol name
     * @return Zend_Service_WindowsAzure_Storage_Blob
     */
    
public function unregisterStreamWrapper($name 'azure')
    {
        
stream_wrapper_unregister($name);
        
$this->unregisterAsClient($name);
    }

    
/**
     * Create resource name
     *
     * @param string $containerName  Container name
     * @param string $blobName Blob name
     * @return string
     */
    
public static function createResourceName($containerName ''$blobName '')
    {
        
// Resource name
        
$resourceName $containerName '/' $blobName;
        if (
$containerName === '' || $containerName === '$root') {
            
$resourceName $blobName;
        }
        if (
$blobName === '') {
            
$resourceName $containerName;
        }

        return 
$resourceName;
    }

    
/**
     * Is valid container name?
     *
     * @param string $containerName Container name
     * @return boolean
     */
    
public static function isValidContainerName($containerName '')
    {
        if (
$containerName == '$root') {
            return 
true;
        }

        if (
preg_match("/^[a-z0-9][a-z0-9-]*$/"$containerName) === 0) {
            return 
false;
        }

        if (
strpos($containerName'--') !== false) {
            return 
false;
        }

        if (
strtolower($containerName) != $containerName) {
            return 
false;
        }

        if (
strlen($containerName) < || strlen($containerName) > 63) {
            return 
false;
        }

        if (
substr($containerName, -1) == '-') {
            return 
false;
        }

        return 
true;
    }

    
/**
     * Get error message from Zend_Http_Response
     *
     * @param Zend_Http_Response $response Repsonse
     * @param string $alternativeError Alternative error message
     * @return string
     */
    
protected function _getErrorMessage(Zend_Http_Response $response$alternativeError 'Unknown error.')
    {
        
$response $this->_parseResponse($response);
        if (
$response && $response->Message) {
            return (string)
$response->Message;
        } else {
            return 
$alternativeError;
        }
    }

    
/**
     * Generate block id
     *
     * @param int $part Block number
     * @return string Windows Azure Blob Storage block number
     */
    
protected function _generateBlockId($part 0)
    {
        
$returnValue $part;
        while (
strlen($returnValue) < 64) {
            
$returnValue '0' $returnValue;
        }

        return 
$returnValue;
    }
}
Онлайн: 1
Реклама