summaryrefslogtreecommitdiffstats
path: root/system/core/URI.php
diff options
context:
space:
mode:
Diffstat (limited to 'system/core/URI.php')
-rw-r--r--system/core/URI.php111
1 files changed, 67 insertions, 44 deletions
diff --git a/system/core/URI.php b/system/core/URI.php
index a991118e8..999015949 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -61,13 +61,17 @@ class CI_URI {
{
if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
{
- // If the URL has a question mark then it's simplest to just
- // build the URI string from the zero index of the $_GET array.
- // This avoids having to deal with $_SERVER variables, which
- // can be unreliable in some environments
- if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
+ // Arguments exist, it must be a command line request
+ if ( ! empty($_SERVER['argv']))
{
- $this->uri_string = key($_GET);
+ $this->uri_string = $this->_parse_cli_args();
+ return;
+ }
+
+ // Let's try the REQUEST_URI first, this will work in most situations
+ if ($uri = $this->_detect_uri())
+ {
+ $this->uri_string = $uri;
return;
}
@@ -88,12 +92,10 @@ class CI_URI {
return;
}
- // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?
- $path = str_replace($_SERVER['SCRIPT_NAME'], '', (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO'));
- if (trim($path, '/') != '' && $path != "/".SELF)
+ // As a last ditch effort lets try using the $_GET array
+ if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
{
- // remove path and script information so we have good URI data
- $this->uri_string = $path;
+ $this->uri_string = key($_GET);
return;
}
@@ -106,7 +108,12 @@ class CI_URI {
if ($uri == 'REQUEST_URI')
{
- $this->uri_string = $this->_parse_request_uri();
+ $this->uri_string = $this->_detect_uri();
+ return;
+ }
+ elseif ($uri == 'CLI')
+ {
+ $this->uri_string = $this->_parse_cli_args();
return;
}
@@ -123,54 +130,70 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Parse the REQUEST_URI
+ * Detects the URI
*
- * Due to the way REQUEST_URI works it usually contains path info
- * that makes it unusable as URI data. We'll trim off the unnecessary
- * data, hopefully arriving at a valid URI that we can use.
+ * This function will detect the URI automatically and fix the query string
+ * if necessary.
*
* @access private
* @return string
*/
- function _parse_request_uri()
+ private function _detect_uri()
{
- if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')
+ if ( ! isset($_SERVER['REQUEST_URI']))
{
return '';
}
- $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));
-
- if ($request_uri == '' OR $request_uri == SELF)
+ $uri = $_SERVER['REQUEST_URI'];
+ if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
{
- return '';
+ $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
}
-
- $fc_path = FCPATH.SELF;
- if (strpos($request_uri, '?') !== FALSE)
+ elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
{
- $fc_path .= '?';
+ $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
}
- $parsed_uri = explode("/", $request_uri);
-
- $i = 0;
- foreach(explode("/", $fc_path) as $segment)
+ // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
+ // URI is found, and also fixes the QUERY_STRING server var and $_GET array.
+ if (strncmp($uri, '?/', 2) === 0)
{
- if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])
- {
- $i++;
- }
+ $uri = substr($uri, 2);
}
-
- $parsed_uri = implode("/", array_slice($parsed_uri, $i));
-
- if ($parsed_uri != '')
+ $parts = preg_split('#\?#i', $uri, 2);
+ $uri = $parts[0];
+ if (isset($parts[1]))
+ {
+ $_SERVER['QUERY_STRING'] = $parts[1];
+ parse_str($_SERVER['QUERY_STRING'], $_GET);
+ }
+ else
{
- $parsed_uri = '/'.$parsed_uri;
+ $_SERVER['QUERY_STRING'] = '';
+ $_GET = array();
}
+ $uri = parse_url($uri, PHP_URL_PATH);
- return $parsed_uri;
+ // Do some final cleaning of the URI and return it
+ return str_replace(array('//', '../'), '/', trim($uri, '/'));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Parse cli arguments
+ *
+ * Take each command line argument and assume it is a URI segment.
+ *
+ * @access private
+ * @return string
+ */
+ private function _parse_cli_args()
+ {
+ $args = array_slice($_SERVER['argv'], 1);
+
+ return $args ? '/' . implode('/', $args) : '';
}
// --------------------------------------------------------------------
@@ -228,7 +251,7 @@ class CI_URI {
*/
function _explode_segments()
{
- foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+ foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
{
// Filter segments for security
$val = trim($this->_filter_uri($val));
@@ -484,7 +507,7 @@ class CI_URI {
{
$leading = '/';
$trailing = '/';
-
+
if ($where == 'trailing')
{
$leading = '';
@@ -493,7 +516,7 @@ class CI_URI {
{
$trailing = '';
}
-
+
return $leading.$this->$which($n).$trailing;
}
@@ -573,7 +596,7 @@ class CI_URI {
*/
function ruri_string()
{
- return '/'.implode('/', $this->rsegment_array()).'/';
+ return '/'.implode('/', $this->rsegment_array());
}
}