2005-04-16 04:33:34 +00:00
|
|
|
<?php
|
|
|
|
|
|
2006-01-07 13:09:30 +00:00
|
|
|
/**
|
|
|
|
|
* PHP script to stream out an image thumbnail.
|
2007-07-11 08:09:21 +00:00
|
|
|
*
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
|
|
|
|
* @ingroup Media
|
2005-04-16 04:33:34 +00:00
|
|
|
*/
|
2007-02-19 23:03:37 +00:00
|
|
|
define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
|
2006-07-14 05:35:31 +00:00
|
|
|
require_once( './includes/WebStart.php' );
|
2005-05-21 07:46:17 +00:00
|
|
|
|
|
|
|
|
$wgTrivialMimeDetection = true; //don't use fancy mime detection, just check the file extension for jpg/gif/png.
|
|
|
|
|
|
2007-04-20 12:31:36 +00:00
|
|
|
require_once( "$IP/includes/StreamFile.php" );
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
wfThumbMain();
|
|
|
|
|
wfLogProfilingData();
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
//--------------------------------------------------------------------------
|
2007-04-20 12:31:36 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
function wfThumbMain() {
|
|
|
|
|
wfProfileIn( __METHOD__ );
|
2010-03-08 22:39:14 +00:00
|
|
|
|
|
|
|
|
$headers = array();
|
|
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
// Get input parameters
|
|
|
|
|
if ( get_magic_quotes_gpc() ) {
|
|
|
|
|
$params = array_map( 'stripslashes', $_REQUEST );
|
|
|
|
|
} else {
|
|
|
|
|
$params = $_REQUEST;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$fileName = isset( $params['f'] ) ? $params['f'] : '';
|
|
|
|
|
unset( $params['f'] );
|
2005-05-21 07:46:17 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
// Backwards compatibility parameters
|
|
|
|
|
if ( isset( $params['w'] ) ) {
|
|
|
|
|
$params['width'] = $params['w'];
|
|
|
|
|
unset( $params['w'] );
|
|
|
|
|
}
|
|
|
|
|
if ( isset( $params['p'] ) ) {
|
|
|
|
|
$params['page'] = $params['p'];
|
|
|
|
|
}
|
|
|
|
|
unset( $params['r'] );
|
|
|
|
|
|
2008-08-13 01:01:58 +00:00
|
|
|
// Is this a thumb of an archived file?
|
|
|
|
|
$isOld = (isset( $params['archived'] ) && $params['archived']);
|
|
|
|
|
unset( $params['archived'] );
|
|
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
// Some basic input validation
|
|
|
|
|
$fileName = strtr( $fileName, '\\/', '__' );
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-08-13 01:01:58 +00:00
|
|
|
// Actually fetch the image. Method depends on whether it is archived or not.
|
|
|
|
|
if( $isOld ) {
|
2008-08-13 01:11:45 +00:00
|
|
|
// Format is <timestamp>!<name>
|
|
|
|
|
$bits = explode( '!', $fileName, 2 );
|
|
|
|
|
if( !isset($bits[1]) ) {
|
|
|
|
|
wfThumbError( 404, wfMsg( 'badtitletext' ) );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2008-12-01 17:14:30 +00:00
|
|
|
$title = Title::makeTitleSafe( NS_FILE, $bits[1] );
|
2008-08-13 01:24:03 +00:00
|
|
|
if( is_null($title) ) {
|
|
|
|
|
wfThumbError( 404, wfMsg( 'badtitletext' ) );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2008-08-13 01:11:45 +00:00
|
|
|
$img = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $fileName );
|
2008-08-13 01:01:58 +00:00
|
|
|
} else {
|
2009-09-30 19:00:48 +00:00
|
|
|
$img = wfLocalFile( $fileName );
|
2008-08-13 01:01:58 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-08 22:39:14 +00:00
|
|
|
// Check permissions if there are read restrictions
|
|
|
|
|
if ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) {
|
|
|
|
|
if ( !$img->getTitle()->userCanRead() ) {
|
|
|
|
|
wfThumbError( 403, 'Access denied. You do not have permission to access ' .
|
|
|
|
|
'the source file.' );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
$headers[] = 'Cache-Control: private';
|
|
|
|
|
$headers[] = 'Vary: Cookie';
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
if ( !$img ) {
|
|
|
|
|
wfThumbError( 404, wfMsg( 'badtitletext' ) );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if ( !$img->exists() ) {
|
|
|
|
|
wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2008-08-13 02:09:10 +00:00
|
|
|
$sourcePath = $img->getPath();
|
2008-01-30 06:12:35 +00:00
|
|
|
if ( $sourcePath === false ) {
|
|
|
|
|
wfThumbError( 500, 'The source file is not locally accessible.' );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2007-05-04 15:05:42 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
// Check IMS against the source file
|
|
|
|
|
// This means that clients can keep a cached copy even after it has been deleted on the server
|
|
|
|
|
if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
|
|
|
|
|
// Fix IE brokenness
|
|
|
|
|
$imsString = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
|
|
|
|
|
// Calculate time
|
|
|
|
|
wfSuppressWarnings();
|
|
|
|
|
$imsUnix = strtotime( $imsString );
|
2010-07-18 13:16:18 +00:00
|
|
|
$stat = stat( $sourcePath );
|
2008-01-30 06:12:35 +00:00
|
|
|
wfRestoreWarnings();
|
|
|
|
|
if ( $stat['mtime'] <= $imsUnix ) {
|
|
|
|
|
header( 'HTTP/1.1 304 Not Modified' );
|
|
|
|
|
return;
|
2007-05-04 15:05:42 +00:00
|
|
|
}
|
2007-04-20 12:31:36 +00:00
|
|
|
}
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
// Stream the file if it exists already
|
|
|
|
|
try {
|
|
|
|
|
if ( false != ( $thumbName = $img->thumbName( $params ) ) ) {
|
|
|
|
|
$thumbPath = $img->getThumbPath( $thumbName );
|
|
|
|
|
|
|
|
|
|
if ( is_file( $thumbPath ) ) {
|
2010-03-08 22:39:14 +00:00
|
|
|
wfStreamFile( $thumbPath, $headers );
|
2008-01-30 06:12:35 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch ( MWException $e ) {
|
|
|
|
|
wfThumbError( 500, $e->getHTML() );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
try {
|
2007-05-30 21:02:32 +00:00
|
|
|
$thumb = $img->transform( $params, File::RENDER_NOW );
|
2008-01-30 06:12:35 +00:00
|
|
|
} catch( Exception $ex ) {
|
|
|
|
|
// Tried to select a page on a non-paged file?
|
2006-10-02 21:12:28 +00:00
|
|
|
$thumb = false;
|
2006-08-13 17:34:48 +00:00
|
|
|
}
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
$errorMsg = false;
|
|
|
|
|
if ( !$thumb ) {
|
|
|
|
|
$errorMsg = wfMsgHtml( 'thumbnail_error', 'File::transform() returned false' );
|
|
|
|
|
} elseif ( $thumb->isError() ) {
|
|
|
|
|
$errorMsg = $thumb->getHtmlMsg();
|
|
|
|
|
} elseif ( !$thumb->getPath() ) {
|
|
|
|
|
$errorMsg = wfMsgHtml( 'thumbnail_error', 'No path supplied in thumbnail object' );
|
2008-08-13 02:09:10 +00:00
|
|
|
} elseif ( $thumb->getPath() == $img->getPath() ) {
|
2008-01-30 06:12:35 +00:00
|
|
|
$errorMsg = wfMsgHtml( 'thumbnail_error', 'Image was not scaled, ' .
|
|
|
|
|
'is the requested width bigger than the source?' );
|
|
|
|
|
} else {
|
2010-03-08 22:39:14 +00:00
|
|
|
wfStreamFile( $thumb->getPath(), $headers );
|
2008-01-30 06:12:35 +00:00
|
|
|
}
|
|
|
|
|
if ( $errorMsg !== false ) {
|
|
|
|
|
wfThumbError( 500, $errorMsg );
|
|
|
|
|
}
|
2005-04-16 04:33:34 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
}
|
2007-04-20 12:31:36 +00:00
|
|
|
|
2008-01-30 06:12:35 +00:00
|
|
|
function wfThumbError( $status, $msg ) {
|
2008-06-19 23:22:03 +00:00
|
|
|
global $wgShowHostnames;
|
2007-05-04 15:05:42 +00:00
|
|
|
header( 'Cache-Control: no-cache' );
|
|
|
|
|
header( 'Content-Type: text/html; charset=utf-8' );
|
2008-01-30 06:12:35 +00:00
|
|
|
if ( $status == 404 ) {
|
|
|
|
|
header( 'HTTP/1.1 404 Not found' );
|
2010-03-08 22:39:14 +00:00
|
|
|
} elseif ( $status == 403 ) {
|
|
|
|
|
header( 'HTTP/1.1 403 Forbidden' );
|
|
|
|
|
header( 'Vary: Cookie' );
|
2008-01-30 06:12:35 +00:00
|
|
|
} else {
|
|
|
|
|
header( 'HTTP/1.1 500 Internal server error' );
|
|
|
|
|
}
|
2008-06-19 23:22:03 +00:00
|
|
|
if( $wgShowHostnames ) {
|
2010-07-18 13:16:18 +00:00
|
|
|
$url = htmlspecialchars( isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' );
|
2008-06-19 23:22:03 +00:00
|
|
|
$hostname = htmlspecialchars( wfHostname() );
|
|
|
|
|
$debug = "<!-- $url -->\n<!-- $hostname -->\n";
|
|
|
|
|
} else {
|
|
|
|
|
$debug = "";
|
|
|
|
|
}
|
2007-05-04 15:05:42 +00:00
|
|
|
echo <<<EOT
|
|
|
|
|
<html><head><title>Error generating thumbnail</title></head>
|
|
|
|
|
<body>
|
|
|
|
|
<h1>Error generating thumbnail</h1>
|
|
|
|
|
<p>
|
|
|
|
|
$msg
|
|
|
|
|
</p>
|
2008-06-19 23:22:03 +00:00
|
|
|
$debug
|
2007-05-04 15:05:42 +00:00
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
|
|
|
|
|
EOT;
|
|
|
|
|
}
|
|
|
|
|
|