Score:1

Apache RedirectMatch not matching double slash

it flag

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?

Score:0
kz flag

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:

fionn avatar
it flag
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.
kz flag
@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.)
kz flag
@fionn Which bit don't you understand? Have you tried my solution above?
fionn avatar
it flag
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 avatar
it flag
This doesn't work, it will redirect `/a//b/` to `/b/` instead of `/a/b/`.
kz flag
@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.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.