Index: branches/wmf/1.17wmf1/includes/GlobalFunctions.php |
— | — | @@ -1451,24 +1451,44 @@ |
1452 | 1452 | return $url; |
1453 | 1453 | } |
1454 | 1454 | |
| 1455 | +define( 'PROTO_HTTP', 'http://' ); |
| 1456 | +define( 'PROTO_HTTPS', 'https://' ); |
| 1457 | +define( 'PROTO_RELATIVE', '//' ); |
| 1458 | +define( 'PROTO_CURRENT', null ); |
| 1459 | + |
1455 | 1460 | /** |
1456 | 1461 | * Expand a potentially local URL to a fully-qualified URL. Assumes $wgServer |
1457 | | - * and $wgProto are correct. |
| 1462 | + * is correct. |
| 1463 | + * |
| 1464 | + * The meaning of the PROTO_* constants is as follows: |
| 1465 | + * PROTO_HTTP: Output a URL starting with http:// |
| 1466 | + * PROTO_HTTPS: Output a URL starting with https:// |
| 1467 | + * PROTO_RELATIVE: Output a URL starting with // (protocol-relative URL) |
| 1468 | + * PROTO_CURRENT: Output a URL starting with either http:// or https:// , depending on which protocol was used for the current incoming request |
1458 | 1469 | * |
1459 | 1470 | * @todo this won't work with current-path-relative URLs |
1460 | 1471 | * like "subdir/foo.html", etc. |
1461 | 1472 | * |
1462 | 1473 | * @param $url String: either fully-qualified or a local path + query |
| 1474 | + * @param $defaultProto Mixed: one of the PROTO_* constants. Determines the protocol to use if $url or $wgServer is protocol-relative |
1463 | 1475 | * @return string Fully-qualified URL |
1464 | 1476 | */ |
1465 | | -function wfExpandUrl( $url ) { |
| 1477 | +function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) { |
1466 | 1478 | global $wgServer; |
| 1479 | + if ( $defaultProto === PROTO_CURRENT ) { |
| 1480 | + $defaultProto = WebRequest::detectProtocol() . '://'; |
| 1481 | + } |
| 1482 | + |
| 1483 | + // Analyze $wgServer to obtain its protocol |
| 1484 | + $bits = wfParseUrl( $wgServer ); |
| 1485 | + $serverHasProto = $bits && $bits['scheme'] != ''; |
| 1486 | + $defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 ); |
| 1487 | + |
1467 | 1488 | if( substr( $url, 0, 2 ) == '//' ) { |
1468 | | - $bits = wfParseUrl( $wgServer ); |
1469 | | - $scheme = $bits && $bits['scheme'] !== '' ? $bits['scheme'] : 'http'; |
1470 | | - return $scheme . ':' . $url; |
| 1489 | + return $defaultProtoWithoutSlashes . $url; |
1471 | 1490 | } elseif( substr( $url, 0, 1 ) == '/' ) { |
1472 | | - return $wgServer . $url; |
| 1491 | + // If $wgServer is protocol-relative, prepend $defaultProtoWithoutSlashes, otherwise leave it alone |
| 1492 | + return ( $serverHasProto ? '' : $defaultProtoWithoutSlashes ) . $wgServer . $url; |
1473 | 1493 | } else { |
1474 | 1494 | return $url; |
1475 | 1495 | } |
Index: branches/wmf/1.17wmf1/includes/WebRequest.php |
— | — | @@ -54,7 +54,51 @@ |
55 | 55 | // We don't use $_REQUEST here to avoid interference from cookies... |
56 | 56 | $this->data = $_POST + $_GET; |
57 | 57 | } |
| 58 | + |
| 59 | + /** |
| 60 | + * Work out an appropriate URL prefix containing scheme and host, based on |
| 61 | + * information detected from $_SERVER |
| 62 | + * |
| 63 | + * @return string |
| 64 | + */ |
| 65 | + public static function detectServer() { |
| 66 | + list( $proto, $stdPort ) = self::detectProtocolAndStdPort(); |
58 | 67 | |
| 68 | + $varNames = array( 'HTTP_HOST', 'SERVER_NAME', 'HOSTNAME', 'SERVER_ADDR' ); |
| 69 | + $host = 'localhost'; |
| 70 | + $port = $stdPort; |
| 71 | + foreach ( $varNames as $varName ) { |
| 72 | + if ( !isset( $_SERVER[$varName] ) ) { |
| 73 | + continue; |
| 74 | + } |
| 75 | + $parts = IP::splitHostAndPort( $_SERVER[$varName] ); |
| 76 | + if ( !$parts ) { |
| 77 | + // Invalid, do not use |
| 78 | + continue; |
| 79 | + } |
| 80 | + $host = $parts[0]; |
| 81 | + if ( $parts[1] === false ) { |
| 82 | + if ( isset( $_SERVER['SERVER_PORT'] ) ) { |
| 83 | + $port = $_SERVER['SERVER_PORT']; |
| 84 | + } // else leave it as $stdPort |
| 85 | + } else { |
| 86 | + $port = $parts[1]; |
| 87 | + } |
| 88 | + break; |
| 89 | + } |
| 90 | + |
| 91 | + return $proto . '://' . IP::combineHostAndPort( $host, $port, $stdPort ); |
| 92 | + } |
| 93 | + |
| 94 | + public static function detectProtocolAndStdPort() { |
| 95 | + return ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == 'on' ) ? array( 'https', 443 ) : array( 'http', 80 ); |
| 96 | + } |
| 97 | + |
| 98 | + public static function detectProtocol() { |
| 99 | + list( $proto, $stdPort ) = self::detectProtocolAndStdPort(); |
| 100 | + return $proto; |
| 101 | + } |
| 102 | + |
59 | 103 | /** |
60 | 104 | * Check for title, action, and/or variant data in the URL |
61 | 105 | * and interpolate it into the GET variables. |