Redirect 301 for everyone but you

Consider this post just a quick note to myself, because I will surely need this again in the future.

Scenario: i have a production server and a development server. As you can easily guess, on the production server i have the live version of the websites and on the development server I develop new features/bug fixes/new websites.

What I usually do is to create a specific subdomain for the development. Sometimes i add that hostname as DNS record, sometimes i just add it to my hosts file. Either way, it’s still possible for others to find your “hidden” development website (for example, Alexa.com displays the subdomains getting traffic, so if you use the Alexa toolbar – not necessarily the official – you will see your development website listed under your domain statistics on Alexa.com).

The solution to the problem is extremely simple: just redirect to the production website the traffic coming from any IP address but yours. Just add to the .htaccess of the development website these lines:

RewriteEngine On
# If it’s not your IP address
RewriteCond %{REMOTE_ADDR} !^1.2.3.4$
# Redirect everything to production host.
RewriteRule ^(.*)$ http://www.stefanogorgoni.com/$1 [R=301,L]

Change of course that 1.2.3.4 to your IP address (if you have a dynamic IP, don’t forget to change the .htaccess accordingly every time the IP changes), and the hostname of destination (the www.stefanogorgoni.com part).

 

Get domain from URL

How to get the domain from the URL? It depends!

Lately i’ve spent some time trying to figure out the best way to solve this problem.

Scenario: a website reachable through two different second-level domains (and a bunch of third-level domains). No redirects from a domain to the other, or from the third-level domains to the second-level (and this behaviour couldn’t be changed). The two SLD have their own virtual host configured on Apache (this detail is very important, as you will see).

Please note: the following possible solutions consider PHP, but i guess that, apart from the different syntax, the logic would be the same with any other language). I’m not a programmer anyway, so won’t put much code here (feel free to add it in the comments, if you want).

One possible solution is to get the server name:

<?php
$_SERVER(‘SERVER_NAME’);
?>

and then take the last two strings starting (separated by a dot) from the end.

So, if SERVER_NAME is www.mydomain.tld, you would get mydomain.tld, which is the second level domain.

This solution can be good enough if you know in advance you are not going to use it with domains including a dot, like co.uk, com.mt or com.au, just to name a few.

But if you have the website accessible through google.com and google.co.uk (the first example coming to my mind, i wonder why), this kind of solution would return google.com and co.uk. Not exactly what you’d want.

A more sophisticated solution would be to check the TLD against a list (there is one here but it’s not complete). If you have a complete list of TLD, you can get the SERVER_NAME, check what TLD is in it, and pick up the part of the hostname before the TLD (plus the TLD itself, of course).

For both the solutions above, you can find a lot of code snippets on Google.

But my favourite solution is the third! In fact, you can set in the virtual host (in the two virtual hosts, in my case) on Apache a variable defining the domain:

<VirtualHost>
ServerName www.domain1.tld
SetEnv MY_DOMAIN domain1.tld
</VirtualHost>

<VirtualHost>
ServerName www.domain2.tld
SetEnv MY_DOMAIN domain2.tld
</VirtualHost>

This way it’s Apache defining the exact domain value, and at this point you can get the variable in php with a simple

<?php
$_SERVER(‘MY_DOMAIN’);
?>

For the record, i needed to use the variable to create a cookie valid for the second level domain and any subdomain of it. So, once defined the variable in the virtualhost, all i had to do was something like this:

$domain = $_SERVER[‘MY_DOMAIN’];
if(isset($_GET[‘parameter’])) {
$variable = htmlentities($_GET[‘parameter’]);
setcookie(“mycookie”, $variable, time()+(60*60*24*7), “/”, $domain);
}

In case you will find yourself in the same situation, hope this saves you some time.

P.s. as you see now, being able to edit the virtual host is essential to use this solution.