Here’s the code I’m trying to apply in httpd.conf:
<VirtualHost *:80>
ServerName www.test.com
ServerAlias www.test.com
DocumentRoot /home/test_com
ErrorLog /home/logs/apache/www_test/www.test.com-error_log
CustomLog /home/logs/apache/www_test/www.test.com.-access_log common env=!do_not_log
# https redirect
RewriteEngine On
RewriteCond %{HTTP_HOST} www.test.com
RewriteCond %{REQUEST_URI} /example
RewriteRule . https://www.test.com/example.html [R=303,L]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}
<Directory "/home/test_com/">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
After applying the code and restarting apache, when I go to /example I get a 404 not found response.
When I test htaccess at (https://htaccess.madewithlove.be), the output is as https://www.test.com/example.html as I want. I wonder what the problem is.
2
Answers
The right part on RewriteRule is the destination file, try change :
To :
Not sure if something has been lost in your exemplification, but from the rules as written, if you request
/example
it will result in a redirect-loop as it will continually redirect to/example.html
again and again. (Unless you are actually making the request over HTTPS, in which case the directive isn’t doing anything at all and you will indeed get a 404!)This is because the second condition
%{REQUEST_URI} /example
also matches the target URL/example.html
. You need to make the regex more specific and match only/example
, not any URL that simply contains/example
. This check can also be moved to theRewriteRule
directive (the condition is not required). For example:The condition that checks the
HTTP_HOST
would not seem necessary, since these directives are in the vHost forwww.test.com
, so it cannot be any other hostname?However, since this rule is in the vHost for port 80, it is only going to apply to HTTP requests (not HTTPS). If you are actually requesting
https://www.test.com/example
(ie. HTTPS) as would seem to be implied by your test results from the MWL tool, then the directive is never going to be processed and you will indeed get a 404.Your HTTP to HTTPS redirect is missing the last part so redirects everything to the homepage. The
RewriteRule
directive should read:However, there’s no point redirecting to HTTPS if all your directives are in the vHost:80 container.
This rule is also more complex than it needs to be. Since you are in the vHost:80 container,
HTTPS
is always going to beoff
– the check is redundant.If you only have one hostname then you don’t need two directives. Only the
ServerName
is required in this case.You don’t have an
.htaccess
file here. You are using the directives directly in the vHost container, which is a different context. The directives behave slightly different here. For example, theRewriteRule
pattern.
(a single dot) has a different result here than when used in.htaccess
. In a virtualhost context it is successful for every request, whereas in.htaccess
it is successful for everything except the homepage (which is probably the intention here).However, the MWL
.htaccess
tester only makes a "single" request (or single pass through the file). It does not "follow" redirects or make multiple passes through the file as it would do in a real server environment. So it cannot catch redirect/rewrite loops – which are a common cause of error.