Aaron Schulz has uploaded a new change for review.
https://gerrit.wikimedia.org/r/173241
Change subject: Improved MIME detection in FileBackend
......................................................................
Improved MIME detection in FileBackend
* The content type detector will now inspect the file contents
to better handle extensionless files.
* Normalize all headers to lower case at the start of the
FileBackend operation methods. This makes it easy for subclasses
to check for certain headers.
* Removed some old Content-Disposition b/c code.
* The Swift backend class now respects Content-Type headers
for create()/store().
Change-Id: Iad59bf6c6a416b706f976a4c425763fd30e2debb
---
M includes/filebackend/FileBackend.php
M includes/filebackend/FileBackendStore.php
M includes/filebackend/SwiftFileBackend.php
3 files changed, 32 insertions(+), 20 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/41/173241/1
diff --git a/includes/filebackend/FileBackend.php
b/includes/filebackend/FileBackend.php
index 8c0a61a..6b2d880 100644
--- a/includes/filebackend/FileBackend.php
+++ b/includes/filebackend/FileBackend.php
@@ -375,11 +375,6 @@
if ( empty( $opts['force'] ) ) { // sanity
unset( $opts['nonLocking'] );
}
- foreach ( $ops as &$op ) {
- if ( isset( $op['disposition'] ) ) { // b/c (MW 1.20)
- $op['headers']['Content-Disposition'] =
$op['disposition'];
- }
- }
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore
client aborts
return $this->doOperationsInternal( $ops, $opts );
}
@@ -608,9 +603,6 @@
}
foreach ( $ops as &$op ) {
$op['overwrite'] = true; // avoids RTTs in key/value
stores
- if ( isset( $op['disposition'] ) ) { // b/c (MW 1.20)
- $op['headers']['Content-Disposition'] =
$op['disposition'];
- }
}
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore
client aborts
return $this->doQuickOperationsInternal( $ops );
diff --git a/includes/filebackend/FileBackendStore.php
b/includes/filebackend/FileBackendStore.php
index 495ac3c..93ed324 100644
--- a/includes/filebackend/FileBackendStore.php
+++ b/includes/filebackend/FileBackendStore.php
@@ -69,8 +69,19 @@
$this->mimeCallback = isset( $config['mimeCallback'] )
? $config['mimeCallback']
: function ( $storagePath, $content, $fsPath ) {
- // @todo handle the case of extension-less
files using the contents
- return StreamFile::contentTypeFromPath(
$storagePath ) ?: 'unknown/unknown';
+ $magic = MimeMagic::singleton();
+ // Trust the extension of the storage path
(caller must validate)
+ $ext = FileBackend::extensionFromPath(
$storagePath );
+ $type = $magic->guessTypesForExtension( $ext );
+ // For files without a valid extension (or one
at all), inspect the contents
+ if ( !$type && $fsPath ) {
+ $type = $magic->guessMimeType( $fsPath,
false );
+ } elseif ( !$type && strlen( $content ) ) {
+ $tmpFile = TempFSFile::factory( 'mime_'
);
+ file_put_contents( $tmpFile->getPath(),
$content );
+ $type = $magic->guessMimeType(
$tmpFile->getPath(), false );
+ }
+ return $type ?: 'unknown/unknown';
};
$this->memCache = new EmptyBagOStuff(); // disabled by default
$this->cheapCache = new ProcessCacheLRU( self::CACHE_CHEAP_SIZE
);
@@ -1075,7 +1086,7 @@
$status = Status::newGood();
// Fix up custom header name/value pairs...
- $ops = array_map( array( $this, 'stripInvalidHeadersFromOp' ),
$ops );
+ $ops = array_map( array( $this, 'sanitizeOpHeaders' ), $ops );
// Build up a list of FileOps...
$performOps = $this->getOperationsInternal( $ops );
@@ -1141,7 +1152,7 @@
$status = Status::newGood();
// Fix up custom header name/value pairs...
- $ops = array_map( array( $this, 'stripInvalidHeadersFromOp' ),
$ops );
+ $ops = array_map( array( $this, 'sanitizeOpHeaders' ), $ops );
// Clear any file cache entries
$this->clearCache();
@@ -1236,7 +1247,9 @@
}
/**
- * Strip long HTTP headers from a file operation.
+ * Normalize and filter HTTP headers from a file operation
+ *
+ * This normalizes and strips long HTTP headers from a file operation.
* Most headers are just numbers, but some are allowed to be long.
* This function is useful for cleaning up headers and avoiding backend
* specific errors, especially in the middle of batch file operations.
@@ -1244,18 +1257,21 @@
* @param array $op Same format as doOperation()
* @return array
*/
- protected function stripInvalidHeadersFromOp( array $op ) {
- static $longs = array( 'Content-Disposition' );
+ protected function sanitizeOpHeaders( array $op ) {
+ static $longs = array( 'content-disposition' );
+
if ( isset( $op['headers'] ) ) { // op sets HTTP headers
+ $newHeaders = array();
foreach ( $op['headers'] as $name => $value ) {
+ $name = strtolower( $name );
$maxHVLen = in_array( $name, $longs ) ? INF :
255;
if ( strlen( $name ) > 255 || strlen( $value )
> $maxHVLen ) {
trigger_error( "Header '$name: $value'
is too long." );
- unset( $op['headers'][$name] );
- } elseif ( !strlen( $value ) ) {
- $op['headers'][$name] = ''; //
null/false => ""
+ } else {
+ $newHeaders[$name] = strlen( $value ) ?
$value : ''; // null/false => ""
}
}
+ $op['headers'] = $newHeaders;
}
return $op;
diff --git a/includes/filebackend/SwiftFileBackend.php
b/includes/filebackend/SwiftFileBackend.php
index 625b9b4..06a1b1b 100644
--- a/includes/filebackend/SwiftFileBackend.php
+++ b/includes/filebackend/SwiftFileBackend.php
@@ -221,7 +221,9 @@
}
$sha1Hash = wfBaseConvert( sha1( $params['content'] ), 16, 36,
31 );
- $contentType = $this->getContentType( $params['dst'],
$params['content'], null );
+ $contentType = isset( $params['headers']['content-type'] )
+ ? $params['headers']['content-type']
+ : $this->getContentType( $params['dst'],
$params['content'], null );
$reqs = array( array(
'method' => 'PUT',
@@ -277,7 +279,9 @@
return $status;
}
$sha1Hash = wfBaseConvert( $sha1Hash, 16, 36, 31 );
- $contentType = $this->getContentType( $params['dst'], null,
$params['src'] );
+ $contentType = isset( $params['headers']['content-type'] )
+ ? $params['headers']['content-type']
+ : $this->getContentType( $params['dst'], null,
$params['src'] );
$handle = fopen( $params['src'], 'rb' );
if ( $handle === false ) { // source doesn't exist?
--
To view, visit https://gerrit.wikimedia.org/r/173241
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iad59bf6c6a416b706f976a4c425763fd30e2debb
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits