Aaron Schulz has uploaded a new change for review. https://gerrit.wikimedia.org/r/86642
Change subject: Added supported for retrieving file metadata/headers ...................................................................... Added supported for retrieving file metadata/headers Change-Id: I4534e9acac2b306086797b3677f85c05b98e39fc --- M includes/filebackend/FileBackend.php M includes/filebackend/FileBackendMultiWrite.php M includes/filebackend/FileBackendStore.php M includes/filebackend/SwiftFileBackend.php 4 files changed, 111 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/42/86642/1 diff --git a/includes/filebackend/FileBackend.php b/includes/filebackend/FileBackend.php index bdeb578..3d73294 100644 --- a/includes/filebackend/FileBackend.php +++ b/includes/filebackend/FileBackend.php @@ -71,6 +71,10 @@ /** @var FileJournal */ protected $fileJournal; + /** Flags for supported features */ + const ATTR_HEADERS = 1; + const ATTR_METADATA = 2; + /** * Create a new backend instance from configuration. * This should only be called from within FileBackendGroup. @@ -162,6 +166,27 @@ */ final public function getReadOnlyReason() { return ( $this->readOnly != '' ) ? $this->readOnly : false; + } + + /** + * Get the a bitfield of extra features supported by the backend medium + * + * @return integer Bitfield of FileBackend::ATTR_* flags + * @since 1.22 + */ + public function getFeatures() { + return 0; + } + + /** + * Check if the backend medium supports a field of extra features + * + * @return integer Bitfield of FileBackend::ATTR_* flags + * @return bool + * @since 1.22 + */ + final public function hasFeatures( $bitfield ) { + return ( $this->getFeatures() & $bitfield ) === $bitfield; } /** @@ -874,6 +899,24 @@ abstract public function getFileContentsMulti( array $params ); /** + * Get metadata about a file at a storage path in the backend. + * If the file does not exist, then this returns false. + * Otherwise, the result is an associative array that includes: + * - headers : map of HTTP headers used for GET/HEAD requests (name => value) + * - metadata : map of file metadata (name => value) + * Additional values may be included for internal use only. + * Use FileBackend::hasFeatures() to check if this is supported. + * + * @param array $params + * $params include: + * - src : source storage path + * - latest : use the latest available data + * @return Array|bool|null Returns null on failure + * @since 1.22 + */ + abstract public function getFileXAttributes( array $params ); + + /** * Get the size (bytes) of a file at a storage path in the backend. * * @param array $params diff --git a/includes/filebackend/FileBackendMultiWrite.php b/includes/filebackend/FileBackendMultiWrite.php index 7d35487..40beafe 100644 --- a/includes/filebackend/FileBackendMultiWrite.php +++ b/includes/filebackend/FileBackendMultiWrite.php @@ -616,6 +616,10 @@ return $this->backends[$this->masterIndex]->getFileList( $realParams ); } + public function getFeatures() { + return $this->backends[$this->masterIndex]->getFeatures(); + } + public function clearCache( array $paths = null ) { foreach ( $this->backends as $backend ) { $realPaths = is_array( $paths ) ? $this->substPaths( $paths, $backend ) : null; diff --git a/includes/filebackend/FileBackendStore.php b/includes/filebackend/FileBackendStore.php index e976a7a..8dbf725 100644 --- a/includes/filebackend/FileBackendStore.php +++ b/includes/filebackend/FileBackendStore.php @@ -606,6 +606,10 @@ $this->cheapCache->set( $path, 'sha1', array( 'hash' => $stat['sha1'], 'latest' => $latest ) ); } + if ( isset( $stat['xattr'] ) ) { // some backends store headers/metadata + $this->cheapCache->set( $path, 'xattr', + array( 'map' => $stat['xattr'], 'latest' => $latest ) ); + } } elseif ( $stat === false ) { // file does not exist $this->cheapCache->set( $path, 'stat', $latest ? 'NOT_EXIST_LATEST' : 'NOT_EXIST' ); $this->cheapCache->set( $path, 'sha1', // the SHA-1 must be false too @@ -643,6 +647,38 @@ wfRestoreWarnings(); } return $contents; + } + + final public function getFileXAttributes( array $params ) { + $path = self::normalizeStoragePath( $params['src'] ); + if ( $path === null ) { + return false; // invalid storage path + } + $section = new ProfileSection( __METHOD__ . "-{$this->name}" ); + $latest = !empty( $params['latest'] ); // use latest data? + if ( $this->cheapCache->has( $path, 'xattr', self::CACHE_TTL ) ) { + $stat = $this->cheapCache->get( $path, 'xattr' ); + // If we want the latest data, check that this cached + // value was in fact fetched with the latest available data. + if ( !$latest || $stat['latest'] ) { + return $stat['map']; + } + } + wfProfileIn( __METHOD__ . '-miss' ); + wfProfileIn( __METHOD__ . '-miss-' . $this->name ); + $fields = $this->doGetFileXAttributes( $params ); + wfProfileOut( __METHOD__ . '-miss-' . $this->name ); + wfProfileOut( __METHOD__ . '-miss' ); + $this->cheapCache->set( $path, 'xattr', array( 'map' => $fields, 'latest' => $latest ) ); + return $fields; + } + + /** + * @see FileBackendStore::getFileXAttributes() + * @return bool|string + */ + protected function doGetFileXAttributes( array $params ) { + return array( 'map' => array(), 'latest' => true ); // not supported } final public function getFileSha1Base36( array $params ) { @@ -1560,6 +1596,10 @@ $this->cheapCache->set( $path, 'sha1', array( 'hash' => $val['sha1'], 'latest' => $val['latest'] ) ); } + if ( isset( $val['xattr'] ) ) { // some backends store headers/metadata + $this->cheapCache->set( $path, 'xattr', + array( 'map' => $val['xattr'], 'latest' => $val['latest'] ) ); + } } } } diff --git a/includes/filebackend/SwiftFileBackend.php b/includes/filebackend/SwiftFileBackend.php index f3aa145..b1a08f4 100644 --- a/includes/filebackend/SwiftFileBackend.php +++ b/includes/filebackend/SwiftFileBackend.php @@ -159,6 +159,10 @@ $this->srvCache = $this->srvCache ? $this->srvCache : new EmptyBagOStuff(); } + public function getFeatures() { + return ( FileBackend::ATTR_HEADERS | FileBackend::ATTR_METADATA ); + } + /** * @see FileBackendStore::resolveContainerPath() * @return null @@ -766,9 +770,12 @@ $this->addMissingMetadata( $srcObj, $params['src'] ); $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' ) + 'mtime' => wfTimestamp( TS_MW, $srcObj->last_modified ), + 'size' => (int)$srcObj->content_length, + 'sha1' => $srcObj->getMetadataValue( 'Sha1base36' ), + 'xattr' => array( + 'headers' => $srcObj->headers, + 'metadata' => $srcObj->metadata ) ); } catch ( NoSuchContainerException $e ) { } catch ( NoSuchObjectException $e ) { @@ -1087,6 +1094,20 @@ return array_reverse( $names ); // keep the paths in original order } + protected function doGetFileXAttributes( array $params ) { + $stat = $this->getFileStat( $params ); + if ( $stat ) { + if ( !isset( $stat['xattr'] ) ) { + // Stat entries filled by file listings don't include metadata/headers + $this->clearCache( array( $params['src'] ) ); + $stat = $this->getFileStat( $params ); + } + return $stat['xattr']; + } else { + return false; + } + } + protected function doGetFileSha1base36( array $params ) { $stat = $this->getFileStat( $params ); if ( $stat ) { -- To view, visit https://gerrit.wikimedia.org/r/86642 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4534e9acac2b306086797b3677f85c05b98e39fc Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Aaron Schulz <asch...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits