/**
  * @dataProvider providePaths
  */
 public function testWfRemoveDotSegments($inputPath, $outputPath)
 {
     $this->assertEquals($outputPath, wfRemoveDotSegments($inputPath), "Testing {$inputPath} expands to {$outputPath}");
 }
/**
 * Expand a potentially local URL to a fully-qualified URL.  Assumes $wgServer
 * is correct.
 *
 * The meaning of the PROTO_* constants is as follows:
 * PROTO_HTTP: Output a URL starting with http://
 * PROTO_HTTPS: Output a URL starting with https://
 * PROTO_RELATIVE: Output a URL starting with // (protocol-relative URL)
 * PROTO_CURRENT: Output a URL starting with either http:// or https:// , depending on which protocol was used for the current incoming request
 * PROTO_CANONICAL: For URLs without a domain, like /w/index.php , use $wgCanonicalServer. For protocol-relative URLs, use the protocol of $wgCanonicalServer
 * PROTO_INTERNAL: Like PROTO_CANONICAL, but uses $wgInternalServer instead of $wgCanonicalServer
 *
 * @todo this won't work with current-path-relative URLs
 * like "subdir/foo.html", etc.
 *
 * @param $url String: either fully-qualified or a local path + query
 * @param $defaultProto Mixed: one of the PROTO_* constants. Determines the
 *                             protocol to use if $url or $wgServer is
 *                             protocol-relative
 * @return string Fully-qualified URL, current-path-relative URL or false if
 *                no valid URL can be constructed
 */
function wfExpandUrl($url, $defaultProto = PROTO_CURRENT)
{
    global $wgServer, $wgCanonicalServer, $wgInternalServer;
    $serverUrl = $wgServer;
    if ($defaultProto === PROTO_CANONICAL) {
        $serverUrl = $wgCanonicalServer;
    }
    // Make $wgInternalServer fall back to $wgServer if not set
    if ($defaultProto === PROTO_INTERNAL && $wgInternalServer !== false) {
        $serverUrl = $wgInternalServer;
    }
    if ($defaultProto === PROTO_CURRENT) {
        $defaultProto = WebRequest::detectProtocol() . '://';
    }
    // Analyze $serverUrl to obtain its protocol
    $bits = wfParseUrl($serverUrl);
    $serverHasProto = $bits && $bits['scheme'] != '';
    if ($defaultProto === PROTO_CANONICAL || $defaultProto === PROTO_INTERNAL) {
        if ($serverHasProto) {
            $defaultProto = $bits['scheme'] . '://';
        } else {
            // $wgCanonicalServer or $wgInternalServer doesn't have a protocol. This really isn't supposed to happen
            // Fall back to HTTP in this ridiculous case
            $defaultProto = PROTO_HTTP;
        }
    }
    $defaultProtoWithoutSlashes = substr($defaultProto, 0, -2);
    if (substr($url, 0, 2) == '//') {
        $url = $defaultProtoWithoutSlashes . $url;
    } elseif (substr($url, 0, 1) == '/') {
        // If $serverUrl is protocol-relative, prepend $defaultProtoWithoutSlashes, otherwise leave it alone
        $url = ($serverHasProto ? '' : $defaultProtoWithoutSlashes) . $serverUrl . $url;
    }
    $bits = wfParseUrl($url);
    if ($bits && isset($bits['path'])) {
        $bits['path'] = wfRemoveDotSegments($bits['path']);
        return wfAssembleUrl($bits);
    } elseif ($bits) {
        # No path to expand
        return $url;
    } elseif (substr($url, 0, 1) != '/') {
        # URL is a relative path
        return wfRemoveDotSegments($url);
    }
    # Expanded URL is not valid.
    return false;
}
Example #3
0
/**
 * Expand a potentially local URL to a fully-qualified URL. Assumes $wgServer
 * is correct.
 *
 * The meaning of the PROTO_* constants is as follows:
 * PROTO_HTTP: Output a URL starting with http://
 * PROTO_HTTPS: Output a URL starting with https://
 * PROTO_RELATIVE: Output a URL starting with // (protocol-relative URL)
 * PROTO_CURRENT: Output a URL starting with either http:// or https:// , depending
 *    on which protocol was used for the current incoming request
 * PROTO_CANONICAL: For URLs without a domain, like /w/index.php , use $wgCanonicalServer.
 *    For protocol-relative URLs, use the protocol of $wgCanonicalServer
 * PROTO_INTERNAL: Like PROTO_CANONICAL, but uses $wgInternalServer instead of $wgCanonicalServer
 *
 * @todo this won't work with current-path-relative URLs
 * like "subdir/foo.html", etc.
 *
 * @param string $url Either fully-qualified or a local path + query
 * @param string $defaultProto One of the PROTO_* constants. Determines the
 *    protocol to use if $url or $wgServer is protocol-relative
 * @return string Fully-qualified URL, current-path-relative URL or false if
 *    no valid URL can be constructed
 */
