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

Reply via email to