mirror of
https://github.com/catalyst/moodle-auth_outage.git
synced 2026-05-16 21:41:31 +02:00
Issue #22 - Auto-detect mime types.
This commit is contained in:
@@ -28,6 +28,7 @@ namespace auth_outage\local\controllers;
|
||||
use auth_outage\local\outage;
|
||||
use coding_exception;
|
||||
use DOMDocument;
|
||||
use finfo;
|
||||
use invalid_parameter_exception;
|
||||
use invalid_state_exception;
|
||||
use moodle_url;
|
||||
@@ -61,7 +62,8 @@ class maintenance_static_page {
|
||||
} else if (PHPUNIT_TEST) {
|
||||
$html = '<html></html>';
|
||||
} else {
|
||||
$html = self::file_get_contents($CFG->wwwroot.'/auth/outage/info.php?auth_outage_hide_warning=1&id='.$outage->id);
|
||||
$data = self::file_get_data($CFG->wwwroot.'/auth/outage/info.php?auth_outage_hide_warning=1&id='.$outage->id);
|
||||
$html = $data['contents'];
|
||||
}
|
||||
|
||||
return self::create_from_html($html);
|
||||
@@ -97,13 +99,33 @@ class maintenance_static_page {
|
||||
* @param string $file File to get.
|
||||
* @return string Contents of $file or an empty string if failed.
|
||||
*/
|
||||
private static function file_get_contents($file) {
|
||||
$contents = @file_get_contents($file);
|
||||
private static function file_get_data($file) {
|
||||
if (self::is_url($file)) {
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $file);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
$contents = curl_exec($curl);
|
||||
$mime = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
|
||||
curl_close($curl);
|
||||
} else {
|
||||
$contents = @file_get_contents($file);
|
||||
$mime = (new finfo(FILEINFO_MIME_TYPE))->buffer($contents); // Not perfect, but try guessing it.
|
||||
}
|
||||
if ($contents === false) {
|
||||
debugging('Cannot fetch: '.$file);
|
||||
return ''; // Better a broken link than halting the generation.
|
||||
$contents = '';
|
||||
$mime = 'unknown';
|
||||
}
|
||||
return $contents;
|
||||
return ['contents' => $contents, 'mime' => $mime];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string starts with "http://" or "https://".
|
||||
* @param $url
|
||||
* @return bool
|
||||
*/
|
||||
private static function is_url($url) {
|
||||
return (bool)preg_match('#^http(s)?://#', $url);
|
||||
}
|
||||
|
||||
/** @var DOMDocument */
|
||||
@@ -269,7 +291,7 @@ class maintenance_static_page {
|
||||
if (($rel != 'stylesheet') || ($href == '')) {
|
||||
continue;
|
||||
}
|
||||
$filename = $this->save_url_file($href, 'css');
|
||||
$filename = $this->save_url_file($href);
|
||||
if (is_null($filename)) {
|
||||
$url = $href; // Skipped, use original URL.
|
||||
} else {
|
||||
@@ -299,7 +321,7 @@ class maintenance_static_page {
|
||||
if (($rel != 'shortcut icon') || ($href == '')) {
|
||||
continue;
|
||||
}
|
||||
$link->setAttribute('href', $this->generate_file_url($href, 'png')); // Works for most image formats.
|
||||
$link->setAttribute('href', $this->generate_file_url($href)); // Works for most image formats.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,18 +336,17 @@ class maintenance_static_page {
|
||||
if ($src == '') {
|
||||
continue;
|
||||
}
|
||||
$link->setAttribute('src', $this->generate_file_url($src, 'png')); // Works for most image formats.
|
||||
$link->setAttribute('src', $this->generate_file_url($src)); // Works for most image formats.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the content of the URL into a file, returning the new URL.
|
||||
* @param string $url Input URL.
|
||||
* @param string $type Type of file.
|
||||
* @return string Output URL.
|
||||
*/
|
||||
private function generate_file_url($url, $type) {
|
||||
$filename = $this->save_url_file($url, $type);
|
||||
private function generate_file_url($url) {
|
||||
$filename = $this->save_url_file($url);
|
||||
if (is_null($filename)) {
|
||||
return $url; // Skipped, use original URL.
|
||||
}
|
||||
@@ -344,13 +365,12 @@ class maintenance_static_page {
|
||||
/**
|
||||
* Saves the content of the URL into a file, returning the local filename.
|
||||
* @param string $url Input URL.
|
||||
* @param string $type Type of file.
|
||||
* @return string|null Output filename or null if skipped.
|
||||
*/
|
||||
private function save_url_file($url, $type) {
|
||||
private function save_url_file($url) {
|
||||
global $CFG;
|
||||
|
||||
if (!preg_match('#^http(s)?://#', $url)) {
|
||||
if (!self::is_url($url)) {
|
||||
debugging('Found a relative url ('.$url.') -- is it using moodle_url()?');
|
||||
return null; // Leave hardcoded URLs as it is.
|
||||
}
|
||||
@@ -364,10 +384,12 @@ class maintenance_static_page {
|
||||
$url = str_replace($CFG->wwwroot, $CFG->dirroot, $url);
|
||||
}
|
||||
|
||||
$contents = self::file_get_contents($url);
|
||||
$filename = sha1($contents).'.'.$type;
|
||||
$data = self::file_get_data($url);
|
||||
|
||||
$mime = trim(base64_encode($data['mime']), '=');
|
||||
$filename = sha1($data['contents']).'.'.$mime;
|
||||
$filepath = $this->get_resources_folder().'/'.$filename;
|
||||
file_put_contents($filepath, $contents);
|
||||
file_put_contents($filepath, $data['contents']);
|
||||
|
||||
if ($this->preview) {
|
||||
$filename = 'preview/'.$filename;
|
||||
|
||||
11
file.php
11
file.php
@@ -28,13 +28,20 @@
|
||||
*/
|
||||
|
||||
// File should have at least 3 characters as we will check the extension below.
|
||||
if (!isset($_GET['file']) || (strlen($_GET['file']) < 3)) {
|
||||
if (!isset($_GET['file'])) {
|
||||
http_response_code(400);
|
||||
die('Missing file parameter.');
|
||||
}
|
||||
|
||||
$parts = explode('.', $_GET['file']);
|
||||
if (count($parts) != 2) {
|
||||
http_response_code(400);
|
||||
die('Invalid file requested.');
|
||||
}
|
||||
$mime = base64_decode($parts[1]);
|
||||
|
||||
// Detect type, we only support css or PNG images.
|
||||
header('Content-Type: '.(substr($_GET['file'], -3) == 'css' ? 'text/css' : 'image/png'));
|
||||
header('Content-Type: '.$mime);
|
||||
|
||||
// Use cache.
|
||||
$lifetime = 60 * 60 * 24; // 1 day.
|
||||
|
||||
@@ -159,6 +159,28 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
|
||||
self::assertFileNotExists($file);
|
||||
}
|
||||
|
||||
public function test_createdfile() {
|
||||
global $CFG;
|
||||
|
||||
$link = $this->get_fixture_path('catalyst.png');
|
||||
$html = "<!DOCTYPE html>\n".
|
||||
'<html><head><title>Title</title></head>'.
|
||||
'<body>Content<img src="'.$link.'" /></body></html>';
|
||||
$page = maintenance_static_page::create_from_html($html);
|
||||
$page->set_preview(true);
|
||||
$page->generate();
|
||||
$generated = trim(file_get_contents($page->get_template_file()));
|
||||
|
||||
// This checks if content is correct and mime type is correct from the encoded name.
|
||||
$file = $page->get_resources_folder().'/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n';
|
||||
self::assertFileExists($file);
|
||||
|
||||
// We can still assert the contents really match, not just the hash.
|
||||
$found = file_get_contents($file);
|
||||
$expected = file_get_contents($CFG->dirroot.'/auth/outage/tests/phpunit/local/controllers/fixtures/catalyst.png');
|
||||
self::assertSame($found, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a fixture file for this test case.
|
||||
* @param $file
|
||||
|
||||
Reference in New Issue
Block a user