PageRenderTime 55ms CodeModel.GetById 18ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/codes-php/phpjakarta/WindowsAzure/Blob/BlobRestProxy.php

http://bukuphpjs.codeplex.com
PHP | 2337 lines | 1619 code | 215 blank | 503 comment | 41 complexity | 2aad45435059f20702f817393653a00f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2
   3/**
   4 * LICENSE: Licensed under the Apache License, Version 2.0 (the "License");
   5 * you may not use this file except in compliance with the License.
   6 * You may obtain a copy of the License at
   7 * http://www.apache.org/licenses/LICENSE-2.0
   8 *
   9 * Unless required by applicable law or agreed to in writing, software
  10 * distributed under the License is distributed on an "AS IS" BASIS,
  11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 * See the License for the specific language governing permissions and
  13 * limitations under the License.
  14 * 
  15 * PHP version 5
  16 *
  17 * @category  Microsoft
  18 * @package   WindowsAzure\Blob
  19 * @author    Azure PHP SDK <azurephpsdk@microsoft.com>
  20 * @copyright 2012 Microsoft Corporation
  21 * @license   http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
  22 * @link      https://github.com/windowsazure/azure-sdk-for-php
  23 */
  24
  25namespace WindowsAzure\Blob;
  26use WindowsAzure\Common\Internal\Utilities;
  27use WindowsAzure\Common\Internal\Resources;
  28use WindowsAzure\Common\Internal\Validate;
  29use WindowsAzure\Common\Models\ServiceProperties;
  30use WindowsAzure\Common\Internal\ServiceRestProxy;
  31use WindowsAzure\Blob\Internal\IBlob;
  32use WindowsAzure\Blob\Models\BlobServiceOptions;
  33use WindowsAzure\Common\Models\GetServicePropertiesResult;
  34use WindowsAzure\Blob\Models\ListContainersOptions;
  35use WindowsAzure\Blob\Models\ListContainersResult;
  36use WindowsAzure\Blob\Models\CreateContainerOptions;
  37use WindowsAzure\Blob\Models\GetContainerPropertiesResult;
  38use WindowsAzure\Blob\Models\GetContainerAclResult;
  39use WindowsAzure\Blob\Models\SetContainerMetadataOptions;
  40use WindowsAzure\Blob\Models\DeleteContainerOptions;
  41use WindowsAzure\Blob\Models\ListBlobsOptions;
  42use WindowsAzure\Blob\Models\ListBlobsResult;
  43use WindowsAzure\Blob\Models\BlobType;
  44use WindowsAzure\Blob\Models\CreateBlobOptions;
  45use WindowsAzure\Blob\Models\BlobProperties;
  46use WindowsAzure\Blob\Models\GetBlobPropertiesOptions;
  47use WindowsAzure\Blob\Models\GetBlobPropertiesResult;
  48use WindowsAzure\Blob\Models\SetBlobPropertiesOptions;
  49use WindowsAzure\Blob\Models\SetBlobPropertiesResult;
  50use WindowsAzure\Blob\Models\GetBlobMetadataOptions;
  51use WindowsAzure\Blob\Models\GetBlobMetadataResult;
  52use WindowsAzure\Blob\Models\SetBlobMetadataOptions;
  53use WindowsAzure\Blob\Models\SetBlobMetadataResult;
  54use WindowsAzure\Blob\Models\GetBlobOptions;
  55use WindowsAzure\Blob\Models\GetBlobResult;
  56use WindowsAzure\Blob\Models\DeleteBlobOptions;
  57use WindowsAzure\Blob\Models\LeaseMode;
  58use WindowsAzure\Blob\Models\AcquireLeaseOptions;
  59use WindowsAzure\Blob\Models\AcquireLeaseResult;
  60use WindowsAzure\Blob\Models\CreateBlobPagesOptions;
  61use WindowsAzure\Blob\Models\CreateBlobPagesResult;
  62use WindowsAzure\Blob\Models\PageWriteOption;
  63use WindowsAzure\Blob\Models\ListPageBlobRangesOptions;
  64use WindowsAzure\Blob\Models\ListPageBlobRangesResult;
  65use WindowsAzure\Blob\Models\CreateBlobBlockOptions;
  66use WindowsAzure\Blob\Models\CommitBlobBlocksOptions;
  67use WindowsAzure\Blob\Models\BlockList;
  68use WindowsAzure\Blob\Models\ListBlobBlocksOptions;
  69use WindowsAzure\Blob\Models\ListBlobBlocksResult;
  70use WindowsAzure\Blob\Models\CopyBlobOptions;
  71use WindowsAzure\Blob\Models\CreateBlobSnapshotOptions;
  72use WindowsAzure\Blob\Models\CreateBlobSnapshotResult;
  73use WindowsAzure\Blob\Models\PageRange;
  74use WindowsAzure\Blob\Models\CopyBlobResult;
  75
  76/**
  77 * This class constructs HTTP requests and receive HTTP responses for blob
  78 * service layer.
  79 *
  80 * @category  Microsoft
  81 * @package   WindowsAzure\Blob
  82 * @author    Azure PHP SDK <azurephpsdk@microsoft.com>
  83 * @copyright 2012 Microsoft Corporation
  84 * @license   http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
  85 * @version   Release: @package_version@
  86 * @link      https://github.com/windowsazure/azure-sdk-for-php
  87 */
  88class BlobRestProxy extends ServiceRestProxy implements IBlob
  89{
  90    /**
  91     * Gets the copy blob source name with specified parameters. 
  92     * 
  93     * @param string                 $containerName The name of the container. 
  94     * @param string                 $blobName      The name of the blob.
  95     * @param Models\CopyBlobOptions $options       The optional parameters.
  96     *
  97     * @return string 
  98     */
  99    private function _getCopyBlobSourceName($containerName, $blobName, $options)
 100    {
 101        $sourceName  = '/' . $this->getAccountName();
 102        $sourceName .= '/' . $this->_createPath($containerName, $blobName);
 103
 104        if (!is_null($options->getSourceSnapshot())) {
 105            $sourceName .= '?snapshot=' . $options->getSourceSnapshot();
 106        }
 107
 108        return $sourceName;
 109    }
 110    
 111    /**
 112     * Creates URI path for blob.
 113     * 
 114     * @param string $container The container name.
 115     * @param string $blob      The blob name.
 116     * 
 117     * @return string
 118     */
 119    private function _createPath($container, $blob)
 120    {
 121        // Empty container means accessing default container
 122        if (empty($container)) {
 123            return $blob;
 124        } else {
 125            return $container . '/' . $blob;
 126        }
 127    }
 128    
 129    /**
 130     * Creates GetBlobPropertiesResult from headers array.
 131     * 
 132     * @param array $headers The HTTP response headers array.
 133     * 
 134     * @return GetBlobPropertiesResult
 135     */
 136    private function _getBlobPropertiesResultFromResponse($headers)
 137    {
 138        $result     = new GetBlobPropertiesResult();
 139        $properties = new BlobProperties();
 140        $d          = $headers[Resources::LAST_MODIFIED];
 141        $bType      = $headers[Resources::X_MS_BLOB_TYPE];
 142        $cLength    = intval($headers[Resources::CONTENT_LENGTH]);
 143        $lStatus    = Utilities::tryGetValue($headers, Resources::X_MS_LEASE_STATUS);
 144        $cType      = Utilities::tryGetValue($headers, Resources::CONTENT_TYPE);
 145        $cMD5       = Utilities::tryGetValue($headers, Resources::CONTENT_MD5);
 146        $cEncoding  = Utilities::tryGetValue($headers, Resources::CONTENT_ENCODING);
 147        $cLanguage  = Utilities::tryGetValue($headers, Resources::CONTENT_LANGUAGE);
 148        $cControl   = Utilities::tryGetValue($headers, Resources::CACHE_CONTROL);
 149        $etag       = $headers[Resources::ETAG];
 150        $metadata   = $this->getMetadataArray($headers);
 151        
 152        if (array_key_exists(Resources::X_MS_BLOB_SEQUENCE_NUMBER, $headers)) {
 153            $sNumber = intval($headers[Resources::X_MS_BLOB_SEQUENCE_NUMBER]);
 154            $properties->setSequenceNumber($sNumber);
 155        }
 156        
 157        $properties->setBlobType($bType);
 158        $properties->setCacheControl($cControl);
 159        $properties->setContentEncoding($cEncoding);
 160        $properties->setContentLanguage($cLanguage);
 161        $properties->setContentLength($cLength);
 162        $properties->setContentMD5($cMD5);
 163        $properties->setContentType($cType);
 164        $properties->setETag($etag);
 165        $properties->setLastModified(Utilities::rfc1123ToDateTime($d));
 166        $properties->setLeaseStatus($lStatus);
 167        
 168        $result->setProperties($properties);
 169        $result->setMetadata($metadata);
 170        
 171        return $result;
 172    }
 173    
 174    /**
 175     * Helper method for getContainerProperties and getContainerMetadata.
 176     * 
 177     * @param string                    $container The container name.
 178     * @param Models\BlobServiceOptions $options   The optional parameters.
 179     * @param string                    $operation The operation string. Should be
 180     * 'metadata' to get metadata.
 181     * 
 182     * @return Models\GetContainerPropertiesResult
 183     */
 184    private function _getContainerPropertiesImpl($container, $options = null,
 185        $operation = null
 186    ) {
 187        Validate::isString($container, 'container');
 188        
 189        $method      = Resources::HTTP_GET;
 190        $headers     = array();
 191        $queryParams = array();
 192        $postParams  = array();
 193        $path        = $container;
 194        $statusCode  = Resources::STATUS_OK;
 195        
 196        if (is_null($options)) {
 197            $options = new BlobServiceOptions();
 198        }
 199        
 200        $this->addOptionalQueryParam(
 201            $queryParams,
 202            Resources::QP_REST_TYPE,
 203            'container'
 204        );
 205        $this->addOptionalQueryParam(
 206            $queryParams,
 207            Resources::QP_COMP,
 208            $operation
 209        );
 210        $this->addOptionalQueryParam(
 211            $queryParams,
 212            Resources::QP_TIMEOUT,
 213            $options->getTimeout()
 214        );
 215        
 216        $response = $this->send(
 217            $method, 
 218            $headers, 
 219            $queryParams, 
 220            $postParams, 
 221            $path, 
 222            $statusCode
 223        );
 224
 225        $result   = new GetContainerPropertiesResult();
 226        $metadata = $this->getMetadataArray($response->getHeader());
 227        $date     = $response->getHeader(Resources::LAST_MODIFIED);
 228        $date     = Utilities::rfc1123ToDateTime($date);
 229        $result->setETag($response->getHeader(Resources::ETAG));
 230        $result->setMetadata($metadata);
 231        $result->setLastModified($date);
 232        
 233        return $result;
 234    }
 235    
 236    /**
 237     * Adds optional create blob headers.
 238     * 
 239     * @param CreateBlobOptions $options The optional parameters.
 240     * @param array             $headers The HTTP request headers.
 241     * 
 242     * @return array
 243     */
 244    private function _addCreateBlobOptionalHeaders($options, $headers)
 245    {
 246        $contentType         = $options->getContentType();
 247        $metadata            = $options->getMetadata();
 248        $blobContentType     = $options->getBlobContentType();
 249        $blobContentEncoding = $options->getBlobContentEncoding();
 250        $blobContentLanguage = $options->getBlobContentLanguage();
 251        $blobContentMD5      = $options->getBlobContentMD5();
 252        $blobCacheControl    = $options->getBlobCacheControl();
 253        $leaseId             = $options->getLeaseId();
 254        
 255        if (!is_null($contentType)) {
 256            $this->addOptionalHeader(
 257                $headers,
 258                Resources::CONTENT_TYPE,
 259                $options->getContentType()
 260            );
 261        } else {
 262            $this->addOptionalHeader(
 263                $headers,
 264                Resources::CONTENT_TYPE,
 265                Resources::BINARY_FILE_TYPE
 266            );
 267        }
 268        $headers = $this->addMetadataHeaders($headers, $metadata);
 269        $headers = $this->addOptionalAccessConditionHeader(
 270            $headers, $options->getAccessCondition()
 271        );
 272        
 273        $this->addOptionalHeader(
 274            $headers,
 275            Resources::CONTENT_ENCODING,
 276            $options->getContentEncoding()
 277        );
 278        $this->addOptionalHeader(
 279            $headers,
 280            Resources::CONTENT_LANGUAGE,
 281            $options->getContentLanguage()
 282        );
 283        $this->addOptionalHeader(
 284            $headers,
 285            Resources::CONTENT_MD5,
 286            $options->getContentMD5()
 287        );
 288        $this->addOptionalHeader(
 289            $headers,
 290            Resources::CACHE_CONTROL,
 291            $options->getCacheControl()
 292        );
 293        
 294        $this->addOptionalHeader(
 295            $headers,
 296            Resources::X_MS_LEASE_ID,
 297            $leaseId
 298        );
 299        $this->addOptionalHeader(
 300            $headers,
 301            Resources::X_MS_BLOB_CONTENT_TYPE,
 302            $blobContentType
 303        );
 304        $this->addOptionalHeader(
 305            $headers,
 306            Resources::X_MS_BLOB_CONTENT_ENCODING,
 307            $blobContentEncoding
 308        );
 309        $this->addOptionalHeader(
 310            $headers,
 311            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
 312            $blobContentLanguage
 313        );
 314        $this->addOptionalHeader(
 315            $headers,
 316            Resources::X_MS_BLOB_CONTENT_MD5,
 317            $blobContentMD5
 318        );
 319        $this->addOptionalHeader(
 320            $headers,
 321            Resources::X_MS_BLOB_CACHE_CONTROL,
 322            $blobCacheControl
 323        );
 324        
 325        return $headers;
 326    }
 327    
 328    /**
 329     * Adds Range header to the headers array.
 330     * 
 331     * @param array   $headers The HTTP request headers.
 332     * @param integer $start   The start byte.
 333     * @param integer $end     The end byte.
 334     * 
 335     * @return array
 336     */
 337    private function _addOptionalRangeHeader($headers, $start, $end)
 338    {
 339        if (!is_null($start) || !is_null($end)) {
 340            $range      = $start . '-' . $end;
 341            $rangeValue = 'bytes=' . $range;
 342            $this->addOptionalHeader($headers, Resources::RANGE, $rangeValue);
 343        }
 344        
 345        return $headers;
 346    }
 347
 348    /**
 349     * Does the actual work for leasing a blob.
 350     * 
 351     * @param string             $leaseAction     The lease action string.
 352     * @param string             $container       The container name.
 353     * @param string             $blob            The blob to lease name.
 354     * @param string             $leaseId         The existing lease id.
 355     * @param BlobServiceOptions $options         The optional parameters.
 356     * @param AccessCondition    $accessCondition The access conditions.
 357     * 
 358     * @return AcquireLeaseResult
 359     */
 360    private function _putLeaseImpl($leaseAction, $container, $blob, $leaseId, 
 361        $options, $accessCondition = null
 362    ) {
 363        Validate::isString($blob, 'blob');
 364        Validate::notNullOrEmpty($blob, 'blob');
 365        Validate::isString($container, 'container');
 366        
 367        $method      = Resources::HTTP_PUT;
 368        $headers     = array();
 369        $queryParams = array();
 370        $postParams  = array();
 371        $path        = $this->_createPath($container, $blob);
 372        $statusCode  = Resources::EMPTY_STRING;
 373        
 374        switch ($leaseAction) {
 375        case LeaseMode::ACQUIRE_ACTION:
 376            $statusCode = Resources::STATUS_CREATED;
 377            break;
 378        case LeaseMode::RENEW_ACTION:
 379            $statusCode = Resources::STATUS_OK;
 380            break;
 381        case LeaseMode::RELEASE_ACTION:
 382            $statusCode = Resources::STATUS_OK;
 383            break;
 384        case LeaseMode::BREAK_ACTION:
 385            $statusCode = Resources::STATUS_ACCEPTED;
 386            break;
 387        default:
 388            throw new \Exception(Resources::NOT_IMPLEMENTED_MSG);
 389        }
 390        
 391        if (!is_null($options)) {
 392            $options = new BlobServiceOptions();
 393        }
 394        
 395        $headers = $this->addOptionalAccessConditionHeader(
 396            $headers, $accessCondition
 397        );
 398
 399        $this->addOptionalHeader($headers, Resources::X_MS_LEASE_ID, $leaseId);
 400        $this->addOptionalHeader(
 401            $headers,
 402            Resources::X_MS_LEASE_ACTION,
 403            $leaseAction
 404        );
 405        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'lease');
 406        $this->addOptionalQueryParam(
 407            $queryParams,
 408            Resources::QP_TIMEOUT,
 409            $options->getTimeout()
 410        );
 411        
 412        $response = $this->send(
 413            $method, 
 414            $headers, 
 415            $queryParams, 
 416            $postParams,
 417            $path, 
 418            $statusCode
 419        );
 420        
 421        return AcquireLeaseResult::create($response->getHeader());
 422    }
 423    
 424    /**
 425     * Does actual work for create and clear blob pages.
 426     * 
 427     * @param string                 $action    Either clear or create.
 428     * @param string                 $container The container name.
 429     * @param string                 $blob      The blob name.
 430     * @param PageRange              $range     The page ranges.
 431     * @param string|resource        $content   The content stream.
 432     * @param CreateBlobPagesOptions $options   The optional parameters.
 433     * 
 434     * @return CreateBlobPagesResult
 435     */
 436    private function _updatePageBlobPagesImpl($action, $container, $blob, $range,
 437        $content, $options = null
 438    ) {
 439        Validate::isString($blob, 'blob');
 440        Validate::notNullOrEmpty($blob, 'blob');
 441        Validate::isString($container, 'container');
 442        Validate::isTrue(
 443            $range instanceof PageRange,
 444            sprintf(
 445                Resources::INVALID_PARAM_MSG,
 446                'range',
 447                get_class(new PageRange())
 448            )
 449        );
 450        Validate::isTrue(
 451            is_string($content) || is_resource($content),
 452            sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource')
 453        );
 454        
 455        $method      = Resources::HTTP_PUT;
 456        $headers     = array();
 457        $queryParams = array();
 458        $postParams  = array();
 459        $path        = $this->_createPath($container, $blob);
 460        $statusCode  = Resources::STATUS_CREATED;
 461        // If read file failed for any reason it will throw an exception.
 462        $body = is_resource($content) ? stream_get_contents($content) : $content;
 463        
 464        if (is_null($options)) {
 465            $options = new CreateBlobPagesOptions();
 466        }
 467        
 468        $headers = $this->_addOptionalRangeHeader(
 469            $headers, $range->getStart(), $range->getEnd()
 470        );
 471        
 472        $headers = $this->addOptionalAccessConditionHeader(
 473            $headers, $options->getAccessCondition()
 474        );
 475        
 476        $this->addOptionalHeader(
 477            $headers,
 478            Resources::X_MS_LEASE_ID,
 479            $options->getLeaseId()
 480        );
 481        $this->addOptionalHeader(
 482            $headers,
 483            Resources::CONTENT_MD5,
 484            $options->getContentMD5()
 485        );
 486        $this->addOptionalHeader(
 487            $headers,
 488            Resources::X_MS_PAGE_WRITE,
 489            $action
 490        );
 491        $this->addOptionalHeader(
 492            $headers,
 493            Resources::CONTENT_TYPE,
 494            Resources::URL_ENCODED_CONTENT_TYPE
 495        );
 496        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page');
 497        $this->addOptionalQueryParam(
 498            $queryParams,
 499            Resources::QP_TIMEOUT,
 500            $options->getTimeout()
 501        );
 502        
 503        $response = $this->send(
 504            $method, 
 505            $headers, 
 506            $queryParams, 
 507            $postParams,
 508            $path, 
 509            $statusCode, 
 510            $body
 511        );
 512        
 513        return CreateBlobPagesResult::create($response->getHeader());
 514    }
 515    
 516    /**
 517     * Gets the properties of the Blob service.
 518     * 
 519     * @param Models\BlobServiceOptions $options The optional parameters.
 520     * 
 521     * @return WindowsAzure\Common\Models\GetServicePropertiesResult
 522     * 
 523     * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452239.aspx
 524     */
 525    public function getServiceProperties($options = null)
 526    {
 527        $method      = Resources::HTTP_GET;
 528        $headers     = array();
 529        $queryParams = array();
 530        $postParams  = array();
 531        $path        = Resources::EMPTY_STRING;
 532        $statusCode  = Resources::STATUS_OK;
 533        
 534        if (is_null($options)) {
 535            $options = new BlobServiceOptions();
 536        }
 537        
 538        $this->addOptionalQueryParam(
 539            $queryParams,
 540            Resources::QP_TIMEOUT,
 541            $options->getTimeout()
 542        );
 543        $this->addOptionalQueryParam(
 544            $queryParams,
 545            Resources::QP_REST_TYPE,
 546            'service'
 547        );
 548        $this->addOptionalQueryParam(
 549            $queryParams,
 550            Resources::QP_COMP,
 551            'properties'
 552        );
 553        
 554        $response = $this->send(
 555            $method, 
 556            $headers, 
 557            $queryParams, 
 558            $postParams,
 559            $path, 
 560            $statusCode
 561        );
 562        $parsed   = $this->dataSerializer->unserialize($response->getBody());
 563        
 564        return GetServicePropertiesResult::create($parsed);
 565    }
 566
 567    /**
 568     * Sets the properties of the Blob service.
 569     * 
 570     * It's recommended to use getServiceProperties, alter the returned object and
 571     * then use setServiceProperties with this altered object.
 572     * 
 573     * @param ServiceProperties         $serviceProperties The service properties.
 574     * @param Models\BlobServiceOptions $options           The optional parameters.
 575     * 
 576     * @return none
 577     * 
 578     * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452235.aspx
 579     */
 580    public function setServiceProperties($serviceProperties, $options = null)
 581    {
 582        Validate::isTrue(
 583            $serviceProperties instanceof ServiceProperties,
 584            Resources::INVALID_SVC_PROP_MSG
 585        );
 586                
 587        $method      = Resources::HTTP_PUT;
 588        $headers     = array();
 589        $queryParams = array();
 590        $postParams  = array();
 591        $statusCode  = Resources::STATUS_ACCEPTED;
 592        $path        = Resources::EMPTY_STRING;
 593        $body        = $serviceProperties->toXml($this->dataSerializer);
 594        
 595        if (is_null($options)) {
 596            $options = new BlobServiceOptions();
 597        }
 598    
 599        $this->addOptionalQueryParam(
 600            $queryParams,
 601            Resources::QP_REST_TYPE,
 602            'service'
 603        );
 604        $this->addOptionalQueryParam(
 605            $queryParams,
 606            Resources::QP_COMP,
 607            'properties'
 608        );
 609        $this->addOptionalQueryParam(
 610            $queryParams,
 611            Resources::QP_TIMEOUT,
 612            $options->getTimeout()
 613        );
 614        $this->addOptionalHeader(
 615            $headers,
 616            Resources::CONTENT_TYPE,
 617            Resources::URL_ENCODED_CONTENT_TYPE
 618        );
 619        
 620        $this->send(
 621            $method, 
 622            $headers, 
 623            $queryParams, 
 624            $postParams,
 625            $path, 
 626            $statusCode, 
 627            $body
 628        );
 629    }
 630    
 631    /**
 632     * Lists all of the containers in the given storage account.
 633     * 
 634     * @param Models\ListContainersOptions $options The optional parameters.
 635     * 
 636     * @return WindowsAzure\Blob\Models\ListContainersResult
 637     * 
 638     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx
 639     */
 640    public function listContainers($options = null)
 641    {
 642        $method      = Resources::HTTP_GET;
 643        $headers     = array();
 644        $queryParams = array();
 645        $postParams  = array();
 646        $path        = Resources::EMPTY_STRING;
 647        $statusCode  = Resources::STATUS_OK;
 648        
 649        if (is_null($options)) {
 650            $options = new ListContainersOptions();
 651        }
 652        
 653        $this->addOptionalQueryParam(
 654            $queryParams,
 655            Resources::QP_TIMEOUT,
 656            $options->getTimeout()
 657        );
 658        $this->addOptionalQueryParam(
 659            $queryParams,
 660            Resources::QP_COMP,
 661            'list'
 662        );
 663        $this->addOptionalQueryParam(
 664            $queryParams,
 665            Resources::QP_PREFIX,
 666            $options->getPrefix()
 667        );
 668        $this->addOptionalQueryParam(
 669            $queryParams,
 670            Resources::QP_MARKER,
 671            $options->getMarker()
 672        );
 673        $this->addOptionalQueryParam(
 674            $queryParams,
 675            Resources::QP_MAX_RESULTS,
 676            $options->getMaxResults()
 677        );
 678        $isInclude = $options->getIncludeMetadata();
 679        $isInclude = $isInclude ? 'metadata' : null;
 680        $this->addOptionalQueryParam(
 681            $queryParams,
 682            Resources::QP_INCLUDE,
 683            $isInclude
 684        );
 685        
 686        $response = $this->send(
 687            $method, 
 688            $headers, 
 689            $queryParams, 
 690            $postParams,
 691            $path, 
 692            $statusCode
 693        );
 694
 695        $parsed = $this->dataSerializer->unserialize($response->getBody());
 696        
 697        return ListContainersResult::create($parsed);
 698    }
 699    
 700    /**
 701     * Creates a new container in the given storage account.
 702     * 
 703     * @param string                        $container The container name.
 704     * @param Models\CreateContainerOptions $options   The optional parameters.
 705     * 
 706     * @return none
 707     * 
 708     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx
 709     */
 710    public function createContainer($container, $options = null)
 711    {
 712        Validate::isString($container, 'container');
 713        Validate::notNullOrEmpty($container, 'container');
 714        
 715        $method      = Resources::HTTP_PUT;
 716        $headers     = array();
 717        $postParams  = array();
 718        $queryParams = array(Resources::QP_REST_TYPE => 'container');
 719        $path        = $container;
 720        $statusCode  = Resources::STATUS_CREATED;
 721        
 722        if (is_null($options)) {
 723            $options = new CreateContainerOptions();
 724        }
 725
 726        $this->addOptionalQueryParam(
 727            $queryParams,
 728            Resources::QP_TIMEOUT,
 729            $options->getTimeout()
 730        );
 731
 732        $metadata = $options->getMetadata();
 733        $headers  = $this->generateMetadataHeaders($metadata);
 734        $this->addOptionalHeader(
 735            $headers,
 736            Resources::X_MS_BLOB_PUBLIC_ACCESS,
 737            $options->getPublicAccess()
 738        );
 739        
 740        $this->send(
 741            $method, 
 742            $headers, 
 743            $queryParams, 
 744            $postParams, 
 745            $path, 
 746            $statusCode
 747        );
 748    }
 749    
 750    /**
 751     * Creates a new container in the given storage account.
 752     * 
 753     * @param string                        $container The container name.
 754     * @param Models\DeleteContainerOptions $options   The optional parameters.
 755     * 
 756     * @return none
 757     * 
 758     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx
 759     */
 760    public function deleteContainer($container, $options = null)
 761    {
 762        Validate::isString($container, 'container');
 763        Validate::notNullOrEmpty($container, 'container');
 764        
 765        $method      = Resources::HTTP_DELETE;
 766        $headers     = array();
 767        $postParams  = array();
 768        $queryParams = array();
 769        $path        = $container;
 770        $statusCode  = Resources::STATUS_ACCEPTED;
 771        
 772        if (is_null($options)) {
 773            $options = new DeleteContainerOptions();
 774        }
 775        
 776        $headers = $this->addOptionalAccessConditionHeader(
 777            $headers, $options->getAccessCondition()
 778        );
 779        
 780        $this->addOptionalQueryParam(
 781            $queryParams,
 782            Resources::QP_TIMEOUT,
 783            $options->getTimeout()
 784        );
 785        $this->addOptionalQueryParam(
 786            $queryParams,
 787            Resources::QP_REST_TYPE,
 788            'container'
 789        );
 790        
 791        $this->send(
 792            $method, 
 793            $headers, 
 794            $queryParams, 
 795            $postParams,
 796            $path, 
 797            $statusCode
 798        );
 799    }
 800    
 801    /**
 802     * Returns all properties and metadata on the container.
 803     * 
 804     * @param string                    $container name
 805     * @param Models\BlobServiceOptions $options   optional parameters
 806     * 
 807     * @return Models\GetContainerPropertiesResult
 808     * 
 809     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx
 810     */
 811    public function getContainerProperties($container, $options = null)
 812    {
 813        return $this->_getContainerPropertiesImpl($container, $options);
 814    }
 815    
 816    /**
 817     * Returns only user-defined metadata for the specified container.
 818     * 
 819     * @param string                    $container name
 820     * @param Models\BlobServiceOptions $options   optional parameters
 821     * 
 822     * @return Models\GetContainerPropertiesResult
 823     * 
 824     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx 
 825     */
 826    public function getContainerMetadata($container, $options = null)
 827    {
 828        return $this->_getContainerPropertiesImpl($container, $options, 'metadata');
 829    }
 830    
 831    /**
 832     * Gets the access control list (ACL) and any container-level access policies 
 833     * for the container.
 834     * 
 835     * @param string                    $container The container name.
 836     * @param Models\BlobServiceOptions $options   The optional parameters.
 837     * 
 838     * @return Models\GetContainerAclResult
 839     * 
 840     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx
 841     */
 842    public function getContainerAcl($container, $options = null)
 843    {
 844        Validate::isString($container, 'container');
 845        
 846        $method      = Resources::HTTP_GET;
 847        $headers     = array();
 848        $postParams  = array();
 849        $queryParams = array();
 850        $path        = $container;
 851        $statusCode  = Resources::STATUS_OK;
 852        
 853        if (is_null($options)) {
 854            $options = new BlobServiceOptions();
 855        }
 856        
 857        $this->addOptionalQueryParam(
 858            $queryParams,
 859            Resources::QP_TIMEOUT,
 860            $options->getTimeout()
 861        );
 862        $this->addOptionalQueryParam(
 863            $queryParams,
 864            Resources::QP_REST_TYPE,
 865            'container'
 866        );
 867        $this->addOptionalQueryParam(
 868            $queryParams,
 869            Resources::QP_COMP,
 870            'acl'
 871        );
 872        
 873        $response = $this->send(
 874            $method, 
 875            $headers, 
 876            $queryParams, 
 877            $postParams,
 878            $path, 
 879            $statusCode
 880        );
 881        
 882        $access       = $response->getHeader(Resources::X_MS_BLOB_PUBLIC_ACCESS);
 883        $etag         = $response->getHeader(Resources::ETAG);
 884        $modified     = $response->getHeader(Resources::LAST_MODIFIED);
 885        $modifiedDate = Utilities::convertToDateTime($modified);
 886        $parsed       = $this->dataSerializer->unserialize($response->getBody());
 887                
 888        return GetContainerAclResult::create($access, $etag, $modifiedDate, $parsed);
 889    }
 890    
 891    /**
 892     * Sets the ACL and any container-level access policies for the container.
 893     * 
 894     * @param string                    $container name
 895     * @param Models\ContainerAcl       $acl       access control list for container
 896     * @param Models\BlobServiceOptions $options   optional parameters
 897     * 
 898     * @return none
 899     * 
 900     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx
 901     */
 902    public function setContainerAcl($container, $acl, $options = null)
 903    {
 904        Validate::isString($container, 'container');
 905        Validate::notNullOrEmpty($acl, 'acl');
 906        
 907        $method      = Resources::HTTP_PUT;
 908        $headers     = array();
 909        $postParams  = array();
 910        $queryParams = array();
 911        $path        = $container;
 912        $statusCode  = Resources::STATUS_OK;
 913        $body        = $acl->toXml($this->dataSerializer);
 914        
 915        if (is_null($options)) {
 916            $options = new BlobServiceOptions();
 917        }
 918        
 919        $this->addOptionalQueryParam(
 920            $queryParams,
 921            Resources::QP_TIMEOUT,
 922            $options->getTimeout()
 923        );
 924        $this->addOptionalQueryParam(
 925            $queryParams,
 926            Resources::QP_REST_TYPE,
 927            'container'
 928        );
 929        $this->addOptionalQueryParam(
 930            $queryParams,
 931            Resources::QP_COMP,
 932            'acl'
 933        );
 934        $this->addOptionalHeader(
 935            $headers,
 936            Resources::X_MS_BLOB_PUBLIC_ACCESS,
 937            $acl->getPublicAccess()
 938        );
 939        $this->addOptionalHeader(
 940            $headers,
 941            Resources::CONTENT_TYPE,
 942            Resources::URL_ENCODED_CONTENT_TYPE
 943        );
 944
 945        $this->send(
 946            $method,    
 947            $headers, 
 948            $queryParams, 
 949            $postParams,
 950            $path, 
 951            $statusCode, 
 952            $body
 953        );
 954    }
 955    
 956    /**
 957     * Sets metadata headers on the container.
 958     * 
 959     * @param string                             $container name
 960     * @param array                              $metadata  metadata key/value pair.
 961     * @param Models\SetContainerMetadataOptions $options   optional parameters
 962     * 
 963     * @return none
 964     * 
 965     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx
 966     */
 967    public function setContainerMetadata($container, $metadata, $options = null)
 968    {
 969        Validate::isString($container, 'container');
 970        $this->validateMetadata($metadata);
 971        
 972        $method      = Resources::HTTP_PUT;
 973        $headers     = $this->generateMetadataHeaders($metadata);
 974        $postParams  = array();
 975        $queryParams = array();
 976        $path        = $container;
 977        $statusCode  = Resources::STATUS_OK;
 978        
 979        if (is_null($options)) {
 980            $options = new SetContainerMetadataOptions();
 981        }
 982        
 983        $this->addOptionalQueryParam(
 984            $queryParams,
 985            Resources::QP_TIMEOUT,
 986            $options->getTimeout()
 987        );
 988        $this->addOptionalQueryParam(
 989            $queryParams,
 990            Resources::QP_REST_TYPE,
 991            'container'
 992        );
 993        $this->addOptionalQueryParam(
 994            $queryParams,
 995            Resources::QP_COMP,
 996            'metadata'
 997        );
 998        
 999        $headers = $this->addOptionalAccessConditionHeader(
1000            $headers,
1001            $options->getAccessCondition()
1002        );
1003
1004        $this->send(
1005            $method, 
1006            $headers, 
1007            $queryParams, 
1008            $postParams, 
1009            $path, 
1010            $statusCode
1011        );
1012    }
1013    
1014    /**
1015     * Lists all of the blobs in the given container.
1016     * 
1017     * @param string                  $container The container name.
1018     * @param Models\ListBlobsOptions $options   The optional parameters.
1019     * 
1020     * @return Models\ListBlobsResult
1021     * 
1022     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
1023     */
1024    public function listBlobs($container, $options = null)
1025    {
1026        Validate::isString($container, 'container');
1027        
1028        $method      = Resources::HTTP_GET;
1029        $headers     = array();
1030        $postParams  = array();
1031        $queryParams = array();
1032        $path        = $container;
1033        $statusCode  = Resources::STATUS_OK;
1034        
1035        if (is_null($options)) {
1036            $options = new ListBlobsOptions();
1037        }
1038        
1039        $this->addOptionalQueryParam(
1040            $queryParams,
1041            Resources::QP_TIMEOUT,
1042            $options->getTimeout()
1043        );
1044        $this->addOptionalQueryParam(
1045            $queryParams,
1046            Resources::QP_REST_TYPE,
1047            'container'
1048        );
1049        $this->addOptionalQueryParam(
1050            $queryParams,
1051            Resources::QP_COMP,
1052            'list'
1053        );
1054        $this->addOptionalQueryParam(
1055            $queryParams,
1056            Resources::QP_PREFIX,
1057            $options->getPrefix()
1058        );
1059        $this->addOptionalQueryParam(
1060            $queryParams,
1061            Resources::QP_MARKER,
1062            $options->getMarker()
1063        );
1064        $this->addOptionalQueryParam(
1065            $queryParams,
1066            Resources::QP_DELIMITER,
1067            $options->getDelimiter()
1068        );
1069        $this->addOptionalQueryParam(
1070            $queryParams,
1071            Resources::QP_MAX_RESULTS,
1072            $options->getMaxResults()
1073        );
1074        
1075        $includeMetadata         = $options->getIncludeMetadata();
1076        $includeSnapshots        = $options->getIncludeSnapshots();
1077        $includeUncommittedBlobs = $options->getIncludeUncommittedBlobs();
1078        
1079        $includeValue = $this->groupQueryValues(
1080            array(
1081                $includeMetadata ? 'metadata' : null, 
1082                $includeSnapshots ? 'snapshots' : null, 
1083                $includeUncommittedBlobs ? 'uncommittedblobs' : null
1084            )
1085        );
1086        
1087        $this->addOptionalQueryParam(
1088            $queryParams,
1089            Resources::QP_INCLUDE,
1090            $includeValue
1091        );
1092        
1093        $response = $this->send(
1094            $method, 
1095            $headers, 
1096            $queryParams,
1097            $postParams,
1098            $path, 
1099            $statusCode
1100        );
1101
1102        $parsed = $this->dataSerializer->unserialize($response->getBody());
1103        
1104        return ListBlobsResult::create($parsed);
1105    }
1106    
1107    /**
1108     * Creates a new page blob. Note that calling createPageBlob to create a page
1109     * blob only initializes the blob.
1110     * To add content to a page blob, call createBlobPages method.
1111     * 
1112     * @param string                   $container The container name.
1113     * @param string                   $blob      The blob name.
1114     * @param integer                  $length    Specifies the maximum size for the
1115     * page blob, up to 1 TB. The page blob size must be aligned to a 512-byte 
1116     * boundary.
1117     * @param Models\CreateBlobOptions $options   The optional parameters.
1118     * 
1119     * @return CopyBlobResult
1120     * 
1121     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1122     */
1123    public function createPageBlob($container, $blob, $length, $options = null)
1124    {
1125        Validate::isString($container, 'container');
1126        Validate::isString($blob, 'blob');
1127        Validate::notNullOrEmpty($blob, 'blob');
1128        Validate::isInteger($length, 'length');
1129        Validate::notNull($length, 'length');
1130        
1131        $method      = Resources::HTTP_PUT;
1132        $headers     = array();
1133        $postParams  = array();
1134        $queryParams = array();
1135        $path        = $this->_createPath($container, $blob);
1136        $statusCode  = Resources::STATUS_CREATED;
1137        
1138        if (is_null($options)) {
1139            $options = new CreateBlobOptions();
1140        }
1141        
1142        $this->addOptionalHeader(
1143            $headers,
1144            Resources::X_MS_BLOB_TYPE,
1145            BlobType::PAGE_BLOB
1146        );
1147        $this->addOptionalHeader(
1148            $headers,
1149            Resources::X_MS_BLOB_CONTENT_LENGTH,
1150            $length
1151        );
1152        $this->addOptionalHeader(
1153            $headers,
1154            Resources::X_MS_BLOB_SEQUENCE_NUMBER,
1155            $options->getSequenceNumber()
1156        );
1157        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1158        
1159        $this->addOptionalQueryParam(
1160            $queryParams,
1161            Resources::QP_TIMEOUT,
1162            $options->getTimeout()
1163        );
1164        
1165        $response = $this->send(
1166            $method, 
1167            $headers, 
1168            $queryParams, 
1169            $postParams,
1170            $path, 
1171            $statusCode
1172        );
1173        
1174        return CopyBlobResult::create($response->getHeader());
1175    }
1176    
1177    /**
1178     * Creates a new block blob or updates the content of an existing block blob.
1179     * 
1180     * Updating an existing block blob overwrites any existing metadata on the blob.
1181     * Partial updates are not supported with createBlockBlob the content of the
1182     * existing blob is overwritten with the content of the new blob. To perform a
1183     * partial update of the content o  f a block blob, use the createBlockList
1184     * method.
1185     * Note that the default content type is application/octet-stream.
1186     * 
1187     * @param string                   $container The name of the container.
1188     * @param string                   $blob      The name of the blob.
1189     * @param string|resource          $content   The content of the blob.
1190     * @param Models\CreateBlobOptions $options   The optional parameters.
1191     * 
1192     * @return CopyBlobResult
1193     * 
1194     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1195     */
1196    public function createBlockBlob($container, $blob, $content, $options = null)
1197    {
1198        Validate::isString($container, 'container');
1199        Validate::isString($blob, 'blob');
1200        Validate::notNullOrEmpty($blob, 'blob');
1201        Validate::isTrue(
1202            is_string($content) || is_resource($content),
1203            sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource')
1204        );
1205        
1206        $method      = Resources::HTTP_PUT;
1207        $headers     = array();
1208        $postParams  = array();
1209        $queryParams = array();
1210        $path        = $this->_createPath($container, $blob);
1211        $statusCode  = Resources::STATUS_CREATED;
1212        // If read file failed for any reason it will throw an exception.
1213        $body = is_resource($content) ? stream_get_contents($content) : $content;
1214        
1215        if (is_null($options)) {
1216            $options = new CreateBlobOptions();
1217        }
1218        
1219        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1220        
1221        $this->addOptionalHeader(
1222            $headers,
1223            Resources::X_MS_BLOB_TYPE,
1224            BlobType::BLOCK_BLOB
1225        );
1226        $this->addOptionalQueryParam(
1227            $queryParams,
1228            Resources::QP_TIMEOUT,
1229            $options->getTimeout()
1230        );
1231        
1232        $response = $this->send(
1233            $method, 
1234            $headers, 
1235            $queryParams, 
1236            $postParams,
1237            $path, 
1238            $statusCode,
1239            $body
1240        );
1241        
1242        return CopyBlobResult::create($response->getHeader());
1243    }
1244    
1245    /**
1246     * Clears a range of pages from the blob.
1247     * 
1248     * @param string                        $container name of the container
1249     * @param string                        $blob      name of the blob
1250     * @param Models\PageRange              $range     Can be up to the value of the
1251     * blob's full size. Note that ranges must be aligned to 512 (0-511, 512-1023)
1252     * @param Models\CreateBlobPagesOptions $options   optional parameters
1253     * 
1254     * @return Models\CreateBlobPagesResult.
1255     * 
1256     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
1257     */
1258    public function clearBlobPages($container, $blob, $range, $options = null)
1259    {
1260        return $this->_updatePageBlobPagesImpl(
1261            PageWriteOption::CLEAR_OPTION,
1262            $container,
1263            $blob,
1264            $range,
1265            Resources::EMPTY_STRING,
1266            $options
1267        );
1268    }
1269    
1270    /**
1271     * Creates a range of pages to a page blob.
1272     * 
1273     * @param string                        $container name of the container
1274     * @param string                        $blob      name of the blob
1275     * @param Models\PageRange              $range     Can be up to 4 MB in size
1276     * Note that ranges must be aligned to 512 (0-511, 512-1023)
1277     * @param string                        $content   the blob contents.
1278     * @param Models\CreateBlobPagesOptions $options   optional parameters
1279     * 
1280     * @return Models\CreateBlobPagesResult.
1281     * 
1282     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
1283     */
1284    public function createBlobPages($container, $blob, $range, $content,
1285        $options = null
1286    ) {
1287        return $this->_updatePageBlobPagesImpl(
1288            PageWriteOption::UPDATE_OPTION,
1289            $container,
1290            $blob,
1291            $range,
1292            $content,
1293            $options
1294        );
1295    }
1296    
1297    /**
1298     * Creates a new block to be committed as part of a block blob.
1299     * 
1300     * @param string                        $container name of the container
1301     * @param string                        $blob      name of the blob
1302     * @param string                        $blockId   must be less than or equal to 
1303     * 64 bytes in size. For a given blob, the length of the value specified for the
1304     * blockid parameter must be the same size for each block.
1305     * @param string                        $content   the blob block contents
1306     * @param Models\CreateBlobBlockOptions $options   optional parameters
1307     * 
1308     * @return none
1309     * 
1310     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx
1311     */
1312    public function createBlobBlock($container, $blob, $blockId, $content,
1313        $options = null
1314    ) {
1315        Validate::isString($container, 'container');
1316        Validate::isString($blob, 'blob');
1317        Validate::notNullOrEmpty($blob, 'blob');
1318        Validate::isString($blockId, 'blockId');
1319        Validate::notNullOrEmpty($blockId, 'blockId');
1320        Validate::isTrue(
1321            is_string($content) || is_resource($content),
1322            sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource')
1323        );
1324        
1325        $method      = Resources::HTTP_PUT;
1326        $headers     = array();
1327        $postParams  = array();
1328        $queryParams = array();
1329        $path        = $this->_createPath($container, $blob);
1330        $statusCode  = Resources::STATUS_CREATED;
1331        $body        = $content;
1332        
1333        if (is_null($options)) {
1334            $options = new CreateBlobBlockOptions();
1335        }
1336        
1337        $this->addOptionalHeader(
1338            $headers,
1339            Resources::X_MS_LEASE_ID,
1340            $options->getLeaseId()
1341        );
1342        $this->addOptionalHeader(
1343            $headers,
1344            Resources::CONTENT_MD5,
1345            $options->getContentMD5()
1346        );
1347        $this->addOptionalHeader(
1348            $headers,
1349            Resources::CONTENT_TYPE,
1350            Resources::URL_ENCODED_CONTENT_TYPE
1351        );
1352        $this->addOptionalQueryParam(
1353            $queryParams,
1354            Resources::QP_TIMEOUT,
1355            $options->getTimeout()
1356        );
1357        $this->addOptionalQueryParam(
1358            $queryParams,
1359            Resources::QP_COMP,
1360            'block'
1361        );
1362        $this->addOptionalQueryParam(
1363            $queryParams,
1364            Resources::QP_BLOCKID,
1365            base64_encode($blockId)
1366        );
1367        
1368        $this->send(
1369            $method, 
1370            $headers, 
1371            $queryParams, 
1372            $postParams,
1373            $path, 
1374            $statusCode,
1375            $body
1376        );
1377    }
1378    
1379    /**
1380     * This method writes a blob by specifying the list of block IDs that make up the
1381     * blob. In order to be written as part of a blob, a block must have been 
1382     * successfully written to the server in a prior createBlobBlock method.
1383     * 
1384     * You can call Put Block List to update a blob by uploading only those blocks 
1385     * that have changed, then committing the new and existing blocks together. 
1386     * You can do this by specifying whether to commit a block from the committed 
1387     * block list or from the uncommitted block list, or to commit the most recently
1388     * uploaded version of the block, whichever list it may belong to.
1389     * 
1390     * @param string                         $container The container name.
1391     * @param string                         $blob      The blob name.
1392     * @param Models\BlockList|array         $blockList The block entries.
1393     * @param Models\CommitBlobBlocksOptions $options   The optional parameters.
1394     * 
1395     * @return none
1396     * 
1397     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx 
1398     */
1399    public function commitBlobBlocks($container, $blob, $blockList, $options = null)
1400    {
1401        Validate::isString($container, 'container');
1402        Validate::isString($blob, 'blob');
1403        Validate::notNullOrEmpty($blob, 'blob');
1404        Validate::isTrue(
1405            $blockList instanceof BlockList || is_array($blockList),
1406            sprintf(
1407                Resources::INVALID_PARAM_MSG,
1408                'blockList',
1409                get_class(new BlockList())
1410            )
1411        );
1412        
1413        $method      = Resources::HTTP_PUT;
1414        $headers     = array();
1415        $postParams  = array();
1416        $queryParams = array();
1417        $path        = $this->_createPath($container, $blob);
1418        $statusCode  = Resources::STATUS_CREATED;
1419        $isArray     = is_array($blockList);
1420        $blockList   = $isArray ? BlockList::create($blockList) : $blockList;
1421        $body        = $blockList->toXml($this->dataSerializer);
1422        
1423        if (is_null($options)) {
1424            $options = new CommitBlobBlocksOptions();
1425        }
1426        
1427        $blobContentType     = $options->getBlobContentType();
1428        $blobContentEncoding = $options->getBlobContentEncoding();
1429        $blobContentLanguage = $options->getBlobContentLanguage();
1430        $blobContentMD5      = $options->getBlobContentMD5();
1431        $blobCacheControl    = $options->getBlobCacheControl();
1432        $leaseId             = $options->getLeaseId();
1433        $contentType         = Resources::URL_ENCODED_CONTENT_TYPE;
1434        
1435        $metadata = $options->getMetadata();
1436        $headers  = $this->generateMetadataHeaders($metadata);
1437        $headers  = $this->addOptionalAccessConditionHeader(
1438            $headers, $options->getAccessCondition()
1439      

Large files files are truncated, but you can click here to view the full file