1

I want to redirect URLs with multiple consecutive slashes (e.g. //) in the path to have only one consecutive slash, e.g. https://example.com/a//b/c/https://example.com/a/b/c/.

My .htaccess file contains the following statement.

RedirectMatch 301 ^(.*)/{2,}(.*)$ $1/$2

This doesn't work. However, the following variants do:

  • just matching a single /,
  • matching some other character, like ^(.*)q{2,}(.*)$.

What's wrong with my RedirectMatch?

fionn
  • 13
  • 5

1 Answers1

0

The URL-path that the RedirectMatch (mod_alias) directive matches against has probably already had multiple slashes reduced (a necessary step when the request is mapped to the filesystem).

To test for multiple slashes you need to use mod_rewrite and check against the THE_REQUEST server variable instead (in a preceding condition). THE_REQUEST is "unprocessed" and contains the first line of the request headers as sent from the client, eg. GET /a//b/c/ HTTP/1.1.

For example, try the following instead, near the top of the root .htaccess file:

RewriteEngine On

RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) /$1 [R=301,L]

This removes (via an external 301 redirect) multiple slashes anywhere in the URL-path part of the URL. (Although you should always test first with a 302 - temporary - redirect in order to avoid any potential caching issues.)

This uses the fact that the URL-path matched (and captured) by the RewriteRule pattern has already had multiple slashes resolved away. The $1 backreference then uses this URL-path (less the multiple slashes) in the substitution string.

The regex \s[^?]*// in the CondPattern tests for multiple slashes in the URL-path and ensures we don't match multiple slashes in the query string (if any) - which would otherwise result in a redirect loop.

Reference:

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • I don't quite follow. Yes, Apache "resolves" it in that it serves `a/b//c/` just as it serves `a/b/c/` (I think this makes "resolves" a "rewrite"). But I want to redirect and don't understand how that's related. – fionn Jun 27 '23 at 17:33
  • @fionn I've added a bit more explanation (and improved wording). "Resolves" is not a "rewrite". There is no "rewrite" here, only a "redirect". You mention "rewrite" in your question, but it's really a "redirect". (It needs to be a "redirect" in order to fix any canonical URL issues that could otherwise affect SEO.) – MrWhite Jun 27 '23 at 18:16
  • @fionn Which bit don't you understand? Have you tried my solution above? – MrWhite Jun 27 '23 at 18:17
  • Oops! Have edited my question to remove the word "rewrite". My interpretation: `mod_rewrite` has already squashed the multiple slashes, so `mod_alias`, operating at a level higher, does not see them so fails to match as a result. Is that correct? – fionn Jun 27 '23 at 18:26
  • This doesn't work, it will redirect `/a//b/` to `/b/` instead of `/a/b/`. – fionn Jul 26 '23 at 13:17
  • @fionn It would only do that if the `.htaccess` file is located in the `/a/` subdirectory, not the root. The `.htaccess` file should be located in the root directory. – MrWhite Jul 26 '23 at 15:37