mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-44828 filelib: Fix open error for force-downloaded files in mobile
Allow guessing of file's MIME type by default. Fallback to application/octet-stream if MIME type cannot be determined.
This commit is contained in:
parent
57739a72cb
commit
0c4c3b9aed
@ -1390,6 +1390,29 @@ function &get_mimetypes_array() {
|
||||
return core_filetypes::get_types();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine a file's MIME type based on the given filename using the function mimeinfo.
|
||||
*
|
||||
* This function retrieves a file's MIME type for a file that will be sent to the user.
|
||||
* This should only be used for file-sending purposes just like in send_stored_file, send_file, and send_temp_file.
|
||||
* Should the file's MIME type cannot be determined by mimeinfo, it will return 'application/octet-stream' as a default
|
||||
* MIME type which should tell the browser "I don't know what type of file this is, so just download it.".
|
||||
*
|
||||
* @param string $filename The file's filename.
|
||||
* @return string The file's MIME type or 'application/octet-stream' if it cannot be determined.
|
||||
*/
|
||||
function get_mimetype_for_sending($filename = '') {
|
||||
// Guess the file's MIME type using mimeinfo.
|
||||
$mimetype = mimeinfo('type', $filename);
|
||||
|
||||
// Use octet-stream as fallback if MIME type cannot be determined by mimeinfo.
|
||||
if (!$mimetype || $mimetype === 'document/unknown') {
|
||||
$mimetype = 'application/octet-stream';
|
||||
}
|
||||
|
||||
return $mimetype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains information about a filetype based on its extension. Will
|
||||
* use a default if no information is present about that particular
|
||||
@ -1988,12 +2011,8 @@ function readstring_accel($string, $mimetype, $accelerate) {
|
||||
function send_temp_file($path, $filename, $pathisstring=false) {
|
||||
global $CFG;
|
||||
|
||||
if (core_useragent::is_firefox()) {
|
||||
// only FF is known to correctly save to disk before opening...
|
||||
$mimetype = mimeinfo('type', $filename);
|
||||
} else {
|
||||
$mimetype = 'application/x-forcedownload';
|
||||
}
|
||||
// Guess the file's MIME type.
|
||||
$mimetype = get_mimetype_for_sending($filename);
|
||||
|
||||
// close session - not needed anymore
|
||||
\core\session\manager::write_close();
|
||||
@ -2076,12 +2095,10 @@ function send_file($path, $filename, $lifetime = null , $filter=0, $pathisstring
|
||||
|
||||
\core\session\manager::write_close(); // Unlock session during file serving.
|
||||
|
||||
// Use given MIME type if specified, otherwise guess it using mimeinfo.
|
||||
// IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
|
||||
// only Firefox saves all files locally before opening when content-disposition: attachment stated
|
||||
$isFF = core_useragent::is_firefox(); // only FF properly tested
|
||||
$mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
|
||||
($mimetype ? $mimetype : mimeinfo('type', $filename));
|
||||
// Use given MIME type if specified, otherwise guess it.
|
||||
if (!$mimetype || $mimetype === 'document/unknown') {
|
||||
$mimetype = get_mimetype_for_sending($filename);
|
||||
}
|
||||
|
||||
// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
|
||||
if (core_useragent::is_ie()) {
|
||||
@ -2254,13 +2271,15 @@ function send_stored_file($stored_file, $lifetime=null, $filter=0, $forcedownloa
|
||||
|
||||
\core\session\manager::write_close(); // Unlock session during file serving.
|
||||
|
||||
// Use given MIME type if specified, otherwise guess it using mimeinfo.
|
||||
// IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
|
||||
// only Firefox saves all files locally before opening when content-disposition: attachment stated
|
||||
$filename = is_null($filename) ? $stored_file->get_filename() : $filename;
|
||||
$isFF = core_useragent::is_firefox(); // only FF properly tested
|
||||
$mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
|
||||
($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename));
|
||||
|
||||
// Use given MIME type if specified.
|
||||
$mimetype = $stored_file->get_mimetype();
|
||||
|
||||
// Otherwise guess it.
|
||||
if (!$mimetype || $mimetype === 'document/unknown') {
|
||||
$mimetype = get_mimetype_for_sending($filename);
|
||||
}
|
||||
|
||||
// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
|
||||
if (core_useragent::is_ie()) {
|
||||
|
@ -879,6 +879,30 @@ EOF;
|
||||
$this->assertEquals(true, $mimeinfo['txt']['defaulticon']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for get_mimetype_for_sending function.
|
||||
*/
|
||||
public function test_get_mimetype_for_sending() {
|
||||
// Without argument.
|
||||
$this->assertEquals('application/octet-stream', get_mimetype_for_sending());
|
||||
|
||||
// Argument is null.
|
||||
$this->assertEquals('application/octet-stream', get_mimetype_for_sending(null));
|
||||
|
||||
// Filename having no extension.
|
||||
$this->assertEquals('application/octet-stream', get_mimetype_for_sending('filenamewithoutextension'));
|
||||
|
||||
// Test using the extensions listed from the get_mimetypes_array function.
|
||||
$mimetypes = get_mimetypes_array();
|
||||
foreach ($mimetypes as $ext => $info) {
|
||||
if ($ext === 'xxx') {
|
||||
$this->assertEquals('application/octet-stream', get_mimetype_for_sending('SampleFile.' . $ext));
|
||||
} else {
|
||||
$this->assertEquals($info['type'], get_mimetype_for_sending('SampleFile.' . $ext));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test curl agent settings.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user