.htaccess rewrite between three servers - apache

I'd like to copy the same htaccess file to three different servers. However I don't want to update the contents each time I do that. How do I make the domain name be detected 'dynamically'?
For example, I have the following:
Redirect 301 /test/directory/page.php http://examplesite.com/original/location.php
This won't work on the other two domains because, obviously, they have different urls.
Should I modify like this:
RewriteRule ^/test/directory/page.php /original/location.php [R=301,L]
Or is there a better way where I don't have to specify the domain name?

Yes, this will work (with one small change -- see notes):
RewriteRule ^test/directory/page.php /original/location.php [R=301,L]
You can also use this (in case you need to change protocol from current HTTP or HTTPS to a specific one):
RewriteRule ^test/directory/page\.php$ http://%{HTTP_HOST}/original/location.php [R=301,L]
NOTES:
%{HTTP_HOST} = current domain name. So if accessed http://examplesite.com/test/directory/page.php then %{HTTP_HOST} will have examplesite.com as its value.
No need for leading slash / after ^ (unless rule will be placed in config file and not .htaccess). For example: when accessing http://examplesite.com/test/directory/page.php the RewriteRule will work with test/directory/page.php.

Related

.htaccess 301 redirects based on TLD

We're in the process of switching our current site from a multiple domain configuration into a single domain, multiple folder format. i.e.
.co.uk/<uri> is becoming .com/en-gb/<uri>
.com/<uri> is becoming .com/en-us/<uri>
I'm hoping that I'll be able to handle this via a couple of well-crafted .htaccess rules, but I'm not sure of code I'm going to need to achieve this. Can you help?
(PS, I've left the actual domain blank, as we only need to test for the TDL, not the entire domain - although whatever the original domain was need to stay the same, with only the TLD changing - i.e. whatever.co.uk would redirect to whatever.com/en-gb/, whatever2.co.uk would redirect to whatever2.com/en-gb/, and whatever.com would redirect to whatever.com/en-us/)
add the following directives to your .htaccess:
RewriteCond %{HTTP_HOST} (.+)\.co\.uk$
RewriteRule (.*) http://%1.com/en-gb/$1 [R=301,L,QSA]
RewriteCond %{HTTP_HOST} \.com$
RewriteCond %{REQUEST_URI} !^/(en-us|en-gb)/
RewriteRule (.*) /en-us/$1 [R=301,L,QSA]
if you have so many domain TLDs, you maybe want to use RewriteMap to avoid duplicating the first rule for every TLD, RewriteMap will map TLD to Uri string (ex: .co.uk to en-gb),

301 redirect but change URL to all lower case in apache

I'd like to set up a 301 redirect in Apache to change the case of the original address before redirecting. So for example if someone enters:
www.website1.com/UsErOfMiXedCase
it should forward to
www.website2.com/userofmixedcase
Would this be a redirect or would it need to be a rewrite? I'm not fussed about individual page forwarding (eg www.website2.com/userofmixedcase/whatever.php) - just www.website1.com/whatever.
Thank you in advance,
Richard
You need to define the rewrite map using Apache's internal tolower function. This can only be done in vhost or server config, and will result in an error if you try to put these directives in an htaccess file:
RewriteEngine On
RewriteMap lowercase int:tolower
Then, in your htaccess file, you can use something like this above any rewrite rules you already have. The redirect rules must be before whatever rules you may have that does routing:
# check that the lower case version of the URI is different than the unchanged URI
RewriteCond %{REQUEST_URI} ^/([^/]+)$
RewriteCond ${lowercase:%1}::%1 !^(.*)::\1$
RewriteRule ^/?(.+)$ http://www.website2.com/${lowercase:$1} [L,R=301]
This will redirect a request like http://www.website1.com/UsErOfMiXedCase to http://www.website2.com/userofmixedcase, thus replacing the URL in the browser's address bar with the one that's all lowercase. Note that it won't affect URLs with multiple path nodes, e.g. http://www.website1.com/SoMe/PathName/UsErOfMiXedCase. If you want it to affect all requests including ones that have multiple paths/subdirectories, then you need to change this line:
RewriteCond %{REQUEST_URI} ^/([^/]+)$
to:
RewriteCond %{REQUEST_URI} ^/(.+)$
You are wanting to use mod-rewrite for this. Something like:
RewriteRule ^/(.*) http://website2.com/$1 [NC]
That is a very general rule, so anything after the leading slash will be lower case. You may want to only do the lower case for specific portions of URL, but I cannot speak to that.
You probably should eyeball the Apache mod-rewrite documentation about the NC flag about this as well.
hth!

Apache Mod Rewrite - Replace www.example.com with www/example.com

First what I have that already works...
On my server I use parked domains where each domain points to the same directory and the software merely determines what the domain is before pulling from the similar named database. For files (images, scripts, etc) I currently have the following setup...
public_html/www.example1.com/
public_html/www.example2.com/
public_html/www.example2.com/
...using the following rewrite...
RewriteCond %{REQUEST_URI} !\.(gif|jpg|js|mp3|png)$
RewriteRule ^[^/]*/(images|search|scripts|sounds)(.+) $1$2 [QSA]
So in example if you request image77.png from example2.com Apache rewrites the (internal) request to...
public_html/www.example2.com/images/image77.png
The external path (in your browser) would simply appear as...
http://www.example2.com/images/image77.png
Secondly, the problem I'm trying to solve...
However as I add more domains this is starting to crowd my *public_html/* directory. What I'm trying to do is simply move all the domain asset directories in to a directory setup that looks like the following...
public_html/www/
...so the www directory would have the following listing...
public_html/www/example1.com/
public_html/www/example2.com/
public_html/www/example2.com/
Lastly, my thoughts on how to possibly approach the problem...
The first Apache variable $1 is generated from %{REQUEST_URI}. If we can simply replace the period . between www and the domain name this should update the rewrite to the newer format though I'm not sure how to do that and keep what works already in tact?
In other words can we can create a rewrite condition to replace just the first period with a slash?
You can capture the domain part after www. and use it later in the RewriteRule as %1
RewriteCond %{HTTP_HOST} ^www\.(.+)$
RewriteRule ^.*?/(.*)$ /public_html/www/%1/$1 [L]

Scalable URL Rewrite Rule

I am organizing sub-websites into different folders on a LAMP server for ease of maintenance, but do not want the end user to know they are organized into those folders via the URL.
Directory structure example:
/category1/website1
/category1/website2
/category2/website3
/category2/website4
/category2/website5
/category3/website6
/category4/website7
etc.
Currently it shows as http://www.example.com/category1/website1 however I want it to show as http://www.example.com/website1 all the time - even if they put the category name in there.
The trick is I need to do this from a .htaccess file with X amount of categories having X amount of sub-websites in them. Currently I am using
Redirect 301 /website1 /category1/website1
for each website to allow users to use the shorter link, but ultimately they end up seeing the category in the address and the .htaccess file is long with 200+ sub-websites involved. :(
Any help would be appreciated!
Using mod_rewrite it's pretty straight-forward if you are going to manually enter them in:
RewriteEngine on
RewriteRule ^/website1$ /category1/website1 [L,NC]
RewriteRule ^/website2$ /category1/website2 [L,NC]
It's possible to create a RewriteMap as well. There's a lot of helpful information in the documention
Hope that helps.
Since there is no discernible "pattern" that links the website to the category subdirectory and you are limited to .htaccess then you have no choice but to manually list all the mappings in your .htaccess file, in the same way you have listed the redirects.
Assuming you want to internally rewrite a URL of the form /website1/<something> to /category1/website1/<something> - in the same way the Redirect directive works (which is prefix-matching).
You could do something like the following in .htaccess:
RewriteEngine On
RewriteRule ^(website1/.*) /category1/$1 [L]
RewriteRule ^(website2/.*) /category1/$1 [L]
$1 is a backreference to the captured group in the RewriteRule pattern. eg. If you request /website1/foo then it will rewrite to /category1/website1/foo.
This does require that you request at least /website1/, with a trailing slash (since this is a directory of sorts).
You can potentially group sites together that are in the same category. For example:
RewriteRule ^((website3|website4|website5)/.*) /category2/$1 [L]
I want it to show as http://www.example.com/website1 all the time - even if they put the category name in there
For this you would need to implement the reverse... a redirect to remove the category from the URL. However, an added complication is that you only want to redirect direct requests and not rewritten requests (as above).
This will need to go before the internal rewrites above.
Unless there is a discernible pattern that distinguishes category names then you will need a rule for each category. For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^category1/(.*) /$1 [R=302,L]
...and repeat for each category.
The check against the REDIRECT_STATUS environment variable ensures that we are only targeting direct requests and not rewritten requests.
Change 302 (temporary) to 301 (permanent) - if that is the intention - only once you have confirmed that it works OK in order to avoid caching issues.
However, this may be easier (and more "scalable") to implement with an additional .htaccess file in each of the category subdirectories instead. And this would be the same directives in each category subdirectory:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=302,L]
Since the URL-path matched by the RewriteRule pattern is relative to the directory containing the .htaccess file, the $1 backreference contains the URL-path less the /category/ prefix.

Apache Rewrite: secondary htaccess for domain specific RedirectMatch

On shared web-hosting my software supports multiple domains (all domains point to the same public_html root directory).
What I want to do is keep redirects (and any RedirectMatch) in their own host specific/dedicated .htaccess file.
Visually the directory structure looks like this...
/public_html/ (all domains are pointed internally to this directory)
/public_html/.htaccess
/public_html/www.example1.com/
/public_html/www.example2.com/
/public_html/www.example3.com/
There are two approaches I'm considering though would appreciate input from others:
The first would be to keep domain specific redirects out of the main .htaccess file as defined above. So I'd like to have redirects handled by the .htaccess files as defined by below if possible...
/public_html/www.example1.com/.htaccess
/public_html/www.example2.com/.htaccess
/public_html/www.example3.com/.htaccess
...if this is not feasible I'll settle for a rewrite to a PHP file to hand off redirects to PHP instead. I imagine this isn't as performance oriented though on the other hand it would give me the opportunity to log redirects and see how long it takes them to level off.
Some clarifications:
I'm using shared web hosting so anything Apache related needs to be done through .htaccess files only.
There are no redirects/matches in the master .htaccess file nor will there ever be since two domains may eventually attempt to use the same redirect.
Since you are on shared host, You cannot afford to have any solutions concerning conf files (which BTW are better). So wont bother to list them. Best way to do the above is like this:
The code was written keeping in mind that none of the domains share any kind of file/data on the server. Every file/data pertaining to a domain is kept under a folder having the name equal to its domainname.
The code below is tested(both static and non static):
RewritEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
And add either of the following to the above:
for doing it statically:
RewriteCond %{HTTP_HOST} ^www\.(example1|example2|example3)(\.com)$ [NC]
RewriteRule ^(.*)$ /www.%1%2/$1 [L]
for doing it statically: and also if you want to access the site without www
RewriteCond %{HTTP_HOST} ^(www\.)?(example1|example2|example3)(\.com)$ [NC]
RewriteRule ^(.*)$ /%1%2%3/$1 [L]
for Non-statically do it: this is a better sol
RewriteRule ^(.*)$ /%{HTTP_HOST}/$1 [L]
All the above will do is redirect URI to their specific domain's folder. All other domain specific rewrites can be handled in the respective folders.
If you have URIs without the www, i.e. example1.com change ^www\.(example1|example2|example3)(\.com)$ to ^(www\.)?(example1|example2|example3)(\.com)$