PageRenderTime 188ms CodeModel.GetById 81ms app.highlight 52ms RepoModel.GetById 48ms app.codeStats 1ms

/Service/Rackspace/Files.php

https://bitbucket.org/bigstylee/zend-framework
PHP | 686 lines | 522 code | 3 blank | 161 comment | 67 complexity | 77ccdf2d60f57948e8f53d9598376d62 MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @category   Zend
 16 * @package    Zend_Service
 17 * @subpackage Rackspace
 18 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 */
 21
 22require_once 'Zend/Service/Rackspace/Abstract.php';
 23require_once 'Zend/Service/Rackspace/Files/ContainerList.php';
 24require_once 'Zend/Service/Rackspace/Files/ObjectList.php';
 25require_once 'Zend/Service/Rackspace/Files/Container.php';
 26require_once 'Zend/Service/Rackspace/Files/Object.php';
 27
 28class Zend_Service_Rackspace_Files extends Zend_Service_Rackspace_Abstract
 29{
 30    const ERROR_CONTAINER_NOT_EMPTY            = 'The container is not empty, I cannot delete it.';
 31    const ERROR_CONTAINER_NOT_FOUND            = 'The container was not found.';
 32    const ERROR_OBJECT_NOT_FOUND               = 'The object was not found.';
 33    const ERROR_OBJECT_MISSING_PARAM           = 'Missing Content-Length or Content-Type header in the request';
 34    const ERROR_OBJECT_CHECKSUM                = 'Checksum of the file content failed';
 35    const ERROR_CONTAINER_EXIST                = 'The container already exists';
 36    const ERROR_PARAM_NO_NAME_CONTAINER        = 'You must specify the container name';
 37    const ERROR_PARAM_NO_NAME_OBJECT           = 'You must specify the object name';
 38    const ERROR_PARAM_NO_CONTENT               = 'You must specify the content of the object';
 39    const ERROR_PARAM_NO_NAME_SOURCE_CONTAINER = 'You must specify the source container name';
 40    const ERROR_PARAM_NO_NAME_SOURCE_OBJECT    = 'You must specify the source object name';
 41    const ERROR_PARAM_NO_NAME_DEST_CONTAINER   = 'You must specify the destination container name';
 42    const ERROR_PARAM_NO_NAME_DEST_OBJECT      = 'You must specify the destination object name';
 43    const ERROR_PARAM_NO_METADATA              = 'You must specify the metadata array';
 44    const ERROR_CDN_TTL_OUT_OF_RANGE           = 'TTL must be a number in seconds, min is 900 sec and maximum is 1577836800 (50 years)';
 45    const ERROR_PARAM_UPDATE_CDN               = 'You must specify at least one the parameters: ttl, cdn_enabled or log_retention';
 46    const HEADER_CONTENT_TYPE                  = 'Content-Type';
 47    const HEADER_HASH                          = 'Etag';
 48    const HEADER_LAST_MODIFIED                 = 'Last-Modified';
 49    const HEADER_CONTENT_LENGTH                = 'Content-Length';
 50    const HEADER_COPY_FROM                     = 'X-Copy-From';
 51    const METADATA_OBJECT_HEADER               = "X-Object-Meta-";
 52    const METADATA_CONTAINER_HEADER            = "X-Container-Meta-";
 53    const CDN_URI                              = "X-CDN-URI";
 54    const CDN_SSL_URI                          = "X-CDN-SSL-URI";
 55    const CDN_ENABLED                          = "X-CDN-Enabled";
 56    const CDN_LOG_RETENTION                    = "X-Log-Retention";
 57    const CDN_ACL_USER_AGENT                   = "X-User-Agent-ACL";
 58    const CDN_ACL_REFERRER                     = "X-Referrer-ACL";
 59    const CDN_TTL                              = "X-TTL";
 60    const CDN_TTL_MIN                          = 900;
 61    const CDN_TTL_MAX                          = 1577836800;
 62    const CDN_EMAIL                            = "X-Purge-Email";
 63    const ACCOUNT_CONTAINER_COUNT              = "X-Account-Container-Count";
 64    const ACCOUNT_BYTES_USED                   = "X-Account-Bytes-Used";
 65    const ACCOUNT_OBJ_COUNT                    = "X-Account-Object-Count";
 66    const CONTAINER_OBJ_COUNT                  = "X-Container-Object-Count";
 67    const CONTAINER_BYTES_USE                  = "X-Container-Bytes-Used";
 68    const MANIFEST_OBJECT_HEADER               = "X-Object-Manifest";
 69
 70    /**
 71     * Return the total count of containers
 72     *
 73     * @return integer
 74     */
 75    public function getCountContainers()
 76    {
 77        $data= $this->getInfoAccount();
 78        return $data['tot_containers'];
 79    }
 80    /**
 81     * Return the size in bytes of all the containers
 82     *
 83     * @return integer
 84     */
 85    public function getSizeContainers()
 86    {
 87        $data= $this->getInfoAccount();
 88        return $data['size_containers'];
 89    }
 90    /**
 91     * Return the count of objects contained in all the containers
 92     *
 93     * @return integer
 94     */
 95    public function getCountObjects()
 96    {
 97        $data= $this->getInfoAccount();
 98        return $data['tot_objects'];
 99    }
100    /**
101     * Get all the containers
102     *
103     * @param array $options
104     * @return Zend_Service_Rackspace_Files_ContainerList|boolean
105     */
106    public function getContainers($options=array())
107    {
108        $result= $this->httpCall($this->getStorageUrl(),'GET',null,$options);
109        if ($result->isSuccessful()) {
110            return new Zend_Service_Rackspace_Files_ContainerList($this,json_decode($result->getBody(),true));
111        }
112        return false;
113    }
114    /**
115     * Get all the CDN containers
116     *
117     * @param array $options
118     * @return array|boolean
119     */
120    public function getCdnContainers($options=array())
121    {
122        $options['enabled_only']= true;
123        $result= $this->httpCall($this->getCdnUrl(),'GET',null,$options);
124        if ($result->isSuccessful()) {
125            return new Zend_Service_Rackspace_Files_ContainerList($this,json_decode($result->getBody(),true));
126        }
127        return false;
128    }
129    /**
130     * Get the metadata information of the accounts:
131     * - total count containers
132     * - size in bytes of all the containers
133     * - total objects in all the containers
134     * 
135     * @return array|boolean
136     */
137    public function getInfoAccount()
138    {
139        $result= $this->httpCall($this->getStorageUrl(),'HEAD');
140        if ($result->isSuccessful()) {
141            $output= array(
142                'tot_containers'  => $result->getHeader(self::ACCOUNT_CONTAINER_COUNT),
143                'size_containers' => $result->getHeader(self::ACCOUNT_BYTES_USED),
144                'tot_objects'     => $result->getHeader(self::ACCOUNT_OBJ_COUNT)
145            );
146            return $output;
147        }
148        return false;
149    }
150    /**
151     * Get all the objects of a container
152     *
153     * @param string $container
154     * @param array $options
155     * @return  Zend_Service_Rackspace_Files_ObjectList|boolean
156     */
157    public function getObjects($container,$options=array())
158    {
159        if (empty($container)) {
160            require_once 'Zend/Service/Rackspace/Exception.php';
161            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
162        }
163        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'GET',null,$options);
164        if ($result->isSuccessful()) {
165            return new Zend_Service_Rackspace_Files_ObjectList($this,json_decode($result->getBody(),true),$container);
166        }
167        return false;
168    }
169    /**
170     * Create a container
171     *
172     * @param string $container
173     * @param array $metadata
174     * @return Zend_Service_Rackspace_Files_Container|boolean
175     */
176    public function createContainer($container,$metadata=array())
177    {
178        if (empty($container)) {
179            require_once 'Zend/Service/Rackspace/Exception.php';
180            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
181        }
182        $headers=array();
183        if (!empty($metadata)) {
184            foreach ($metadata as $key => $value) {
185                $headers[self::METADATA_CONTAINER_HEADER.rawurlencode(strtolower($key))]= rawurlencode($value);
186            }
187        }
188        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'PUT',$headers);
189        $status= $result->getStatus();
190        switch ($status) {
191            case '201': // break intentionally omitted
192                $data= array(
193                    'name' => $container
194                );
195                return new Zend_Service_Rackspace_Files_Container($this,$data);
196            case '202':
197                $this->errorMsg= self::ERROR_CONTAINER_EXIST;
198                break;
199            default:
200                $this->errorMsg= $result->getBody();
201                break;
202        }
203        $this->errorCode= $status;
204        return false;
205    }
206    /**
207     * Delete a container (only if it's empty)
208     *
209     * @param sting $container
210     * @return boolean
211     */
212    public function deleteContainer($container)
213    {
214        if (empty($container)) {
215            require_once 'Zend/Service/Rackspace/Exception.php';
216            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
217        }
218        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'DELETE');
219        $status= $result->getStatus();
220        switch ($status) {
221            case '204': // break intentionally omitted
222                return true;
223            case '409':
224                $this->errorMsg= self::ERROR_CONTAINER_NOT_EMPTY;
225                break;
226            case '404':
227                $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
228                break;
229            default:
230                $this->errorMsg= $result->getBody();
231                break;
232        }
233        $this->errorCode= $status;
234        return false;
235    }
236    /**
237     * Get the metadata of a container
238     *
239     * @param string $container
240     * @return array|boolean
241     */
242    public function getMetadataContainer($container)
243    {
244        if (empty($container)) {
245            require_once 'Zend/Service/Rackspace/Exception.php';
246            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
247        }
248        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'HEAD');
249        $status= $result->getStatus();
250        switch ($status) {
251            case '204': // break intentionally omitted
252                $headers= $result->getHeaders();
253                $count= strlen(self::METADATA_CONTAINER_HEADER);
254                // Zend_Http_Response alters header name in array key, so match our header to what will be in the headers array
255                $headerName = ucwords(strtolower(self::METADATA_CONTAINER_HEADER)); 
256                $metadata= array();
257                foreach ($headers as $type => $value) {
258                    if (strpos($type,$headerName)!==false) {
259                        $metadata[strtolower(substr($type, $count))]= $value;
260                    }
261                }
262                $data= array (
263                    'name'     => $container,
264                    'count'    => $result->getHeader(self::CONTAINER_OBJ_COUNT),
265                    'bytes'    => $result->getHeader(self::CONTAINER_BYTES_USE),
266                    'metadata' => $metadata
267                );
268                return $data;
269            case '404':
270                $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
271                break;
272            default:
273                $this->errorMsg= $result->getBody();
274                break;
275        }
276        $this->errorCode= $status;
277        return false;
278    }
279    /**
280     * Get a container
281     * 
282     * @param string $container
283     * @return Container|boolean
284     */
285    public function getContainer($container) {
286        $result= $this->getMetadataContainer($container);
287        if (!empty($result)) {
288            return new Zend_Service_Rackspace_Files_Container($this,$result);
289        }
290        return false;
291    }
292    /**
293     * Get an object in a container
294     *
295     * @param string $container
296     * @param string $object
297     * @param array $headers
298     * @return Zend_Service_Rackspace_Files_Object|boolean
299     */
300    public function getObject($container,$object,$headers=array())
301    {
302        if (empty($container)) {
303            require_once 'Zend/Service/Rackspace/Exception.php';
304            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
305        }
306        if (empty($object)) {
307            require_once 'Zend/Service/Rackspace/Exception.php';
308            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
309        }
310        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'GET',$headers);
311        $status= $result->getStatus();
312        switch ($status) {
313            case '200': // break intentionally omitted
314                $data= array(
315                    'name'          => $object,
316                    'container'     => $container,
317                    'hash'          => $result->getHeader(self::HEADER_HASH),
318                    'bytes'         => $result->getHeader(self::HEADER_CONTENT_LENGTH),
319                    'last_modified' => $result->getHeader(self::HEADER_LAST_MODIFIED),
320                    'content_type'  => $result->getHeader(self::HEADER_CONTENT_TYPE),
321                    'content'       => $result->getBody()
322                );
323                return new Zend_Service_Rackspace_Files_Object($this,$data);
324            case '404':
325                $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
326                break;
327            default:
328                $this->errorMsg= $result->getBody();
329                break;
330        }
331        $this->errorCode= $status;
332        return false;
333    }
334    /**
335     * Store a file in a container 
336     *
337     * @param string $container
338     * @param string $object
339     * @param string $content
340     * @param array $metadata
341     * @return boolean
342     */
343    public function storeObject($container,$object,$content,$metadata=array()) {
344        if (empty($container)) {
345            require_once 'Zend/Service/Rackspace/Exception.php';
346            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
347        }
348        if (empty($object)) {
349            require_once 'Zend/Service/Rackspace/Exception.php';
350            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
351        }
352        if (empty($content)) {
353            require_once 'Zend/Service/Rackspace/Exception.php';
354            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_CONTENT);
355        }
356        if (!empty($metadata) && is_array($metadata)) {
357            foreach ($metadata as $key => $value) {
358                $headers[self::METADATA_OBJECT_HEADER.$key]= $value;
359            }
360        }
361        $headers[self::HEADER_HASH]= md5($content);
362        $headers[self::HEADER_CONTENT_LENGTH]= strlen($content);
363        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'PUT',$headers,null,$content);
364        $status= $result->getStatus();
365        switch ($status) {
366            case '201': // break intentionally omitted
367                return true;
368            case '412':
369                $this->errorMsg= self::ERROR_OBJECT_MISSING_PARAM;
370                break;
371            case '422':
372                $this->errorMsg= self::ERROR_OBJECT_CHECKSUM;
373                break;
374            default:
375                $this->errorMsg= $result->getBody();
376                break;
377        }
378        $this->errorCode= $status;
379        return false;
380    }
381    /**
382     * Delete an object in a container
383     *
384     * @param string $container
385     * @param string $object
386     * @return boolean
387     */
388    public function deleteObject($container,$object) {
389        if (empty($container)) {
390            require_once 'Zend/Service/Rackspace/Exception.php';
391            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
392        }
393        if (empty($object)) {
394            require_once 'Zend/Service/Rackspace/Exception.php';
395            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
396        }
397        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'DELETE');
398        $status= $result->getStatus();
399        switch ($status) {
400            case '204': // break intentionally omitted
401                return true;
402            case '404':
403                $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
404                break;
405            default:
406                $this->errorMsg= $result->getBody();
407                break;
408        }
409        $this->errorCode= $status;
410        return false;
411    }
412    /**
413     * Copy an object from a container to another
414     *
415     * @param string $container_source
416     * @param string $obj_source
417     * @param string $container_dest
418     * @param string $obj_dest
419     * @param array $metadata
420     * @param string $content_type
421     * @return boolean
422     */
423    public function copyObject($container_source,$obj_source,$container_dest,$obj_dest,$metadata=array(),$content_type=null) {
424        if (empty($container_source)) {
425            require_once 'Zend/Service/Rackspace/Exception.php';
426            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_SOURCE_CONTAINER);
427        }
428        if (empty($obj_source)) {
429            require_once 'Zend/Service/Rackspace/Exception.php';
430            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_SOURCE_OBJECT);
431        }
432        if (empty($container_dest)) {
433            require_once 'Zend/Service/Rackspace/Exception.php';
434            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_DEST_CONTAINER);
435        }
436        if (empty($obj_dest)) {
437            require_once 'Zend/Service/Rackspace/Exception.php';
438            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_DEST_OBJECT);
439        }
440        $headers= array(
441            self::HEADER_COPY_FROM => '/'.rawurlencode($container_source).'/'.rawurlencode($obj_source),
442            self::HEADER_CONTENT_LENGTH => 0
443        );
444        if (!empty($content_type)) {
445            $headers[self::HEADER_CONTENT_TYPE]= $content_type;
446        }
447        if (!empty($metadata) && is_array($metadata)) {
448            foreach ($metadata as $key => $value) {
449                $headers[self::METADATA_OBJECT_HEADER.$key]= $value;
450            }
451        }
452        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container_dest).'/'.rawurlencode($obj_dest),'PUT',$headers);
453        $status= $result->getStatus();
454        switch ($status) {
455            case '201': // break intentionally omitted
456                return true;
457            default:
458                $this->errorMsg= $result->getBody();
459                break;
460        }
461        $this->errorCode= $status;
462        return false;
463    }
464    /**
465     * Get the metadata of an object
466     *
467     * @param string $container
468     * @param string $object
469     * @return array|boolean
470     */
471    public function getMetadataObject($container,$object) {
472        if (empty($container)) {
473            require_once 'Zend/Service/Rackspace/Exception.php';
474            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
475        }
476        if (empty($object)) {
477            require_once 'Zend/Service/Rackspace/Exception.php';
478            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
479        }
480        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'HEAD');
481        $status= $result->getStatus();
482        switch ($status) {
483            case '200': // break intentionally omitted
484                $headers= $result->getHeaders();
485                $count= strlen(self::METADATA_OBJECT_HEADER);
486                // Zend_Http_Response alters header name in array key, so match our header to what will be in the headers array
487                $headerName = ucwords(strtolower(self::METADATA_OBJECT_HEADER)); 
488                $metadata= array();
489                foreach ($headers as $type => $value) {
490                    if (strpos($type,$headerName)!==false) {
491                        $metadata[strtolower(substr($type, $count))]= $value;
492                    }
493                }
494                $data= array (
495                    'name'          => $object,
496                    'container'     => $container,
497                    'hash'          => $result->getHeader(self::HEADER_HASH),
498                    'bytes'         => $result->getHeader(self::HEADER_CONTENT_LENGTH),
499                    'content_type'  => $result->getHeader(self::HEADER_CONTENT_TYPE),
500                    'last_modified' => $result->getHeader(self::HEADER_LAST_MODIFIED),
501                    'metadata'      => $metadata
502                );
503                return $data;
504            case '404':
505                $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
506                break;
507            default:
508                $this->errorMsg= $result->getBody();
509                break;
510        }
511        $this->errorCode= $status;
512        return false;
513    }
514    /**
515     * Set the metadata of a object in a container
516     * The old metadata values are replaced with the new one
517     * 
518     * @param string $container
519     * @param string $object
520     * @param array $metadata
521     * @return boolean
522     */
523    public function setMetadataObject($container,$object,$metadata)
524    {
525        if (empty($container)) {
526            require_once 'Zend/Service/Rackspace/Exception.php';
527            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
528        }
529        if (empty($object)) {
530            require_once 'Zend/Service/Rackspace/Exception.php';
531            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
532        }
533        if (empty($metadata) || !is_array($metadata)) {
534            require_once 'Zend/Service/Rackspace/Exception.php';
535            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
536        }
537        $headers=array();
538        foreach ($metadata as $key => $value) {
539            $headers[self::METADATA_OBJECT_HEADER.$key]= $value;
540        }
541        $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'POST',$headers);
542        $status= $result->getStatus();
543        switch ($status) {
544            case '202': // break intentionally omitted
545                return true;
546            case '404':
547                $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
548                break;
549            default:
550                $this->errorMsg= $result->getBody();
551                break;
552        }
553        $this->errorCode= $status;
554        return false;
555    }
556    /**
557     * Enable the CDN for a container
558     *
559     * @param  string $container
560     * @param  integer $ttl
561     * @return array|boolean
562     */
563    public function enableCdnContainer ($container,$ttl=self::CDN_TTL_MIN) {
564        if (empty($container)) {
565            require_once 'Zend/Service/Rackspace/Exception.php';
566            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
567        }
568        $headers=array();
569        if (is_numeric($ttl) && ($ttl>=self::CDN_TTL_MIN) && ($ttl<=self::CDN_TTL_MAX)) {
570            $headers[self::CDN_TTL]= $ttl;
571        } else {
572            require_once 'Zend/Service/Rackspace/Exception.php';
573            throw new Zend_Service_Rackspace_Exception(self::ERROR_CDN_TTL_OUT_OF_RANGE);
574        }
575        $result= $this->httpCall($this->getCdnUrl().'/'.rawurlencode($container),'PUT',$headers);
576        $status= $result->getStatus();
577        switch ($status) {
578            case '201':
579            case '202': // break intentionally omitted
580                $data= array (
581                    'cdn_uri'     => $result->getHeader(self::CDN_URI),
582                    'cdn_uri_ssl' => $result->getHeader(self::CDN_SSL_URI)
583                );
584                return $data;
585            case '404':
586                $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
587                break;
588            default:
589                $this->errorMsg= $result->getBody();
590                break;
591        }
592        $this->errorCode= $status;
593        return false;
594    }
595    /**
596     * Update the attribute of a CDN container
597     *
598     * @param  string $container
599     * @param  integer $ttl
600     * @param  boolean $cdn_enabled
601     * @param  boolean $log
602     * @return boolean
603     */
604    public function updateCdnContainer($container,$ttl=null,$cdn_enabled=null,$log=null)
605    {
606        if (empty($container)) {
607            require_once 'Zend/Service/Rackspace/Exception.php';
608            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
609        }
610        if (empty($ttl) && (!isset($cdn_enabled)) && (!isset($log))) {
611            require_once 'Zend/Service/Rackspace/Exception.php';
612            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_UPDATE_CDN);
613        }
614        $headers=array();
615        if (isset($ttl)) {
616            if (is_numeric($ttl) && ($ttl>=self::CDN_TTL_MIN) && ($ttl<=self::CDN_TTL_MAX)) {
617                $headers[self::CDN_TTL]= $ttl;
618            } else {
619                require_once 'Zend/Service/Rackspace/Exception.php';
620                throw new Zend_Service_Rackspace_Exception(self::ERROR_CDN_TTL_OUT_OF_RANGE);
621            }
622        }
623        if (isset($cdn_enabled)) {
624            if ($cdn_enabled===true) {
625                $headers[self::CDN_ENABLED]= 'true';
626            } else {
627                $headers[self::CDN_ENABLED]= 'false';
628            }
629        }
630        if (isset($log)) {
631            if ($log===true) {
632                $headers[self::CDN_LOG_RETENTION]= 'true';
633            } else  {
634                $headers[self::CDN_LOG_RETENTION]= 'false';
635            }
636        }
637        $result= $this->httpCall($this->getCdnUrl().'/'.rawurlencode($container),'POST',$headers);
638        $status= $result->getStatus();
639        switch ($status) {
640            case '200':
641            case '202': // break intentionally omitted
642                return true;
643            case '404':
644                $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
645                break;
646            default:
647                $this->errorMsg= $result->getBody();
648                break;
649        }
650        $this->errorCode= $status;
651        return false;
652    }
653    /**
654     * Get the information of a Cdn container
655     *
656     * @param string $container
657     * @return array|boolean
658     */
659    public function getInfoCdnContainer($container) {
660        if (empty($container)) {
661            require_once 'Zend/Service/Rackspace/Exception.php';
662            throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
663        }
664        $result= $this->httpCall($this->getCdnUrl().'/'.rawurlencode($container),'HEAD');
665        $status= $result->getStatus();
666        switch ($status) {
667            case '204': // break intentionally omitted
668                $data= array (
669                    'ttl'         => $result->getHeader(self::CDN_TTL),
670                    'cdn_uri'     => $result->getHeader(self::CDN_URI),
671                    'cdn_uri_ssl' => $result->getHeader(self::CDN_SSL_URI)
672                );
673                $data['cdn_enabled']= (strtolower($result->getHeader(self::CDN_ENABLED))!=='false');
674                $data['log_retention']= (strtolower($result->getHeader(self::CDN_LOG_RETENTION))!=='false');
675                return $data;
676            case '404':
677                $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
678                break;
679            default:
680                $this->errorMsg= $result->getBody();
681                break;
682        }
683        $this->errorCode= $status;
684        return false;
685    }
686}