web/lib/Zend/Service/WindowsAzure/Storage/Blob.php
changeset 807 877f952ae2bd
parent 207 621fa6caec0c
child 1230 68c69c656a2c
equal deleted inserted replaced
805:5e7a0fedabdf 807:877f952ae2bd
    13  * to license@zend.com so we can send you a copy immediately.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category   Zend
    15  * @category   Zend
    16  * @package    Zend_Service_WindowsAzure
    16  * @package    Zend_Service_WindowsAzure
    17  * @subpackage Storage
    17  * @subpackage Storage
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    18  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    19  * @license    http://todo     name_todo
    19  * @license    http://todo     name_todo
    20  * @version    $Id: Blob.php 23167 2010-10-19 17:53:31Z mabe $
    20  * @version    $Id: Blob.php 24697 2012-03-23 13:11:04Z ezimuel $
    21  */
    21  */
    22 
    22 
    23 /**
    23 /**
    24  * @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract_SharedKey
    24  * @see Zend_Service_WindowsAzure_Storage
    25  */
    25  */
    26 require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php';
    26 require_once 'Zend/Service/WindowsAzure/Storage.php';
       
    27 
       
    28 /**
       
    29  * @see Zend_Service_WindowsAzure_Storage_BlobInstance
       
    30  */
       
    31 require_once 'Zend/Service/WindowsAzure/Storage/BlobInstance.php';
       
    32 
       
    33 /**
       
    34  * @see Zend_Service_WindowsAzure_Storage_BlobContainer
       
    35  */
       
    36 require_once 'Zend/Service/WindowsAzure/Storage/BlobContainer.php';
       
    37 
       
    38 /**
       
    39  * @see Zend_Service_WindowsAzure_Storage_PageRegionInstance
       
    40  */
       
    41 require_once 'Zend/Service/WindowsAzure/Storage/PageRegionInstance.php';
       
    42 
       
    43 /**
       
    44  * @see Zend_Service_WindowsAzure_Storage_LeaseInstance
       
    45  */
       
    46 require_once 'Zend/Service/WindowsAzure/Storage/LeaseInstance.php';
       
    47 
       
    48 /**
       
    49  * @see Zend_Service_WindowsAzure_Storage_Blob_Stream
       
    50  */
       
    51 require_once 'Zend/Service/WindowsAzure/Storage/Blob/Stream.php';
    27 
    52 
    28 /**
    53 /**
    29  * @see Zend_Service_WindowsAzure_Credentials_SharedAccessSignature
    54  * @see Zend_Service_WindowsAzure_Credentials_SharedAccessSignature
    30  */
    55  */
    31 require_once 'Zend/Service/WindowsAzure/Credentials/SharedAccessSignature.php';
    56 require_once 'Zend/Service/WindowsAzure/Credentials/SharedAccessSignature.php';
    32 
       
    33 /**
       
    34  * @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
       
    35  */
       
    36 require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
       
    37 
       
    38 /**
       
    39  * @see Zend_Http_Client
       
    40  */
       
    41 require_once 'Zend/Http/Client.php';
       
    42 
       
    43 /**
       
    44  * @see Zend_Http_Response
       
    45  */
       
    46 require_once 'Zend/Http/Response.php';
       
    47 
       
    48 /**
       
    49  * @see Zend_Service_WindowsAzure_Storage
       
    50  */
       
    51 require_once 'Zend/Service/WindowsAzure/Storage.php';
       
    52 
       
    53 /**
       
    54  * @see Zend_Service_WindowsAzure_Storage_BlobContainer
       
    55  */
       
    56 require_once 'Zend/Service/WindowsAzure/Storage/BlobContainer.php';
       
    57 
       
    58 /**
       
    59  * @see Zend_Service_WindowsAzure_Storage_BlobInstance
       
    60  */
       
    61 require_once 'Zend/Service/WindowsAzure/Storage/BlobInstance.php';
       
    62 
       
    63 /**
       
    64  * @see Zend_Service_WindowsAzure_Storage_PageRegionInstance
       
    65  */
       
    66 require_once 'Zend/Service/WindowsAzure/Storage/PageRegionInstance.php';
       
    67 
       
    68 /**
       
    69  * @see Zend_Service_WindowsAzure_Storage_LeaseInstance
       
    70  */
       
    71 require_once 'Zend/Service/WindowsAzure/Storage/LeaseInstance.php';
       
    72 
       
    73 /**
       
    74  * @see Zend_Service_WindowsAzure_Storage_SignedIdentifier
       
    75  */
       
    76 require_once 'Zend/Service/WindowsAzure/Storage/SignedIdentifier.php';
       
    77 
       
    78 /**
       
    79  * @see Zend_Service_WindowsAzure_Exception
       
    80  */
       
    81 require_once 'Zend/Service/WindowsAzure/Exception.php';
       
    82 
       
    83 
       
    84 /**
    57 /**
    85  * @category   Zend
    58  * @category   Zend
    86  * @package    Zend_Service_WindowsAzure
    59  * @package    Zend_Service_WindowsAzure
    87  * @subpackage Storage
    60  * @subpackage Storage
    88  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    61  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    89  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    62  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    90  */
    63  */
    91 class Zend_Service_WindowsAzure_Storage_Blob extends Zend_Service_WindowsAzure_Storage
    64 class Zend_Service_WindowsAzure_Storage_Blob extends Zend_Service_WindowsAzure_Storage
    92 {
    65 {
    93 	/**
    66 	/**
   152 	/**
   125 	/**
   153 	 * SharedAccessSignature credentials
   126 	 * SharedAccessSignature credentials
   154 	 *
   127 	 *
   155 	 * @var Zend_Service_WindowsAzure_Credentials_SharedAccessSignature
   128 	 * @var Zend_Service_WindowsAzure_Credentials_SharedAccessSignature
   156 	 */
   129 	 */
   157 	private $_sharedAccessSignatureCredentials = null;
   130 	protected $_sharedAccessSignatureCredentials = null;
   158 
   131 
   159 	/**
   132 	/**
   160 	 * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance
   133 	 * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance
   161 	 *
   134 	 *
   162 	 * @param string $host Storage host name
   135 	 * @param string $host Storage host name
   185 	 * @return boolean
   158 	 * @return boolean
   186 	 */
   159 	 */
   187 	public function blobExists($containerName = '', $blobName = '', $snapshotId = null)
   160 	public function blobExists($containerName = '', $blobName = '', $snapshotId = null)
   188 	{
   161 	{
   189 		if ($containerName === '') {
   162 		if ($containerName === '') {
   190 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   163 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   191 		}
   164 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   192 		if (!self::isValidContainerName($containerName)) {
   165 		}
       
   166 		if (!self::isValidContainerName($containerName)) {
       
   167 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   193 			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.');
   168 			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.');
   194 		}
   169 		}
   195 		if ($blobName === '') {
   170 		if ($blobName === '') {
       
   171 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   196 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   172 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   197 		}
   173 		}
   198 
   174 
   199 		// Get blob instance
   175 		// Get blob instance
   200 		try {
   176 		try {
   213 	 * @return boolean
   189 	 * @return boolean
   214 	 */
   190 	 */
   215 	public function containerExists($containerName = '')
   191 	public function containerExists($containerName = '')
   216 	{
   192 	{
   217 		if ($containerName === '') {
   193 		if ($containerName === '') {
   218 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   194 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   219 		}
   195 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   220 		if (!self::isValidContainerName($containerName)) {
   196 		}
       
   197 		if (!self::isValidContainerName($containerName)) {
       
   198 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   221 			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.');
   199 			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.');
   222 		}
   200 		}
   223 			
   201 			
   224 		// List containers
   202 		// List containers
   225 		$containers = $this->listContainers($containerName, 1);
   203 		$containers = $this->listContainers($containerName, 1);
   241 	 * @throws Zend_Service_WindowsAzure_Exception
   219 	 * @throws Zend_Service_WindowsAzure_Exception
   242 	 */
   220 	 */
   243 	public function createContainer($containerName = '', $metadata = array())
   221 	public function createContainer($containerName = '', $metadata = array())
   244 	{
   222 	{
   245 		if ($containerName === '') {
   223 		if ($containerName === '') {
   246 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   224 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   247 		}
   225 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   248 		if (!self::isValidContainerName($containerName)) {
   226 		}
       
   227 		if (!self::isValidContainerName($containerName)) {
       
   228 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   249 			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.');
   229 			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.');
   250 		}
   230 		}
   251 		if (!is_array($metadata)) {
   231 		if (!is_array($metadata)) {
       
   232 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   252 			throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
   233 			throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
   253 		}
   234 		}
   254 			
   235 			
   255 		// Create metadata headers
   236 		// Create metadata headers
   256 		$headers = array();
   237 		$headers = array();
   257 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   238 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   258 
   239 
   259 		// Perform request
   240 		// Perform request
   260 		$response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   241 		$response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   261 		if ($response->isSuccessful()) {
   242 		if ($response->isSuccessful()) {
       
   243 			
   262 			return new Zend_Service_WindowsAzure_Storage_BlobContainer(
   244 			return new Zend_Service_WindowsAzure_Storage_BlobContainer(
   263 			$containerName,
   245 			$containerName,
   264 			$response->getHeader('Etag'),
   246 			$response->getHeader('Etag'),
   265 			$response->getHeader('Last-modified'),
   247 			$response->getHeader('Last-modified'),
   266 			$metadata
   248 			$metadata
   267 			);
   249 			);
   268 		} else {
   250 		} else {
       
   251 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   269 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   252 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
       
   253 		}
       
   254 	}
       
   255 	
       
   256 	/**
       
   257 	 * Create container if it does not exist
       
   258 	 *
       
   259 	 * @param string $containerName Container name
       
   260 	 * @param array  $metadata      Key/value pairs of meta data
       
   261 	 * @throws Zend_Service_WindowsAzure_Exception
       
   262 	 */
       
   263 	public function createContainerIfNotExists($containerName = '', $metadata = array())
       
   264 	{
       
   265 		if (!$this->containerExists($containerName)) {
       
   266 			$this->createContainer($containerName, $metadata);
   270 		}
   267 		}
   271 	}
   268 	}
   272 
   269 
   273 	/**
   270 	/**
   274 	 * Get container ACL
   271 	 * Get container ACL
   279 	 * @throws Zend_Service_WindowsAzure_Exception
   276 	 * @throws Zend_Service_WindowsAzure_Exception
   280 	 */
   277 	 */
   281 	public function getContainerAcl($containerName = '', $signedIdentifiers = false)
   278 	public function getContainerAcl($containerName = '', $signedIdentifiers = false)
   282 	{
   279 	{
   283 		if ($containerName === '') {
   280 		if ($containerName === '') {
   284 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   281 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   285 		}
   282 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   286 		if (!self::isValidContainerName($containerName)) {
   283 		}
       
   284 		if (!self::isValidContainerName($containerName)) {
       
   285 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   287 			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.');
   286 			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.');
   288 		}
   287 		}
   289 
   288 
   290 		// Perform request
   289 		// Perform request
   291 		$response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
   290 		$response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
   311 					} else {
   310 					} else {
   312 						$entries = array($result->SignedIdentifier);
   311 						$entries = array($result->SignedIdentifier);
   313 					}
   312 					}
   314 				}
   313 				}
   315 
   314 
       
   315 				require_once 'Zend/Service/WindowsAzure/Storage/SignedIdentifier.php';
   316 				// Return value
   316 				// Return value
   317 				$returnValue = array();
   317 				$returnValue = array();
   318 				foreach ($entries as $entry) {
   318 				foreach ($entries as $entry) {
   319 					$returnValue[] = new Zend_Service_WindowsAzure_Storage_SignedIdentifier(
   319 					$returnValue[] = new Zend_Service_WindowsAzure_Storage_SignedIdentifier(
   320 					$entry->Id,
   320 					$entry->Id,
   326 
   326 
   327 				// Return
   327 				// Return
   328 				return $returnValue;
   328 				return $returnValue;
   329 			}
   329 			}
   330 		} else {
   330 		} else {
       
   331 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   331 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   332 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   332 		}
   333 		}
   333 	}
   334 	}
   334 
   335 
   335 	/**
   336 	/**
   341 	 * @throws Zend_Service_WindowsAzure_Exception
   342 	 * @throws Zend_Service_WindowsAzure_Exception
   342 	 */
   343 	 */
   343 	public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array())
   344 	public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array())
   344 	{
   345 	{
   345 		if ($containerName === '') {
   346 		if ($containerName === '') {
   346 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   347 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   347 		}
   348 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   348 		if (!self::isValidContainerName($containerName)) {
   349 		}
       
   350 		if (!self::isValidContainerName($containerName)) {
       
   351 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   349 			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.');
   352 			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.');
   350 		}
   353 		}
   351 
   354 
   352 		// Headers
   355 		// Headers
   353 		$headers = array();
   356 		$headers = array();
   354 
   357 
   355 		// Acl specified?
   358 		// Acl specified?
   356 		if ($acl != self::ACL_PRIVATE && $acl !== null && $acl != '') {
   359 		if ($acl != self::ACL_PRIVATE && !is_null($acl) && $acl != '') {
   357 			$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'] = $acl;
   360 			$headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'] = $acl;
   358 		}
   361 		}
   359 
   362 
   360 		// Policies
   363 		// Policies
   361 		$policies = null;
   364 		$policies = null;
   380 		}
   383 		}
   381 
   384 
   382 		// Perform request
   385 		// Perform request
   383 		$response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::PUT, $headers, false, $policies, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   386 		$response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::PUT, $headers, false, $policies, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   384 		if (!$response->isSuccessful()) {
   387 		if (!$response->isSuccessful()) {
       
   388 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   385 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   389 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   386 		}
   390 		}
   387 	}
   391 	}
   388 
   392 
   389 	/**
   393 	/**
   394 	 * @throws Zend_Service_WindowsAzure_Exception
   398 	 * @throws Zend_Service_WindowsAzure_Exception
   395 	 */
   399 	 */
   396 	public function getContainer($containerName = '')
   400 	public function getContainer($containerName = '')
   397 	{
   401 	{
   398 		if ($containerName === '') {
   402 		if ($containerName === '') {
   399 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   403 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   400 		}
   404 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   401 		if (!self::isValidContainerName($containerName)) {
   405 		}
       
   406 		if (!self::isValidContainerName($containerName)) {
       
   407 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   402 			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.');
   408 			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.');
   403 		}
   409 		}
   404 
   410 
   405 		// Perform request
   411 		// Perform request
   406 		$response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
   412 		$response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
   414 			$response->getHeader('Etag'),
   420 			$response->getHeader('Etag'),
   415 			$response->getHeader('Last-modified'),
   421 			$response->getHeader('Last-modified'),
   416 			$metadata
   422 			$metadata
   417 			);
   423 			);
   418 		} else {
   424 		} else {
       
   425 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   419 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   426 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   420 		}
   427 		}
   421 	}
   428 	}
   422 
   429 
   423 	/**
   430 	/**
   428 	 * @throws Zend_Service_WindowsAzure_Exception
   435 	 * @throws Zend_Service_WindowsAzure_Exception
   429 	 */
   436 	 */
   430 	public function getContainerMetadata($containerName = '')
   437 	public function getContainerMetadata($containerName = '')
   431 	{
   438 	{
   432 		if ($containerName === '') {
   439 		if ($containerName === '') {
   433 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   440 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   434 		}
   441 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   435 		if (!self::isValidContainerName($containerName)) {
   442 		}
       
   443 		if (!self::isValidContainerName($containerName)) {
       
   444 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   436 			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.');
   445 			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.');
   437 		}
   446 		}
   438 
   447 
   439 		return $this->getContainer($containerName)->Metadata;
   448 		return $this->getContainer($containerName)->Metadata;
   440 	}
   449 	}
   450 	 * @throws Zend_Service_WindowsAzure_Exception
   459 	 * @throws Zend_Service_WindowsAzure_Exception
   451 	 */
   460 	 */
   452 	public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array())
   461 	public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array())
   453 	{
   462 	{
   454 		if ($containerName === '') {
   463 		if ($containerName === '') {
   455 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   464 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   456 		}
   465 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   457 		if (!self::isValidContainerName($containerName)) {
   466 		}
       
   467 		if (!self::isValidContainerName($containerName)) {
       
   468 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   458 			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.');
   469 			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.');
   459 		}
   470 		}
   460 		if (!is_array($metadata)) {
   471 		if (!is_array($metadata)) {
       
   472 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   461 			throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
   473 			throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
   462 		}
   474 		}
   463 		if (count($metadata) == 0) {
   475 		if (count($metadata) == 0) {
   464 			return;
   476 			return;
   465 		}
   477 		}
   474 		}
   486 		}
   475 
   487 
   476 		// Perform request
   488 		// Perform request
   477 		$response = $this->_performRequest($containerName, '?restype=container&comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   489 		$response = $this->_performRequest($containerName, '?restype=container&comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   478 		if (!$response->isSuccessful()) {
   490 		if (!$response->isSuccessful()) {
       
   491 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   479 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   492 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   480 		}
   493 		}
   481 	}
   494 	}
   482 
   495 
   483 	/**
   496 	/**
   488 	 * @throws Zend_Service_WindowsAzure_Exception
   501 	 * @throws Zend_Service_WindowsAzure_Exception
   489 	 */
   502 	 */
   490 	public function deleteContainer($containerName = '', $additionalHeaders = array())
   503 	public function deleteContainer($containerName = '', $additionalHeaders = array())
   491 	{
   504 	{
   492 		if ($containerName === '') {
   505 		if ($containerName === '') {
   493 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   506 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   494 		}
   507 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   495 		if (!self::isValidContainerName($containerName)) {
   508 		}
       
   509 		if (!self::isValidContainerName($containerName)) {
       
   510 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   496 			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.');
   511 			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.');
   497 		}
   512 		}
   498 			
   513 			
   499 		// Additional headers?
   514 		// Additional headers?
   500 		$headers = array();
   515 		$headers = array();
   503 		}
   518 		}
   504 
   519 
   505 		// Perform request
   520 		// Perform request
   506 		$response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   521 		$response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   507 		if (!$response->isSuccessful()) {
   522 		if (!$response->isSuccessful()) {
       
   523 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   508 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   524 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   509 		}
   525 		}
   510 	}
   526 	}
   511 
   527 
   512 	/**
   528 	/**
   522 	 */
   538 	 */
   523 	public function listContainers($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
   539 	public function listContainers($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
   524 	{
   540 	{
   525 		// Build query string
   541 		// Build query string
   526 		$queryString = array('comp=list');
   542 		$queryString = array('comp=list');
   527 		if ($prefix !== null) {
   543 		if (!is_null($prefix)) {
   528 			$queryString[] = 'prefix=' . $prefix;
   544 			$queryString[] = 'prefix=' . $prefix;
   529 		}
   545 		}
   530 		if ($maxResults !== null) {
   546 		if (!is_null($maxResults)) {
   531 			$queryString[] = 'maxresults=' . $maxResults;
   547 			$queryString[] = 'maxresults=' . $maxResults;
   532 		}
   548 		}
   533 		if ($marker !== null) {
   549 		if (!is_null($marker)) {
   534 			$queryString[] = 'marker=' . $marker;
   550 			$queryString[] = 'marker=' . $marker;
   535 		}
   551 		}
   536 		if ($include !== null) {
   552 		if (!is_null($include)) {
   537 			$queryString[] = 'include=' . $include;
   553 			$queryString[] = 'include=' . $include;
   538 		}
   554 		}
   539 		$queryString = self::createQueryStringFromArray($queryString);
   555 		$queryString = self::createQueryStringFromArray($queryString);
   540 		 
   556 		 
   541 		// Perform request
   557 		// Perform request
   543 		if ($response->isSuccessful()) {
   559 		if ($response->isSuccessful()) {
   544 			$xmlContainers = $this->_parseResponse($response)->Containers->Container;
   560 			$xmlContainers = $this->_parseResponse($response)->Containers->Container;
   545 			$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
   561 			$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
   546 
   562 
   547 			$containers = array();
   563 			$containers = array();
   548 			if ($xmlContainers !== null) {
   564 			if (!is_null($xmlContainers)) {
   549 				for ($i = 0; $i < count($xmlContainers); $i++) {
   565 				for ($i = 0; $i < count($xmlContainers); $i++) {
       
   566 					
   550 					$containers[] = new Zend_Service_WindowsAzure_Storage_BlobContainer(
   567 					$containers[] = new Zend_Service_WindowsAzure_Storage_BlobContainer(
   551 					(string)$xmlContainers[$i]->Name,
   568 					(string)$xmlContainers[$i]->Name,
   552 					(string)$xmlContainers[$i]->Etag,
   569 					(string)$xmlContainers[$i]->Etag,
   553 					(string)$xmlContainers[$i]->LastModified,
   570 					(string)$xmlContainers[$i]->LastModified,
   554 					$this->_parseMetadataElement($xmlContainers[$i])
   571 					$this->_parseMetadataElement($xmlContainers[$i])
   555 					);
   572 					);
   556 				}
   573 				}
   557 			}
   574 			}
   558 			$currentResultCount = $currentResultCount + count($containers);
   575 			$currentResultCount = $currentResultCount + count($containers);
   559 			if ($maxResults !== null && $currentResultCount < $maxResults) {
   576 			if (!is_null($maxResults) && $currentResultCount < $maxResults) {
   560 				if ($xmlMarker !== null && $xmlMarker != '') {
   577 				if (!is_null($xmlMarker) && $xmlMarker != '') {
   561 					$containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $include, $currentResultCount));
   578 					$containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $include, $currentResultCount));
   562 				}
   579 				}
   563 			}
   580 			}
   564 			if ($maxResults !== null && count($containers) > $maxResults) {
   581 			if (!is_null($maxResults) && count($containers) > $maxResults) {
   565 				$containers = array_slice($containers, 0, $maxResults);
   582 				$containers = array_slice($containers, 0, $maxResults);
   566 			}
   583 			}
   567 			 
   584 			 
   568 			return $containers;
   585 			return $containers;
   569 		} else {
   586 		} else {
       
   587 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   570 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   588 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   571 		}
   589 		}
   572 	}
   590 	}
   573 
   591 
   574 	/**
   592 	/**
   584 	 * @throws Zend_Service_WindowsAzure_Exception
   602 	 * @throws Zend_Service_WindowsAzure_Exception
   585 	 */
   603 	 */
   586 	public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
   604 	public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
   587 	{
   605 	{
   588 		if ($containerName === '') {
   606 		if ($containerName === '') {
   589 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   607 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   590 		}
   608 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   591 		if (!self::isValidContainerName($containerName)) {
   609 		}
       
   610 		if (!self::isValidContainerName($containerName)) {
       
   611 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   592 			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.');
   612 			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.');
   593 		}
   613 		}
   594 		if ($blobName === '') {
   614 		if ($blobName === '') {
       
   615 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   595 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   616 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   596 		}
   617 		}
   597 		if ($localFileName === '') {
   618 		if ($localFileName === '') {
       
   619 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   598 			throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
   620 			throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
   599 		}
   621 		}
   600 		if (!file_exists($localFileName)) {
   622 		if (!file_exists($localFileName)) {
       
   623 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   601 			throw new Zend_Service_WindowsAzure_Exception('Local file not found.');
   624 			throw new Zend_Service_WindowsAzure_Exception('Local file not found.');
   602 		}
   625 		}
   603 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
   626 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
   627 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   604 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   628 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   605 		}
   629 		}
   606 			
   630 			
   607 		// Check file size
   631 		// Check file size
   608 		if (filesize($localFileName) >= self::MAX_BLOB_SIZE) {
   632 		if (filesize($localFileName) >= self::MAX_BLOB_SIZE) {
   609 			return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata, $leaseId);
   633 			return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders);
   610 		}
   634 		}
   611 
   635 
   612 		// Put the data to Windows Azure Storage
   636 		// Put the data to Windows Azure Storage
   613 		return $this->putBlobData($containerName, $blobName, file_get_contents($localFileName), $metadata, $leaseId, $additionalHeaders);
   637 		return $this->putBlobData($containerName, $blobName, file_get_contents($localFileName), $metadata, $leaseId, $additionalHeaders);
   614 	}
   638 	}
   626 	 * @throws Zend_Service_WindowsAzure_Exception
   650 	 * @throws Zend_Service_WindowsAzure_Exception
   627 	 */
   651 	 */
   628 	public function putBlobData($containerName = '', $blobName = '', $data = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
   652 	public function putBlobData($containerName = '', $blobName = '', $data = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
   629 	{
   653 	{
   630 		if ($containerName === '') {
   654 		if ($containerName === '') {
   631 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   655 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   632 		}
   656 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   633 		if (!self::isValidContainerName($containerName)) {
   657 		}
       
   658 		if (!self::isValidContainerName($containerName)) {
       
   659 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   634 			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.');
   660 			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.');
   635 		}
   661 		}
   636 		if ($blobName === '') {
   662 		if ($blobName === '') {
       
   663 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   637 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   664 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   638 		}
   665 		}
   639 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
   666 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
   667 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   640 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   668 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   641 		}
   669 		}
   642 
   670 
   643 		// Create metadata headers
   671 		// Create metadata headers
   644 		$headers = array();
   672 		$headers = array();
   645 		if ($leaseId !== null) {
   673 		if (!is_null($leaseId)) {
   646 			$headers['x-ms-lease-id'] = $leaseId;
   674 			$headers['x-ms-lease-id'] = $leaseId;
   647 		}
   675 		}
   648 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   676 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   649 
   677 
   650 		// Additional headers?
   678 		// Additional headers?
   659 		$resourceName = self::createResourceName($containerName , $blobName);
   687 		$resourceName = self::createResourceName($containerName , $blobName);
   660 
   688 
   661 		// Perform request
   689 		// Perform request
   662 		$response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, $data, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   690 		$response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, $data, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   663 		if ($response->isSuccessful()) {
   691 		if ($response->isSuccessful()) {
       
   692 			
   664 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
   693 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
   665 			$containerName,
   694 			$containerName,
   666 			$blobName,
   695 			$blobName,
   667 			null,
   696 			null,
   668 			$response->getHeader('Etag'),
   697 			$response->getHeader('Etag'),
   674 				'',
   703 				'',
   675 			false,
   704 			false,
   676 			$metadata
   705 			$metadata
   677 			);
   706 			);
   678 		} else {
   707 		} else {
       
   708 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   679 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   709 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   680 		}
   710 		}
   681 	}
   711 	}
   682 
   712 
   683 	/**
   713 	/**
   686 	 * @param string $containerName Container name
   716 	 * @param string $containerName Container name
   687 	 * @param string $blobName Blob name
   717 	 * @param string $blobName Blob name
   688 	 * @param string $localFileName Local file name to be uploaded
   718 	 * @param string $localFileName Local file name to be uploaded
   689 	 * @param array  $metadata      Key/value pairs of meta data
   719 	 * @param array  $metadata      Key/value pairs of meta data
   690 	 * @param string $leaseId       Lease identifier
   720 	 * @param string $leaseId       Lease identifier
       
   721 	 * @param array  $additionalHeaders  Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
   691 	 * @return object Partial blob properties
   722 	 * @return object Partial blob properties
   692 	 * @throws Zend_Service_WindowsAzure_Exception
   723 	 * @throws Zend_Service_WindowsAzure_Exception
   693 	 */
   724 	 */
   694 	public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null)
   725 	public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
   695 	{
   726 	{
   696 		if ($containerName === '') {
   727 		if ($containerName === '') {
   697 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   728 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   698 		}
   729 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   699 		if (!self::isValidContainerName($containerName)) {
   730 		}
       
   731 		if (!self::isValidContainerName($containerName)) {
       
   732 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   700 			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.');
   733 			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.');
   701 		}
   734 		}
   702 		if ($blobName === '') {
   735 		if ($blobName === '') {
       
   736 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   703 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   737 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   704 		}
   738 		}
   705 		if ($localFileName === '') {
   739 		if ($localFileName === '') {
       
   740 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   706 			throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
   741 			throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
   707 		}
   742 		}
   708 		if (!file_exists($localFileName)) {
   743 		if (!file_exists($localFileName)) {
       
   744 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   709 			throw new Zend_Service_WindowsAzure_Exception('Local file not found.');
   745 			throw new Zend_Service_WindowsAzure_Exception('Local file not found.');
   710 		}
   746 		}
   711 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
   747 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
   748 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   712 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   749 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   713 		}
   750 		}
   714 			
   751 			
   715 		// Check file size
   752 		// Check file size
   716 		if (filesize($localFileName) < self::MAX_BLOB_SIZE) {
   753 		if (filesize($localFileName) < self::MAX_BLOB_SIZE) {
   717 			return $this->putBlob($containerName, $blobName, $localFileName, $metadata);
   754 			return $this->putBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders);
   718 		}
   755 		}
   719 			
   756 			
   720 		// Determine number of parts
   757 		// Determine number of parts
   721 		$numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE );
   758 		$numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE );
   722 
   759 
   727 		}
   764 		}
   728 
   765 
   729 		// Open file
   766 		// Open file
   730 		$fp = fopen($localFileName, 'r');
   767 		$fp = fopen($localFileName, 'r');
   731 		if ($fp === false) {
   768 		if ($fp === false) {
       
   769 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   732 			throw new Zend_Service_WindowsAzure_Exception('Could not open local file.');
   770 			throw new Zend_Service_WindowsAzure_Exception('Could not open local file.');
   733 		}
   771 		}
   734 			
   772 			
   735 		// Upload parts
   773 		// Upload parts
   736 		for ($i = 0; $i < $numberOfParts; $i++) {
   774 		for ($i = 0; $i < $numberOfParts; $i++) {
   750 
   788 
   751 		// Close file
   789 		// Close file
   752 		fclose($fp);
   790 		fclose($fp);
   753 
   791 
   754 		// Put block list
   792 		// Put block list
   755 		$this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata, $leaseId);
   793 		$this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata, $leaseId, $additionalHeaders);
   756 
   794 
   757 		// Return information of the blob
   795 		// Return information of the blob
   758 		return $this->getBlobInstance($containerName, $blobName, null, $leaseId);
   796 		return $this->getBlobInstance($containerName, $blobName, null, $leaseId);
   759 	}
   797 	}
   760 		
   798 		
   769 	 * @throws Zend_Service_WindowsAzure_Exception
   807 	 * @throws Zend_Service_WindowsAzure_Exception
   770 	 */
   808 	 */
   771 	public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '', $leaseId = null)
   809 	public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '', $leaseId = null)
   772 	{
   810 	{
   773 		if ($containerName === '') {
   811 		if ($containerName === '') {
   774 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   812 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   775 		}
   813 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   776 		if (!self::isValidContainerName($containerName)) {
   814 		}
       
   815 		if (!self::isValidContainerName($containerName)) {
       
   816 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   777 			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.');
   817 			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.');
   778 		}
   818 		}
   779 		if ($identifier === '') {
   819 		if ($identifier === '') {
       
   820 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   780 			throw new Zend_Service_WindowsAzure_Exception('Block identifier is not specified.');
   821 			throw new Zend_Service_WindowsAzure_Exception('Block identifier is not specified.');
   781 		}
   822 		}
   782 		if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) {
   823 		if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) {
       
   824 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   783 			throw new Zend_Service_WindowsAzure_Exception('Block size is too big.');
   825 			throw new Zend_Service_WindowsAzure_Exception('Block size is too big.');
   784 		}
   826 		}
   785 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
   827 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
   828 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   786 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   829 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   787 		}
   830 		}
   788 
   831 
   789 		// Headers
   832 		// Headers
   790 		$headers = array();
   833 		$headers = array();
   791 		if ($leaseId !== null) {
   834 		if (!is_null($leaseId)) {
   792 			$headers['x-ms-lease-id'] = $leaseId;
   835 			$headers['x-ms-lease-id'] = $leaseId;
   793 		}
   836 		}
   794 			
   837 			
   795 		// Resource name
   838 		// Resource name
   796 		$resourceName = self::createResourceName($containerName , $blobName);
   839 		$resourceName = self::createResourceName($containerName , $blobName);
   797 
   840 
   798 		// Upload
   841 		// Upload
   799 		$response = $this->_performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   842 		$response = $this->_performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   800 		if (!$response->isSuccessful()) {
   843 		if (!$response->isSuccessful()) {
       
   844 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   801 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   845 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   802 		}
   846 		}
   803 	}
   847 	}
   804 
   848 
   805 	/**
   849 	/**
   814 	 * @throws Zend_Service_WindowsAzure_Exception
   858 	 * @throws Zend_Service_WindowsAzure_Exception
   815 	 */
   859 	 */
   816 	public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $leaseId = null, $additionalHeaders = array())
   860 	public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $leaseId = null, $additionalHeaders = array())
   817 	{
   861 	{
   818 		if ($containerName === '') {
   862 		if ($containerName === '') {
   819 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   863 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   820 		}
   864 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   821 		if (!self::isValidContainerName($containerName)) {
   865 		}
       
   866 		if (!self::isValidContainerName($containerName)) {
       
   867 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   822 			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.');
   868 			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.');
   823 		}
   869 		}
   824 		if ($blobName === '') {
   870 		if ($blobName === '') {
       
   871 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   825 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   872 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   826 		}
   873 		}
   827 		if (count($blockList) == 0) {
   874 		if (count($blockList) == 0) {
       
   875 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   828 			throw new Zend_Service_WindowsAzure_Exception('Block list does not contain any elements.');
   876 			throw new Zend_Service_WindowsAzure_Exception('Block list does not contain any elements.');
   829 		}
   877 		}
   830 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
   878 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
   879 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   831 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   880 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   832 		}
   881 		}
   833 
   882 
   834 		// Generate block list
   883 		// Generate block list
   835 		$blocks = '';
   884 		$blocks = '';
   837 			$blocks .= '  <Latest>' . base64_encode($block) . '</Latest>' . "\n";
   886 			$blocks .= '  <Latest>' . base64_encode($block) . '</Latest>' . "\n";
   838 		}
   887 		}
   839 
   888 
   840 		// Generate block list request
   889 		// Generate block list request
   841 		$fileContents = utf8_encode(implode("\n", array(
   890 		$fileContents = utf8_encode(implode("\n", array(
   842 			'<?xml version="1.0" encoding="utf-8"?>',
   891 				'<?xml version="1.0" encoding="utf-8"?>',
   843 			'<BlockList>',
   892 				'<BlockList>',
   844 		$blocks,
   893 				$blocks,
   845 			'</BlockList>'
   894 				'</BlockList>'
   846 			)));
   895 			)));
   847 
   896 
   848 			// Create metadata headers
   897 			// Create metadata headers
   849 			$headers = array();
   898 			$headers = array();
   850 			if ($leaseId !== null) {
   899 			if (!is_null($leaseId)) {
   851 				$headers['x-ms-lease-id'] = $leaseId;
   900 				$headers['x-ms-lease-id'] = $leaseId;
   852 			}
   901 			}
   853 			$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   902 			$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   854 
   903 
   855 			// Additional headers?
   904 			// Additional headers?
   861 			$resourceName = self::createResourceName($containerName , $blobName);
   910 			$resourceName = self::createResourceName($containerName , $blobName);
   862 
   911 
   863 			// Perform request
   912 			// Perform request
   864 			$response = $this->_performRequest($resourceName, '?comp=blocklist', Zend_Http_Client::PUT, $headers, false, $fileContents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   913 			$response = $this->_performRequest($resourceName, '?comp=blocklist', Zend_Http_Client::PUT, $headers, false, $fileContents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
   865 			if (!$response->isSuccessful()) {
   914 			if (!$response->isSuccessful()) {
       
   915 				require_once 'Zend/Service/WindowsAzure/Exception.php';
   866 				throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   916 				throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   867 			}
   917 			}
   868 	}
   918 	}
   869 
   919 
   870 	/**
   920 	/**
   879 	 * @throws Zend_Service_WindowsAzure_Exception
   929 	 * @throws Zend_Service_WindowsAzure_Exception
   880 	 */
   930 	 */
   881 	public function getBlockList($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $type = 0)
   931 	public function getBlockList($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $type = 0)
   882 	{
   932 	{
   883 		if ($containerName === '') {
   933 		if ($containerName === '') {
   884 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   934 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   885 		}
   935 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   886 		if (!self::isValidContainerName($containerName)) {
   936 		}
       
   937 		if (!self::isValidContainerName($containerName)) {
       
   938 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   887 			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.');
   939 			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.');
   888 		}
   940 		}
   889 		if ($blobName === '') {
   941 		if ($blobName === '') {
       
   942 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   890 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   943 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   891 		}
   944 		}
   892 		if ($type < 0 || $type > 2) {
   945 		if ($type < 0 || $type > 2) {
       
   946 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   893 			throw new Zend_Service_WindowsAzure_Exception('Invalid type of block list to retrieve.');
   947 			throw new Zend_Service_WindowsAzure_Exception('Invalid type of block list to retrieve.');
   894 		}
   948 		}
   895 
   949 
   896 		// Set $blockListType
   950 		// Set $blockListType
   897 		$blockListType = 'all';
   951 		$blockListType = 'all';
   902 			$blockListType = 'uncommitted';
   956 			$blockListType = 'uncommitted';
   903 		}
   957 		}
   904 
   958 
   905 		// Headers
   959 		// Headers
   906 		$headers = array();
   960 		$headers = array();
   907 		if ($leaseId !== null) {
   961 		if (!is_null($leaseId)) {
   908 			$headers['x-ms-lease-id'] = $leaseId;
   962 			$headers['x-ms-lease-id'] = $leaseId;
   909 		}
   963 		}
   910 
   964 
   911 		// Build query string
   965 		// Build query string
   912 		$queryString = array('comp=blocklist', 'blocklisttype=' . $blockListType);
   966 		$queryString = array('comp=blocklist', 'blocklisttype=' . $blockListType);
   913 		if ($snapshotId !== null) {
   967 		if (!is_null($snapshotId)) {
   914 			$queryString[] = 'snapshot=' . $snapshotId;
   968 			$queryString[] = 'snapshot=' . $snapshotId;
   915 		}
   969 		}
   916 		$queryString = self::createQueryStringFromArray($queryString);
   970 		$queryString = self::createQueryStringFromArray($queryString);
   917 
   971 
   918 		// Resource name
   972 		// Resource name
   943 				}
   997 				}
   944 			}
   998 			}
   945 
   999 
   946 			return $returnValue;
  1000 			return $returnValue;
   947 		} else {
  1001 		} else {
       
  1002 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   948 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1003 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
   949 		}
  1004 		}
   950 	}
  1005 	}
   951 
  1006 
   952 	/**
  1007 	/**
   962 	 * @throws Zend_Service_WindowsAzure_Exception
  1017 	 * @throws Zend_Service_WindowsAzure_Exception
   963 	 */
  1018 	 */
   964 	public function createPageBlob($containerName = '', $blobName = '', $size = 0, $metadata = array(), $leaseId = null, $additionalHeaders = array())
  1019 	public function createPageBlob($containerName = '', $blobName = '', $size = 0, $metadata = array(), $leaseId = null, $additionalHeaders = array())
   965 	{
  1020 	{
   966 		if ($containerName === '') {
  1021 		if ($containerName === '') {
   967 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1022 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   968 		}
  1023 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
   969 		if (!self::isValidContainerName($containerName)) {
  1024 		}
       
  1025 		if (!self::isValidContainerName($containerName)) {
       
  1026 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   970 			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.');
  1027 			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.');
   971 		}
  1028 		}
   972 		if ($blobName === '') {
  1029 		if ($blobName === '') {
       
  1030 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   973 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1031 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
   974 		}
  1032 		}
   975 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1033 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1034 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   976 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1035 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
   977 		}
  1036 		}
   978 		if ($size <= 0) {
  1037 		if ($size <= 0) {
       
  1038 			require_once 'Zend/Service/WindowsAzure/Exception.php';
   979 			throw new Zend_Service_WindowsAzure_Exception('Page blob size must be specified.');
  1039 			throw new Zend_Service_WindowsAzure_Exception('Page blob size must be specified.');
   980 		}
  1040 		}
   981 
  1041 
   982 		// Create metadata headers
  1042 		// Create metadata headers
   983 		$headers = array();
  1043 		$headers = array();
   984 		if ($leaseId !== null) {
  1044 		if (!is_null($leaseId)) {
   985 			$headers['x-ms-lease-id'] = $leaseId;
  1045 			$headers['x-ms-lease-id'] = $leaseId;
   986 		}
  1046 		}
   987 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
  1047 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
   988 
  1048 
   989 		// Additional headers?
  1049 		// Additional headers?
  1000 		$resourceName = self::createResourceName($containerName , $blobName);
  1060 		$resourceName = self::createResourceName($containerName , $blobName);
  1001 
  1061 
  1002 		// Perform request
  1062 		// Perform request
  1003 		$response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, '', Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1063 		$response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, '', Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1004 		if ($response->isSuccessful()) {
  1064 		if ($response->isSuccessful()) {
       
  1065 			
  1005 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1066 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1006 			$containerName,
  1067 			$containerName,
  1007 			$blobName,
  1068 			$blobName,
  1008 			null,
  1069 			null,
  1009 			$response->getHeader('Etag'),
  1070 			$response->getHeader('Etag'),
  1015 				'',
  1076 				'',
  1016 			false,
  1077 			false,
  1017 			$metadata
  1078 			$metadata
  1018 			);
  1079 			);
  1019 		} else {
  1080 		} else {
       
  1081 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1020 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1082 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1021 		}
  1083 		}
  1022 	}
  1084 	}
  1023 
  1085 
  1024 	/**
  1086 	/**
  1035 	 * @throws Zend_Service_WindowsAzure_Exception
  1097 	 * @throws Zend_Service_WindowsAzure_Exception
  1036 	 */
  1098 	 */
  1037 	public function putPage($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $contents = '', $writeMethod = self::PAGE_WRITE_UPDATE, $leaseId = null, $additionalHeaders = array())
  1099 	public function putPage($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $contents = '', $writeMethod = self::PAGE_WRITE_UPDATE, $leaseId = null, $additionalHeaders = array())
  1038 	{
  1100 	{
  1039 		if ($containerName === '') {
  1101 		if ($containerName === '') {
  1040 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1102 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1041 		}
  1103 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1042 		if (!self::isValidContainerName($containerName)) {
  1104 		}
       
  1105 		if (!self::isValidContainerName($containerName)) {
       
  1106 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1043 			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.');
  1107 			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.');
  1044 		}
  1108 		}
  1045 		if ($blobName === '') {
  1109 		if ($blobName === '') {
       
  1110 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1046 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1111 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1047 		}
  1112 		}
  1048 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1113 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1114 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1049 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1115 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1050 		}
  1116 		}
  1051 		if ($startByteOffset % 512 != 0) {
  1117 		if ($startByteOffset % 512 != 0) {
       
  1118 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1052 			throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
  1119 			throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
  1053 		}
  1120 		}
  1054 		if (($endByteOffset + 1) % 512 != 0) {
  1121 		if (($endByteOffset + 1) % 512 != 0) {
       
  1122 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1055 			throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
  1123 			throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
  1056 		}
  1124 		}
  1057 
  1125 
  1058 		// Determine size
  1126 		// Determine size
  1059 		$size = strlen($contents);
  1127 		$size = strlen($contents);
  1060 		if ($size >= self::MAX_BLOB_TRANSFER_SIZE) {
  1128 		if ($size >= self::MAX_BLOB_TRANSFER_SIZE) {
       
  1129 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1061 			throw new Zend_Service_WindowsAzure_Exception('Page blob size must not be larger than ' + self::MAX_BLOB_TRANSFER_SIZE . ' bytes.');
  1130 			throw new Zend_Service_WindowsAzure_Exception('Page blob size must not be larger than ' + self::MAX_BLOB_TRANSFER_SIZE . ' bytes.');
  1062 		}
  1131 		}
  1063 
  1132 
  1064 		// Create metadata headers
  1133 		// Create metadata headers
  1065 		$headers = array();
  1134 		$headers = array();
  1066 		if ($leaseId !== null) {
  1135 		if (!is_null($leaseId)) {
  1067 			$headers['x-ms-lease-id'] = $leaseId;
  1136 			$headers['x-ms-lease-id'] = $leaseId;
  1068 		}
  1137 		}
  1069 
  1138 
  1070 		// Additional headers?
  1139 		// Additional headers?
  1071 		foreach ($additionalHeaders as $key => $value) {
  1140 		foreach ($additionalHeaders as $key => $value) {
  1082 		$resourceName = self::createResourceName($containerName , $blobName);
  1151 		$resourceName = self::createResourceName($containerName , $blobName);
  1083 
  1152 
  1084 		// Perform request
  1153 		// Perform request
  1085 		$response = $this->_performRequest($resourceName, '?comp=page', Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1154 		$response = $this->_performRequest($resourceName, '?comp=page', Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1086 		if (!$response->isSuccessful()) {
  1155 		if (!$response->isSuccessful()) {
       
  1156 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1087 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1157 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1088 		}
  1158 		}
  1089 	}
  1159 	}
  1090 
  1160 
  1091 	/**
  1161 	/**
  1100 	 * @throws Zend_Service_WindowsAzure_Exception
  1170 	 * @throws Zend_Service_WindowsAzure_Exception
  1101 	 */
  1171 	 */
  1102 	public function getPageRegions($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $leaseId = null)
  1172 	public function getPageRegions($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $leaseId = null)
  1103 	{
  1173 	{
  1104 		if ($containerName === '') {
  1174 		if ($containerName === '') {
  1105 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1175 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1106 		}
  1176 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1107 		if (!self::isValidContainerName($containerName)) {
  1177 		}
       
  1178 		if (!self::isValidContainerName($containerName)) {
       
  1179 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1108 			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.');
  1180 			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.');
  1109 		}
  1181 		}
  1110 		if ($blobName === '') {
  1182 		if ($blobName === '') {
       
  1183 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1111 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1184 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1112 		}
  1185 		}
  1113 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1186 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1187 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1114 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1188 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1115 		}
  1189 		}
  1116 		if ($startByteOffset % 512 != 0) {
  1190 		if ($startByteOffset % 512 != 0) {
       
  1191 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1117 			throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
  1192 			throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
  1118 		}
  1193 		}
  1119 		if ($endByteOffset > 0 && ($endByteOffset + 1) % 512 != 0) {
  1194 		if ($endByteOffset > 0 && ($endByteOffset + 1) % 512 != 0) {
       
  1195 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1120 			throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
  1196 			throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
  1121 		}
  1197 		}
  1122 
  1198 
  1123 		// Create metadata headers
  1199 		// Create metadata headers
  1124 		$headers = array();
  1200 		$headers = array();
  1125 		if ($leaseId !== null) {
  1201 		if (!is_null($leaseId)) {
  1126 			$headers['x-ms-lease-id'] = $leaseId;
  1202 			$headers['x-ms-lease-id'] = $leaseId;
  1127 		}
  1203 		}
  1128 
  1204 
  1129 		// Specify range?
  1205 		// Specify range?
  1130 		if ($endByteOffset > 0) {
  1206 		if ($endByteOffset > 0) {
  1142 			if (count($result->PageRange) > 1) {
  1218 			if (count($result->PageRange) > 1) {
  1143 				$xmlRanges = $result->PageRange;
  1219 				$xmlRanges = $result->PageRange;
  1144 			} else {
  1220 			} else {
  1145 				$xmlRanges = array($result->PageRange);
  1221 				$xmlRanges = array($result->PageRange);
  1146 			}
  1222 			}
  1147 
  1223 			
       
  1224 			
  1148 			$ranges = array();
  1225 			$ranges = array();
       
  1226 			
  1149 			for ($i = 0; $i < count($xmlRanges); $i++) {
  1227 			for ($i = 0; $i < count($xmlRanges); $i++) {
  1150 				$ranges[] = new Zend_Service_WindowsAzure_Storage_PageRegionInstance(
  1228 				$ranges[] = new Zend_Service_WindowsAzure_Storage_PageRegionInstance(
  1151 				(int)$xmlRanges[$i]->Start,
  1229 				(int)$xmlRanges[$i]->Start,
  1152 				(int)$xmlRanges[$i]->End
  1230 				(int)$xmlRanges[$i]->End
  1153 				);
  1231 				);
  1154 			}
  1232 			}
  1155 			 
  1233 			 
  1156 			return $ranges;
  1234 			return $ranges;
  1157 		} else {
  1235 		} else {
       
  1236 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1158 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1237 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1159 		}
  1238 		}
  1160 	}
  1239 	}
  1161 		
  1240 		
  1162 	/**
  1241 	/**
  1174 	 * @throws Zend_Service_WindowsAzure_Exception
  1253 	 * @throws Zend_Service_WindowsAzure_Exception
  1175 	 */
  1254 	 */
  1176 	public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $sourceSnapshotId = null, $destinationLeaseId = null, $additionalHeaders = array())
  1255 	public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $sourceSnapshotId = null, $destinationLeaseId = null, $additionalHeaders = array())
  1177 	{
  1256 	{
  1178 		if ($sourceContainerName === '') {
  1257 		if ($sourceContainerName === '') {
       
  1258 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1179 			throw new Zend_Service_WindowsAzure_Exception('Source container name is not specified.');
  1259 			throw new Zend_Service_WindowsAzure_Exception('Source container name is not specified.');
  1180 		}
  1260 		}
  1181 		if (!self::isValidContainerName($sourceContainerName)) {
  1261 		if (!self::isValidContainerName($sourceContainerName)) {
       
  1262 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1182 			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.');
  1263 			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.');
  1183 		}
  1264 		}
  1184 		if ($sourceBlobName === '') {
  1265 		if ($sourceBlobName === '') {
       
  1266 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1185 			throw new Zend_Service_WindowsAzure_Exception('Source blob name is not specified.');
  1267 			throw new Zend_Service_WindowsAzure_Exception('Source blob name is not specified.');
  1186 		}
  1268 		}
  1187 		if ($destinationContainerName === '') {
  1269 		if ($destinationContainerName === '') {
       
  1270 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1188 			throw new Zend_Service_WindowsAzure_Exception('Destination container name is not specified.');
  1271 			throw new Zend_Service_WindowsAzure_Exception('Destination container name is not specified.');
  1189 		}
  1272 		}
  1190 		if (!self::isValidContainerName($destinationContainerName)) {
  1273 		if (!self::isValidContainerName($destinationContainerName)) {
       
  1274 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1191 			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.');
  1275 			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.');
  1192 		}
  1276 		}
  1193 		if ($destinationBlobName === '') {
  1277 		if ($destinationBlobName === '') {
       
  1278 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1194 			throw new Zend_Service_WindowsAzure_Exception('Destination blob name is not specified.');
  1279 			throw new Zend_Service_WindowsAzure_Exception('Destination blob name is not specified.');
  1195 		}
  1280 		}
  1196 		if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false) {
  1281 		if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false) {
       
  1282 		require_once 'Zend/Service/WindowsAzure/Exception.php';
  1197 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1283 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1198 		}
  1284 		}
  1199 		if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false) {
  1285 		if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false) {
       
  1286 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1200 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1287 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1201 		}
  1288 		}
  1202 
  1289 
  1203 		// Create metadata headers
  1290 		// Create metadata headers
  1204 		$headers = array();
  1291 		$headers = array();
  1205 		if ($destinationLeaseId !== null) {
  1292 		if (!is_null($destinationLeaseId)) {
  1206 			$headers['x-ms-lease-id'] = $destinationLeaseId;
  1293 			$headers['x-ms-lease-id'] = $destinationLeaseId;
  1207 		}
  1294 		}
  1208 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
  1295 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
  1209 
  1296 
  1210 		// Additional headers?
  1297 		// Additional headers?
  1212 			$headers[$key] = $value;
  1299 			$headers[$key] = $value;
  1213 		}
  1300 		}
  1214 
  1301 
  1215 		// Resource names
  1302 		// Resource names
  1216 		$sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName);
  1303 		$sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName);
  1217 		if ($sourceSnapshotId !== null) {
  1304 		if (!is_null($sourceSnapshotId)) {
  1218 			$sourceResourceName .= '?snapshot=' . $sourceSnapshotId;
  1305 			$sourceResourceName .= '?snapshot=' . $sourceSnapshotId;
  1219 		}
  1306 		}
  1220 		$destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName);
  1307 		$destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName);
  1221 
  1308 
  1222 		// Set source blob
  1309 		// Set source blob
  1223 		$headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName;
  1310 		$headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName;
  1224 
  1311 
  1225 		// Perform request
  1312 		// Perform request
  1226 		$response = $this->_performRequest($destinationResourceName, '', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1313 		$response = $this->_performRequest($destinationResourceName, '', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1227 		if ($response->isSuccessful()) {
  1314 		if ($response->isSuccessful()) {
       
  1315 			
  1228 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1316 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1229 			$destinationContainerName,
  1317 			$destinationContainerName,
  1230 			$destinationBlobName,
  1318 			$destinationBlobName,
  1231 			null,
  1319 			null,
  1232 			$response->getHeader('Etag'),
  1320 			$response->getHeader('Etag'),
  1238 				'',
  1326 				'',
  1239 			false,
  1327 			false,
  1240 			$metadata
  1328 			$metadata
  1241 			);
  1329 			);
  1242 		} else {
  1330 		} else {
       
  1331 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1243 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1332 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1244 		}
  1333 		}
  1245 	}
  1334 	}
  1246 
  1335 
  1247 	/**
  1336 	/**
  1256 	 * @throws Zend_Service_WindowsAzure_Exception
  1345 	 * @throws Zend_Service_WindowsAzure_Exception
  1257 	 */
  1346 	 */
  1258 	public function getBlob($containerName = '', $blobName = '', $localFileName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1347 	public function getBlob($containerName = '', $blobName = '', $localFileName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1259 	{
  1348 	{
  1260 		if ($containerName === '') {
  1349 		if ($containerName === '') {
  1261 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1350 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1262 		}
  1351 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1263 		if (!self::isValidContainerName($containerName)) {
  1352 		}
       
  1353 		if (!self::isValidContainerName($containerName)) {
       
  1354 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1264 			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.');
  1355 			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.');
  1265 		}
  1356 		}
  1266 		if ($blobName === '') {
  1357 		if ($blobName === '') {
       
  1358 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1267 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1359 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1268 		}
  1360 		}
  1269 		if ($localFileName === '') {
  1361 		if ($localFileName === '') {
       
  1362 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1270 			throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
  1363 			throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.');
  1271 		}
  1364 		}
  1272 
  1365 
  1273 		// Fetch data
  1366 		// Fetch data
  1274 		file_put_contents($localFileName, $this->getBlobData($containerName, $blobName, $snapshotId, $leaseId, $additionalHeaders));
  1367 		file_put_contents($localFileName, $this->getBlobData($containerName, $blobName, $snapshotId, $leaseId, $additionalHeaders));
  1286 	 * @throws Zend_Service_WindowsAzure_Exception
  1379 	 * @throws Zend_Service_WindowsAzure_Exception
  1287 	 */
  1380 	 */
  1288 	public function getBlobData($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1381 	public function getBlobData($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1289 	{
  1382 	{
  1290 		if ($containerName === '') {
  1383 		if ($containerName === '') {
  1291 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1384 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1292 		}
  1385 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1293 		if (!self::isValidContainerName($containerName)) {
  1386 		}
       
  1387 		if (!self::isValidContainerName($containerName)) {
       
  1388 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1294 			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.');
  1389 			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.');
  1295 		}
  1390 		}
  1296 		if ($blobName === '') {
  1391 		if ($blobName === '') {
       
  1392 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1297 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1393 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1298 		}
  1394 		}
  1299 
  1395 
  1300 		// Build query string
  1396 		// Build query string
  1301 		$queryString = array();
  1397 		$queryString = array();
  1302 		if ($snapshotId !== null) {
  1398 		if (!is_null($snapshotId)) {
  1303 			$queryString[] = 'snapshot=' . $snapshotId;
  1399 			$queryString[] = 'snapshot=' . $snapshotId;
  1304 		}
  1400 		}
  1305 		$queryString = self::createQueryStringFromArray($queryString);
  1401 		$queryString = self::createQueryStringFromArray($queryString);
  1306 
  1402 
  1307 		// Additional headers?
  1403 		// Additional headers?
  1308 		$headers = array();
  1404 		$headers = array();
  1309 		if ($leaseId !== null) {
  1405 		if (!is_null($leaseId)) {
  1310 			$headers['x-ms-lease-id'] = $leaseId;
  1406 			$headers['x-ms-lease-id'] = $leaseId;
  1311 		}
  1407 		}
  1312 		foreach ($additionalHeaders as $key => $value) {
  1408 		foreach ($additionalHeaders as $key => $value) {
  1313 			$headers[$key] = $value;
  1409 			$headers[$key] = $value;
  1314 		}
  1410 		}
  1319 		// Perform request
  1415 		// Perform request
  1320 		$response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
  1416 		$response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
  1321 		if ($response->isSuccessful()) {
  1417 		if ($response->isSuccessful()) {
  1322 			return $response->getBody();
  1418 			return $response->getBody();
  1323 		} else {
  1419 		} else {
       
  1420 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1324 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1421 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1325 		}
  1422 		}
  1326 	}
  1423 	}
  1327 
  1424 
  1328 	/**
  1425 	/**
  1337 	 * @throws Zend_Service_WindowsAzure_Exception
  1434 	 * @throws Zend_Service_WindowsAzure_Exception
  1338 	 */
  1435 	 */
  1339 	public function getBlobInstance($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1436 	public function getBlobInstance($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1340 	{
  1437 	{
  1341 		if ($containerName === '') {
  1438 		if ($containerName === '') {
  1342 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1439 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1343 		}
  1440 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1344 		if (!self::isValidContainerName($containerName)) {
  1441 		}
       
  1442 		if (!self::isValidContainerName($containerName)) {
       
  1443 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1345 			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.');
  1444 			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.');
  1346 		}
  1445 		}
  1347 		if ($blobName === '') {
  1446 		if ($blobName === '') {
       
  1447 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1348 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1448 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1349 		}
  1449 		}
  1350 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1450 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1451 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1351 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1452 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1352 		}
  1453 		}
  1353 
  1454 
  1354 		// Build query string
  1455 		// Build query string
  1355 		$queryString = array();
  1456 		$queryString = array();
  1356 		if ($snapshotId !== null) {
  1457 		if (!is_null($snapshotId)) {
  1357 			$queryString[] = 'snapshot=' . $snapshotId;
  1458 			$queryString[] = 'snapshot=' . $snapshotId;
  1358 		}
  1459 		}
  1359 		$queryString = self::createQueryStringFromArray($queryString);
  1460 		$queryString = self::createQueryStringFromArray($queryString);
  1360 		 
  1461 		 
  1361 		// Additional headers?
  1462 		// Additional headers?
  1362 		$headers = array();
  1463 		$headers = array();
  1363 		if ($leaseId !== null) {
  1464 		if (!is_null($leaseId)) {
  1364 			$headers['x-ms-lease-id'] = $leaseId;
  1465 			$headers['x-ms-lease-id'] = $leaseId;
  1365 		}
  1466 		}
  1366 		foreach ($additionalHeaders as $key => $value) {
  1467 		foreach ($additionalHeaders as $key => $value) {
  1367 			$headers[$key] = $value;
  1468 			$headers[$key] = $value;
  1368 		}
  1469 		}
  1373 		// Perform request
  1474 		// Perform request
  1374 		$response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::HEAD, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
  1475 		$response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::HEAD, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
  1375 		if ($response->isSuccessful()) {
  1476 		if ($response->isSuccessful()) {
  1376 			// Parse metadata
  1477 			// Parse metadata
  1377 			$metadata = $this->_parseMetadataHeaders($response->getHeaders());
  1478 			$metadata = $this->_parseMetadataHeaders($response->getHeaders());
  1378 
  1479 			
  1379 			// Return blob
  1480 			// Return blob
  1380 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1481 			return new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1381 			$containerName,
  1482 				$containerName,
  1382 			$blobName,
  1483 				$blobName,
  1383 			$snapshotId,
  1484 				$snapshotId,
  1384 			$response->getHeader('Etag'),
  1485 				$response->getHeader('Etag'),
  1385 			$response->getHeader('Last-modified'),
  1486 				$response->getHeader('Last-modified'),
  1386 			$this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
  1487 				$this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
  1387 			$response->getHeader('Content-Length'),
  1488 				$response->getHeader('Content-Length'),
  1388 			$response->getHeader('Content-Type'),
  1489 				$response->getHeader('Content-Type'),
  1389 			$response->getHeader('Content-Encoding'),
  1490 				$response->getHeader('Content-Encoding'),
  1390 			$response->getHeader('Content-Language'),
  1491 				$response->getHeader('Content-Language'),
  1391 			$response->getHeader('Cache-Control'),
  1492 				$response->getHeader('Cache-Control'),
  1392 			$response->getHeader('x-ms-blob-type'),
  1493 				$response->getHeader('x-ms-blob-type'),
  1393 			$response->getHeader('x-ms-lease-status'),
  1494 				$response->getHeader('x-ms-lease-status'),
  1394 			false,
  1495 				false,
  1395 			$metadata
  1496 				$metadata
  1396 			);
  1497 			);
  1397 		} else {
  1498 		} else {
       
  1499 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1398 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1500 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1399 		}
  1501 		}
  1400 	}
  1502 	}
  1401 
  1503 
  1402 	/**
  1504 	/**
  1410 	 * @throws Zend_Service_WindowsAzure_Exception
  1512 	 * @throws Zend_Service_WindowsAzure_Exception
  1411 	 */
  1513 	 */
  1412 	public function getBlobMetadata($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null)
  1514 	public function getBlobMetadata($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null)
  1413 	{
  1515 	{
  1414 		if ($containerName === '') {
  1516 		if ($containerName === '') {
  1415 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1517 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1416 		}
  1518 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1417 		if (!self::isValidContainerName($containerName)) {
  1519 		}
       
  1520 		if (!self::isValidContainerName($containerName)) {
       
  1521 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1418 			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.');
  1522 			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.');
  1419 		}
  1523 		}
  1420 		if ($blobName === '') {
  1524 		if ($blobName === '') {
       
  1525 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1421 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1526 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1422 		}
  1527 		}
  1423 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1528 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1529 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1424 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1530 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1425 		}
  1531 		}
  1426 
  1532 
  1427 		return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId)->Metadata;
  1533 		return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId)->Metadata;
  1428 	}
  1534 	}
  1440 	 * @throws Zend_Service_WindowsAzure_Exception
  1546 	 * @throws Zend_Service_WindowsAzure_Exception
  1441 	 */
  1547 	 */
  1442 	public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
  1548 	public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
  1443 	{
  1549 	{
  1444 		if ($containerName === '') {
  1550 		if ($containerName === '') {
  1445 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1551 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1446 		}
  1552 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1447 		if (!self::isValidContainerName($containerName)) {
  1553 		}
       
  1554 		if (!self::isValidContainerName($containerName)) {
       
  1555 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1448 			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.');
  1556 			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.');
  1449 		}
  1557 		}
  1450 		if ($blobName === '') {
  1558 		if ($blobName === '') {
       
  1559 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1451 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1560 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1452 		}
  1561 		}
  1453 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1562 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1563 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1454 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1564 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1455 		}
  1565 		}
  1456 		if (count($metadata) == 0) {
  1566 		if (count($metadata) == 0) {
  1457 			return;
  1567 			return;
  1458 		}
  1568 		}
  1459 
  1569 
  1460 		// Create metadata headers
  1570 		// Create metadata headers
  1461 		$headers = array();
  1571 		$headers = array();
  1462 		if ($leaseId !== null) {
  1572 		if (!is_null($leaseId)) {
  1463 			$headers['x-ms-lease-id'] = $leaseId;
  1573 			$headers['x-ms-lease-id'] = $leaseId;
  1464 		}
  1574 		}
  1465 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
  1575 		$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
  1466 
  1576 
  1467 		// Additional headers?
  1577 		// Additional headers?
  1470 		}
  1580 		}
  1471 
  1581 
  1472 		// Perform request
  1582 		// Perform request
  1473 		$response = $this->_performRequest($containerName . '/' . $blobName, '?comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1583 		$response = $this->_performRequest($containerName . '/' . $blobName, '?comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1474 		if (!$response->isSuccessful()) {
  1584 		if (!$response->isSuccessful()) {
       
  1585 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1475 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1586 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1476 		}
  1587 		}
  1477 	}
  1588 	}
  1478 
  1589 
  1479 	/**
  1590 	/**
  1488 	 * @throws Zend_Service_WindowsAzure_Exception
  1599 	 * @throws Zend_Service_WindowsAzure_Exception
  1489 	 */
  1600 	 */
  1490 	public function setBlobProperties($containerName = '', $blobName = '', $leaseId = null, $additionalHeaders = array())
  1601 	public function setBlobProperties($containerName = '', $blobName = '', $leaseId = null, $additionalHeaders = array())
  1491 	{
  1602 	{
  1492 		if ($containerName === '') {
  1603 		if ($containerName === '') {
  1493 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1604 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1494 		}
  1605 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1495 		if (!self::isValidContainerName($containerName)) {
  1606 		}
       
  1607 		if (!self::isValidContainerName($containerName)) {
       
  1608 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1496 			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.');
  1609 			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.');
  1497 		}
  1610 		}
  1498 		if ($blobName === '') {
  1611 		if ($blobName === '') {
       
  1612 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1499 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1613 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1500 		}
  1614 		}
  1501 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1615 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1616 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1502 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1617 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1503 		}
  1618 		}
  1504 		if (count($additionalHeaders) == 0) {
  1619 		if (count($additionalHeaders) == 0) {
       
  1620 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1505 			throw new Zend_Service_WindowsAzure_Exception('No additional headers are specified.');
  1621 			throw new Zend_Service_WindowsAzure_Exception('No additional headers are specified.');
  1506 		}
  1622 		}
  1507 
  1623 
  1508 		// Create headers
  1624 		// Create headers
  1509 		$headers = array();
  1625 		$headers = array();
  1510 
  1626 
  1511 		// Lease set?
  1627 		// Lease set?
  1512 		if ($leaseId !== null) {
  1628 		if (!is_null($leaseId)) {
  1513 			$headers['x-ms-lease-id'] = $leaseId;
  1629 			$headers['x-ms-lease-id'] = $leaseId;
  1514 		}
  1630 		}
  1515 
  1631 
  1516 		// Additional headers?
  1632 		// Additional headers?
  1517 		foreach ($additionalHeaders as $key => $value) {
  1633 		foreach ($additionalHeaders as $key => $value) {
  1519 		}
  1635 		}
  1520 
  1636 
  1521 		// Perform request
  1637 		// Perform request
  1522 		$response = $this->_performRequest($containerName . '/' . $blobName, '?comp=properties', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1638 		$response = $this->_performRequest($containerName . '/' . $blobName, '?comp=properties', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1523 		if (!$response->isSuccessful()) {
  1639 		if (!$response->isSuccessful()) {
       
  1640 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1524 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1641 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1525 		}
  1642 		}
  1526 	}
  1643 	}
  1527 
  1644 
  1528 	/**
  1645 	/**
  1536 	 * @throws Zend_Service_WindowsAzure_Exception
  1653 	 * @throws Zend_Service_WindowsAzure_Exception
  1537 	 */
  1654 	 */
  1538 	public function getBlobProperties($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null)
  1655 	public function getBlobProperties($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null)
  1539 	{
  1656 	{
  1540 		if ($containerName === '') {
  1657 		if ($containerName === '') {
  1541 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1658 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1542 		}
  1659 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1543 		if (!self::isValidContainerName($containerName)) {
  1660 		}
       
  1661 		if (!self::isValidContainerName($containerName)) {
       
  1662 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1544 			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.');
  1663 			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.');
  1545 		}
  1664 		}
  1546 		if ($blobName === '') {
  1665 		if ($blobName === '') {
       
  1666 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1547 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1667 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1548 		}
  1668 		}
  1549 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1669 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1670 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1550 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1671 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1551 		}
  1672 		}
  1552 
  1673 
  1553 		return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId);
  1674 		return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId);
  1554 	}
  1675 	}
  1564 	 * @throws Zend_Service_WindowsAzure_Exception
  1685 	 * @throws Zend_Service_WindowsAzure_Exception
  1565 	 */
  1686 	 */
  1566 	public function deleteBlob($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1687 	public function deleteBlob($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
  1567 	{
  1688 	{
  1568 		if ($containerName === '') {
  1689 		if ($containerName === '') {
  1569 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1690 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1570 		}
  1691 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1571 		if (!self::isValidContainerName($containerName)) {
  1692 		}
       
  1693 		if (!self::isValidContainerName($containerName)) {
       
  1694 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1572 			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.');
  1695 			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.');
  1573 		}
  1696 		}
  1574 		if ($blobName === '') {
  1697 		if ($blobName === '') {
       
  1698 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1575 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1699 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1576 		}
  1700 		}
  1577 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1701 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1702 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1578 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1703 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1579 		}
  1704 		}
  1580 
  1705 
  1581 		// Build query string
  1706 		// Build query string
  1582 		$queryString = array();
  1707 		$queryString = array();
  1583 		if ($snapshotId !== null) {
  1708 		if (!is_null($snapshotId)) {
  1584 			$queryString[] = 'snapshot=' . $snapshotId;
  1709 			$queryString[] = 'snapshot=' . $snapshotId;
  1585 		}
  1710 		}
  1586 		$queryString = self::createQueryStringFromArray($queryString);
  1711 		$queryString = self::createQueryStringFromArray($queryString);
  1587 			
  1712 			
  1588 		// Additional headers?
  1713 		// Additional headers?
  1589 		$headers = array();
  1714 		$headers = array();
  1590 		if ($leaseId !== null) {
  1715 		if (!is_null($leaseId)) {
  1591 			$headers['x-ms-lease-id'] = $leaseId;
  1716 			$headers['x-ms-lease-id'] = $leaseId;
  1592 		}
  1717 		}
  1593 		foreach ($additionalHeaders as $key => $value) {
  1718 		foreach ($additionalHeaders as $key => $value) {
  1594 			$headers[$key] = $value;
  1719 			$headers[$key] = $value;
  1595 		}
  1720 		}
  1598 		$resourceName = self::createResourceName($containerName , $blobName);
  1723 		$resourceName = self::createResourceName($containerName , $blobName);
  1599 
  1724 
  1600 		// Perform request
  1725 		// Perform request
  1601 		$response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1726 		$response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1602 		if (!$response->isSuccessful()) {
  1727 		if (!$response->isSuccessful()) {
       
  1728 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1603 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1729 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1604 		}
  1730 		}
  1605 	}
  1731 	}
  1606 
  1732 
  1607 	/**
  1733 	/**
  1615 	 * @throws Zend_Service_WindowsAzure_Exception
  1741 	 * @throws Zend_Service_WindowsAzure_Exception
  1616 	 */
  1742 	 */
  1617 	public function snapshotBlob($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array())
  1743 	public function snapshotBlob($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array())
  1618 	{
  1744 	{
  1619 		if ($containerName === '') {
  1745 		if ($containerName === '') {
  1620 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1746 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1621 		}
  1747 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1622 		if (!self::isValidContainerName($containerName)) {
  1748 		}
       
  1749 		if (!self::isValidContainerName($containerName)) {
       
  1750 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1623 			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.');
  1751 			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.');
  1624 		}
  1752 		}
  1625 		if ($blobName === '') {
  1753 		if ($blobName === '') {
       
  1754 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1626 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1755 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1627 		}
  1756 		}
  1628 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1757 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1758 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1629 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1759 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1630 		}
  1760 		}
  1631 
  1761 
  1632 		// Additional headers?
  1762 		// Additional headers?
  1633 		$headers = array();
  1763 		$headers = array();
  1641 		// Perform request
  1771 		// Perform request
  1642 		$response = $this->_performRequest($resourceName, '?comp=snapshot', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1772 		$response = $this->_performRequest($resourceName, '?comp=snapshot', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1643 		if ($response->isSuccessful()) {
  1773 		if ($response->isSuccessful()) {
  1644 			return $response->getHeader('x-ms-snapshot');
  1774 			return $response->getHeader('x-ms-snapshot');
  1645 		} else {
  1775 		} else {
       
  1776 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1646 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1777 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1647 		}
  1778 		}
  1648 	}
  1779 	}
  1649 
  1780 
  1650 	/**
  1781 	/**
  1658 	 * @throws Zend_Service_WindowsAzure_Exception
  1789 	 * @throws Zend_Service_WindowsAzure_Exception
  1659 	 */
  1790 	 */
  1660 	public function leaseBlob($containerName = '', $blobName = '', $leaseAction = self::LEASE_ACQUIRE, $leaseId = null)
  1791 	public function leaseBlob($containerName = '', $blobName = '', $leaseAction = self::LEASE_ACQUIRE, $leaseId = null)
  1661 	{
  1792 	{
  1662 		if ($containerName === '') {
  1793 		if ($containerName === '') {
  1663 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1794 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1664 		}
  1795 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1665 		if (!self::isValidContainerName($containerName)) {
  1796 		}
       
  1797 		if (!self::isValidContainerName($containerName)) {
       
  1798 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1666 			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.');
  1799 			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.');
  1667 		}
  1800 		}
  1668 		if ($blobName === '') {
  1801 		if ($blobName === '') {
       
  1802 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1669 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1803 			throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.');
  1670 		}
  1804 		}
  1671 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
  1805 		if ($containerName === '$root' && strpos($blobName, '/') !== false) {
       
  1806 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1672 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1807 			throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1673 		}
  1808 		}
  1674 
  1809 
  1675 		// Additional headers?
  1810 		// Additional headers?
  1676 		$headers = array();
  1811 		$headers = array();
  1677 		$headers['x-ms-lease-action'] = strtolower($leaseAction);
  1812 		$headers['x-ms-lease-action'] = strtolower($leaseAction);
  1678 		if ($leaseId !== null) {
  1813 		if (!is_null($leaseId)) {
  1679 			$headers['x-ms-lease-id'] = $leaseId;
  1814 			$headers['x-ms-lease-id'] = $leaseId;
  1680 		}
  1815 		}
  1681 
  1816 
  1682 		// Resource name
  1817 		// Resource name
  1683 		$resourceName = self::createResourceName($containerName , $blobName);
  1818 		$resourceName = self::createResourceName($containerName , $blobName);
  1684 
  1819 
  1685 		// Perform request
  1820 		// Perform request
  1686 		$response = $this->_performRequest($resourceName, '?comp=lease', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
  1821 		$response = $this->_performRequest($resourceName, '?comp=lease', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
       
  1822 		
       
  1823 		
       
  1824 		
  1687 		if ($response->isSuccessful()) {
  1825 		if ($response->isSuccessful()) {
  1688 			return new Zend_Service_WindowsAzure_Storage_LeaseInstance(
  1826 			return new Zend_Service_WindowsAzure_Storage_LeaseInstance(
  1689 			$containerName,
  1827 			$containerName,
  1690 			$blobName,
  1828 			$blobName,
  1691 			$response->getHeader('x-ms-lease-id'),
  1829 			$response->getHeader('x-ms-lease-id'),
  1692 			$response->getHeader('x-ms-lease-time'));
  1830 			$response->getHeader('x-ms-lease-time'));
  1693 		} else {
  1831 		} else {
       
  1832 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1694 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1833 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1695 		}
  1834 		}
  1696 	}
  1835 	}
  1697 
  1836 
  1698 	/**
  1837 	/**
  1709 	 * @throws Zend_Service_WindowsAzure_Exception
  1848 	 * @throws Zend_Service_WindowsAzure_Exception
  1710 	 */
  1849 	 */
  1711 	public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
  1850 	public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
  1712 	{
  1851 	{
  1713 		if ($containerName === '') {
  1852 		if ($containerName === '') {
  1714 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1853 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1715 		}
  1854 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1716 		if (!self::isValidContainerName($containerName)) {
  1855 		}
       
  1856 		if (!self::isValidContainerName($containerName)) {
       
  1857 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1717 			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.');
  1858 			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.');
  1718 		}
  1859 		}
  1719 			
  1860 			
  1720 		// Build query string
  1861 		// Build query string
  1721 		$queryString = array('restype=container', 'comp=list');
  1862 		$queryString = array('restype=container', 'comp=list');
  1722 		if ($prefix !== null) {
  1863 		if (!is_null($prefix)) {
  1723 			$queryString[] = 'prefix=' . $prefix;
  1864 			$queryString[] = 'prefix=' . $prefix;
  1724 		}
  1865 		}
  1725 		if ($delimiter !== '') {
  1866 		if ($delimiter !== '') {
  1726 			$queryString[] = 'delimiter=' . $delimiter;
  1867 			$queryString[] = 'delimiter=' . $delimiter;
  1727 		}
  1868 		}
  1728 		if ($maxResults !== null) {
  1869 		if (!is_null($maxResults)) {
  1729 			$queryString[] = 'maxresults=' . $maxResults;
  1870 			$queryString[] = 'maxresults=' . $maxResults;
  1730 		}
  1871 		}
  1731 		if ($marker !== null) {
  1872 		if (!is_null($marker)) {
  1732 			$queryString[] = 'marker=' . $marker;
  1873 			$queryString[] = 'marker=' . $marker;
  1733 		}
  1874 		}
  1734 		if ($include !== null) {
  1875 		if (!is_null($include)) {
  1735 			$queryString[] = 'include=' . $include;
  1876 			$queryString[] = 'include=' . $include;
  1736 		}
  1877 		}
  1737 		$queryString = self::createQueryStringFromArray($queryString);
  1878 		$queryString = self::createQueryStringFromArray($queryString);
  1738 
  1879 
  1739 		// Perform request
  1880 		// Perform request
  1740 		$response = $this->_performRequest($containerName, $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST);
  1881 		$response = $this->_performRequest($containerName, $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST);
  1741 		if ($response->isSuccessful()) {
  1882 		if ($response->isSuccessful()) {
  1742 			// Return value
  1883 			// Return value
  1743 			$blobs = array();
  1884 			$blobs = array();
  1744 
  1885 	
  1745 			// Blobs
  1886 			// Blobs
  1746 			$xmlBlobs = $this->_parseResponse($response)->Blobs->Blob;
  1887 			$xmlBlobs = $this->_parseResponse($response)->Blobs->Blob;
  1747 			if ($xmlBlobs !== null) {
  1888 			if (!is_null($xmlBlobs)) {
       
  1889 				
  1748 				for ($i = 0; $i < count($xmlBlobs); $i++) {
  1890 				for ($i = 0; $i < count($xmlBlobs); $i++) {
  1749 					$properties = (array)$xmlBlobs[$i]->Properties;
  1891 					$properties = (array)$xmlBlobs[$i]->Properties;
  1750 						
  1892 						
  1751 					$blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1893 					$blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1752 					$containerName,
  1894 					$containerName,
  1769 			}
  1911 			}
  1770 				
  1912 				
  1771 			// Blob prefixes (folders)
  1913 			// Blob prefixes (folders)
  1772 			$xmlBlobs = $this->_parseResponse($response)->Blobs->BlobPrefix;
  1914 			$xmlBlobs = $this->_parseResponse($response)->Blobs->BlobPrefix;
  1773 				
  1915 				
  1774 			if ($xmlBlobs !== null) {
  1916 			if (!is_null($xmlBlobs)) {
       
  1917 				
  1775 				for ($i = 0; $i < count($xmlBlobs); $i++) {
  1918 				for ($i = 0; $i < count($xmlBlobs); $i++) {
  1776 					$blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1919 					$blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance(
  1777 					$containerName,
  1920 					$containerName,
  1778 					(string)$xmlBlobs[$i]->Name,
  1921 					(string)$xmlBlobs[$i]->Name,
  1779 					null,
  1922 					null,
  1794 			}
  1937 			}
  1795 				
  1938 				
  1796 			// More blobs?
  1939 			// More blobs?
  1797 			$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
  1940 			$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
  1798 			$currentResultCount = $currentResultCount + count($blobs);
  1941 			$currentResultCount = $currentResultCount + count($blobs);
  1799 			if ($maxResults !== null && $currentResultCount < $maxResults) {
  1942 			if (!is_null($maxResults) && $currentResultCount < $maxResults) {
  1800 				if ($xmlMarker !== null && $xmlMarker != '') {
  1943 				if (!is_null($xmlMarker) && $xmlMarker != '') {
  1801 					$blobs = array_merge($blobs, $this->listBlobs($containerName, $prefix, $delimiter, $maxResults, $marker, $include, $currentResultCount));
  1944 					$blobs = array_merge($blobs, $this->listBlobs($containerName, $prefix, $delimiter, $maxResults, $marker, $include, $currentResultCount));
  1802 				}
  1945 				}
  1803 			}
  1946 			}
  1804 			if ($maxResults !== null && count($blobs) > $maxResults) {
  1947 			if (!is_null($maxResults) && count($blobs) > $maxResults) {
  1805 				$blobs = array_slice($blobs, 0, $maxResults);
  1948 				$blobs = array_slice($blobs, 0, $maxResults);
  1806 			}
  1949 			}
  1807 				
  1950 				
  1808 			return $blobs;
  1951 			return $blobs;
  1809 		} else {
  1952 		} else {
       
  1953 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1810 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1954 			throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
  1811 		}
  1955 		}
  1812 	}
  1956 	}
  1813 
  1957 
  1814 	/**
  1958 	/**
  1824 	 * @return string
  1968 	 * @return string
  1825 	 */
  1969 	 */
  1826 	public function generateSharedAccessUrl($containerName = '', $blobName = '', $resource = 'b', $permissions = 'r', $start = '', $expiry = '', $identifier = '')
  1970 	public function generateSharedAccessUrl($containerName = '', $blobName = '', $resource = 'b', $permissions = 'r', $start = '', $expiry = '', $identifier = '')
  1827 	{
  1971 	{
  1828 		if ($containerName === '') {
  1972 		if ($containerName === '') {
  1829 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1973 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1830 		}
  1974 			throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.');
  1831 		if (!self::isValidContainerName($containerName)) {
  1975 		}
       
  1976 		if (!self::isValidContainerName($containerName)) {
       
  1977 			require_once 'Zend/Service/WindowsAzure/Exception.php';
  1832 			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.');
  1978 			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.');
  1833 		}
  1979 		}
  1834 
  1980 
  1835 		// Resource name
  1981 		// Resource name
  1836 		$resourceName = self::createResourceName($containerName , $blobName);
  1982 		$resourceName = self::createResourceName($containerName , $blobName);
  1887 	 *
  2033 	 *
  1888 	 * @param  string $name Protocol name
  2034 	 * @param  string $name Protocol name
  1889 	 */
  2035 	 */
  1890 	public function registerStreamWrapper($name = 'azure')
  2036 	public function registerStreamWrapper($name = 'azure')
  1891 	{
  2037 	{
  1892 		/**
       
  1893 		 * @see Zend_Service_WindowsAzure_Storage_Blob_Stream
       
  1894 		 */
       
  1895 		require_once 'Zend/Service/WindowsAzure/Storage/Blob/Stream.php';
       
  1896 
       
  1897 		stream_register_wrapper($name, 'Zend_Service_WindowsAzure_Storage_Blob_Stream');
  2038 		stream_register_wrapper($name, 'Zend_Service_WindowsAzure_Storage_Blob_Stream');
  1898 		$this->registerAsClient($name);
  2039 		$this->registerAsClient($name);
  1899 	}
  2040 	}
  1900 
  2041 
  1901 	/**
  2042 	/**