1<?php 2 3/** 4 * DokuWiki media passthrough file 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Andreas Gohr <andi@splitbrain.org> 8 */ 9 10use dokuwiki\Input\Input; 11use dokuwiki\Extension\Event; 12 13if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../../'); 14if (!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); 15require_once(DOKU_INC . 'inc/init.php'); 16session_write_close(); //close session 17 18require_once(DOKU_INC . 'inc/fetch.functions.php'); 19 20if (defined('SIMPLE_TEST')) { 21 $INPUT = new Input(); 22} 23 24// BEGIN main 25$mimetypes = getMimeTypes(); 26 27//get input 28$MEDIA = stripctl(getID('media', false)); // no cleaning except control chars - maybe external 29$CACHE = calc_cache($INPUT->str('cache')); 30$WIDTH = $INPUT->int('w'); 31$HEIGHT = $INPUT->int('h'); 32$REV = &$INPUT->ref('rev'); 33//sanitize revision 34$REV = preg_replace('/[^0-9]/', '', $REV); 35 36[$EXT, $MIME, $DL] = mimetype($MEDIA, false); 37if ($EXT === false) { 38 $EXT = 'unknown'; 39 $MIME = 'application/octet-stream'; 40 $DL = true; 41} 42 43// check for permissions, preconditions and cache external files 44[$STATUS, $STATUSMESSAGE] = checkFileStatus($MEDIA, $FILE, $REV, $WIDTH, $HEIGHT); 45 46// prepare data for plugin events 47$data = [ 48 'media' => $MEDIA, 49 'file' => $FILE, 50 'orig' => $FILE, 51 'mime' => $MIME, 52 'download' => $DL, 53 'cache' => $CACHE, 54 'ext' => $EXT, 55 'width' => $WIDTH, 56 'height' => $HEIGHT, 57 'status' => $STATUS, 58 'statusmessage' => $STATUSMESSAGE, 59 'ispublic' => media_ispublic($MEDIA), 60 'csp' => [ 61 'default-src' => "'none'", 62 'style-src' => "'unsafe-inline'", 63 'media-src' => "'self'", 64 'object-src' => "'self'", 65 'font-src' => "'self' data:", 66 'form-action' => "'none'", 67 'frame-ancestors' => "'self'", 68 ] 69]; 70 71// handle the file status 72$evt = new Event('FETCH_MEDIA_STATUS', $data); 73if ($evt->advise_before()) { 74 // redirects 75 if ($data['status'] > 300 && $data['status'] <= 304) { 76 if (defined('SIMPLE_TEST')) return; //TestResponse doesn't recognize redirects 77 send_redirect($data['statusmessage']); 78 } 79 // send any non 200 status 80 if ($data['status'] != 200) { 81 http_status($data['status'], $data['statusmessage']); 82 } 83 // die on errors 84 if ($data['status'] > 203) { 85 echo $data['statusmessage']; 86 if (defined('SIMPLE_TEST')) return; 87 exit; 88 } 89} 90$evt->advise_after(); 91unset($evt); 92 93//handle image resizing/cropping 94$evt = new Event('MEDIA_RESIZE', $data); 95if ($evt->advise_before()) { 96 if ( 97 $MIME != 'image/svg+xml' && 98 str_starts_with($MIME, 'image') && 99 ($WIDTH || $HEIGHT) 100 ) { 101 if ($HEIGHT && $WIDTH) { 102 $data['file'] = $FILE = media_crop_image($data['file'], $EXT, $WIDTH, $HEIGHT); 103 } else { 104 $data['file'] = $FILE = media_resize_image($data['file'], $EXT, $WIDTH, $HEIGHT); 105 } 106 } 107} 108$evt->advise_after(); 109unset($evt); 110 111// finally send the file to the client 112$evt = new Event('MEDIA_SENDFILE', $data); 113if ($evt->advise_before()) { 114 sendFile( 115 $data['file'], 116 $data['mime'], 117 $data['download'], 118 $data['cache'], 119 $data['ispublic'], 120 $data['orig'], 121 $data['csp'] 122 ); 123} 124// Do something after the download finished. 125$evt->advise_after(); // will not be emitted on 304 or x-sendfile 126 127// END DO main 128