Be Google’s friend: Make your URLs canonical with .htaccess
July 18, 2008 by Thomas I
Filed under .htaccess, Apache, Server Management
This subject is… is… well ![]()
Every second site on the net has at least one article about this subject. But to be honest, it’s good to have so many articles about this, in a way. At least people recognize they should use it. Or not.
So, what’s the fuss around the URL canonicalization? One thing only: the search engines and their hate of duplicated content. If your website is accessible both on www.example.com and the plain example.com the search engines will index both areas, they think you duplicated your content to get more positions in the search results, so they penalize your domain. Weird. They should know it’s the same website, or at least the coders should teach them that www is the same with non-www. Or at least on well-configured servers.
So, here pops Apache in and throws a resolution for the issue: the mod_rewrite engine, again. You will have to have mod_rewrite bundled into Apache and working correctly.
As always, here’s the code for those who just want to copy&paste and then the explanation for all the lines.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^/(.*) http://example.com/$1 [R=301,L]
That is. Placed in a .htaccess file, it will redirect with code [301:Moved Permanently] all the queries sent to the www.domain.com to domain.com. Now let’s explain it line-by-line:
- We switch On the mod_rewrite module, thus telling Apache we want to work with it.
- If the hostname contains “www”, apply the rule, so this a condition
- This last line is the rule which has to be done if the condition can be applied on the HTTP request. In our case do a 301 redirection to the non-www version of the site
That was all. Search engines are now happy, World saved again.
As always, if something is unclear, drop a comment and i answer as soon as possible.
Hotlink Protection using .htaccess made easy
July 18, 2008 by Thomas I
Filed under .htaccess, Apache, Server Management
This is one of the most used tricks by the webmasters who care about their allocated bandwidth. The code which controls what are domains where your images can show up is very short, 4 line that is.
As always, I provide the full code, then below it I explain everything.
To use this code, you have to have an Apache web-server with mod_rewrite correctly installed.
So, let’s see the code for those who don’t want the explanations:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
Now some explanations:
The first line,
RewriteEngine on
practically tells Apache we will do something with mod_rewrite so turn it on. This line is optional if you already turned it on before in the same .htaccess where you put the above code in.
The second line,
RewriteCond %{HTTP_REFERER} !^$
this is nastier. Basically, if there is no referrer, let the image to be displayed. I guess this needs a bit of explanation. When you navigate on the internet from one site to the other, the browser always sends a “referrer” header to the host you are accessing. So, for example if you are currently on http://www.Google.com and you navigate to http://yahoo.com, the browser will send yahoo the following : “Referrer: http://www.google.com”. This header is what we use in our .htaccess to prevent hotlinking, BUT! Some antiviruses, firewalls clears this header on the clients’ side so there is no referrer at all, thus we don’t know the user browses our site, or it’s hotlinking our image on another site. Thus we just let the image to be displayed if there is no referrer.
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
If the referrer domain is our own domain, display the image. We set: http(s)?://(www\.)?yourdomain.com, so our condition will work on HTTP, HTTPS and also on our www and non-www hostname/domain.
And the last step is to tell Apache which files to protect:
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
In the above case the jpg, jpeg, png and gif images will be protected. If you want to protect your Flash-files as well, put swf in the list and your movies will not display embedded in remote sites.
On our domain the php files are also protected because the Imagick examples are parsed by php codes.
I hope the above example was somewhat useful, if you need help with it, just say your problem below and will answer as soon as possible.
Use IPTables to reroute or just annoy your visitors
July 15, 2008 by Thomas I
Filed under Linux, Server Management
Yeah, I know, I’m an idiot.
So, what I wanted to do is to annoy one of my friends in a way he never observes I did something. He is a frequent visitor of one of the site’s I manage, as I couldn’t find a better way, I decided to do something with the site somehow. The site I couldn’t alter as it’s too popular. But I knew his IP from the logs so I decided to redirect him each time he tries to access the site.
Since php had the header() function disabled redirecting him via IP matching didn’t work, had to use something else. Meta refresh isn’t good, Javascript neither as he has it disabled all the time.
IPTables! Godly touch …
iptables -A PREROUTING -s HIS.IP.ADDRESS.01/255.255.255.0 -p tcp -j DNAT --to-destination 64.233.167.99
Every request from him to the server will forward him to Google search. Nice. The problem was, that I had to listen his theory of how Google bought his favorite site.
Why is this more effective than any other script-based method?
Well, that’s obvious why is better than the client-side methods, it can’t be overridden. As of why is better than the server side codes, a valid reason would be that if you simply can not use header resetting methods.
The website which made me WOW!
My partner (an excellent web developer) had/has a client which asked him to develop him a layout which would make him WOW. He couldn’t, anything he showed him wasn’t enough.
The other day I was lurking over the net without any point, just pressing links and buttons without meaning, then I arrived to a page which, well, if I say the most interesting page I didn’t say enough.
It’s pure Flash, that’s its only con, but in rest… WOW.
Check it out yourself then let me know what do you think about it: The WOW site
Probably that design would have WOW my partner’s client.
Filter your variables easily but like a pro!
July 13, 2008 by Thomas I
Filed under Development, PHP
How painful input validation is! Think about all the possible threats, combination of threats… think with the users’ mind. It’s a pain. And usually who can write scripts which filters effectively the user inputs is considered a pro, without hesitation. Just because it’s hard to do it.
Take the following scenario: you have a text-field which accepts text as user comment. You don’t want to let the user to use HTML in the comment box, and definitely not to allow the user to put javascript in the comment.
So how do you sanitize the string you get? It’s a long and hard way. You would use RegExp to exclude some entities then some php inbuilt functions to encode the remaining or even better to strip tags.
I show you an easier way:
filter_var(’<script>alert('Hello');</script>', FILTER_SANITIZE_STRING);
Done, the <script> tags will be stripped so the string will arrive in the database as alert(’Hello World’).
There are many available filters, just to mention the most interesting ones:
- FILTER_SANITIZE_EMAIL — it sanitizes email address, strips characters which are not in conformance with the applicable RFC (link)
- FILTER_SANITIZE_URL — whether the URL from the variable is in conformance with the applicable RFC (link)
- FILTER_VALIDATE_IP — whether if the input is an IP address or not
I recommend using the filter_var() function and its filters for two obvious reasons: it saves you a lot of headaches and saves you time. Even though the filter_var function was introduced only in php 5.2 the function is extremely useful and gives another reason for you of why to upgrade to php5
For a complete reference please check php.net.
Installing ImageMagick without headaches
July 13, 2008 by Thomas I
Filed under Server Management, Softwares
This is simple: on windows systems you have the option to use the automated installer here, it’s neither complicated or hard to install. On Linux based systems I recommend to install it from source for obvious reasons like you know what’s installed, where, and if there was a problem, you can debug easily because the log is displayed.
So, login using SSH, you will need to login with a username which has compiling and install privileges.
After you logged in, create a directory where you place the gzipped package you will download from Imagemagick.org.
after you created the directory, type in the console:
wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-6.4.2-1.tar.gz
Currently (13th of July, 2008) 6.4.2 is the latest version of ImageMagick, you may want to check what is the latest release when you install your ImageMagick.
So, the above command will download the imagemagick package to your server.
Let’s depack it using tar, tar, not untar as there’s no such command on Linux ![]()
tar xvfz ImageMagick-6.4.2-1.tar.gz
Depacked. Change the directory to the newly created ImageMagick directory, then let’s configure and compile it:
./configure
make
If everything was OK, no error, warning or any other weird stuff during compile, you are safe to install it:
make install
And theoretically you are done. To test your installation try Imagemagick’s convert program, if it works, you’re the best! Type the following in the command line:
/usr/local/bin/convert logo: logo.gif
ImageMagick is a dependency for Imagick PECL, so before you can use it in PHP for example, the first step is to install ImageMagick THEN Imagick.
Additional tweaks to tighten php
July 13, 2008 by Thomas I
Filed under PHP, Server Management
Believe me or not, the resource limiting of PHP can also be an enormous security factor.
Take this scenario: Mr. John Hacker managed somehow to upload to your server a script, let’s say an IRC bot which eats up computing power and RAM. Your server became inaccessible due to the running script, who your regular users blame? You, of course, who else?
Php has some very neat settings you can tweak in order to limit its memory usage, to expose what version of php you are using or not, and others.
Let’s start from the beginning:
asp_tags and short_open_tags, whether to allow the use of asp-like tags like “<%” and short open tags like “<?” instead of “<?php”. I usually set these to off, for one reason: I usually know I set them to off thus I’m not trying to use them in the scripts, but others don’t know. If they manage to upload a script containing these tags it will be much likely useless for them as PHP won’t do anything with them.
expose_php if set to on, will append to the server signature the PHP version you are using. If you didn’t upgrade yet to the latest php, you should set it to off, else it’s up to you what you do. I like to set it off, let’s not allow others what version the server runs.
memory_limit, this is a nice one and you should tweak it to extreme. You can set how much memory would you like to allocate for PHP. If your scripts are not memory eaters, this should be a low value, if they are, a higher value. You can also disable the directive by setting a value of -1, but be aware that with -1, PHP can use as much memory as it wants. I learned that the golden middle is 32, try first that value and if everything is running well, leave at that value.
register_globals, the black sheep :|. Whether to register the $_ENV, $_GET, $_POST, $_SERVER and $_COOKIE variables as global variables. This is covered in too much articles already, i won’t explain why to set it OFF. If you rely on it, stop doing so, learn how to not rely on it or give up coding, period.
file_uploads and upload_max_filesize, whether to allow or not file uploads, and if you allow, what’s the maximum filesize you would like to accept via the HTTP request. The file upload is pretty useless to have it enabled if you don’t use file upload scripts, so if you are not using disable it. Why let Mr. John Hacker to put file-upload scripts on your server?
And these were all the settings I wanted to cover in this post. Consider using them, think carefully before allowing something and before setting something, always.
Here are the settings I recommend:
asp_tags = Off
short_open_tags = Off
expose_php = Off
memory_limit = 32M
register_globals = Off
file_uploads = Off
upload_max_filesize = 2M
Again, much likely others would do it in another way, that’s my way, feel free to use it or not ![]()
Create thumbnails on-the-fly using Imagick
OK, this will be simple. I said it’s simple, more simpler than anyone can expect. Let’s see the overcomplicated code:
<?php $im = new Imagick( 'path/to/your/image.jpg' ); $im->thumbnailImage( 200, null ); header( "Content-Type: image/jpg" ); echo $im; ?>
That was all. Yup.
OK, now step by step:
- We instruct Imagick to work with the file from the parameter.
- Ask nicely Imagick to create a thumbnail: width should be 200px and no fixed height. That’s good, cos Imagick will automatically preserve the aspect ratio, so, bye-bye ugly thumbnails
- Set the correct Content-type header
- echo() the Imagick object which contains the image data, namely $im
That’s all. We saved the world again…
If something is not clear, the comments are open, just ask and will try to answer as soon as possible.
Watermarking images using Imagick
This is a perfect day to show all how easy is to use php’s imagick library to watermark an image.
What you need is to have imagick installed and working correctly, a font you will use to write your website’s name on the image and of course an image you will put the text on.
I will explain each step but for those who don’t want to read, here’s the script:
<?php
$img = 'path/to/your/image.jpg';
$text = 'devoracles.com';
$font = 'path/to/your/yourfont.ttf'
$font_size = '20';
$watermark = array();
$image = new Imagick($img);
$image->setImageFormat("jpg");
$draw = new ImagickDraw();
$draw->setGravity(Imagick::GRAVITY_CENTER);
$draw->setFont($font);
$draw->setFontSize($font_size);
$textColor = new ImagickPixel("black");
$draw->setFillColor($textColor);
$im = new imagick();
$properties = $im->queryFontMetrics($draw,$text);
$watermark['w'] = intval($properties["textWidth"] + 5);
$watermark['h'] = intval($properties["textHeight"] + 5);
$im->newImage($watermark['w'],$watermark['h'],new ImagickPixel("transparent"));
$im->setImageFormat("jpg");
$im->annotateImage($draw, 0, 0, 0, $text);
$watermark = $im->clone();
$watermark->setImageBackgroundColor($textColor);
$watermark->shadowImage(80, 2, 2, 2);
$watermark->compositeImage($im, Imagick::COMPOSITE_OVER, 0, 0);
$image->compositeImage($watermark, Imagick::COMPOSITE_OVER, 0, 0);
header("Content-Type: image/jpg");
echo $image;
?>
And the result is:
Watermark with Imagick
That was all, now a bit of explanation for almost all the lines. The first steps, as you see was to set up some variables which will be used in the script, I think the variable names talk for themselves so I don’t have to explain them. Do I?
Next, I instructed imagick to read the image which will be worked with and specified the type of the image, in the above case a “jpg”.
$image = new Imagick($img);
$image->setImageFormat("jpg");
By the way, if you want to write a script you will pass through all your images, thus all the images are watermarked, first assure that the image you work with is from your server, read, no one can use your script to watermark images on another server. The second thing, you can get the image’s extension using mime_content_type(’path/to/your/image.jpg’). Not the best method I admit, but it’s simple and effective.
Let’s proceed further. I fired up a new class, ImagickDraw(), this will let Imagick know what font to use and also the text’s properties like font size, font color, etc. “Imagick::GRAVITY_CENTER” basically means to center the text on it’s, say, layer. You can play with it and try to set other parameters too, like “Imagick::GRAVITY_SOUTH” which means to place the text on the bottom of the layer, “Imagick::GRAVITY_WEST” to put it on the left side, you get the point.
$draw = new ImagickDraw();
$draw->setGravity(Imagick::GRAVITY_CENTER);
$draw->setFont($font);
$draw->setFontSize($f_size);
$textColor = new ImagickPixel("black");
$draw->setFillColor($textColor);
We get then the parameters of the text we want to put on the image and we add an additional 5 pixels to it, both horizontal and vertical axis. The 5 pixels will be needed later to have place for the drop-down shadow of the text. Then we simply create the canvas and with annotateImage() we put the text on the image.
$im = new imagick();
$properties = $im->queryFontMetrics($draw,$text);
$watermark['w'] = intval($properties["textWidth"] + 5);
$watermark['h'] = intval($properties["textHeight"] + 5);
$im->newImage($watermark['w'],$watermark['h'],new ImagickPixel(”transparent”));
$im->setImageFormat(”jpg”);
$im->annotateImage($draw, 0, 0, 0, $text);
OK, now let’s play a bit with the shadow. First we clone the $im object, which is basically the text we’ll put on the image. The color of the image will be the same as the text’s. And now the interesting stuff: shadowImage(). This will create the drop-down shadow and the parameters tells Imagick how to create that shadow. The usage is:
shadowImage ( float $opacity , float $sigma , int $x , int $y )
So the first parameter sets how opaque the shadow has to be, the last two sets where to drop that shadow. Don’t ask me the second what does, i have no idea ![]()
OK, lastly let’s put our shadow on the image with compositeImage().
$watermark = $im->clone();
$watermark->setImageBackgroundColor($textColor);
$watermark->shadowImage(80, 2, 2, 2);
$watermark->compositeImage($im, Imagick::COMPOSITE_OVER, 0, 0);
The last steps are to put the watermark on the image, set the correct content-type header image/jpg in our case and echo the data. Why do we have to set the content-type header? Well, if I’m not mistaken, this is a php script and the browsers, if not overridden expects text/html, which in our case is not good at all.
$image->compositeImage($watermark, Imagick::COMPOSITE_OVER, 0, 0);
header("Content-Type: image/jpg");
echo $image;
That’s all. It was a bit complicated, but I’d rate its difficulty as ‘medium’ but it’s extremely useful in many cases. This is not JavaScript, so the watermark will be in place whatever the user does. If you are at least a bit familiar with object oriented PHP, I say give it a go and try it.
If something is not clear, the comments are open, just ask and will try to answer as soon as possible.
Migrating from php4 to php5? Pros and cons
July 10, 2008 by Thomas I
Filed under Development, PHP
You think it’s hard? You think you will brake codes?
Why? Probably cos everyone told you so. I tell you something else: You have nothing to fear of.
Maybe the title is a bit unrelated to the post as I can’t seem to find a valid and justified con against it.
Anyway, some thing you should know: PHP 5 was released cos it contains dozens of fixes, upgrades. It wasn’t released cos the team which manages the project had a godly touch or they were drunk and when they woke up all they knew was they have to release a new PHP. No. There was a very good reason, and just for the matter of the argument, when something is free anyway, why wouldn’t you upgrade to a better, improved version? Huh?
The guy who I work with day-by-day, and probably my best friend as well, will say “don’t fix what is not broken”. I say, if something contains bugs, isn’t that thing broken?
So, as I said, you have nothing to fear of, much likely your code will work on the new platform as well, sincerely, when I upgraded to PHP 5 none of my scripts stopped working and there are a few hundred of separate scripts, but just to be sure, let’s check some things.
First of all, i don’t know if you know or not, there are some reserved words you can’t define in your scripts as variables or constants. That’s clear I guess, the “why don’t” has a simple answer… well, two: the first is, cos this is what the developers of PHP said, secondly cos why would you want to define a constant which was previously defined in the PHP core as a function. For example, “echo”, would you redefine it as a constant? I hope you wouldn’t. Also, the same applies to reserved words like “FALSE”, “TRUE”, “NULL”, etc. as these are reserved constants. Have a look on php.net on the reserved keywords list, well, table (link). Also, someone asked me of why “parent” and “self” throws errors when using them in scripts as (re)defined constants. Well, they are inbuilt classes, simple.
Another major change is that array_merge() accepts only arrays. This should be obvious anyway but as of PHP5 it returns NULL. There are some other changes as well, php.net has a more comprehensive list here (link).
And probably that was all you feared of. Really. ![]()







