MediaWiki master
StreamFile.php
Go to the documentation of this file.
1<?php
2
10namespace MediaWiki\Output;
11
12use InvalidArgumentException;
19
24
25 private const UNKNOWN_CONTENT_TYPE = 'unknown/unknown';
26
39 public static function stream(
40 $fname,
41 $headers = [],
42 $sendErrors = true,
43 $optHeaders = [],
44 $flags = 0
45 ) {
46 if ( FileBackend::isStoragePath( $fname ) ) {
47 throw new InvalidArgumentException( __FUNCTION__ . " given storage path '$fname'." );
48 }
49
50 $streamer = new HTTPFileStreamer(
51 $fname,
52 [
53 'obResetFunc' => 'wfResetOutputBuffers',
54 'streamMimeFunc' => [ self::class, 'contentTypeFromPath' ],
55 'headerFunc' => [ self::class, 'setHeader' ],
56 ]
57 );
58
59 return $streamer->stream( $headers, $sendErrors, $optHeaders, $flags );
60 }
61
67 public static function setHeader( $header ) {
68 RequestContext::getMain()->getRequest()->response()->header( $header );
69 }
70
78 public static function contentTypeFromPath( $filename, $safe = true ) {
79 // NOTE: TrivialMimeDetection is forced by ThumbnailEntryPoint. When this
80 // code is moved to a non-static method in a service object, we can no
81 // longer rely on that.
82 $trivialMimeDetection = MediaWikiServices::getInstance()->getMainConfig()
84
85 $ext = strrchr( $filename, '.' );
86 $ext = $ext ? strtolower( substr( $ext, 1 ) ) : '';
87
88 # trivial detection by file extension,
89 # used for thumbnails (thumb.php)
90 if ( $trivialMimeDetection ) {
91 switch ( $ext ) {
92 case 'gif':
93 return 'image/gif';
94 case 'png':
95 return 'image/png';
96 case 'jpg':
97 case 'jpeg':
98 return 'image/jpeg';
99 case 'webp':
100 return 'image/webp';
101 }
102
103 return self::UNKNOWN_CONTENT_TYPE;
104 }
105
106 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
107 // Use the extension only, rather than magic numbers, to avoid opening
108 // up vulnerabilities due to uploads of files with allowed extensions
109 // but disallowed types.
110 $type = $magic->getMimeTypeFromExtensionOrNull( $ext );
111
116 if ( $safe ) {
117 $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
118 $prohibitedFileExtensions = $mainConfig->get( MainConfigNames::ProhibitedFileExtensions );
119 $checkFileExtensions = $mainConfig->get( MainConfigNames::CheckFileExtensions );
120 $strictFileExtensions = $mainConfig->get( MainConfigNames::StrictFileExtensions );
121 $fileExtensions = $mainConfig->get( MainConfigNames::FileExtensions );
122 $verifyMimeType = $mainConfig->get( MainConfigNames::VerifyMimeType );
123 $mimeTypeExclusions = $mainConfig->get( MainConfigNames::MimeTypeExclusions );
124 [ , $extList ] = UploadBase::splitExtensions( $filename );
125 if ( UploadBase::checkFileExtensionList( $extList, $prohibitedFileExtensions ) ) {
126 return self::UNKNOWN_CONTENT_TYPE;
127 }
128 if (
129 $checkFileExtensions &&
130 $strictFileExtensions &&
131 !UploadBase::checkFileExtensionList( $extList, $fileExtensions )
132 ) {
133 return self::UNKNOWN_CONTENT_TYPE;
134 }
135 if ( $verifyMimeType && $type !== null && in_array( strtolower( $type ), $mimeTypeExclusions ) ) {
136 return self::UNKNOWN_CONTENT_TYPE;
137 }
138 }
139 return $type;
140 }
141}
142
144class_alias( StreamFile::class, 'StreamFile' );
Group all the pieces relevant to the context of a request into one instance.
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.
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.