Skip to content
Snippets Groups Projects
Commit 35b88e29 authored by Olav Morken's avatar Olav Morken
Browse files

Utilities: add resolveURL to resolve (possibly) relative URLs.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@618 44740490-163a-0410-bde0-09ae8108e29a
parent 80d860a0
No related branches found
No related tags found
No related merge requests found
...@@ -974,6 +974,88 @@ class SimpleSAML_Utilities { ...@@ -974,6 +974,88 @@ class SimpleSAML_Utilities {
return $ret; return $ret;
} }
/**
* Resolve a (possibly) relative URL relative to a given base URL.
*
* This function supports these forms of relative URLs:
* ^\w+: Absolute URL
* ^// Same protocol.
* ^/ Same protocol and host.
* ^? Same protocol, host and path, replace query string & fragment
* ^# Same protocol, host, path and query, replace fragment
* The rest: Relative to the base path.
*
* @param $url The relative URL.
* @param $base The base URL. Defaults to the base URL of this installation of simpleSAMLphp.
* @return An absolute URL for the given relative URL.
*/
public static function resolveURL($url, $base = NULL) {
if($base === NULL) {
$config = SimpleSAML_Configuration::getInstance();
$base = self::selfURLhost() . '/' . $config->getBaseURL();
}
if(!preg_match('$^((((\w+:)//[^/]+)(/[^?#]*))(?:\?[^#]*)?)(?:#.*)?$', $base, $baseParsed)) {
throw new Exception('Unable to parse base url: ' . $base);
}
$baseDir = dirname($baseParsed[5] . 'filename');
$baseScheme = $baseParsed[4];
$baseHost = $baseParsed[3];
$basePath = $baseParsed[2];
$baseQuery = $baseParsed[1];
if(preg_match('$^\w+:$', $url)) {
return $url;
}
if(substr($url, 0, 2) === '//') {
return $baseScheme . $url;
}
$firstChar = substr($url, 0, 1);
if($firstChar === '/') {
return $baseHost . $url;
}
if($firstChar === '?') {
return $basePath . $url;
}
if($firstChar === '#') {
return $baseQuery . $url;
}
/* We have a relative path. Remove query string/fragment and save it as $tail. */
$queryPos = strpos($url, '?');
$fragmentPos = strpos($url, '#');
if($queryPos !== FALSE || $fragmentPos !== FALSE) {
if($queryPos === FALSE) {
$tailPos = $fragmentPos;
} elseif($fragmentPos === FALSE) {
$tailPos = $queryPos;
} elseif($queryPos < $fragmentPos) {
$tailPos = $queryPos;
} else {
$tailPos = $fragmentPos;
}
$tail = substr($url, $tailPos);
$dir = substr($url, 0, $tailPos);
} else {
$dir = $url;
$tail = '';
}
$dir = self::resolvePath($dir, $baseDir);
return $baseHost . $dir . $tail;
}
} }
?> ?>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment