Htaccess rewrite subfolder to subdomain - apache

i have a domain with many subdomain; what i want to do is to map specific subdomains do specific subfolder.
let's suppose the domain is example.com, i have these domains:
example.com
www.example.com
demo1.example.com
demo2.example.com
and 2 subfolders in my var/www/html folder:
/var/www/html (for example.com and www.example.com)
/var/www/html/demo1 (for demo1.example.com)
/var/www/html/demo2 (for demo2.example.com)
So what i want to is set up the correct mapping so that:
opening (www.)example.com/demo1 should redirect to demo1.example.com
opening (www.)example.com/demo2 should redirect to demo2.example.com
opening (www.)example.com/anything-else should do nothing (content in /var/www/html)
Obviusly demo1.example.com should use the content in /var/www/html/demo1 and demo2.example.com should use the content in /var/www/html/demo2

You probably want to implement rules handling both directions:
1. redireting requests to the "www" host to the "subdomain" (actually another host name)
2. rewriting requests to the non-www hosts to a folder, if such folder exists
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$
RewriteRule ^/?demo1/(.*)$ https://demo1.example.com/$1 [R=301]
RewriteRule ^/?demo2/(.*)$ https://demo2.example.com/$1 [R=301]
RewriteCond %{HTTP_HOST} ^demo1\.example\.com$
RewriteRule ^ /demo1/%{REQUEST_URI} [END,QSA]
RewriteCond %{HTTP_HOST} ^demo2\.example\.com$
RewriteRule ^ /demo2/%{REQUEST_URI} [END,QSA]
You could certainly implement a more generalized rule for the second part (the internal rewriting), but above explicit approach is easier to reach, thus easier to maintain. I prefer it for that reason.
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
These rules will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Related

.htaccess entry for redirecting to a folder without showing the folder name in url

my website resides in public_html/rhf folder.
1. i want if some one enter url https://rhf.in , it should be redirected to https://rhf.in/rhf in background and browser should display only https://rhf.in
also for if some one enters http://rhf.in or http://www.rhf.in it should redirected to https://rhf.in/rhf and shows only https://rhf.in/ in browser address bar.
first case is working fine for me by adding following in .htaccess
RewriteRule !^rhf/ /rhf%{REQUEST_URI} [L]
But second case is not working
Kindly help in this regard
This would be the classical setup:
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,END]
RewriteCond %{REQUEST_URI} !^/rhf(?:/|$)
RewriteRule ^ /rhf%{REQUEST_URI} [QSA,END]
For the first redirection to http you obviously need to listen and react to the unencrypted http protocol at all. This implements a general redirection. In case you only want to redirect for that specific path you mentioned, the rule would have to be extended by a condition as well.
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

htaccess RewriteRule creates only root-url, not the expected one

here are some possible URL's i need to rewrite:
https://www.example.org/products/rubbers/1234-super-special-rubber
https://www.example.org/forum/2345-hello-world
https://www.example.org/3456-very-special-article
I want to remove all numbers and the - sticking to the number from the URL:
https://www.example.org/products/rubbers/super-special-rubber
https://www.example.org/forum/hello-world
https://www.example.org/very-special-article
What i tried so far (4 digits and -):
RewriteCond %{REQUEST_URI} ^.*[/][0-9][0-9][0-9][0-9]-.*$
RewriteRule ^.*[/][0-9][0-9][0-9][0-9]-.*$ /$1 [R=301,L]
The redirect works not as expected, it only takes me to:
https://www.example.org/
I also tried
RewriteEngine On
RewriteBase /
RewriteRule (\d+)-([^/]*) $2 [R=301,L]
this should work, but it cuts '/products/rubbers' away :(
https://www.example.org/super-special-rubber
How do i tell the RewriteRule to cut out the numbers and the first - ?
Thank you :)
The $1 reference you use in your rule references the first captured group from your matching pattern, but you did not define any such group. That is why it is empty and you rewrite to what you call the "root URL".
Take a look at this instead:
RewriteEngine on
RewriteRule ^/?(.*)/\d{4}-(.+)$ /$1/$2 [R=301,END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Redirect all subdomains to file

I have a server to which many domains points. So I need a generic .htaccess rule. I need to create a .htaccess file which redirects all subdomains to their correspondent subdomain folder.
Is that possible? Thanks.
For example:
http(s)://apple.domain1.com -> https://domain1.com/redir/apple/index..html
http(s)://orange.2domain.co.uk -> https://2domain.co.uk/redir/orange/index.asp
http(s)://banana.doma3n.org -> https://doma3n.org/redir/banana/index.php
OK, so now it suddenly are three questions in one :-)
I don't really understand why you need separate folders for this. Why not one script that handles those requests, regardless on what host ("subdomain") is called? The script knows about what host has been called, so it can act accordingly.
Anyway, your question is how to rewrite to separate folders, so that is what I will answer to...
In addition to rewriting hosts acting as landing pages you also want to configure your default host (the fallback host) such that it delivers something that does make sense.
Anyway, this should point you into the right direction:
First you need to configure your DirectoryIndex:
DirectoryIndex index.html
DirectoryIndex index.php
DirectoryIndex index.asp
Consult the documentation for more details and where to place those directives:
https://httpd.apache.org/docs/2.4/mod/mod_dir.html
Second you need to rewrite the incoming requests to internal directories:
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REMOTE_ADDR} ^10\.
RewriteRule ^ /redir_internal [END]
RewriteCond %{HTTP_HOST} ^([^.]+)\.
RewriteCond -d %1
RewriteRule ^ /%1 [END]
RewriteRule ^ /something_that_acts_as_a_fallback
Consult the documentation for more details:
https://httpd.apache.org/docs/current/mod/mod_rewrite.html
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Apache mod_rewrite redirect subdomains on specific basis

