HTTP to HTTPS redirect exposes subdirectory instead of redirecting to subdomain - apache

After several hours of research, I give up!
When I type this: https://scan.example.com (note HTTPS) it works fine.
But when I type this in browser: http://scan.example.com
it goes to: https://example.com/scan (it puts the subdomain at the end)
How do I prevent this and make sure it goes to https://scan.example.com?
Here is my current .htaccess (Which works perfectly for me for everything else besides the issue above):
Options -MultiViews
RewriteEngine On
# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://example.com/$1 [R=301,L]
# Abort early if the request already maps to (or looks like) a file or directory
RewriteCond %{REQUEST_URI} \.\w{2,4}$ [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# 3. Extensionless URLs for other requests
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
*PS: The reason I have example.com/$1 is because I want to be able to access for example account.php in root like this:
https://example.com/account.

I assume your .htaccess file is located in the root directory of the example.com host, in which /scan is a subdirectory (that the subdomain presumably points to)? And this .htaccess file should apply to both the domain apex and the subdomain?
In which case you'll need to use the REQUEST_URI server variable instead of the $1 backreference in the substitution string. Since the $1 backreference will contain the /scan subdirectory when you request the subdomain.
Try the following instead:
# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Note sure why you have the first condition, unless you are hosting multiple domains?
The above will remove the www subdomain, but will preserve any other subdomain, including scan. However, this does not specifically canonicalize www to non-www, since it only redirects HTTP.

Related

Rewrite any subdomain to https

Currently I am running a little web server with apache on my LAMP system. I already created a https certificate for my domain. Now I would like to rewrite any subdomain and directory of subdomain to https without www. I already have a code in my .htaccess file and it rewrites the www version to non www and to https.
Here's the code in my .htaccess file (located in the root apache directory):
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
I already tried to just exchange the "www" with "(.*)" but I am not sure what "%1" and "$1" does because I found that code in the internet and they didn't explained it. I researched about regular expressions but I can't find anything.
RewriteEngine On
RewriteBase /
# domain starts with www (change yourdomain to your domain name)
# adding the domain name will ensure its not trying to capture a subdomain with www
# For example: ^www\.(.*)$ will redirect www.subdomain.domain.com to https.
RewriteCond %{HTTP_HOST} ^www\.(yourdomain) [NC]
# then redirect to HTTPS
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]
# check if HTTPS is not being used
RewriteCond %{HTTPS} off
# and because we already redirect www. we exclude it
RewriteCond %{HTTP_HOST} !^www\. [NC]
# and now we test to see if its a subdomain (change yourdomain to your domain name)
RewriteCond %{HTTP_HOST} ^[^\.]+\.yourdomain [NC]
# now we finally redirect it
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]
Once you confirm the subdomain redirection is working, you change R=302 to R=301, the reason behind this, is to avoid your browser from caching the redirection until you can ensure its working.
If you do a mistake while using R=301 the redirection will be cached and results may not be reliable in your browse until it clears up or you use a different browser.
%1 is used when you're capturing something from the RewriteCond whereas $1 is captured from the RewriteRule.
The number represent the captured value index, if you have anything resulting in multiple values, as you can see below with $1 and $2.
When using # for comments ensure they are always in a new line and not at the end of the rule or it will fail to work.

.htaccess rewrite in subdirectory

I am currently deploying a number of sites from one hosting account. I have all of the sites in their own folder including the primary domain. The issue I have is when I rewrite the primary domains address with my current code, it includes the subdirectory in it. So currently if I type in http://www.example.com/url it rewrites to https://example.com/folder/url. I just want it to rewrite without the folder.
Any ideas. I know I am complicating this by running my primary domain in a subdirectory, just trying to clean up hosting as best as possible.
In my public_html .htaccess file:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/folder/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /folder/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ folder/index.php [L]
and in public_html/folder .htaccess:
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
So currently if I type in http://www.site.whatever/url it rewrites to https://site.whatever/folder/url.
This is a "redirect", not a rewrite.
This is happening because of the use of the REQUEST_URI server variable in your HTTP to HTTPS redirect in your public_html/folder .htaccess file:
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
The REQUEST_URI server variable contains the full URL-path of the request, which, by the time the subdirectory's .htaccess file is called, has been updated to contain /folder.
You need to either:
Move your canonical www to non-www and HTTP to HTTPS redirects to the .htaccess file in the document root. (This would be preferable if you have no other mod_rewrite directives in your public_html/folder .htaccess file.)
OR,
Modify the above directive to use the $1 backreference (to the captured RewriteRule pattern) as you are doing in the preceding www to non-www redirect. For example:
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
(Note that this should ultimately be a 301 redirect, once you have confirmed it works OK.)
And don't forget to escape literal dots in the regex.

