From d4516e3562b1c412d7c3edea874eaa6e6922ad0e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 14:44:38 +0200 Subject: CI_URI::_detect_uri() to accept absolute URIs (thanks to @sourcejedi, PR #1326) For HTTP/1.1 compliance, RFC2616 specifies that both relative and absolute URI formats must be accepted: - http://localhost/path/ (absolute) - /path/ (relative) --- system/core/URI.php | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index d67a35d4b..3d942eda7 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -185,37 +185,39 @@ class CI_URI { return ''; } - if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) - { - $uri = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); - } - elseif (strpos($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME'])) === 0) + $uri = parse_url($_SERVER['REQUEST_URI']); + $query = isset($uri['query']) ? $uri['query'] : ''; + $uri = isset($uri['path']) ? $uri['path'] : ''; + + if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) { - $uri = substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME']))); + $uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME'])); } - else + elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) { - $uri = $_SERVER['REQUEST_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 (strpos($uri, '?/') === 0) + + if ($uri === '' && strncmp($query, '/', 1) === 0) + { + $query = explode('?', $query, 2); + $uri = $query[0]; + $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; + } + else { - $uri = substr($uri, 2); + $_SERVER['QUERY_STRING'] = $query; } - $parts = explode('?', $uri, 2); - $uri = $parts[0]; - if (isset($parts[1])) + if ($_SERVER['QUERY_STRING'] === '') { - $_SERVER['QUERY_STRING'] = $parts[1]; - parse_str($_SERVER['QUERY_STRING'], $_GET); + $_GET = array(); } else { - $_SERVER['QUERY_STRING'] = ''; - $_GET = array(); + parse_str($_SERVER['QUERY_STRING'], $_GET); } if ($uri === '/' OR $uri === '') @@ -223,8 +225,6 @@ class CI_URI { return '/'; } - $uri = parse_url('pseudo://hostname/'.$uri, PHP_URL_PATH); - // Do some final cleaning of the URI and return it return str_replace(array('//', '../'), '/', trim($uri, '/')); } -- cgit v1.2.3-24-g4f1b From f2b19fee7876708c7a7bb5cba6b7df682a9d2a53 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 16:16:24 +0200 Subject: 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()). --- system/core/URI.php | 103 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 28 deletions(-) (limited to 'system/core/URI.php') 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 === '') { @@ -231,6 +225,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? * @@ -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) : ''; } // -------------------------------------------------------------------- -- cgit v1.2.3-24-g4f1b From 704f3f5223637dd6008106b1d04a68668458590e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 16:50:13 +0200 Subject: Fix an erroneous variable name --- system/core/URI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index 6692d07a6..407a6ce88 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -114,7 +114,7 @@ class CI_URI { $uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); if (trim($uri, '/') !== '' && $uri !== '/'.SELF) { - $this->_set_uri_string($path); + $this->_set_uri_string($uri); return; } -- cgit v1.2.3-24-g4f1b From 9dd2dbb8b9a3edecddcb3907b65a402fd1ae71b4 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 17:54:56 +0200 Subject: Fix issues #388 & #705 (thanks to @sourcejedi, PR #1326 for pointing inconsistencies with RFC2616 --- system/core/URI.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index 407a6ce88..4a8d33e88 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -188,7 +188,7 @@ class CI_URI { $uri = parse_url($_SERVER['REQUEST_URI']); $query = isset($uri['query']) ? $uri['query'] : ''; - $uri = isset($uri['path']) ? $uri['path'] : ''; + $uri = isset($uri['path']) ? rawurldecode($uri['path']) : ''; if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) { @@ -204,7 +204,7 @@ class CI_URI { if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) { $query = explode('?', $query, 2); - $uri = $query[0]; + $uri = rawurldecode($query[0]); $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; } else @@ -245,8 +245,9 @@ class CI_URI { { $uri = explode('?', $uri, 2); $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : ''; - $uri = $uri[0]; + $uri = rawurldecode($uri[0]); } + $this->_reset_query_string(); return str_replace(array('//', '../'), '/', trim($uri, '/')); @@ -325,7 +326,7 @@ class CI_URI { { // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', urldecode($str))) + if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '|')).']+$|i', $str)) { show_error('The URI you submitted has disallowed characters.', 400); } -- cgit v1.2.3-24-g4f1b From ea6688b3b9a7a208d1c44439c4f01801fd3b8c65 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 21:52:11 +0200 Subject: Fix issue in resetting QUERY_STRING, GET vars introduced in f2b19fee7876708c7a7bb5cba6b7df682a9d2a53 --- system/core/URI.php | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index 4a8d33e88..3b7718fff 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -212,7 +212,7 @@ class CI_URI { $_SERVER['QUERY_STRING'] = $query; } - $this->_reset_query_string(); + parse_str($_SERVER['QUERY_STRING'], $_GET); if ($uri === '/' OR $uri === '') { @@ -248,37 +248,13 @@ class CI_URI { $uri = rawurldecode($uri[0]); } - $this->_reset_query_string(); + parse_str($_SERVER['QUERY_STRING'], $_GET); 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? * -- cgit v1.2.3-24-g4f1b From 3b72eb58e61581b7e92012a322be48e216491d7c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 00:45:26 +0200 Subject: Changed URI auto-detection to try PATH_INFO first (thanks to @sourcejedi, PR #1326) Up until PHP 5.2.4 (which is our new lowest requirement), there was a bug related to PATH_INFO which made REQUEST_URI a more reliable choice. This is now no longer the case, see https://bugs.php.net/bug.php?id=31892 for more details. Also removed ORIG_PATH_INFO from the suggested alternatives for uri_protocol in application/config/config.php as it will not exist in most of PHP's recent versions and is pointless when you can use PATH_INFO anyway. --- system/core/URI.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index 3b7718fff..309c77630 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -102,23 +102,21 @@ class CI_URI { return; } - // Let's try the REQUEST_URI first, this will work in most situations - if (($uri = $this->_parse_request_uri()) !== '') + // Is there a PATH_INFO variable? This should be the easiest solution. + if (isset($_SERVER['PATH_INFO'])) { - $this->_set_uri_string($uri); + $this->_set_uri_string($_SERVER['PATH_INFO']); return; } - // Is there a PATH_INFO variable? - // Note: some servers seem to have trouble with getenv() so we'll test it two ways - $uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); - if (trim($uri, '/') !== '' && $uri !== '/'.SELF) + // Let's try REQUEST_URI then, this will work in most situations + if (($uri = $this->_parse_request_uri()) !== '') { $this->_set_uri_string($uri); return; } - // No PATH_INFO?... What about QUERY_STRING? + // No REQUEST_URI either?... What about QUERY_STRING? if (($uri = $this->_parse_query_string()) !== '') { $this->_set_uri_string($uri); -- cgit v1.2.3-24-g4f1b From c5536aac5752054f7f76e448d58b86407d8f574e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 17:33:58 +0200 Subject: Manually apply PR #1594 (fixing phpdoc page-level generation/warnings) Also partially fixes issue #1295, fixes inconsistencies in some page-level docblocks and adds include checks in language files. --- system/core/URI.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index 309c77630..2f6cade34 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -1,4 +1,4 @@ - Date: Thu, 1 Nov 2012 21:21:20 +0200 Subject: Fix issue #122 --- system/core/URI.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index 2f6cade34..e2cac8d89 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -696,7 +696,14 @@ class CI_URI { */ public function ruri_string() { - return implode('/', $this->rsegment_array()); + global $RTR; + + if (($dir = $RTR->fetch_directory()) === '/') + { + $dir = ''; + } + + return $dir.implode('/', $this->rsegment_array()); } } -- cgit v1.2.3-24-g4f1b From c3751f843e9e4f646f3da2617df25cae6660f3af Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 2 Nov 2012 16:50:00 +0200 Subject: Fix #1956 --- system/core/URI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core/URI.php') diff --git a/system/core/URI.php b/system/core/URI.php index e2cac8d89..91740254c 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -301,7 +301,7 @@ class CI_URI { { // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '|')).']+$|i', $str)) + if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str)) { show_error('The URI you submitted has disallowed characters.', 400); } -- cgit v1.2.3-24-g4f1b