I'm developing an application that is running on my domain.
All works as expected, but I cannot seem to find any good answer to my problem relating subdomains.
This application allows for different clients to register themselves and get their own "environment" inside the application.
E.g. if client1 registers himself, his environment will be at https://main.application.com/v/client1
Now, as you can see, this is quite ugly. I want him to be able to go to https://client1.application.com/ and in the background it would show him https://main.application.com/v/client1.
I've read this is possible with apache rewrite.
My case is a little bit more complex than a simple rewrite, I'm guessing. What I'm trying to achieve is this:
User goes to | Has to redirect to
client1.application.com | main.application.com/v/client1
client1.application.com/register | main.application.com/v/client1/register
client1.application.com/dashboard | main.application.com/dashboard
client1.application.com/... | main.application.com/...
As you can see, the only time I want to redirect with the /v/client1 appended to my domain, is when somebody is trying to register or trying to reach the login page for their environment. In all other scenarios, I just want to take what's behind the URL and append it to main.application.com (which is where the main app runs). I also don't want the users to notice the redirect, but that the URL in the address bar stays the same.
I've tried to come up with a bit of pseudocode that explains what I want to do:
If subdomain.application.com/ or subdomain.application.com/register
--> take subdomain and paste it like this:
main.application.com/v/SUBDOMAIN/ or main.application.com/v/SUBDOMAIN/register
Else
--> Redirect to main.application.com/URL
e.g. client1.application.com/dashboard --> main.application.com/dashboard
But I'm completely lost on how I should write it with a Rewrite.
Has anybody got experience in this matter that would be able to help me out with those rewrites here? I'm new to this and I cannot find documentation for my specific case.
Assuming that all requests to those host names ("sub domains") are handled by the same http host (by means of a ServerAlias or simply using the default fallback host) this should be pretty straight forward...
do not rewrite any requests directly to example.com or www.example.com
rewrite requests to other hosts that do not specify any path
rewrite requests to other hosts that specify the /register path
no treatment for other paths required if your http host uses the same file system layout (DOCUMENT_ROOT) for all these hosts ("sub domains")
That leaves is with this:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^ - [END]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$
RewriteRule ^/?$ /v/%1 [END]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$
RewriteRule ^/?register/?$ /v/%1/register [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

.htaccess redirects if the condition doe not match/ negative condition

I am modifying the .htaccess file of a legacy PHP web application. I am not familiar with apache .htaccess syntax. I found this tutorial. What I am trying to do is that I am trying to redirect all the requests to a URL/ path if the request URL is not a specific URL/ path. For example, all the requests to the website will be redirected to localhost/my-custom-page unless the request URL is localhost/my-custom-page.
I know how to redirect mapping 1 to 1 as follows:
RewriteEngine on
RewriteRule ^my-old-url.html$ /my-new-url.html [R=301,L]
But, what I am trying to do is that redirecting all the requests to the specific page unless the request is to that page. Even the home page will be redirected to that page. How can I do that?
When I tried the following solution
RewriteEngine on
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
I get the error
I want to check using OR condition as well. For example, if the path is not path-one or path-two, redirect all the requests to path-one.
Your question is a bit vague, due to your wording. But I assume this is what you are actually looking for:
RewriteEngine on
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
RewriteCond %{REQUEST_URI} !/my-new-url\.html
RewriteRule ^ /my-new-url.html [R=301]
There are a few potential issues with this, particularly since you hint in a comment that you are perhaps using a front-controller to "route" the URL.
This redirect satisfies the conditions outlined in the question, but does assume that you have no other rewrites, have an essentially "static site" and are not linking to any static resources.
You are missing an L (last) flag, so processing will continue through the file and possibly be rewritten if you have later rewrites.
If you are rewriting the URL to a front-controller in order to route the URL (as you suggest in comments) then this redirect will break, as it will redirect away from the front-controller. You need to only redirect direct requests, ie. when the REDIRECT_STATUS environment variable is empty.
If you are linking to any static resources in the same file space then these will also be redirected. You need to create an exception for any static resources you are using, either by file extension (eg. (css|js|jpg|png)) or by location (eg. /static).
So, try the following instead:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} !\.(js|css|jpg|png)$
RewriteRule !^my-custom-url$ /my-custom-url [R=302,L]
You don't need a separate condition to implement the exception for the URL you are redirecting to. It is more efficient to do this directly in the RewriteRule pattern.
The first condition ensures we are only redirecting direct requests and not rewritten requests to your front-controller.
The second condition avoids any static resources also being redirected. You could alternatively check the filesystem path if all your resources are stored under a common root. Or, as a last resort, implement filesystem checks (ie. RewriteCond %{REQUEST_FILENAME} !-f) if your static resources are too varied - but note that this is less efficient.
You will need to clear your browser cache before testing, since any earlier (erroneous) 301s are cached persistently by the browser.