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