Have this rewrite rule in vHost context. But it does not rewrite requests that begin with //.* (double slash). Just serves them up from /.* (single slash) instead of responding with a redirect to /.*

RewriteRule "^//(.*)" "/$1" [R=301,L]

Why doesn't this work?

  • Do you have any other rewrite rules? Aug 17 '20 at 11:46
  • Yes plenty of rewrite rules. All are working as expected. Suspect that Apache is stripping the extra leading slash(s). But I'd like to know for sure what is going on. A redirect directive for // works. So maybe Apache is not stripping the leading slashe(s). Or maybe its where they are being stripped. Maybe rewrite_mod strips them. I'd prefer to use rewrite rule rather than redirect directive because I have some additional plans for this. Like rewriting to a cgi script.
    – NOYB
    Aug 17 '20 at 22:04
  • 1
    The answers don't explain why they are doing it, but the rules to remove duplicate slashes on this Stack Overflow question are all getting matched against %{THE_REQUEST} in a RewriteCond rather against the path in the RewriteRule. stackoverflow.com/questions/17080652/… Maybe leading slashes aren't available to RewriteRule? Aug 17 '20 at 23:24
RewriteRule "^//(.*)" "/$1" [R=301,L]

This will never match because the URL-path that the RewriteRule pattern matches against has already had all instances of multiple slashes reduced to a single slash.

To redirect such requests you can make use of this "feature" and simply redirect "to itself" and check against THE_REQUEST server variable instead in order to determine whether multiple slashes were present on the initial request. THE_REQUEST is the first line of the request header and contains the raw unprocessed request URL (excluding protocol and hostname, but including the query string) as sent from the client.

For example, to redirect all instances of multiple slashes to a single slash throughout the URL-path, not just at the start then you can do something like this:

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

The regex \s[^?]*// ensures we don't match multiple slashes in the query string part of the URL (which would otherwise result in a redirect loop).

Would RewriteCond %{THE_REQUEST} ^// allow us to apply the rewrite rule to only those that begin with double slashes, ignoring all other instances of double slashes?

Not quite, THE_REQUEST server variable actually contains the entire first line of the HTTP request header. In other words, a string of the form:

GET /foo/bar.html HTTP/1.1

Or GET //foo/bar.html HTTP/1.1 if there is a double slash at the start of the URL-path, so you would need something like this instead:

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

...in order to catch all request methods. And specifically just a double slash, not triple slashes, etc. at the start of the URL-path only.

\s//[^/] - That's a space (after the request method) followed by 2 slashes and something other than a slash (ie. either a space for the document root, or some other URL-path).

  • Thanks Mr. White for the explanation. Would RewriteCond %{THE_REQUEST} ^// allow us to apply the rewrite rule to only those that begin with double slashes, ignoring all other instances of double slashes?
    – NOYB
    Aug 18 '20 at 0:08
  • 1
    Not quite, I've updated my answer.
    – MrWhite
    Aug 18 '20 at 0:19
  • Okay. That helps a lot. Thank you much.
    – NOYB
    Aug 18 '20 at 0:21
  • Minor update to my answer... I simplified the regex that matches a double slash at the start of the URL-path. I also "corrected" the regex in the first example (to match multiple slashes anywhere in the URL-path) so as to avoid matching multiple slashes in the query string.
    – MrWhite
    Aug 18 '20 at 0:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.