3

I am trying to 301 redirect all URLs from http:// to https://, using .htaccess. Some dynamically generated URLs should be excluded.

Example of some URLs I do not want to redirect:

example.com/tt.php?xxx (where xxx can be any number)
example.com/top/xxx/site/xxx (where xxx can be any number or characters)

Right now my .htaccess looks like this:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

How can I "exclude" my dynamic URLs?

bjoster
  • 4,423
  • 5
  • 22
  • 32
Rogge
  • 33
  • 3

1 Answers1

2

Right now my .htaccess looks like this:

If that is all you have in your .htaccess file then you can include some exceptions for the URLs you want to exclude before your existing rule that redirects.

For example:

# Prevent further processing if requesting a URL of the form
# example.com/tt.php?xxx (where xxx can be any number)
RewriteCond %{QUERY_STRING} ^\d+$
RewriteRule ^tt\.php$ - [L]

# Prevent further processing if requesting a URL of the form
# example.com/top/xxx/site/xxx (where xxx can be any number or characters)
RewriteRule ^top/[^/]+/site/ - [L]

By placing the above "exceptions" first then any directives that follow (ie. the redirect) will be skipped.


UPDATE: If you had other directives in your .htaccess file that should still apply to these URLs then you can instead add additional conditions to your existing redirect rule instead.

For example:

RewriteCond %{THE_REQUEST} !^[A-Z]{3,6}\s/tt\.php\?\d+\sHTTP
RewriteCond %{REQUEST_URI} !^/top/[^/]+/site/

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

Note that the first two conditions have a ! prefix on the CondPattern in order to negate its meaning. So, the condition is only successful if the regex does not match.

Note that instead of using two directives (RewriteCond and RewriteRule) as I did in the first example to match against the URL /tt.php?xxx I combined this into a single rule and matched against THE_REQUEST - this is to simplify the logic in this one rule.

THE_REQUEST server variable holds the first line of the HTTP request.

MrWhite
  • 11,643
  • 4
  • 25
  • 40
  • 1
    I've updated my answer. – MrWhite Oct 02 '19 at 20:45
  • Thanks for the answer MrWhite! the first row worked perfectly but the second row: RewriteCond %{REQUEST_URI} !^top/[^/]+/site/ did not work, it still gets 301 redirected to https – Rogge Oct 03 '19 at 13:55
  • 1
    @Rogge Sorry, there needs to be a slash prefix on that regex, ie. `!^/top/[^/]+/site/` (different to the regex in the first example). I've updated my answer – MrWhite Oct 03 '19 at 14:03
  • 1
    You will need to make sure you've cleared your browser cache. (It can be easier to test with 302 temporary redirects for this reason.) – MrWhite Oct 03 '19 at 14:12
  • 1
    Thanks a lot MrWhite it works perfectly now! :) – Rogge Oct 03 '19 at 14:13