Merge "Remove hphpc support and deprecate related functions"
[lhc/web/wiklou.git] / includes / filebackend / SwiftFileBackend.php
index 78386e0..1527cfe 100644 (file)
@@ -104,7 +104,7 @@ class SwiftFileBackend extends FileBackendStore {
         */
        public function __construct( array $config ) {
                parent::__construct( $config );
-               if ( !MWInit::classExists( 'CF_Constants' ) ) {
+               if ( !class_exists( 'CF_Constants' ) ) {
                        throw new MWException( 'SwiftCloudFiles extension not installed.' );
                }
                // Required settings
@@ -132,7 +132,7 @@ class SwiftFileBackend extends FileBackendStore {
                        : false;
                $this->swiftCDNExpiry = isset( $config['swiftCDNExpiry'] )
                        ? $config['swiftCDNExpiry']
-                       : 12*3600; // 12 hours is safe (tokens last 24 hours per http://docs.openstack.org)
+                       : 12 * 3600; // 12 hours is safe (tokens last 24 hours per http://docs.openstack.org)
                $this->swiftCDNPurgable = isset( $config['swiftCDNPurgable'] )
                        ? $config['swiftCDNPurgable']
                        : true;
@@ -194,7 +194,19 @@ class SwiftFileBackend extends FileBackendStore {
        }
 
        /**
-        * @param string $disposition Content-Disposition header value
+        * @param $headers array
+        * @return array
+        */
+       protected function sanitizeHdrs( array $headers ) {
+               // By default, Swift has annoyingly low maximum header value limits
+               if ( isset( $headers['Content-Disposition'] ) ) {
+                       $headers['Content-Disposition'] = $this->truncDisp( $headers['Content-Disposition'] );
+               }
+               return $headers;
+       }
+
+       /**
+        * @param $disposition string Content-Disposition header value
         * @return string Truncated Content-Disposition header value to meet Swift limits
         */
        protected function truncDisp( $disposition ) {
@@ -252,13 +264,9 @@ class SwiftFileBackend extends FileBackendStore {
                        if ( !strlen( $obj->content_type ) ) { // special case
                                $obj->content_type = 'unknown/unknown';
                        }
-                       // Set the Content-Disposition header if requested
-                       if ( isset( $params['disposition'] ) ) {
-                               $obj->headers['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
-                       }
                        // Set any other custom headers if requested
                        if ( isset( $params['headers'] ) ) {
-                               $obj->headers += $params['headers'];
+                               $obj->headers += $this->sanitizeHdrs( $params['headers'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                $op = $obj->write_async( $params['content'] );
@@ -337,13 +345,9 @@ class SwiftFileBackend extends FileBackendStore {
                        if ( !strlen( $obj->content_type ) ) { // special case
                                $obj->content_type = 'unknown/unknown';
                        }
-                       // Set the Content-Disposition header if requested
-                       if ( isset( $params['disposition'] ) ) {
-                               $obj->headers['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
-                       }
                        // Set any other custom headers if requested
                        if ( isset( $params['headers'] ) ) {
-                               $obj->headers += $params['headers'];
+                               $obj->headers += $this->sanitizeHdrs( $params['headers'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                wfSuppressWarnings();
@@ -411,7 +415,9 @@ class SwiftFileBackend extends FileBackendStore {
                        $sContObj = $this->getContainer( $srcCont );
                        $dContObj = $this->getContainer( $dstCont );
                } catch ( NoSuchContainerException $e ) {
-                       $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
+                       if ( empty( $params['ignoreMissingSource'] ) || isset( $sContObj ) ) {
+                               $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
+                       }
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
@@ -422,8 +428,9 @@ class SwiftFileBackend extends FileBackendStore {
                try {
                        $dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
                        $hdrs = array(); // source file headers to override with new values
-                       if ( isset( $params['disposition'] ) ) {
-                               $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
+                       // Set any other custom headers if requested
+                       if ( isset( $params['headers'] ) ) {
+                               $hdrs += $this->sanitizeHdrs( $params['headers'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                $op = $sContObj->copy_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
@@ -481,7 +488,9 @@ class SwiftFileBackend extends FileBackendStore {
                        $sContObj = $this->getContainer( $srcCont );
                        $dContObj = $this->getContainer( $dstCont );
                } catch ( NoSuchContainerException $e ) {
-                       $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
+                       if ( empty( $params['ignoreMissingSource'] ) || isset( $sContObj ) ) {
+                               $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
+                       }
                        return $status;
                } catch ( CloudFilesException $e ) { // some other exception?
                        $this->handleException( $e, $status, __METHOD__, $params );
@@ -493,8 +502,9 @@ class SwiftFileBackend extends FileBackendStore {
                        $srcObj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
                        $dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
                        $hdrs = array(); // source file headers to override with new values
-                       if ( isset( $params['disposition'] ) ) {
-                               $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
+                       // Set any other custom headers if requested
+                       if ( isset( $params['headers'] ) ) {
+                               $hdrs += $this->sanitizeHdrs( $params['headers'] );
                        }
                        if ( !empty( $params['async'] ) ) { // deferred
                                $op = $sContObj->move_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
@@ -557,7 +567,9 @@ class SwiftFileBackend extends FileBackendStore {
                } catch ( CDNNotEnabledException $e ) {
                        // CDN not enabled; nothing to see here
                } catch ( NoSuchContainerException $e ) {
-                       $status->fatal( 'backend-fail-delete', $params['src'] );
+                       if ( empty( $params['ignoreMissingSource'] ) ) {
+                               $status->fatal( 'backend-fail-delete', $params['src'] );
+                       }
                } catch ( NoSuchObjectException $e ) {
                        if ( empty( $params['ignoreMissingSource'] ) ) {
                                $status->fatal( 'backend-fail-delete', $params['src'] );
@@ -597,19 +609,15 @@ class SwiftFileBackend extends FileBackendStore {
                        return $status;
                }
 
-               $hdrs = isset( $params['headers'] ) ? $params['headers'] : array();
-               // Set the Content-Disposition header if requested
-               if ( isset( $params['disposition'] ) ) {
-                       $hdrs['Content-Disposition'] = $this->truncDisp( $params['disposition'] );
-               }
-
                try {
                        $sContObj = $this->getContainer( $srcCont );
                        // Get the latest version of the current metadata
                        $srcObj = $sContObj->get_object( $srcRel,
                                $this->headersFromParams( array( 'latest' => true ) ) );
                        // Merge in the metadata updates...
-                       $srcObj->headers = $hdrs + $srcObj->headers;
+                       if ( isset( $params['headers'] ) ) {
+                               $srcObj->headers = $this->sanitizeHdrs( $params['headers'] ) + $srcObj->headers;
+                       }
                        $srcObj->sync_metadata(); // save to Swift
                        $this->purgeCDNCache( array( $srcObj ) );
                } catch ( CDNNotEnabledException $e ) {
@@ -799,8 +807,8 @@ class SwiftFileBackend extends FileBackendStore {
                        $stat = array(
                                // Convert dates like "Tue, 03 Jan 2012 22:01:04 GMT" to TS_MW
                                'mtime' => wfTimestamp( TS_MW, $srcObj->last_modified ),
-                               'size'  => (int)$srcObj->content_length,
-                               'sha1'  => $srcObj->getMetadataValue( 'Sha1base36' )
+                               'size' => (int)$srcObj->content_length,
+                               'sha1' => $srcObj->getMetadataValue( 'Sha1base36' )
                        );
                } catch ( NoSuchContainerException $e ) {
                } catch ( NoSuchObjectException $e ) {
@@ -1231,8 +1239,8 @@ class SwiftFileBackend extends FileBackendStore {
                                                str_replace( '/swift/v1', '', // S3 API is the rgw default
                                                        $sContObj->cfs_http->getStorageUrl() . $spath ),
                                                array(
-                                                       'Signature'      => $signature,
-                                                       'Expires'        => $expires,
+                                                       'Signature' => $signature,
+                                                       'Expires' => $expires,
                                                        'AWSAccessKeyId' => $this->rgwS3AccessKey )
                                        );
                                }
@@ -1257,7 +1265,7 @@ class SwiftFileBackend extends FileBackendStore {
         * on a FileBackend params array, e.g. that of getLocalCopy().
         * $params is currently only checked for a 'latest' flag.
         *
-        * @param $params Array
+        * @param array $params
         * @return Array
         */
        protected function headersFromParams( array $params ) {
@@ -1308,7 +1316,7 @@ class SwiftFileBackend extends FileBackendStore {
         *                           matches the expression and the request is not for a listing.
         *                           Setting this to '*' effectively makes a container public.
         *   -".rlistings:<regex>" : Grants access if the request is from a referrer host that
-        *                           matches the expression and the request for a listing.
+        *                           matches the expression and the request is for a listing.
         *
         * $writeGrps is a list of the possible criteria for a request to have
         * access to write to a container. Each item is of the following format:
@@ -1389,12 +1397,12 @@ class SwiftFileBackend extends FileBackendStore {
                        if ( is_array( $creds ) ) { // cache hit
                                $this->auth->load_cached_credentials(
                                        $creds['auth_token'], $creds['storage_url'], $creds['cdnm_url'] );
-                               $this->sessionStarted = time() - ceil( $this->authTTL/2 ); // skew for worst case
+                               $this->sessionStarted = time() - ceil( $this->authTTL / 2 ); // skew for worst case
                        } else { // cache miss
                                try {
                                        $this->auth->authenticate();
                                        $creds = $this->auth->export_credentials();
-                                       $this->srvCache->add( $cacheKey, $creds, ceil( $this->authTTL/2 ) ); // cache
+                                       $this->srvCache->add( $cacheKey, $creds, ceil( $this->authTTL / 2 ) ); // cache
                                        $this->sessionStarted = time();
                                } catch ( CloudFilesException $e ) {
                                        $this->connException = $e; // don't keep re-trying
@@ -1514,7 +1522,7 @@ class SwiftFileBackend extends FileBackendStore {
         * @param $e Exception
         * @param $status Status|null
         * @param $func string
-        * @param $params Array
+        * @param array $params
         * @return void
         */
        protected function handleException( Exception $e, $status, $func, array $params ) {
@@ -1583,7 +1591,7 @@ abstract class SwiftFileBackendList implements Iterator {
         * @param $backend SwiftFileBackend
         * @param string $fullCont Resolved container name
         * @param string $dir Resolved directory relative to container
-        * @param $params Array
+        * @param array $params
         */
        public function __construct( SwiftFileBackend $backend, $fullCont, $dir, array $params ) {
                $this->backend = $backend;
@@ -1656,7 +1664,7 @@ abstract class SwiftFileBackendList implements Iterator {
         * @param string $dir Resolved path relative to container
         * @param $after string|null
         * @param $limit integer
-        * @param $params Array
+        * @param array $params
         * @return Traversable|Array|null Returns null on failure
         */
        abstract protected function pageFromList( $container, $dir, &$after, $limit, array $params );