.htaccess RewriteRule not retaining capture group during domain redirection - apache

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]

Related

HTTP to HTTPS redirect exposes subdirectory instead of redirecting to subdomain

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.

.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.

http:// redirects to https://www.www with htaccess

I have a CI installation in my root domain. SSL certificate is installed and working properly. When I redirect http:// to https://www it redirects to https://www.www (an extra www), that too on some computers and some browsers as users have reported. However, when I remove 'www' from redirection, its all fine. Seems like www is looping. So far, I've digged my code hundred times, and see no sign of redirection from code (I mean addition of extra www). I'm doing it with htaceess. Any help will be highly appreciated. This is my htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#Force SSL
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R,L]
#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
I'm running it on apache with Centos VPS.
Thank you so much!
The HTTP_HOST is the "target host" part of the request, like: www.mydomain.com.
The REQUEST_URI is generally the path which was given in order to access a certain page; for instance, ‘/folder/index.html’.
In your RewriteRule you say to put 'www.' in front of the requested domainname.
You don't want that, when someone asks for http://www.yourdomain.com.
Without the www. in your RewriteRule someone who requests for http://yourdomain.com gets redirected to https://yourdomain.com
When you want to redirect to https and www you need to add conditions. Look into Apache docs on Canonical host and on questions/4083221/how-to-redirect-all-http-requests-to-https for this solution:
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTPS_HOST} !^www.yourdomain.com$ [NC]
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [L,R=301]

redirect to subfolder

I have set up url redirect on my host--but its not working.
my htaccess looks like this now
rewriteengine on
rewritecond %{HTTP_HOST} ^.*$
rewriterule ^http:\/\/www\.bangkoksoftball\.info "http\:\/\/www\.bangkoksoftball\.info\/wordpress" [R=301,L] #4d3a8d4534e567
what i want is any request to http://www.bangkoksoftball.info to be redirected to http://www.bangkoksoftball.info/wordpress/
but any request to a path file or directory off the root not to be redirected
this so people can still access the old site via /home.html or index.html etc.. and still be able to navigate outside the wordpress folder
Try this in your .htaccess file:
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^(www\.)?bangkoksoftball\.info$ [NC]
RewriteRule ^/?$ /wordpress/ [R,L,NE]
Remember there is NO presence of http/https in %{HTTP_HOST} or %{REQUEST_URI} variables. Also . needs to be escaped in domain match. NE flag is for not escaping the query parameters.
The rewriterule line does not look at the domain, you must specify the domain the rule applies to in the RewriteCond line. In the rewriterule line, you specify first the paths that should trigger the rule, and the path the user should be sent to instead.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^http:\/\/www\.bangkoksoftball\.info$
RewriteRule ^/$ "http\:\/\/www\.bangkoksoftball\.info\/wordpress" [R=301,L]
This will send only requests to www.bangkoksoftball.info/ to the wordpress folder. If you want to also redirect www.bangkoksoftball.info/index.php to the wordpress folder, you would need to add an additional set of directives:
RewriteCond %{HTTP_HOST} ^http:\/\/www\.bangkoksoftball\.info$
RewriteRule ^/index\.php$ "http\:\/\/www\.bangkoksoftball\.info\/wordpress" [R=301,L]
This should work for you as it worked here:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?bangkoksoftball.info$ [NC]
RewriteRule ^/$ http://www.bangkoksoftball.info/wordpress/$1 [R=301,L]

redirect into subdirectory AND out of subdirectory

i have a mod_rewrite redirection problem i cannot figure out.
all requests from a specific domain get "silently" rewritten into a designated subdirectory. e.g. www.mydomain.net/hello.html retrieves the file in /net/hello.html. the following .htaccess (placed in my hosting root) achieves this perfectly:
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} 200 # <-- i will need this later. read to the end of the post.
RewriteRule .* - [L]
rewriteCond %{HTTP_HOST} ^www.mydomain.net$
rewriteCond %{REQUEST_URI} !^/net.*$
rewriteRule (.*) /net/$1 [L]
however, direct URLs into this directory however should visibly redirect with a 301 to the URL without that subdirectory. e.g. www.mydomain.net/net/hello.html should redirect to www.mydomain.net/hello.html (which than still retrieves the file in /net/hello.html). my .htacces file for this (placed in /net) unfortunately doesn't work:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^localhost$
RewriteRule ^(.*) /$1 [R=301,L]
i get an infinitive redirect loop despite the RewriteCond %{ENV:REDIRECT_STATUS} 200 block in the root .htaccess file... so what's wrong?
btw, i have to use mod_rewrite, because the site is externaly hosted and i have no access to the apache configs.
many thanks for any pointers.
Inspect the HTTP request line in THE_REQUEST instead:
RewriteCond %{THE_REQUEST} ^GET\ /net[/? ]
RewriteRule ^net($|/(.*)) /$2 [L,R=301]