Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

htaccess redirectMatch all files of a type except a certain one

Say I have a web folder with:

/index.html
/assets/css/styles.css
/assets/images/logo.png
/something.html
/holdingpage.html
/finale.html
/folder/somefile.html
/else.html
/PDFs/something.pdf

I want to put in place an htaccess RedirectMatch for this to "catch" all the files that are html files except the finale.html and redirect to there.

What I have so far is:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

RedirectMatch 302 ".*/$" "/finale.html"

Which correctly catches all folder without filenames (indexes).
What I need is to catch all the html but not that destination one.

RedirectMatch 302 ".*(\.html)$" "/finale.html" # This loops obviously. 

So I tried to be more specific;

RedirectMatch 302 ".*!(finale.html)$" "/finale.html" 

RedirectMatch 302 ".*!(finale\.html)$" "/finale.html" 

But this doesn’t catch other files. Also by the looks of it I’d expect this to also catch assets and images.

I am trying to find a redirectMatch that finds every .html page that is NOT finale.html and redirect it to that page.

IT should be a redirectMatch and NOT a rewriteCond / rewriteRule. The user needs to see they’re being redirected.

I imagine I want something like:

RedirectMatch 302 ".*((\.html) BUT NOT (finale.html))$" "/finale.html" 

I have read the Apache Documentation but this doesn’t really elaborate on this concept very much.

>Solution :

You can use a negative lookahead to match all .html files except for /finale.html (in the document root).

For example:

RedirectMatch 302 (?!^/finale\.html$)^/.+\.html$ /finale.html

IT should be a redirectMatch and NOT a rewriteCond / rewriteRule. The user needs to see they’re being redirected.

I’m not sure of the logic here. mod_rewrite can produce external redirects just the same as RedirectMatch and in fact, you should probably be using mod_rewrite here if you have existing mod_rewrite directives (primarily to avoid unexpected conflicts).

With mod_rewrite, you can do it similar to above with a negative lookahead. For example:

RewriteEngine On

RewriteRule (?!^finale\.html$)^.+\.html$ /finale.html [R=302,L]

Or, use an additional condition to make an exception for finale.html, instead of using a negative lookahead. For example:

RewriteCond %{REQUEST_URI} !^/finale\.html$
RewriteRule \.html$ /finale.html [R=302,L]

Which is arguably easier to read and possibly more efficient (the regex at least).

This matches all URLs that end in .html, except for /finale.html (exactly) and externally 302 redirects to /finale.html.


Aside:

RedirectMatch 302 ".*!(finale.html)$" "/finale.html" 

The ! in the middle of the regex is a literal character here. The ! prefix-operator is a feature of mod_rewrite. (It is a prefix-operator, not part of the regex syntax itself.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading