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