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