http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90105

Revision: 90105
Author:   tstarling
Date:     2011-06-15 07:35:47 +0000 (Wed, 15 Jun 2011)
Log Message:
-----------
* (bug 28798) Set $wgServer in the default LocalSettings.php
* (bug 14977) When detecting $wgServer, treat IPv6 addresses in 
$_SERVER['SERVER_NAME'] etc. in a sensible way. 
* Tests for the new functions in IP.php and Installer.php

Modified Paths:
--------------
    trunk/phase3/includes/IP.php
    trunk/phase3/includes/installer/Installer.i18n.php
    trunk/phase3/includes/installer/Installer.php
    trunk/phase3/includes/installer/LocalSettingsGenerator.php
    trunk/phase3/includes/installer/WebInstallerPage.php
    trunk/phase3/tests/phpunit/includes/IPTest.php

Added Paths:
-----------
    trunk/phase3/tests/phpunit/includes/installer/
    trunk/phase3/tests/phpunit/includes/installer/InstallerTest.php

Modified: trunk/phase3/includes/IP.php
===================================================================
--- trunk/phase3/includes/IP.php        2011-06-15 03:48:58 UTC (rev 90104)
+++ trunk/phase3/includes/IP.php        2011-06-15 07:35:47 UTC (rev 90105)
@@ -186,6 +186,76 @@
        }
 
        /**
+        * Given a host/port string, like one might find in the host part of a 
URL 
+        * per RFC 2732, split the hostname part and the port part and return 
an 
+        * array with an element for each. If there is no port part, the array 
will 
+        * have false in place of the port. If the string was invalid in some 
way, 
+        * false is returned.
+        *
+        * This was easy with IPv4 and was generally done in an ad-hoc way, but 
+        * with IPv6 it's somewhat more complicated due to the need to parse 
the 
+        * square brackets and colons.
+        *
+        * A bare IPv6 address is accepted despite the lack of square brackets.
+        *
+        * @param $both The string with the host and port
+        * @return array
+        */
+       public static function splitHostAndPort( $both ) {
+               if ( substr( $both, 0, 1 ) === '[' ) {
+                       if ( preg_match( '/^\[(' . RE_IPV6_ADD . 
')\](?::(?P<port>\d+))?$/', $both, $m ) ) {
+                               if ( isset( $m['port'] ) ) {
+                                       return array( $m[1], intval( $m['port'] 
) );
+                               } else {
+                                       return array( $m[1], false );
+                               }
+                       } else {
+                               // Square bracket found but no IPv6
+                               return false;
+                       }
+               }
+               $numColons = substr_count( $both, ':' );
+               if ( $numColons >= 2 ) {
+                       // Is it a bare IPv6 address?
+                       if ( preg_match( '/^' . RE_IPV6_ADD . '$/', $both ) ) {
+                               return array( $both, false );
+                       } else {
+                               // Not valid IPv6, but too many colons for 
anything else
+                               return false;
+                       }
+               }
+               if ( $numColons >= 1 ) {
+                       // Host:port?
+                       $bits = explode( ':', $both );
+                       if ( preg_match( '/^\d+/', $bits[1] ) ) {
+                               return array( $bits[0], intval( $bits[1] ) );
+                       } else {
+                               // Not a valid port
+                               return false;
+                       }
+               }
+               // Plain hostname
+               return array( $both, false );
+       }
+
+       /**
+        * Given a host name and a port, combine them into host/port string like
+        * you might find in a URL. If the host contains a colon, wrap it in 
square
+        * brackets like in RFC 2732. If the port matches the default port, 
omit 
+        * the port specification
+        */
+       public static function combineHostAndPort( $host, $port, $defaultPort = 
false ) {
+               if ( strpos( $host, ':' ) !== false ) {
+                       $host = "[$host]";
+               }
+               if ( $defaultPort !== false && $port == $defaultPort ) {
+                       return $host;
+               } else {
+                       return "$host:$port";
+               }
+       }
+
+       /**
         * Given an unsigned integer, returns an IPv6 address in octet notation
         *
         * @param $ip_int String: IP address.

Modified: trunk/phase3/includes/installer/Installer.i18n.php
===================================================================
--- trunk/phase3/includes/installer/Installer.i18n.php  2011-06-15 03:48:58 UTC 
(rev 90104)
+++ trunk/phase3/includes/installer/Installer.i18n.php  2011-06-15 07:35:47 UTC 
(rev 90105)
@@ -147,6 +147,7 @@
 Image thumbnailing will be disabled.',
        'config-no-uri'                   => "'''Error:''' Could not determine 
the current URI.
 Installation aborted.",
+       'config-using-server'             => 'Using server name 
"<nowiki>$1</nowiki>".',
        'config-uploads-not-safe'         => "'''Warning:''' Your default 
directory for uploads <code>$1</code> is vulnerable to arbitrary scripts 
execution.
 Although MediaWiki checks all uploaded files for security threats, it is 
highly recommended to 
[http://www.mediawiki.org/wiki/Manual:Security#Upload_security close this 
security vulnerability] before enabling uploads.",
        'config-brokenlibxml'             => 'Your system has a combination of 
PHP and libxml2 versions which is buggy and can cause hidden data corruption in 
MediaWiki and other web applications.

Modified: trunk/phase3/includes/installer/Installer.php
===================================================================
--- trunk/phase3/includes/installer/Installer.php       2011-06-15 03:48:58 UTC 
(rev 90104)
+++ trunk/phase3/includes/installer/Installer.php       2011-06-15 07:35:47 UTC 
(rev 90105)
@@ -99,6 +99,7 @@
                'envCheckCache',
                'envCheckDiff3',
                'envCheckGraphics',
+               'envCheckServer',
                'envCheckPath',
                'envCheckExtension',
                'envCheckShellLocale',
@@ -131,6 +132,8 @@
                'wgDiff3',
                'wgImageMagickConvertCommand',
                'IP',
+               'wgServer',
+               'wgProto',
                'wgScriptPath',
                'wgScriptExtension',
                'wgMetaNamespace',
@@ -838,6 +841,47 @@
        }
 
        /**
+        * Environment check for the server hostname.
+        */
+       protected function envCheckServer() {
+               if ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == 'on') {
+                       $proto = 'https';
+                       $stdPort = 443;
+               } else {
+                       $proto = 'http';
+                       $stdPort = 80;
+               }
+
+               $varNames = array( 'HTTP_HOST', 'SERVER_NAME', 'HOSTNAME', 
'SERVER_ADDR' );
+               $host = 'localhost';
+               $port = $stdPort;
+               foreach ( $varNames as $varName ) {
+                       if ( !isset( $_SERVER[$varName] ) ) {
+                               continue;
+                       }
+                       $parts = IP::splitHostAndPort( $_SERVER[$varName] );
+                       if ( !$parts ) {
+                               // Invalid, do not use
+                               continue;
+                       }
+                       $host = $parts[0];
+                       if ( $parts[1] === false ) {
+                               if ( isset( $_SERVER['SERVER_PORT'] ) ) {
+                                       $port = $_SERVER['SERVER_PORT'];
+                               } // else leave it as $stdPort
+                       } else {
+                               $port = $parts[1];
+                       }
+                       break;
+               }
+
+               $server = $proto . '://' . IP::combineHostAndPort( $host, 
$port, $stdPort );
+               $this->showMessage( 'config-using-server', $server );
+               $this->setVar( 'wgServer', $server );
+               $this->setVar( 'wgProto', $proto );
+       }
+
+       /**
         * Environment check for setting $IP and $wgScriptPath.
         */
        protected function envCheckPath() {
@@ -955,10 +999,10 @@
         * TODO: document
         */
        protected function envCheckUploadsDirectory() {
-               global $IP, $wgServer;
+               global $IP;
 
                $dir = $IP . '/images/';
-               $url = $wgServer . $this->getVar( 'wgScriptPath' ) . '/images/';
+               $url = $this->getVar( 'wgServer' ) . $this->getVar( 
'wgScriptPath' ) . '/images/';
                $safe = !$this->dirIsExecutable( $dir, $url );
 
                if ( $safe ) {

Modified: trunk/phase3/includes/installer/LocalSettingsGenerator.php
===================================================================
--- trunk/phase3/includes/installer/LocalSettingsGenerator.php  2011-06-15 
03:48:58 UTC (rev 90104)
+++ trunk/phase3/includes/installer/LocalSettingsGenerator.php  2011-06-15 
07:35:47 UTC (rev 90105)
@@ -39,7 +39,7 @@
 
                $confItems = array_merge(
                        array(
-                               'wgScriptPath', 'wgScriptExtension',
+                               'wgServer', 'wgProto', 'wgScriptPath', 
'wgScriptExtension',
                                'wgPasswordSender', 
'wgImageMagickConvertCommand', 'wgShellLocale',
                                'wgLanguageCode', 'wgEnableEmail', 
'wgEnableUserEmail', 'wgDiff3',
                                'wgEnotifUserTalk', 'wgEnotifWatchlist', 
'wgEmailAuthentication',
@@ -249,6 +249,12 @@
 \$wgScriptPath       = \"{$this->values['wgScriptPath']}\";
 \$wgScriptExtension  = \"{$this->values['wgScriptExtension']}\";
 
+## The server name to use in fully-qualified URLs
+\$wgServer           = \"{$this->values['wgServer']}\";
+
+## The URL protocol, may be http or https
+\$wgProto            = \"{$this->values['wgProto']}\";
+
 ## The relative URL path to the skins directory
 \$wgStylePath        = \"\$wgScriptPath/skins\";
 

Modified: trunk/phase3/includes/installer/WebInstallerPage.php
===================================================================
--- trunk/phase3/includes/installer/WebInstallerPage.php        2011-06-15 
03:48:58 UTC (rev 90104)
+++ trunk/phase3/includes/installer/WebInstallerPage.php        2011-06-15 
07:35:47 UTC (rev 90105)
@@ -531,7 +531,7 @@
                $this->addHTML(
                        $this->parent->getInfoBox(
                                wfMsgNoTrans( $msg,
-                                       $GLOBALS['wgServer'] .
+                                       $this->getVar( 'wgServer' ) .
                                                $this->getVar( 'wgScriptPath' ) 
. '/index' .
                                                $this->getVar( 
'wgScriptExtension' )
                                ), 'tick-32.png'
@@ -934,8 +934,8 @@
         * @return string
         */
        public function getCCPartnerUrl() {
-               global $wgServer;
-               $exitUrl = $wgServer . $this->parent->getUrl( array(
+               $server = $this->getVar( 'wgServer' );
+               $exitUrl = $server . $this->parent->getUrl( array(
                        'page' => 'Options',
                        'SubmitCC' => 'indeed',
                        'config__LicenseCode' => 'cc',
@@ -943,7 +943,7 @@
                        'config_wgRightsText' => '[license_name]',
                        'config_wgRightsIcon' => '[license_button]',
                ) );
-               $styleUrl = $wgServer . dirname( dirname( 
$this->parent->getUrl() ) ) .
+               $styleUrl = $server . dirname( dirname( $this->parent->getUrl() 
) ) .
                        '/skins/common/config-cc.css';
                $iframeUrl = 'http://creativecommons.org/license/?' .
                        wfArrayToCGI( array(
@@ -1147,7 +1147,7 @@
        public function execute() {
                // Pop up a dialog box, to make it difficult for the user to 
forget
                // to download the file
-               $lsUrl = $GLOBALS['wgServer'] . $this->parent->getURL( array( 
'localsettings' => 1 ) );
+               $lsUrl = $this->getVar( 'wgServer' ) . $this->parent->getURL( 
array( 'localsettings' => 1 ) );
                if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && strpos( 
$_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false ) {
                        // JS appears the only method that works consistently 
with IE7+
                        $this->addHtml( "\n<script type=\"" . 
$GLOBALS['wgJsMimeType'] . '">jQuery( document ).ready( function() { 
document.location='
@@ -1162,7 +1162,7 @@
                        $this->parent->getInfoBox(
                                wfMsgNoTrans( 'config-install-done',
                                        $lsUrl,
-                                       $GLOBALS['wgServer'] .
+                                       $this->getVar( 'wgServer' ) .
                                                $this->getVar( 'wgScriptPath' ) 
. '/index' .
                                                $this->getVar( 
'wgScriptExtension' ),
                                        '<downloadlink/>'

Modified: trunk/phase3/tests/phpunit/includes/IPTest.php
===================================================================
--- trunk/phase3/tests/phpunit/includes/IPTest.php      2011-06-15 03:48:58 UTC 
(rev 90104)
+++ trunk/phase3/tests/phpunit/includes/IPTest.php      2011-06-15 07:35:47 UTC 
(rev 90105)
@@ -426,4 +426,56 @@
                        array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
                );
        }
+
+       /**
+        * Test for IP::splitHostAndPort().
+        * @dataProvider provideSplitHostAndPort
+        */
+       function testSplitHostAndPort( $expected, $input, $description ) {
+               $this->assertEquals( $expected, IP::splitHostAndPort( $input ), 
$description );
+       }
+
+       /**
+        * Provider for IP::splitHostAndPort()
+        */
+       function provideSplitHostAndPort() {
+               return array(
+                       array( false, '[', 'Unclosed square bracket' ),
+                       array( false, '[::', 'Unclosed square bracket 2' ),
+                       array( array( '::', false ), '::', 'Bare IPv6 0' ),
+                       array( array( '::1', false ), '::1', 'Bare IPv6 1' ),
+                       array( array( '::', false ), '[::]', 'Bracketed IPv6 0' 
),
+                       array( array( '::1', false ), '[::1]', 'Bracketed IPv6 
1' ),
+                       array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 
with port' ),
+                       array( false, '::x', 'Double colon but no IPv6' ),
+                       array( array( 'x', 80 ), 'x:80', 'Hostname and port' ),
+                       array( false, 'x:x', 'Hostname and invalid port' ),
+                       array( array( 'x', false ), 'x', 'Plain hostname' )
+               );
+       }
+
+       /**
+        * Test for IP::combineHostAndPort()
+        * @dataProvider provideCombineHostAndPort
+        */
+       function testCombineHostAndPort( $expected, $input, $description ) {
+               list( $host, $port, $defaultPort ) = $input;
+               $this->assertEquals( 
+                       $expected, 
+                       IP::combineHostAndPort( $host, $port, $defaultPort ), 
+                       $description );
+       }
+
+       /**
+        * Provider for IP::combineHostAndPort()
+        */
+       function provideCombineHostAndPort() {
+               return array(
+                       array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default 
port' ),
+                       array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 
non-default port' ),
+                       array( 'x', array( 'x', 2, 2 ), 'Normal default port' ),
+                       array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default 
port' ),
+               );
+       }
+
 }

Added: trunk/phase3/tests/phpunit/includes/installer/InstallerTest.php
===================================================================
--- trunk/phase3/tests/phpunit/includes/installer/InstallerTest.php             
                (rev 0)
+++ trunk/phase3/tests/phpunit/includes/installer/InstallerTest.php     
2011-06-15 07:35:47 UTC (rev 90105)
@@ -0,0 +1,102 @@
+<?php
+
+class Installer_TestHelper extends Installer {
+       function showMessage( $msg ) {}
+       function showError( $msg ) {}
+       function showStatusMessage( Status $status ) {}
+
+       function __construct() {
+               $this->settings = array();
+       }
+
+}
+
+class InstallerTest extends MediaWikiTestCase {
+       /**
+        * @dataProvider provideEnvCheckServer
+        */
+       function testEnvCheckServer( $expected, $input, $description ) {
+               $installer = new Installer_TestHelper;
+               $oldServer = $_SERVER;
+               $_SERVER = $input;
+               $rm = new ReflectionMethod( 'Installer_TestHelper', 
'envCheckServer' );
+               $rm->setAccessible( true );
+               $rm->invoke( $installer );
+               $_SERVER = $oldServer;
+               $this->assertEquals( $expected, $installer->getVar( 'wgServer' 
), $description );
+       }
+
+       function provideEnvCheckServer() {
+               return array(
+                       array(
+                               'http://x',
+                               array(
+                                       'HTTP_HOST' => 'x'
+                               ),
+                               'Host header'
+                       ),
+                       array(
+                               'https://x',
+                               array(
+                                       'HTTP_HOST' => 'x',
+                                       'HTTPS' => 'on',
+                               ),
+                               'Host header with secure'
+                       ),
+                       array(
+                               'http://x',
+                               array(
+                                       'HTTP_HOST' => 'x',
+                                       'SERVER_PORT' => 80,
+                               ),
+                               'Default SERVER_PORT',
+                       ),
+                       array(
+                               'http://x',
+                               array(
+                                       'HTTP_HOST' => 'x',
+                                       'HTTPS' => 'off',
+                               ),
+                               'Secure off'
+                       ),
+                       array(
+                               'http://y',
+                               array(
+                                       'SERVER_NAME' => 'y',
+                               ),
+                               'Server name'
+                       ),
+                       array(
+                               'http://x',
+                               array(
+                                       'HTTP_HOST' => 'x',
+                                       'SERVER_NAME' => 'y',
+                               ),
+                               'Host server name precedence'
+                       ),
+                       array(
+                               'http://[::1]:81',
+                               array(
+                                       'HTTP_HOST' => '[::1]',
+                                       'SERVER_NAME' => '::1',
+                                       'SERVER_PORT' => '81',
+                               ),
+                               'Apache bug 26005'
+                       ),
+                       array(
+                               'http://localhost',
+                               array(
+                                       'SERVER_NAME' => '[2001'
+                               ),
+                               'Kind of like lighttpd per commit message in MW 
r83847',
+                       ),
+                       array(
+                               'http://[2a01:e35:2eb4:1::2]:777',
+                               array(
+                                       'SERVER_NAME' => 
'[2a01:e35:2eb4:1::2]:777'
+                               ),
+                               'Possible lighttpd environment per bug 14977 
comment 13',
+                       ),
+               );
+       }
+}


Property changes on: 
trunk/phase3/tests/phpunit/includes/installer/InstallerTest.php
___________________________________________________________________
Added: svn:eol-style
   + native


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to