You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

128 lines
3.3 KiB

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