OutputPage: Support UploadPath in testTransformResourcePath()
authorTimo Tijhof <krinklemail@gmail.com>
Fri, 10 Feb 2017 00:03:06 +0000 (00:03 +0000)
committerAaron Schulz <aschulz@wikimedia.org>
Sat, 11 Feb 2017 04:45:15 +0000 (04:45 +0000)
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
tests/phpunit/includes/OutputPageTest.php

index 91fc75c..af82436 100644 (file)
@@ -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 );
        }
 
        /**
index d2494da..50f851c 100644 (file)
@@ -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 );