function wfExpandUrl($url, $defaultProto = PROTO_CURRENT)
{
    global $wgServer, $wgCanonicalServer, $wgInternalServer, $wgRequest, $wgHttpsPort;
    if ($defaultProto === PROTO_CANONICAL) {
        $serverUrl = $wgCanonicalServer;
    } elseif ($defaultProto === PROTO_INTERNAL && $wgInternalServer !== false) {
        // Make $wgInternalServer fall back to $wgServer if not set
        $serverUrl = $wgInternalServer;
    } else {
        $serverUrl = $wgServer;
        if ($defaultProto === PROTO_CURRENT) {
            $defaultProto = $wgRequest->getProtocol() . '://';
        }
    }
    // Analyze $serverUrl to obtain its protocol
    $bits = wfParseUrl($serverUrl);
    $serverHasProto = $bits && $bits['scheme'] != '';
    if ($defaultProto === PROTO_CANONICAL || $defaultProto === PROTO_INTERNAL) {
        if ($serverHasProto) {
            $defaultProto = $bits['scheme'] . '://';
        } else {
            // $wgCanonicalServer or $wgInternalServer doesn't have a protocol.
            // This really isn't supposed to happen. Fall back to HTTP in this
            // ridiculous case.
            $defaultProto = PROTO_HTTP;
        }
    }
    $defaultProtoWithoutSlashes = substr($defaultProto, 0, -2);
    if (substr($url, 0, 2) == '//') {
        $url = $defaultProtoWithoutSlashes . $url;
    } elseif (substr($url, 0, 1) == '/') {
        // If $serverUrl is protocol-relative, prepend $defaultProtoWithoutSlashes,
        // otherwise leave it alone.
        $url = ($serverHasProto ? '' : $defaultProtoWithoutSlashes) . $serverUrl . $url;
    }
    $bits = wfParseUrl($url);
    // ensure proper port for HTTPS arrives in URL
    // https://bugzilla.wikimedia.org/show_bug.cgi?id=65184
    if ($defaultProto === PROTO_HTTPS && $wgHttpsPort != 443) {
        $bits['port'] = $wgHttpsPort;
    }
    if ($bits && isset($bits['path'])) {
        $bits['path'] = wfRemoveDotSegments($bits['path']);
        return wfAssembleUrl($bits);
    } elseif ($bits) {
        # No path to expand
        return $url;
    } elseif (substr($url, 0, 1) != '/') {
        # URL is a relative path
        return wfRemoveDotSegments($url);
    }
    # Expanded URL is not valid.
    return false;
}
Example #4
0
 /**
  * Remap or embed a CSS URL path.
  *
  * @param string $file URL to remap/embed
  * @param string $query
  * @param string $local File path where the source was read from
  * @param string $remote URL path to the file
  * @param bool $embed Whether to do any data URI embedding
  * @return string Remapped/embedded URL data
  */
 public static function remapOne($file, $query, $local, $remote, $embed)
 {
     // The full URL possibly with query, as passed to the 'url()' value in CSS
     $url = $file . $query;
     // Expand local URLs with absolute paths like /w/index.php to possibly protocol-relative URL, if
     // wfExpandUrl() is available. (This will not be the case if we're running outside of MW.)
     if (self::isLocalUrl($url) && function_exists('wfExpandUrl')) {
         return wfExpandUrl($url, PROTO_RELATIVE);
     }
     // Pass thru fully-qualified and protocol-relative URLs and data URIs, as well as local URLs if
     // we can't expand them.
     if (self::isRemoteUrl($url) || self::isLocalUrl($url)) {
         return $url;
     }
     if ($local === false) {
         // Assume that all paths are relative to $remote, and make them absolute
         $url = $remote . '/' . $url;
     } else {
         // We drop the query part here and instead make the path relative to $remote
         $url = "{$remote}/{$file}";
         // Path to the actual file on the filesystem
         $localFile = "{$local}/{$file}";
         if (file_exists($localFile)) {
             // Add version parameter as the first five hex digits
             // of the MD5 hash of the file's contents.
             $url .= '?' . substr(md5_file($localFile), 0, 5);
             if ($embed) {
                 $data = self::encodeImageAsDataURI($localFile);
                 if ($data !== false) {
                     return $data;
                 }
             }
         }
         // If any of these conditions failed (file missing, we don't want to embed it
         // or it's not embeddable), return the URL (possibly with ?timestamp part)
     }
     if (function_exists('wfRemoveDotSegments')) {
         $url = wfRemoveDotSegments($url);
     }
     return $url;
 }