I took over a website and noticed the previous developer had multiple .htaccess
rewrite rules, this is a short example:
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing$ landing.php?page=$1
The Rewrite Condition is always the same for all rules, is there a way to combine the Rewrite Rules so the conditions just have to be written once?
I have looked into the skipping flag but it has no backreference possible. As far as I see I do not need backreferences with those conditions, however, is skipping the best approach? Or is there a best practice on how to achieve this? (Someone suggested to me to use the QSA flag, however, upon research I don't think that has anything to do with what I want to accomplish.)
Best Answer
This messy block of conditions is injected automatically by cPanel before every
RewriteRule
directive when it auto-renews an SSL (Let's Encrypt?) security certificate. These conditions ensure that the validation file (required in order to renew the SSL cert) is accessible.Unfortunately, I've not been able to get to the bottom of why cPanel does it this way - it can be a maintenance nightmare and I have encountered directives that have been broken by these conditions (admittedly the directives were less than perfect to begin with). (I've tried asking on the cPanel forums, but I've never had a good response.)
Yes. You can move these conditions to their own block at the start of the
.htaccess
file and reverse their meaning, so instead of only triggering theRewriteRule
when a request does not match the pattern (using a negated regex). You can prevent further rewrites when a request does match the pattern. For example:Note the removal of the
!
(negation) prefix on the CondPattern and the additionalOR
flag on the first three conditions. TheRewriteRule
then prevents further mod_rewrite directives being processed should the request match.(On Apache 2.4.8+ these directives can be moved entirely to the server config. With the help of
RewriteOptions InheritDownBefore
.)Then, followed by just the
RewriteRule
directives you had before (although I've added theL
flag):You should probably be including
L
flags on those remaining rewrites.You could also combine those 3 rewrites into a single directive if you wanted, but that would depend if your application handles empty URL parameters.
Yes, that doesn't really have anything to do with this particular problem. The
QSA
(Query String Append) flag would allow you to merge any query string that was present on the request with the query string you are writing in theRewriteRule
substitution.