X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Ffilebackend%2FSwiftFileBackend.php;h=408194f49eebe432dd3925acac321f60ab4a0ea9;hb=524c5849274e224449414926cd32559aa76b53e6;hp=3db235b192fac1fcb97b56fd4041c03f19875e0c;hpb=494334891b35e9ff6e6e84d3efddcc38938c9e48;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/filebackend/SwiftFileBackend.php b/includes/filebackend/SwiftFileBackend.php index 3db235b192..408194f49e 100644 --- a/includes/filebackend/SwiftFileBackend.php +++ b/includes/filebackend/SwiftFileBackend.php @@ -138,13 +138,12 @@ class SwiftFileBackend extends FileBackendStore { if ( PHP_SAPI === 'cli' ) { $this->srvCache = wfGetMainCache(); // preferrably memcached } else { - try { // look for APC, XCache, WinCache, ect... - $this->srvCache = ObjectCache::newAccelerator( array() ); - } catch ( Exception $e ) { - } + // look for APC, XCache, WinCache, ect... + $this->srvCache = ObjectCache::newAccelerator( CACHE_NONE ); } + } else { + $this->srvCache = new EmptyBagOStuff(); } - $this->srvCache = $this->srvCache ?: new EmptyBagOStuff(); } public function getFeatures() { @@ -173,30 +172,40 @@ class SwiftFileBackend extends FileBackendStore { /** * Sanitize and filter the custom headers from a $params array. - * We only allow certain Content- and X-Content- headers. + * Only allows certain "standard" Content- and X-Content- headers. * * @param array $params * @return array Sanitized value of 'headers' field in $params */ protected function sanitizeHdrs( array $params ) { + return isset( $params['headers'] ) + ? $this->getCustomHeaders( $params['headers'] ) + : array(); + + } + + /** + * @param array $rawHeaders + * @return array Custom non-metadata HTTP headers + */ + protected function getCustomHeaders( array $rawHeaders ) { $headers = array(); // Normalize casing, and strip out illegal headers - if ( isset( $params['headers'] ) ) { - foreach ( $params['headers'] as $name => $value ) { - $name = strtolower( $name ); - if ( preg_match( '/^content-(type|length)$/', $name ) ) { - continue; // blacklisted - } elseif ( preg_match( '/^(x-)?content-/', $name ) ) { - $headers[$name] = $value; // allowed - } elseif ( preg_match( '/^content-(disposition)/', $name ) ) { - $headers[$name] = $value; // allowed - } + foreach ( $rawHeaders as $name => $value ) { + $name = strtolower( $name ); + if ( preg_match( '/^content-(type|length)$/', $name ) ) { + continue; // blacklisted + } elseif ( preg_match( '/^(x-)?content-/', $name ) ) { + $headers[$name] = $value; // allowed + } elseif ( preg_match( '/^content-(disposition)/', $name ) ) { + $headers[$name] = $value; // allowed } } // By default, Swift has annoyingly low maximum header value limits if ( isset( $headers['content-disposition'] ) ) { $disposition = ''; + // @note: assume FileBackend::makeContentDisposition() already used foreach ( explode( ';', $headers['content-disposition'] ) as $part ) { $part = trim( $part ); $new = ( $disposition === '' ) ? $part : "{$disposition};{$part}"; @@ -212,6 +221,35 @@ class SwiftFileBackend extends FileBackendStore { return $headers; } + /** + * @param array $rawHeaders + * @return array Custom metadata headers + */ + protected function getMetadataHeaders( array $rawHeaders ) { + $headers = array(); + foreach ( $rawHeaders as $name => $value ) { + $name = strtolower( $name ); + if ( strpos( $name, 'x-object-meta-' ) === 0 ) { + $headers[$name] = $value; + } + } + + return $headers; + } + + /** + * @param array $rawHeaders + * @return array Custom metadata headers with prefix removed + */ + protected function getMetadata( array $rawHeaders ) { + $metadata = array(); + foreach ( $this->getMetadataHeaders( $rawHeaders ) as $name => $value ) { + $metadata[substr( $name, strlen( 'x-object-meta-' ) )] = $value; + } + + return $metadata; + } + protected function doCreateInternal( array $params ) { $status = Status::newGood(); @@ -677,6 +715,11 @@ class SwiftFileBackend extends FileBackendStore { return $objHdrs; // failed } + // Find prior custom HTTP headers + $postHeaders = $this->getCustomHeaders( $objHdrs ); + // Find prior metadata headers + $postHeaders += $this->getMetadataHeaders( $objHdrs ); + $status = Status::newGood(); /** @noinspection PhpUnusedLocalVariableInspection */ $scopeLockS = $this->getScopedFileLocks( array( $path ), LockManager::LOCK_UW, $status ); @@ -686,11 +729,13 @@ class SwiftFileBackend extends FileBackendStore { $hash = $tmpFile->getSha1Base36(); if ( $hash !== false ) { $objHdrs['x-object-meta-sha1base36'] = $hash; + // Merge new SHA1 header into the old ones + $postHeaders['x-object-meta-sha1base36'] = $hash; list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $path ); - list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array( + list( $rcode ) = $this->http->run( array( 'method' => 'POST', 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ), - 'headers' => $this->authTokenHeaders( $auth ) + $objHdrs + 'headers' => $this->authTokenHeaders( $auth ) + $postHeaders ) ); if ( $rcode >= 200 && $rcode <= 299 ) { $this->deleteFileCache( $path ); @@ -1550,22 +1595,16 @@ class SwiftFileBackend extends FileBackendStore { */ protected function getStatFromHeaders( array $rhdrs ) { // Fetch all of the custom metadata headers - $metadata = array(); - foreach ( $rhdrs as $name => $value ) { - if ( strpos( $name, 'x-object-meta-' ) === 0 ) { - $metadata[substr( $name, strlen( 'x-object-meta-' ) )] = $value; - } - } + $metadata = $this->getMetadata( $rhdrs ); // Fetch all of the custom raw HTTP headers $headers = $this->sanitizeHdrs( array( 'headers' => $rhdrs ) ); + return array( // Convert various random Swift dates to TS_MW 'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ), // Empty objects actually return no content-length header in Ceph 'size' => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0, - 'sha1' => isset( $rhdrs['x-object-meta-sha1base36'] ) - ? $rhdrs['x-object-meta-sha1base36'] - : null, + 'sha1' => isset( $metadata['sha1base36'] ) ? $metadata['sha1base36'] : null, // Note: manifiest ETags are not an MD5 of the file 'md5' => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null, 'xattr' => array( 'metadata' => $metadata, 'headers' => $headers )