MediaWiki master
StreamFile.php
Go to the documentation of this file.
1<?php
2
24namespace MediaWiki\Output;
25
26use FileBackend;
28use InvalidArgumentException;
31use RequestContext;
32use UploadBase;
33
39 private const UNKNOWN_CONTENT_TYPE = 'unknown/unknown';
40
53 public static function stream(
54 $fname,
55 $headers = [],
56 $sendErrors = true,
57 $optHeaders = [],
58 $flags = 0
59 ) {
60 if ( FileBackend::isStoragePath( $fname ) ) {
61 throw new InvalidArgumentException( __FUNCTION__ . " given storage path '$fname'." );
62 }
63
64 $streamer = new HTTPFileStreamer(
65 $fname,
66 [
67 'obResetFunc' => 'wfResetOutputBuffers',
68 'streamMimeFunc' => [ __CLASS__, 'contentTypeFromPath' ],
69 'headerFunc' => [ __CLASS__, 'setHeader' ],
70 ]
71 );
72
73 return $streamer->stream( $headers, $sendErrors, $optHeaders, $flags );
74 }
75
81 public static function setHeader( $header ) {
82 RequestContext::getMain()->getRequest()->response()->header( $header );
83 }
84
92 public static function contentTypeFromPath( $filename, $safe = true ) {
93 // NOTE: TrivialMimeDetection is forced by ThumbnailEntryPoint. When this
94 // code is moved to a non-static method in a service object, we can no
95 // longer rely on that.
96 $trivialMimeDetection = MediaWikiServices::getInstance()->getMainConfig()
98
99 $ext = strrchr( $filename, '.' );
100 $ext = $ext ? strtolower( substr( $ext, 1 ) ) : '';
101
102 # trivial detection by file extension,
103 # used for thumbnails (thumb.php)
104 if ( $trivialMimeDetection ) {
105 switch ( $ext ) {
106 case 'gif':
107 return 'image/gif';
108 case 'png':
109 return 'image/png';
110 case 'jpg':
111 case 'jpeg':
112 return 'image/jpeg';
113 }
114
115 return self::UNKNOWN_CONTENT_TYPE;
116 }
117
118 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
119 // Use the extension only, rather than magic numbers, to avoid opening
120 // up vulnerabilities due to uploads of files with allowed extensions
121 // but disallowed types.
122 $type = $magic->getMimeTypeFromExtensionOrNull( $ext );
123
128 if ( $safe ) {
129 $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
130 $prohibitedFileExtensions = $mainConfig->get( MainConfigNames::ProhibitedFileExtensions );
131 $checkFileExtensions = $mainConfig->get( MainConfigNames::CheckFileExtensions );
132 $strictFileExtensions = $mainConfig->get( MainConfigNames::StrictFileExtensions );
133 $fileExtensions = $mainConfig->get( MainConfigNames::FileExtensions );
134 $verifyMimeType = $mainConfig->get( MainConfigNames::VerifyMimeType );
135 $mimeTypeExclusions = $mainConfig->get( MainConfigNames::MimeTypeExclusions );
136 [ , $extList ] = UploadBase::splitExtensions( $filename );
137 if ( UploadBase::checkFileExtensionList( $extList, $prohibitedFileExtensions ) ) {
138 return self::UNKNOWN_CONTENT_TYPE;
139 }
140 if (
141 $checkFileExtensions &&
142 $strictFileExtensions &&
143 !UploadBase::checkFileExtensionList( $extList, $fileExtensions )
144 ) {
145 return self::UNKNOWN_CONTENT_TYPE;
146 }
147 if ( $verifyMimeType && $type !== null && in_array( strtolower( $type ), $mimeTypeExclusions ) ) {
148 return self::UNKNOWN_CONTENT_TYPE;
149 }
150 }
151 return $type;
152 }
153}
154
156class_alias( StreamFile::class, 'StreamFile' );
Base class for all file backend classes (including multi-write backends).
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.
const MimeTypeExclusions
Name constant for the MimeTypeExclusions setting, for use with Config::get()
const ProhibitedFileExtensions
Name constant for the ProhibitedFileExtensions setting, for use with Config::get()
const TrivialMimeDetection
Name constant for the TrivialMimeDetection setting, for use with Config::get()
const VerifyMimeType
Name constant for the VerifyMimeType setting, for use with Config::get()
const StrictFileExtensions
Name constant for the StrictFileExtensions setting, for use with Config::get()
const FileExtensions
Name constant for the FileExtensions setting, for use with Config::get()
const CheckFileExtensions
Name constant for the CheckFileExtensions setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Functions related to the output of file content.
static setHeader( $header)
static contentTypeFromPath( $filename, $safe=true)
Determine the file type of a file based on the path.
static stream( $fname, $headers=[], $sendErrors=true, $optHeaders=[], $flags=0)
Stream a file to the browser, adding all the headings and fun stuff.
UploadBase and subclasses are the backend of MediaWiki's file uploads.
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.
$header