thumb.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * PHP script to stream out an image thumbnail.
  4. *
  5. * @file
  6. * @ingroup Media
  7. */
  8. define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
  9. require_once( './includes/WebStart.php' );
  10. $wgTrivialMimeDetection = true; //don't use fancy mime detection, just check the file extension for jpg/gif/png.
  11. require_once( "$IP/includes/StreamFile.php" );
  12. wfThumbMain();
  13. wfLogProfilingData();
  14. //--------------------------------------------------------------------------
  15. function wfThumbMain() {
  16. wfProfileIn( __METHOD__ );
  17. // Get input parameters
  18. if ( get_magic_quotes_gpc() ) {
  19. $params = array_map( 'stripslashes', $_REQUEST );
  20. } else {
  21. $params = $_REQUEST;
  22. }
  23. $fileName = isset( $params['f'] ) ? $params['f'] : '';
  24. unset( $params['f'] );
  25. // Backwards compatibility parameters
  26. if ( isset( $params['w'] ) ) {
  27. $params['width'] = $params['w'];
  28. unset( $params['w'] );
  29. }
  30. if ( isset( $params['p'] ) ) {
  31. $params['page'] = $params['p'];
  32. }
  33. unset( $params['r'] );
  34. // Is this a thumb of an archived file?
  35. $isOld = (isset( $params['archived'] ) && $params['archived']);
  36. unset( $params['archived'] );
  37. // Some basic input validation
  38. $fileName = strtr( $fileName, '\\/', '__' );
  39. // Actually fetch the image. Method depends on whether it is archived or not.
  40. if( $isOld ) {
  41. // Format is <timestamp>!<name>
  42. $bits = explode( '!', $fileName, 2 );
  43. if( !isset($bits[1]) ) {
  44. wfThumbError( 404, wfMsg( 'badtitletext' ) );
  45. return;
  46. }
  47. $title = Title::makeTitleSafe( NS_FILE, $bits[1] );
  48. if( is_null($title) ) {
  49. wfThumbError( 404, wfMsg( 'badtitletext' ) );
  50. return;
  51. }
  52. $img = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $fileName );
  53. } else {
  54. $img = wfLocalFile( $fileName );
  55. }
  56. if ( !$img ) {
  57. wfThumbError( 404, wfMsg( 'badtitletext' ) );
  58. return;
  59. }
  60. if ( !$img->exists() ) {
  61. wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
  62. return;
  63. }
  64. $sourcePath = $img->getPath();
  65. if ( $sourcePath === false ) {
  66. wfThumbError( 500, 'The source file is not locally accessible.' );
  67. return;
  68. }
  69. // Check IMS against the source file
  70. // This means that clients can keep a cached copy even after it has been deleted on the server
  71. if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
  72. // Fix IE brokenness
  73. $imsString = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
  74. // Calculate time
  75. wfSuppressWarnings();
  76. $imsUnix = strtotime( $imsString );
  77. wfRestoreWarnings();
  78. $stat = @stat( $sourcePath );
  79. if ( $stat['mtime'] <= $imsUnix ) {
  80. header( 'HTTP/1.1 304 Not Modified' );
  81. return;
  82. }
  83. }
  84. // Stream the file if it exists already
  85. try {
  86. if ( false != ( $thumbName = $img->thumbName( $params ) ) ) {
  87. $thumbPath = $img->getThumbPath( $thumbName );
  88. if ( is_file( $thumbPath ) ) {
  89. wfStreamFile( $thumbPath );
  90. return;
  91. }
  92. }
  93. } catch ( MWException $e ) {
  94. wfThumbError( 500, $e->getHTML() );
  95. return;
  96. }
  97. try {
  98. $thumb = $img->transform( $params, File::RENDER_NOW );
  99. } catch( Exception $ex ) {
  100. // Tried to select a page on a non-paged file?
  101. $thumb = false;
  102. }
  103. $errorMsg = false;
  104. if ( !$thumb ) {
  105. $errorMsg = wfMsgHtml( 'thumbnail_error', 'File::transform() returned false' );
  106. } elseif ( $thumb->isError() ) {
  107. $errorMsg = $thumb->getHtmlMsg();
  108. } elseif ( !$thumb->getPath() ) {
  109. $errorMsg = wfMsgHtml( 'thumbnail_error', 'No path supplied in thumbnail object' );
  110. } elseif ( $thumb->getPath() == $img->getPath() ) {
  111. $errorMsg = wfMsgHtml( 'thumbnail_error', 'Image was not scaled, ' .
  112. 'is the requested width bigger than the source?' );
  113. } else {
  114. wfStreamFile( $thumb->getPath() );
  115. }
  116. if ( $errorMsg !== false ) {
  117. wfThumbError( 500, $errorMsg );
  118. }
  119. wfProfileOut( __METHOD__ );
  120. }
  121. function wfThumbError( $status, $msg ) {
  122. global $wgShowHostnames;
  123. header( 'Cache-Control: no-cache' );
  124. header( 'Content-Type: text/html; charset=utf-8' );
  125. if ( $status == 404 ) {
  126. header( 'HTTP/1.1 404 Not found' );
  127. } else {
  128. header( 'HTTP/1.1 500 Internal server error' );
  129. }
  130. if( $wgShowHostnames ) {
  131. $url = htmlspecialchars( @$_SERVER['REQUEST_URI'] );
  132. $hostname = htmlspecialchars( wfHostname() );
  133. $debug = "<!-- $url -->\n<!-- $hostname -->\n";
  134. } else {
  135. $debug = "";
  136. }
  137. echo <<<EOT
  138. <html><head><title>Error generating thumbnail</title></head>
  139. <body>
  140. <h1>Error generating thumbnail</h1>
  141. <p>
  142. $msg
  143. </p>
  144. $debug
  145. </body>
  146. </html>
  147. EOT;
  148. }