My .htaccess file is:
# remove "www"
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
# add trailing slash "/"
RewriteCond %{HTTP_HOST} ^(www\.)?example.com$
RewriteRule ^(.*(?:^|/)[^/\.] )$ $1/ [R=301,L]
# other rules needed
RewriteCond %{HTTP_HOST} ^(www\.)?example.com$
RewriteRule ^old-link/$ https://example.com/new-link/ [R=301,L]
With this my goal is to make http://www.example.com/something-after redirect to https://example.com/something-after After that I wish to add "/" at the end: https://example.com/something-after/
However, I have tested this in a online tester and it says that the "The tests are stopped, using a different host will cause a redirect" on the first rule and for this reason the second rule is never met.
CodePudding user response:
I have tested this in a online tester and it says that the "The tests are stopped, using a different host will cause a redirect" on the first rule and for this reason the second rule is never met.
Most online testers only make a single pass (in a single request) through the directives. On a real server, multiple passes (and multiple requests) can occur.
There isn't really an issue with these directives, except that it will potentially trigger multiple redirects. eg. a request for https://www.example.com/foo
will trigger two external redirects. The first to https://example.com/foo
(removing www) and the 2nd to https://example.com/foo/
(appending the trailing slash). At the extreme, a request for https://www.example.com/old-link
(no trailing slash) will trigger three external redirects.
These multiple redirects can be avoided by simply reordering the rules and explicitly including the scheme hostname in the redirect to append the trailing slash (currently the 2nd rule), as you have done in the other two rules. Also, allowing an optional trailing slash on the /old-link/
rule.
For example:
# Specific redirects
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com) [NC]
RewriteRule ^old-link/?$ https://%1/new-link/ [R=301,L]
# Add trailing slash "/"
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com) [NC]
RewriteRule ^(.*(?:^|/)[^/\.] )$ https://%1/$1/ [R=301,L]
# Remove "www"
RewriteCond %{HTTP_HOST} ^www\.(example\.com) [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Now, only one rule ever needs to be processed. The removal of www, appending a slash and redirecting /old-link
are all handled by a single rule.
Other minor changes:
- I've captured the domain in the CondPattern and used a
%1
backreference in the substitution string. This simply saves having to explicitly repeat the domain name in the substitution string. - Removed
$
(end-of-string anchor) from the CondPattern to allow for a FQDN that ends in a dot. - Added the
NC
flag to theRewriteCond
directive. (A bot could potentially request a mixed caseHost
header.)
However, another issue here is you don't currently have an HTTP to HTTPS redirect. You could add this as the last rule:
# Redirect HTTP to HTTPS
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This is just a standard HTTP to HTTPS redirect, assuming the SSL cert is installed directly on the application server.
By placing the rule last you only need to check for example.com
(and not www.example.com
) since the request must already have been canonicalized (to remove the www subdomain) by the preceding rule (if needed).