404 not found when not typing www - .htaccess

I'm getting a 404 when typing my domain in the address bar without www in front of it. Only Safari on a Mac seems to work fine, but Chrome and Firefox get a 404 not found. Why is that, and how to I change it?
domain.nl works in Safari but returns 404 in Chrome/Firefox/etc.
www.domain.nl works in all browsers.
The non-www version does not automatically change to the www version in Chrome/Firefox/etc.
RewriteEngine On
# AUTO HTTP TO HTTPS
RewriteCond %{HTTP_HOST} ^domain\.nl$
RewriteRule ^(.*) http://www.domain.nl/$1 [R=301]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php?_route_=$1 [L,QSA]
# FOR NON-WWW QUERIES
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [R=301,L]
Please note: I have replaced the actual domain with the text "domain" in the code.

# AUTO HTTP TO HTTPS
RewriteCond %{HTTP_HOST} ^domain\.nl$
RewriteRule ^(.*) http://www.domain.nl/$1 [R=301]
You have a couple of "errors" in your first rule that redirects non-www to www, which are going to cause problems:
You are missing the L flag on the rule so processing is going to continue and possibly be rewritten, resulting in a malformed redirect (that could result in a 404).
You are redirecting to HTTP, not HTTPS.
The first rule should read:
RewriteCond %{HTTP_HOST} ^domain\.nl
RewriteRule (.*) https://www.domain.nl/$1 [R=301,L]
# FOR NON-WWW QUERIES
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [R=301,L]
Your last rule is superfluous and can be deleted, since this is what the first rule does! Except this rule is rather more general and does not explicitly include the domain name.
Alternatively, you replace the first rule with this one. However, this rule doesn't necessarily work if you have other subdomains, unless you want all subdomains to also have a www sub-subdomain?
You will need to clear your browser cache before testing, since any erroneous 301 (permanent) redirect will have been cached by the browser. (Test first with 302 - temporary - redirects to avoid potential caching issues.)
Caching might explain the difference in browser behaviour you are seeing?
Aside:
RewriteRule ^(.*)\?*$ index.php?_route_=$1 [L,QSA]
The regex you are using here is a bit "odd" and probably isn't doing what you think it's doing. The regex ^(.*)\?*$ is the same as simply (.*) because .* is greedy and \?* is effectively optional (matching 0 or more times), so .* consumes (and (.*) captures) the entire URL-path anyway.
The presence of \?*$ at the end of the regex would seem to suggest you are expecting %3F (URL encoded ?) at the end of the URL-path. However, the regex as stated does not exclude these from the capturing group.

Related

Forced SSL in htaccess going to only the home page

