1<?php 2 3/** 4 * Tests for the nginx X-Accel-Redirect URL construction 5 * 6 * @see http_xaccel_url() 7 * @see https://github.com/dokuwiki/dokuwiki/issues/2895 8 */ 9class httputils_xaccel_test extends DokuWikiTest 10{ 11 /** 12 * Files inside the DokuWiki directory keep their path relative to the root. 13 * This is the default layout and must match the historic behaviour. 14 */ 15 public function test_file_inside_dokuwiki() 16 { 17 $file = DOKU_INC . 'data/media/wiki/dokuwiki.png'; 18 $this->assertEquals( 19 DOKU_REL . 'data/media/wiki/dokuwiki.png', 20 http_xaccel_url($file) 21 ); 22 } 23 24 /** 25 * lib/ files (also inside the DokuWiki directory) work too. 26 */ 27 public function test_libfile_inside_dokuwiki() 28 { 29 $file = DOKU_INC . 'lib/images/fileicons/png.png'; 30 $this->assertEquals( 31 DOKU_REL . 'lib/images/fileicons/png.png', 32 http_xaccel_url($file) 33 ); 34 } 35 36 /** 37 * A media directory moved out of the DokuWiki root is mapped to the URL it 38 * would have by default (below data/media/). This is the regression in 39 * issue #2895, where the previous blind substr() produced a broken path. 40 */ 41 public function test_relocated_mediadir() 42 { 43 global $conf; 44 $conf['mediadir'] = '/srv/dokuwiki-media'; 45 $file = '/srv/dokuwiki-media/wiki/dokuwiki.png'; 46 $this->assertEquals( 47 DOKU_REL . 'data/media/wiki/dokuwiki.png', 48 http_xaccel_url($file) 49 ); 50 } 51 52 /** 53 * The cache directory (used for resized media, compiled CSS/JS and the 54 * sitemap) is mapped as well when relocated. 55 */ 56 public function test_relocated_cachedir() 57 { 58 global $conf; 59 $conf['cachedir'] = '/var/cache/dokuwiki'; 60 $file = '/var/cache/dokuwiki/a/abcdef0123.css'; 61 $this->assertEquals( 62 DOKU_REL . 'data/cache/a/abcdef0123.css', 63 http_xaccel_url($file) 64 ); 65 } 66 67 /** 68 * The most specific (longest) configured directory must win, so a file 69 * below a relocated mediadir is not swallowed by a relocated savedir. 70 */ 71 public function test_most_specific_dir_wins() 72 { 73 global $conf; 74 $conf['savedir'] = '/srv/dwdata'; 75 $conf['mediadir'] = '/srv/dwdata/media'; 76 $file = '/srv/dwdata/media/wiki/dokuwiki.png'; 77 $this->assertEquals( 78 DOKU_REL . 'data/media/wiki/dokuwiki.png', 79 http_xaccel_url($file) 80 ); 81 } 82 83 /** 84 * A file outside DokuWiki and all data directories (e.g. served by a 85 * plugin from an arbitrary location) is emitted as its absolute path 86 * behind the dedicated opt-in prefix. 87 */ 88 public function test_arbitrary_file_uses_escape_hatch() 89 { 90 $file = '/opt/secret-downloads/report.pdf'; 91 $this->assertEquals( 92 DOKU_REL . '_x_accel_redirect/opt/secret-downloads/report.pdf', 93 http_xaccel_url($file) 94 ); 95 } 96 97 /** 98 * File names with spaces or other special characters must be URL-encoded, 99 * because nginx URL-decodes the X-Accel-Redirect target. 100 */ 101 public function test_special_characters_are_encoded() 102 { 103 $file = DOKU_INC . 'data/media/wiki/some file & more.png'; 104 $this->assertEquals( 105 DOKU_REL . 'data/media/wiki/some%20file%20%26%20more.png', 106 http_xaccel_url($file) 107 ); 108 } 109} 110