RewriteCond for a folder only on a specific domain extension

I have a site that can be accessed via 3 domains (domain.com, domain.ch, domain.fr). The three use exactly the same files and folder, though.
Regarding the .fr domain (and only this domain), I need the following:
redirect domain.fr (root) to domain.com/fr/france.
This has been achieved with the following rule:
RewriteCond %{HTTP_HOST} ^www\.domain\.fr$
RewriteRule ^/?$ "http\:\/\/www\.domain\.com\/fr\/france" [R=301,L]
It works. (There's also a functioning rule to force www. in front of every URL.)
What I can't get to work is:
redirect domain.fr/fr also to domain.com/fr/france.
and finally, redirect any URL domain.fr/fr/* to domain.com/fr/*
(keeping whatever * stands for).
The trick (to me) is that the same .htaccess file will also be present on domain.com and domain.ch, but those rules must not activate for those domains.
You can put these rules in your htaccess
# Redirect [www.]domain.fr and [www.]domain.fr/fr to www.domain.com/fr/france
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.fr$ [NC]
RewriteRule ^(|fr)$ http://www.domain.com/fr/france [R=301,L]
# Redirect domain.fr/fr/* to domain.com/fr/*
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.fr$ [NC]
RewriteRule ^fr/(.*)$ http://www.domain.com/fr/$1 [R=301,L]
Try :
RewriteCond %{HTTP_HOST} ^www\.domain\.fr$
RewriteCond %{REQUEST_URI} !^/fr/france
RewriteRule ^fr/(.*)$ http://www.domain.com/fr/france/$1 [R=301,L]

.htaccess RewriteRule not retaining capture group during domain redirection

I have an HTTPS subdomain, https://donate.example.com/, which points to the same web root as the www domain. I have a script on my server in the folder /donate/, and inside of there I have an .htaccess file which has the following code. I want to make sure any requests to http://www.example.com/donation/ (or http://direct.example.com/donation/) will redirect to https://donate.example.com/donation/.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} !^donate\.example\.com$ [NC,OR]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://donate.example.com/$1 [R=301,L]
</IfModule>
The issue I'm having is that the capture-group in RewriteRule (^(.*)$) is not being copied into the destination URL ($1), so the user is only being redirected to the webroot instead of the full path. This means that the user is being redirected to https://donate.example.com/ instead of https://donate.example.com/donation/ (which is the behavior I need/expect).
Any idea why the capture-group isn't working?
Problem is that inside /donation/ folder captured value for http://www.example.com/donation/ will be empty since it is relative to /donation/.
Try this code instead:
RewriteEngine on
RewriteBase /donation/
RewriteCond %{HTTP_HOST} !^donate\.example\.com$ [NC,OR]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^ https://donate.example.com%{REQUEST_URI} [R=301,L,NE]

redirect http to https for some page in site in APACHE

I want to one of my site's page will use only HTTPS.
I have given manually link to all sites to https.
But I want that if user manually types that page URL with http then it should be redirected to https page.
So if user types:
http://example.com/application.php
then it should be redirected to
https://example.com/application.php
Thanks
Avinash
Here's a couple of lines I used in an .htaccess file for my blog, some time ago :
RewriteCond %{HTTP_HOST} =www.example.com
RewriteCond %{REQUEST_URI} ^/admin*
RewriteCond %{HTTPS} !=on
RewriteRule ^admin/(.*)$ https://www.example.com/admin/$1 [QSA,R=301,L]
Basically, the idea here is to :
determine whether the host is www.example.com
and the URL is /admin/*
Because I only wanted the admin interface to be in https
which means this second condition should not be useful, in your case
and https is off (i.e. the request was made as http)
And, if so, redirect to the requested page, using https instead of http.
I suppose you could use this as a starting point, for your specific case :-)
You'll probably just have to :
change the first and last line
remove the second one
Edit after the comment : well, what about something like this :
RewriteCond %{HTTP_HOST} =mydomain.com
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://mydomain.com/$1 [QSA,R=301,L]
Basically :
using your own domain name
removing the parts about admin
Try this rule:
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^application\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This rule is intended to be used in the .htaccess file in the document root of your server. If you want to use it in the server configuration file, add a leading slash to the pattern of RewriteRule.
use this:
RewriteEngine On
# Turn SSL on for /user/login
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/user/login
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
# Turn SSL off everything but /user/login
RewriteBase /
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/user/login
RewriteRule ^(.*)$ http://%{HTTP_HOST}$1 [R=301,L]
website
open httpd.conf or .htaccess file (mod_rewrite not required):
# vim httpd.conf
Append following line :
Redirect permanent / https://example.com/