From adc0e79124154dd5cd8d99a5b02b79b45e3fe16c Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Fri, 10 Feb 2017 00:03:06 +0000 Subject: [PATCH] OutputPage: Support UploadPath in testTransformResourcePath() Updated tests to reflect this use case. Currently we assume all web-accessible paths within ResourceBasePath (e.g "/w") to exist on disk at the same path in $IP (e.g. "/var/www/mw"). While in theory any number of web server rewrites or aliases could exist, there is one case in particular that we should support since the information is available in the configuration: UploadDir and UploadPath. This path may be rewritten in a way that varies by wiki in multi-wiki installs that share the same source code. E.g. a server may rewrite "/w/images" to somewhere else, which means it will not match the directory on disk that is shared between wikis. Bug: T155146 Change-Id: I320478c9c262cc012f08b585b48d290594ec2420 --- includes/OutputPage.php | 14 +++- tests/phpunit/includes/OutputPageTest.php | 78 +++++++++++++++++++---- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 91fc75c9bd..af8243646b 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -3697,6 +3697,8 @@ class OutputPage extends ContextSource { */ public static function transformResourcePath( Config $config, $path ) { global $IP; + + $localDir = $IP; $remotePathPrefix = $config->get( 'ResourceBasePath' ); if ( $remotePathPrefix === '' ) { // The configured base path is required to be empty string for @@ -3710,8 +3712,18 @@ class OutputPage extends ContextSource { // - Path is protocol-relative. Fixes T155310. Not supported by RelPath lib. return $path; } + // For files in resources, extensions/ or skins/, ResourceBasePath is preferred here. + // For other misc files in $IP, we'll fallback to that as well. There is, however, a fourth + // supported dir/path pair in the configuration (wgUploadDirectory, wgUploadPath) + // which is not expected to be in wgResourceBasePath on CDNs. (T155146) + $uploadPath = $config->get( 'UploadPath' ); + if ( strpos( $path, $uploadPath ) === 0 ) { + $localDir = $config->get( 'UploadDirectory' ); + $remotePathPrefix = $remotePath = $uploadPath; + } + $path = RelPath\getRelativePath( $path, $remotePath ); - return self::transformFilePath( $remotePathPrefix, $IP, $path ); + return self::transformFilePath( $remotePathPrefix, $localDir, $path ); } /** diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index d2494dacd9..50f851c6c2 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -181,22 +181,63 @@ class OutputPageTest extends MediaWikiTestCase { $baseDir = dirname( __DIR__ ) . '/data/media'; return [ // File that matches basePath, and exists. Hash found and appended. - [ 'baseDir' => $baseDir, 'basePath' => '/w', '/w/test.jpg', '/w/test.jpg?edcf2' ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + '/w/test.jpg', + '/w/test.jpg?edcf2' + ], // File that matches basePath, but not found on disk. Empty query. - [ 'baseDir' => $baseDir, 'basePath' => '/w', '/w/unknown.png', '/w/unknown.png?' ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + '/w/unknown.png', + '/w/unknown.png?' + ], // File not matching basePath. Ignored. - [ 'baseDir' => $baseDir, 'basePath' => '/w', '/files/test.jpg' ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + '/files/test.jpg' + ], // Empty string. Ignored. - [ 'baseDir' => $baseDir, 'basePath' => '/w', '', '' ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + '', + '' + ], // Similar path, but with domain component. Ignored. - [ 'baseDir' => $baseDir, 'basePath' => '/w', '//example.org/w/test.jpg' ], - [ 'baseDir' => $baseDir, 'basePath' => '/w', 'https://example.org/w/test.jpg' ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + '//example.org/w/test.jpg' + ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + 'https://example.org/w/test.jpg' + ], // Unrelated path with domain component. Ignored. - [ 'baseDir' => $baseDir, 'basePath' => '/w', 'https://example.org/files/test.jpg' ], - [ 'baseDir' => $baseDir, 'basePath' => '/w', '//example.org/files/test.jpg' ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + 'https://example.org/files/test.jpg' + ], + [ + 'baseDir' => $baseDir, 'basePath' => '/w', + '//example.org/files/test.jpg' + ], // Unrelated path with domain, and empty base path (root mw install). Ignored. - [ 'baseDir' => $baseDir, 'basePath' => '', 'https://example.org/files/test.jpg' ], - [ 'baseDir' => $baseDir, 'basePath' => '', '//example.org/files/test.jpg' ], // T155310 + [ + 'baseDir' => $baseDir, 'basePath' => '', + 'https://example.org/files/test.jpg' + ], + [ + 'baseDir' => $baseDir, 'basePath' => '', + // T155310 + '//example.org/files/test.jpg' + ], + // Check UploadPath before ResourceBasePath (T155146) + [ + 'baseDir' => dirname( $baseDir ), 'basePath' => '', + 'uploadDir' => $baseDir, 'uploadPath' => '/images', + '/images/test.jpg', + '/images/test.jpg?edcf2' + ], ]; } @@ -205,9 +246,22 @@ class OutputPageTest extends MediaWikiTestCase { * @covers OutputPage::transformFilePath * @covers OutputPage::transformResourcePath */ - public function testTransformResourcePath( $baseDir, $basePath, $path, $expected = null ) { + public function testTransformResourcePath( $baseDir, $basePath, $uploadDir = null, + $uploadPath = null, $path = null, $expected = null + ) { + if ( $path === null ) { + // Skip optional $uploadDir and $uploadPath + $path = $uploadDir; + $expected = $uploadPath; + $uploadDir = "$baseDir/images"; + $uploadPath = "$basePath/images"; + } $this->setMwGlobals( 'IP', $baseDir ); - $conf = new HashConfig( [ 'ResourceBasePath' => $basePath ] ); + $conf = new HashConfig( [ + 'ResourceBasePath' => $basePath, + 'UploadDirectory' => $uploadDir, + 'UploadPath' => $uploadPath, + ] ); MediaWiki\suppressWarnings(); $actual = OutputPage::transformResourcePath( $conf, $path ); -- 2.20.1