commit 3f2467a85e71592cdaaca067f923f87351f14d71 Author: pwolanin Date: Thu Jan 19 13:31:30 2017 -0500 almost there diff --git a/core/lib/Drupal/Core/Routing/RouteCompiler.php b/core/lib/Drupal/Core/Routing/RouteCompiler.php index dfe2e76..72694e7 100644 --- a/core/lib/Drupal/Core/Routing/RouteCompiler.php +++ b/core/lib/Drupal/Core/Routing/RouteCompiler.php @@ -38,7 +38,8 @@ public static function compile(Route $route) { // The Drupal-specific compiled information. $stripped_path = static::getPathWithoutDefaults($route); $fit = static::getFit($stripped_path); - $pattern_outline = static::getPatternOutline($stripped_path); + // Store a lower-case pattern outline to enable case-insensitive matching. + $pattern_outline = Unicode::strtolower(static::getPatternOutline($stripped_path)); // We count the number of parts including any optional trailing parts. This // allows the RouteProvider to filter candidate routes more efficiently. $num_parts = count(explode('/', trim($route->getPath(), '/'))); @@ -47,24 +48,28 @@ public static function compile(Route $route) { $fit, $pattern_outline, $num_parts, - // These are the Symfony compiled parts. - $symfony_compiled->getStaticPrefix(), - $symfony_compiled->getRegex(), + // These are the compiled parts Symfony uses in + // \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection(). + // Set the static prefix to an empty string since it is redundant to + // the matching in \Drupal\Core\Routing\RouteProvider::getRoutesByPath() + // and by skipping it we more easily make the routing case insensitive. + '', + // Set the regex to use UTF-8 and be case-insensitive. + $symfony_compiled->getRegex() . 'ui', $symfony_compiled->getTokens(), $symfony_compiled->getPathVariables(), $symfony_compiled->getHostRegex(), $symfony_compiled->getHostTokens(), $symfony_compiled->getHostVariables(), $symfony_compiled->getVariables() - ); + ); } /** * Returns the pattern outline. * * The pattern outline is the path pattern but normalized so that all - * placeholders are equal strings and default values are removed, and the path - * is converted to lowercase. + * placeholders are the string '%'. * * @param string $path * The path for which we want the normalized outline. @@ -73,7 +78,7 @@ public static function compile(Route $route) { * The path pattern outline. */ public static function getPatternOutline($path) { - return Unicode::strtolower(preg_replace('#\{\w+\}#', '%', $path)); + return preg_replace('#\{\w+\}#', '%', $path); } /** diff --git a/core/lib/Drupal/Core/Routing/RouteProvider.php b/core/lib/Drupal/Core/Routing/RouteProvider.php index d65e1ce..aa20f7e 100644 --- a/core/lib/Drupal/Core/Routing/RouteProvider.php +++ b/core/lib/Drupal/Core/Routing/RouteProvider.php @@ -146,17 +146,16 @@ public function getRouteCollectionForRequest(Request $request) { // Cache both the system path as well as route parameters and matching // routes. We can not yet convert the path to lowercase since wildcard path // portions may be case sensitive if they contain data like a base64 encoded - // token. - $cid = 'route:' . $request->getPathInfo() . ':' . $request->getQueryString(); + // token. We remove repeated and trailing slashes to normalize the path. + $parts = preg_split('@/+@', $request->getPathInfo(), NULL, PREG_SPLIT_NO_EMPTY); + $path = '/' . implode('/', $parts); + $cid = 'route:' . $path . ':' . $request->getQueryString(); if ($cached = $this->cache->get($cid)) { $this->currentPath->setPath($cached->data['path'], $request); $request->query->replace($cached->data['query']); return $cached->data['routes']; } else { - $path = $request->getPathInfo(); - // Just trim path on the right side. - $path = $path === '/' ? $path : rtrim($path, '/'); $path = $this->pathProcessor->processInbound($path, $request); $this->currentPath->setPath($path, $request); // Incoming path processors may also set query parameters. @@ -328,8 +327,8 @@ public function getRoutesByPattern($pattern) { protected function getRoutesByPath($path) { // Split the path up on the slashes, ignoring multiple slashes in a row // or leading or trailing slashes. Convert to lower case here so we can - // have a case insensitive match from the incoming path to the pattern - // outlines from \Drupal\Core\Routing\RouteCompiler::getPatternOutline() + // have a case insensitive match from the incoming path to the lower case + // pattern outlines from \Drupal\Core\Routing\RouteCompiler::compile(). $parts = preg_split('@/+@', Unicode::strtolower($path), NULL, PREG_SPLIT_NO_EMPTY); $collection = new RouteCollection();