diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-01-29 22:40:41 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-01-29 22:40:41 +0000 |
commit | 1df3cfffefefc93ed2d29041d148938d08bb9d4e (patch) | |
tree | 3f2488086535e8ce70f656f32113dd6eef4fd545 /includes | |
parent | 139f4375615216dfd077caba957508ff60778f45 (diff) | |
download | brdo-1df3cfffefefc93ed2d29041d148938d08bb9d4e.tar.gz brdo-1df3cfffefefc93ed2d29041d148938d08bb9d4e.tar.bz2 |
- Patch #284899 by c960657, voxpelli, mattconnolly: fixed Drupal url problem with clean urls.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/bootstrap.inc | 55 | ||||
-rw-r--r-- | includes/common.inc | 33 | ||||
-rw-r--r-- | includes/file.inc | 4 | ||||
-rw-r--r-- | includes/path.inc | 2 | ||||
-rw-r--r-- | includes/stream_wrappers.inc | 2 |
5 files changed, 66 insertions, 30 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 4184c4036..8fff1c40e 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -492,6 +492,13 @@ function drupal_environment_initialize() { $_SERVER['HTTP_HOST'] = ''; } + // When clean URLs are enabled, emulate ?q=foo/bar using REQUEST_URI. It is + // not possible to append the query string using mod_rewrite without the B + // flag (this was added in Apache 2.2.8), because mod_rewrite unescapes the + // path before passing it on to PHP. This is a problem when the path contains + // e.g. "&" or "%" that have special meanings in URLs and must be encoded. + $_GET['q'] = request_path(); + // Enforce E_ALL, but allow users to set levels not part of E_ALL. error_reporting(E_ALL | error_reporting()); @@ -559,8 +566,8 @@ function drupal_settings_initialize() { // $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not // be modified by a visitor. - if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) { - $base_path = "/$dir"; + if ($dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/')) { + $base_path = $dir; $base_url .= $base_path; $base_path .= '/'; } @@ -1859,6 +1866,50 @@ function language_default($property = NULL) { } /** + * Returns the requested URL path of the page being viewed. + * + * Examples: + * - http://example.com/node/306 returns "node/306". + * - http://example.com/drupalfolder/node/306 returns "node/306" while + * base_path() returns "/drupalfolder/". + * - http://example.com/path/alias (which is a path alias for node/306) returns + * "path/alias" as opposed to the internal path. + * + * @return + * The requested Drupal URL path. + * + * @see current_path() + */ +function request_path() { + static $path; + + if (isset($path)) { + return $path; + } + + if (isset($_GET['q'])) { + // This is a request with a ?q=foo/bar query string. $_GET['q'] is + // overwritten in drupal_path_initialize(), but request_path() is called + // very early in the bootstrap process, so the original value is saved in + // $path and returned in later calls. + $path = $_GET['q']; + } + elseif (isset($_SERVER['REQUEST_URI'])) { + // This is a request using a clean URL. Extract the path from REQUEST_URI. + $request_path = strtok($_SERVER['REQUEST_URI'], '?'); + $base_path_len = strlen(rtrim(dirname($_SERVER['SCRIPT_NAME']), '\/')); + // Unescape and strip $base_path prefix, leaving q without a leading slash. + $path = substr(urldecode($request_path), $base_path_len + 1); + } + else { + // This is the front page. + $path = ''; + } + + return $path; +} + +/** * If Drupal is behind a reverse proxy, we use the X-Forwarded-For header * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of * the proxy server, and not the client's. If Drupal is run in a cluster diff --git a/includes/common.inc b/includes/common.inc index c6472be18..20b0648c7 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -501,7 +501,6 @@ function drupal_http_build_query(array $query, $parent = '') { } else { // For better readability of paths in query strings, we decode slashes. - // @see drupal_encode_path() $params[] = $key . '=' . str_replace('%2F', '/', rawurlencode($value)); } } @@ -623,38 +622,18 @@ function drupal_parse_url($url) { } /** - * Encode a path for usage in a URL. + * Encodes a Drupal path for use in a URL. * - * Wrapper around rawurlencode() which avoids Apache quirks. Should be used when - * placing arbitrary data into the path component of an URL. + * For aesthetic reasons slashes are not escaped. * - * Do not use this function to pass a path to url(). url() properly handles - * and encodes paths internally. - * This function should only be used on paths, not on query string arguments. - * Otherwise, unwanted double encoding will occur. - * - * Notes: - * - For aesthetic reasons, we do not escape slashes. This also avoids a 'feature' - * in Apache where it 404s on any path containing '%2F'. - * - mod_rewrite unescapes %-encoded ampersands, hashes, and slashes when clean - * URLs are used, which are interpreted as delimiters by PHP. These - * characters are double escaped so PHP will still see the encoded version. - * - With clean URLs, Apache changes '//' to '/', so every second slash is - * double escaped. + * Note that url() takes care of calling this function, so a path passed to that + * function should not be encoded in advance. * * @param $path - * The URL path component to encode. + * The Drupal path to encode. */ function drupal_encode_path($path) { - if (!empty($GLOBALS['conf']['clean_url'])) { - return str_replace(array('%2F', '%26', '%23', '//'), - array('/', '%2526', '%2523', '/%252F'), - rawurlencode($path) - ); - } - else { - return str_replace('%2F', '/', rawurlencode($path)); - } + return str_replace('%2F', '/', rawurlencode($path)); } /** diff --git a/includes/file.inc b/includes/file.inc index 6395c6323..ccac9cabc 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -901,6 +901,10 @@ function file_unmunge_filename($filename) { * of $basename. */ function file_create_filename($basename, $directory) { + // Strip control characters (ASCII value < 32). Though these are allowed in + // some filesystems, not many applications handle them well. + $basename = preg_replace('/[\x00-\x1F]/u', '_', $basename); + // A URI or path may already have a trailing slash or look like "public://". if (substr($directory, -1) == '/') { $separator = ''; diff --git a/includes/path.inc b/includes/path.inc index 0f61d6c27..8585a3b78 100644 --- a/includes/path.inc +++ b/includes/path.inc @@ -384,6 +384,8 @@ function drupal_match_path($path, $patterns) { * * @return * The current Drupal URL path. + * + * @see request_path() */ function current_path() { return $_GET['q']; diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc index b4edb0933..2940b1e66 100644 --- a/includes/stream_wrappers.inc +++ b/includes/stream_wrappers.inc @@ -639,7 +639,7 @@ class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper { */ function getExternalUrl() { $path = str_replace('\\', '/', file_uri_target($this->uri)); - return $GLOBALS['base_url'] . '/' . self::getDirectoryPath() . '/' . $path; + return $GLOBALS['base_url'] . '/' . self::getDirectoryPath() . '/' . drupal_encode_path($path); } } |