summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
authorAndrey Andreev <narf@bofh.bg>2012-10-31 15:16:24 +0100
committerAndrey Andreev <narf@bofh.bg>2012-10-31 15:16:24 +0100
commitf2b19fee7876708c7a7bb5cba6b7df682a9d2a53 (patch)
tree55ff9ee5bca8ed79a039108347e6ede2ff5969a8 /system
parentd4516e3562b1c412d7c3edea874eaa6e6922ad0e (diff)
Multiple improvements to the URI class
(thanks to @sourcejedi, PR #1326 for most of the ideas) - Renamed _detect_uri() and _parse_cli_args() to _parse_request_uri() and _parse_argv() respectively. - Added _parse_query_string() which allows us to detect the URI path from QUERY_STRING much like it is done in _parse_request_uri(). (the above changes also allow for a simpler logic in the case where the *uri_protocol* setting is not set to 'AUTO') - Updated application/config/config.php with a better list of the *uri_protocol* options. - Added _reset_query_string() to aid in re-processing from the QUERY_STRING (utilized in _parse_request_uri() and _parse_query_string()).
Diffstat (limited to 'system')
-rw-r--r--system/core/URI.php103
1 files changed, 75 insertions, 28 deletions
diff --git a/system/core/URI.php b/system/core/URI.php
index 3d942eda7..6692d07a6 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -98,12 +98,12 @@ class CI_URI {
// Is the request coming from the command line?
if ($this->_is_cli_request())
{
- $this->_set_uri_string($this->_parse_cli_args());
+ $this->_set_uri_string($this->_parse_argv());
return;
}
// Let's try the REQUEST_URI first, this will work in most situations
- if ($uri = $this->_detect_uri())
+ if (($uri = $this->_parse_request_uri()) !== '')
{
$this->_set_uri_string($uri);
return;
@@ -111,18 +111,17 @@ class CI_URI {
// Is there a PATH_INFO variable?
// Note: some servers seem to have trouble with getenv() so we'll test it two ways
- $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
- if (trim($path, '/') !== '' && $path !== '/'.SELF)
+ $uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
+ if (trim($uri, '/') !== '' && $uri !== '/'.SELF)
{
$this->_set_uri_string($path);
return;
}
// No PATH_INFO?... What about QUERY_STRING?
- $path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
- if (trim($path, '/') !== '')
+ if (($uri = $this->_parse_query_string()) !== '')
{
- $this->_set_uri_string($path);
+ $this->_set_uri_string($uri);
return;
}
@@ -140,19 +139,19 @@ class CI_URI {
$uri = strtoupper($this->config->item('uri_protocol'));
- if ($uri === 'REQUEST_URI')
+ if ($uri === 'CLI')
{
- $this->_set_uri_string($this->_detect_uri());
+ $this->_set_uri_string($this->_parse_argv());
return;
}
- elseif ($uri === 'CLI')
+ elseif (method_exists($this, ($method = '_parse_'.strtolower($uri))))
{
- $this->_set_uri_string($this->_parse_cli_args());
+ $this->_set_uri_string($this->$method());
return;
}
- $path = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri);
- $this->_set_uri_string($path);
+ $uri = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri);
+ $this->_set_uri_string($uri);
}
// --------------------------------------------------------------------
@@ -172,13 +171,15 @@ class CI_URI {
// --------------------------------------------------------------------
/**
- * Detects URI
+ * Parse REQUEST_URI
*
- * Will detect the URI automatically and fix the query string if necessary.
+ * Will parse REQUEST_URI and automatically detect the URI from it,
+ * while fixing the query string if necessary.
*
+ * @used-by CI_URI::_fetch_uri_string()
* @return string
*/
- protected function _detect_uri()
+ protected function _parse_request_uri()
{
if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
{
@@ -197,10 +198,10 @@ class CI_URI {
{
$uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
}
+
// 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 ($uri === '' && strncmp($query, '/', 1) === 0)
+ if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0)
{
$query = explode('?', $query, 2);
$uri = $query[0];
@@ -211,14 +212,7 @@ class CI_URI {
$_SERVER['QUERY_STRING'] = $query;
}
- if ($_SERVER['QUERY_STRING'] === '')
- {
- $_GET = array();
- }
- else
- {
- parse_str($_SERVER['QUERY_STRING'], $_GET);
- }
+ $this->_reset_query_string();
if ($uri === '/' OR $uri === '')
{
@@ -232,6 +226,59 @@ class CI_URI {
// --------------------------------------------------------------------
/**
+ * Parse QUERY_STRING
+ *
+ * Will parse QUERY_STRING and automatically detect the URI from it.
+ *
+ * @used-by CI_URI::_fetch_uri_string()
+ * @return string
+ */
+ protected function _parse_query_string()
+ {
+ $uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
+
+ if (trim($uri, '/') === '')
+ {
+ return '';
+ }
+ elseif (strncmp($uri, '/', 1) === 0)
+ {
+ $uri = explode('?', $uri, 2);
+ $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : '';
+ $uri = $uri[0];
+ }
+ $this->_reset_query_string();
+
+ return str_replace(array('//', '../'), '/', trim($uri, '/'));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Reset QUERY_STRING
+ *
+ * Re-processes QUERY_STRING to and fetches the real GET values from it.
+ * Useful for cases where we got the URI path from it's query string.
+ *
+ * @used-by CI_URI::_parse_request_uri()
+ * @used-by CI_URI::_parse_query_string()
+ * @return void
+ */
+ protected function _reset_query_string()
+ {
+ if ($_SERVER['QUERY_STRING'] === '')
+ {
+ $_GET = array();
+ }
+ else
+ {
+ parse_str($_SERVER['QUERY_STRING']);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
* Is CLI Request?
*
* Duplicate of method from the Input class to test to see if
@@ -255,10 +302,10 @@ class CI_URI {
*
* @return string
*/
- protected function _parse_cli_args()
+ protected function _parse_argv()
{
$args = array_slice($_SERVER['argv'], 1);
- return $args ? '/'.implode('/', $args) : '';
+ return $args ? implode('/', $args) : '';
}
// --------------------------------------------------------------------