|
|
|
@ -308,7 +308,7 @@ class Pico |
|
|
|
|
$this->triggerEvent('onRequestUrl', array(&$this->requestUrl)); |
|
|
|
|
|
|
|
|
|
// discover requested file |
|
|
|
|
$this->discoverRequestFile(); |
|
|
|
|
$this->requestFile = $this->resolveFilePath($this->requestUrl); |
|
|
|
|
$this->triggerEvent('onRequestFile', array(&$this->requestFile)); |
|
|
|
|
|
|
|
|
|
// load raw file content |
|
|
|
@ -735,24 +735,29 @@ class Pico |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Uses the request URL to discover the content file to serve |
|
|
|
|
* Resolves a given file path to its corresponding content file |
|
|
|
|
* |
|
|
|
|
* This method also prevents `content_dir` breakouts using malicious |
|
|
|
|
* request URLs. We don't use `realpath()`, because we neither want to |
|
|
|
|
* check for file existance, nor prohibit symlinks which intentionally |
|
|
|
|
* point to somewhere outside the `content_dir` folder. It is STRONGLY |
|
|
|
|
* RECOMMENDED to use PHP's `open_basedir` feature - always, not just |
|
|
|
|
* with Pico! |
|
|
|
|
* |
|
|
|
|
* @see Pico::getRequestFile() |
|
|
|
|
* @return void |
|
|
|
|
* @param string $requestUrl path name (likely from a URL) to resolve |
|
|
|
|
* @return string path to the resolved content file |
|
|
|
|
*/ |
|
|
|
|
protected function discoverRequestFile() |
|
|
|
|
public function resolveFilePath($requestUrl) |
|
|
|
|
{ |
|
|
|
|
$contentDir = $this->getConfig('content_dir'); |
|
|
|
|
$contentExt = $this->getConfig('content_ext'); |
|
|
|
|
|
|
|
|
|
if (empty($this->requestUrl)) { |
|
|
|
|
$this->requestFile = $contentDir . 'index' . $contentExt; |
|
|
|
|
if (empty($requestUrl)) { |
|
|
|
|
return $contentDir . 'index' . $contentExt; |
|
|
|
|
} else { |
|
|
|
|
// prevent content_dir breakouts using malicious request URLs |
|
|
|
|
// we don't use realpath() here because we neither want to check for file existance |
|
|
|
|
// nor prohibit symlinks which intentionally point to somewhere outside the content_dir |
|
|
|
|
// it is STRONGLY RECOMMENDED to use open_basedir - always, not just with Pico! |
|
|
|
|
$requestUrl = str_replace('\\', '/', $this->requestUrl); |
|
|
|
|
// prevent content_dir breakouts |
|
|
|
|
$requestUrl = str_replace('\\', '/', $requestUrl); |
|
|
|
|
$requestUrlParts = explode('/', $requestUrl); |
|
|
|
|
|
|
|
|
|
$requestFileParts = array(); |
|
|
|
@ -768,31 +773,29 @@ class Pico |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (empty($requestFileParts)) { |
|
|
|
|
$this->requestFile = $contentDir . 'index' . $contentExt; |
|
|
|
|
return; |
|
|
|
|
return $contentDir . 'index' . $contentExt; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// discover the content file to serve |
|
|
|
|
// Note: $requestFileParts neither contains a trailing nor a leading slash |
|
|
|
|
$this->requestFile = $contentDir . implode('/', $requestFileParts); |
|
|
|
|
if (is_dir($this->requestFile)) { |
|
|
|
|
$requestFile = $contentDir . implode('/', $requestFileParts); |
|
|
|
|
if (is_dir($requestFile)) { |
|
|
|
|
// if no index file is found, try a accordingly named file in the previous dir |
|
|
|
|
// if this file doesn't exist either, show the 404 page, but assume the index |
|
|
|
|
// file as being requested (maintains backward compatibility to Pico < 1.0) |
|
|
|
|
$indexFile = $this->requestFile . '/index' . $contentExt; |
|
|
|
|
if (file_exists($indexFile) || !file_exists($this->requestFile . $contentExt)) { |
|
|
|
|
$this->requestFile = $indexFile; |
|
|
|
|
return; |
|
|
|
|
$indexFile = $requestFile . '/index' . $contentExt; |
|
|
|
|
if (file_exists($indexFile) || !file_exists($requestFile . $contentExt)) { |
|
|
|
|
return $indexFile; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
$this->requestFile .= $contentExt; |
|
|
|
|
return $requestFile . $contentExt; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns the absolute path to the content file to serve |
|
|
|
|
* |
|
|
|
|
* @see Pico::discoverRequestFile() |
|
|
|
|
* @see Pico::resolveFilePath() |
|
|
|
|
* @return string|null file path |
|
|
|
|
*/ |
|
|
|
|
public function getRequestFile() |
|
|
|
|