MediaWiki  master
StreamFile.php
Go to the documentation of this file.
1 <?php
2 
26 
30 class StreamFile {
31  // Do not send any HTTP headers unless requested by caller (e.g. body only)
34  // Do not try to tear down any PHP output buffers
37 
51  public static function stream(
52  $fname, $headers = [], $sendErrors = true, $optHeaders = [], $flags = 0
53  ) {
54  if ( FileBackend::isStoragePath( $fname ) ) {
55  throw new InvalidArgumentException( __FUNCTION__ . " given storage path '$fname'." );
56  }
57 
58  $streamer = new HTTPFileStreamer(
59  $fname,
60  [
61  'obResetFunc' => 'wfResetOutputBuffers',
62  'streamMimeFunc' => [ __CLASS__, 'contentTypeFromPath' ]
63  ]
64  );
65 
66  return $streamer->stream( $headers, $sendErrors, $optHeaders, $flags );
67  }
68 
76  public static function contentTypeFromPath( $filename, $safe = true ) {
77  $trivialMimeDetection = MediaWikiServices::getInstance()->getMainConfig()
78  ->get( MainConfigNames::TrivialMimeDetection );
79 
80  $ext = strrchr( $filename, '.' );
81  $ext = $ext ? strtolower( substr( $ext, 1 ) ) : '';
82 
83  # trivial detection by file extension,
84  # used for thumbnails (thumb.php)
85  if ( $trivialMimeDetection ) {
86  switch ( $ext ) {
87  case 'gif':
88  return 'image/gif';
89  case 'png':
90  return 'image/png';
91  case 'jpg':
92  case 'jpeg':
93  return 'image/jpeg';
94  }
95 
96  return 'unknown/unknown';
97  }
98 
99  $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
100  // Use the extension only, rather than magic numbers, to avoid opening
101  // up vulnerabilities due to uploads of files with allowed extensions
102  // but disallowed types.
103  $type = $magic->getMimeTypeFromExtensionOrNull( $ext );
104 
109  if ( $safe ) {
110  $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
111  $prohibitedFileExtensions = $mainConfig->get( MainConfigNames::ProhibitedFileExtensions );
112  $checkFileExtensions = $mainConfig->get( MainConfigNames::CheckFileExtensions );
113  $strictFileExtensions = $mainConfig->get( MainConfigNames::StrictFileExtensions );
114  $fileExtensions = $mainConfig->get( MainConfigNames::FileExtensions );
115  $verifyMimeType = $mainConfig->get( MainConfigNames::VerifyMimeType );
116  $mimeTypeExclusions = $mainConfig->get( MainConfigNames::MimeTypeExclusions );
117  [ , $extList ] = UploadBase::splitExtensions( $filename );
118  if ( UploadBase::checkFileExtensionList( $extList, $prohibitedFileExtensions ) ) {
119  return 'unknown/unknown';
120  }
121  if ( $checkFileExtensions && $strictFileExtensions
122  && !UploadBase::checkFileExtensionList( $extList, $fileExtensions )
123  ) {
124  return 'unknown/unknown';
125  }
126  if ( $verifyMimeType && $type !== null && in_array( strtolower( $type ), $mimeTypeExclusions ) ) {
127  return 'unknown/unknown';
128  }
129  }
130  return $type;
131  }
132 }
static isStoragePath( $path)
Check if a given path is a "mwstore://" path.
Functions related to the output of file content.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
Functions related to the output of file content.
Definition: StreamFile.php:30
static contentTypeFromPath( $filename, $safe=true)
Determine the file type of a file based on the path.
Definition: StreamFile.php:76
const STREAM_HEADLESS
Definition: StreamFile.php:33
const STREAM_ALLOW_OB
Definition: StreamFile.php:36
static stream( $fname, $headers=[], $sendErrors=true, $optHeaders=[], $flags=0)
Stream a file to the browser, adding all the headings and fun stuff.
Definition: StreamFile.php:51
static splitExtensions( $filename)
Split a file into a base name and all dot-delimited 'extensions' on the end.
static checkFileExtensionList( $ext, $list)
Perform case-insensitive match against a list of file extensions.
if(!is_readable( $file)) $ext
Definition: router.php:48