I have recently added an SSL to my sites. I have added the code to the .htaccess file to force the https. The issue is that my external links that go to pages within the site are now being redirected to the homepage. The code I am using is:
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^(.*)$ https://www.watsonelec.com%1 [R,L]
I think the issue is in the last line, as the rule is telling it to redirect to the homepage. What I can't seem to find is a rule that will say for it to go to the URL provided in the link but give it an https instead of the HTTP.
I did do a search for this topic, but all the code I found was similar to what I already had. Thank you for all your help.
Update
I have two sites I am trying to work this out for, watsonenerysolutions.com and watsonelec.com.
When I tried
RewriteOptions InheritDownBefore
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^(.*)$ https://www.watsonenergysolutions.com/$1 [R,L]
It still sent to the homepage
When I tried
RewriteOptions InheritDownBefore
RewriteCond %{ENV:HTTPS} !on [NC]
RewriteRule ^ https://www.watsonenergysolution.com%{REQUEST_URI} [R,L]
I received an error message that said Safari can't open the page "https://www.watsonenergysolutions.com/index.php" because Safari can't find server "www.watsonenergysolutions.com"
%N backreferences are what you match in RewriteCond's. In your case, it is empty. That's why anything is going to the homepage.
You need to use $1 or %{REQUEST_URI}, both rules below are equivalent (the second may be faster because you don't -re-match unnecessarily)
RewriteRule ^(.*)$ https://www.watsonelec.com/$1 [R,L]
RewriteRule ^ https://www.watsonelec.com%{REQUEST_URI} [R,L]
Note 1: %{REQUEST_URI} value always begins with a leading /, while what you can match in a RewriteRule never begins with a leading /
Note 2: R flag uses a 302 redirect by default. Maybe you'll want to use a 301 ([R=301,L])

https to http while keeping path

I have here a little problem with a website and its WordPress blog.
For a short time, we had setup everything with https, until we were facing some issues and had to go back to HTTP.
Back then, I had a little collection of .htaccess files to deal with these kinds of problems, but I never actually tried my "non-www to www - ssl"
The intent was to add www and redirect https to http
RewriteCond %{HTTPS} on
RewriteRule ^/?$ http://%{SERVER_NAME}/ [R=301,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Seemed pretty simple to me and I thought it should work.
I have two .htaccess files, one for http://www.example.com/ and one for http://www.example.com/blog both with the same content, as users are primarily coming from SE's via Blog.
The Problem is: If I load https://www.example.com/blog I get redirected to http://www.example.com/ instead of http://www.example.com/blog.
While writing the Question I thought I try this Question I had the idea to add this
RewriteCond %{HTTPS} on
RewriteRule ^/?$ http://%{SERVER_NAME}/{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
but then I get only redirected to http://www.example.com/{REQUEST_URI}
Could someone please tell me how I can keep the path on that redirect query?
RewriteCond %{HTTPS} on
RewriteRule ^/?$ http://%{SERVER_NAME}/{REQUEST_URI} [R=301,L]
If you notice that in your other directive you have %{REQUEST_URI}. You are missing the % prefix above. This is required syntax in order to get the value of the REQUEST_URI server variable. But also note that the value of REQUEST_URI already includes a slash prefix, so the slash should be omitted from the substitution. ie. instead of /{REQUEST_URI} it should be %{REQUEST_URI}.
Also note that the RewriteRule pattern (^/?$) only matches the root of your site (or /blog subdirectory if this .htaccess file is in that subdirectory). You need to match everything. So, modify the above RewriteRule like this:
RewriteRule ^ http://www.example.com%{REQUEST_URI} [R=301,L]
I've also hardcoded the domain, otherwise, you'll end up with a double redirect when requesting the non-canonical (ie. non-www) host.

htaccess redirect from A record to www and new page

Need to redirect example.com/page to www.example.com/page_2. Can also be from www.example.com/page to www.example.com/page_2. I have tried
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com/page [NC]
RewriteRule (.*) https://www.example.com/page_2 [R=301,L]
But that does not appear to work.
The HTTP_HOST server variable contains just the Host header, as its name suggests (eg. www.example.com), it does not include the URL-path as well (ie. /page).
You match the URL-path with the RewriteRule pattern. So, try the following instead:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^page$ https://www.example.com/page_2 [R=302,L]
Change the 302 (temporary) redirect to 301 (permanent) only when you are sure it's working OK (if this is indeed intended to be permanent). 301s are cached hard by the browser so can make testing problematic.
Unless you have multiple domains on this account, you can remove the RewriteCond directive altogether.

Force HTTP for all pages except specific URLs

I have a situation where I need to force every single page in my site to redirect to HTTP except for two specific URLs which need to force redirect to HTTPS.
The two pages that need to redirect to HTTPS pages are:
/microsoft-moc-on-demand-video-training/moc-registration-page/
/courses/register/
The code I've been using in my .htaccess file looks like this:
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/courses/register/
RewriteCond %{REQUEST_URI} !^/microsoft-moc-on-demand-video-training/moc-registration-page/
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(/courses/register/|/microsoft-moc-on-demand-video-training/moc-registration-page/)/ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Unfortunately this doesn't seem to be working. The entire site does redirect to HTTP (so part of the code works), but those two exceptions (which should redirect to HTTPS) do not do that, they stay as HTTP links.
Any idea what I'm doing wrong here?
The problem is that for RewriteRule, there is no initial / in the requested path. Therefore, you're trying to match something that isn't present.
You also had an extra / at the end of each option in the first capture group, which when combined with the final / would require a path such as /courses/register//.
The following code should suit your needs:
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/courses/register/
RewriteCond %{REQUEST_URI} !^/microsoft-moc-on-demand-video-training/moc-registration-page/
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(courses/register|microsoft-moc-on-demand-video-training/moc-registration-page)/ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Htaccess non-www and strip index.php in a nice way

I'm having some trouble with my .htaccess redirections.
I want a situation in which the (non-www)domain.tld is redirected to the www.domain.tld. And I want to rewrite the arguments to skip the index.php, making a request for /foo go to index.php/foo.
Initial situation
First I had these rules
RewriteCond %{HTTP_HOST} ^domain\.tld [NC]
RewriteRule ^(.*)$ http://www.domain.tld/$1 [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_\ /:-]*)$ index.php [L]
And this worked. Mostly. What didn't work was that in PHP $_SERVER['PATH_INFO'] stayed empty and I disliked the whitelisting of the characters.
Change for PATH_INFO and to accept more
So I changed the last line into this:
RewriteRule ^(.*)$ index.php/$1 [L]
This fixed the PATH_INFO and the limited characters. However, I recently noticed that this caused the non-www redirect to www. to fail miserably.. When going to the non-www domain Apache says
Moved Permanently
The document has moved here.
Where 'here' is linked to the same thing I typed (non-www domain.tld) and thus failing to serve the user.
Continuing the search..
I found a lot of Q&A here and elsewhere or the topic of non-www redirections, but all seem to fail in some way. For example:
RewriteCond %{HTTP_HOST} !^www.*$ [NC]
RewriteRule ^/.+www\/(.*)$ http://www.%{HTTP_HOST}/$1 [R=301]
This just didn't do that much. Nothing got redirected, although the website was served on the non-www.
Anyone knowing what I do wrong or having a solution for this mess? :)
(Preferably, I would like the non-www redirection to be global. So that I don't have to change the actual domain name every time.)
I guess you’re just missing the L flag to end the rewriting process:
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
And make sure to put this rule in front of those rules that just cause an internal rewrite.

Resources