Site Moved

This site has been moved to a new location - Bin-Blog. All new post will appear at the new location.

Bin-Blog

Multiple Versions of Apache on a Single System

Some times it is necessary to have multiple versions on Apache in your system. The system I am currently working on has two versions of Apache - the first is Apache 1.3 with PHP 4 and MySQL 3. The second apache is Apache 2.0 with PHP 5 and MySQL 5. It is very easy to install multiple versions of Apache in your system - the only limitation is that you can't have all the versions run at once - only one instance of apache must be running at any one point.

I installed multiple versions of apache by using the 'prefix' keyword while compiling the software. To do this, you must have the source tarball of the apache program. Install it using the commands...

./configure --prefix=/usr/local/apache2
make && make install

The prefix keyword is the location where apache will be installed to. When create multiple installation of apache, keep changing this location - so that the previous installation will not be overwritten. You can start apache using the command...

/usr/local/apache2/bin/apachectl start

This command will start the apache server at /usr/local/apache2/ folder. The configuration files for this installation will be at /usr/local/apache2/conf/. Open the folder '/usr/local/apache2/' and you will see the other folders in this directory - like document root, logs etc. You can change the default locations of these folders using the httpd.conf file.

Apache can be stopped using any one of the following commands...

service httpd stop

OR

/usr/local/apache2/bin/apachectl stop

Make sure that the running instance of Apache is stopped before starting a new instance - else a failure message will be shown. You can do this by using the command line...

$ service httpd stop
Stopping httpd:                        [  OK  ]
$ /usr/local/apache2/bin/apachectl start

Or you can use a neat script I created in Tcl/Tk. Save the following code into a file, say, 'ApacheRemote.tcl' and execute it using the command 'wish ApacheRemote.tcl'. NOTE: You must have Tcl/Tk on your system for this to work.


#!/usr/bin/wish
# ApacheRemote V 2.00.A
# http://www.bin-co.com/tcl/

proc showMsg { result } {
 .txt insert end "$result\n"
}

############################### GUI Code ####################################
label .lab_top -text "Apache Remote"
pack .lab_top

frame .frm_common
button .frm_common.but_stop -text "Stop Apache" -command {
 catch { exec "service" "httpd" "stop" } result
 showMsg $result
}
button .frm_common.but_status -text "Status" -command {
 catch { exec "service" "httpd" "status" } result
 showMsg $result
}
pack .frm_common.but_stop .frm_common.but_status -side left
pack .frm_common

frame .frm
button .frm.but_start -text "Start /usr/local" -command {
 catch { exec "/usr/local/apache/bin/apachectl" "start" } result
 showMsg $result
 #exit
}
button .frm.but_start_default -text "Start Default" -command {
 catch { exec "service" "httpd" "start" } result
 showMsg $result
 #exit
}

pack .frm.but_start .frm.but_start_default -side left
pack .frm

#Result Display Area
text .txt 
pack .txt -fill both -expand 1 -side top

bind . <Key-Escape> { exit }

Filed Under...

Read More...

Practical Uses for mod_rewrite

I have explained how to use mod_rewrite to create structured URLs and about the most used mod_rewrite directives. Now to see some practical use of mod_rewrite in various situations.

URL Change

Good URLs don't change - but sometimes you have to do it. Move one file from its previous location to a new one. Even I have done it - I moved my site from http://www.geocities.com/binnyva/ to Bin-Co, OpenJS and BinnyVA. When you make such a move, you want to make sure that your visitors move with you. This can be done using mod_rewrite.

Lets say you are moving the a page from http://www.domain.com/oldfile.html to http://www.domain.com/stuff/newfile.html. Now when ever someone visits the oldfile.html file, they get a 404 error. You can use the following script to make sure that all visitors to the old page is redirected to the new one...


RewriteRule ^oldfile\.html$ http://www.domain.com/stuff/newfile.html [R]

Escape the Slashdot Effect

Slashdot Effect is a situation when a link to a smaller site appear in a heavy traffic site like Slashdot or Digg. Due to the huge traffic this brings, many site with low bandwidth will crumble. One method to prevent this is to deny access to all visitors who have come from the high traffic site(let us assume it is slashdot.org). There are other methods also(eg. mirroring). So you have two requirements...

  • Deny access to all from slashdot.org
  • Allow access to all others.

RewriteCond %{HTTP_REFERER} ^http://slashdot\.org [NC,OR]
RewriteCond %{HTTP_REFERER} ^http://www\.slashdot\.org [NC]
RewriteRule ^.*$ /denied.html [F]

The logic behind the above code goes somewhat like this...

RewriteCond %{HTTP_REFERER} ^http://slashdot\.org [NC,OR] - If the visitor have come from http://slashdot.org OR,
RewriteCond %{HTTP_REFERER} ^http://www\.slashdot\.org [NC] - if he have come from http://www.slashdot.org
RewriteRule ^.*$ /denied.html [F] - Show a 'Forbidden' message.

Prevent Image Hot Linking

Hot Linking is when someone links to a file from our server directly in a way that our bandwidth will be used when anyone visits the other person's site. For example, let say we have a cool picture called, say, 'cool_picture.jpg'. We have kept it in 'http://www.our-domain.com/pictures/cool_picture.jpg'. Now some guy from another site, likes this picture and decided to show the image in his site - so he uses the HTML code...

<img src="http://www.our-domain.com/pictures/cool_picture.jpg" />

So whenever someone visits this guys site, the image is fetched from our server - thus increasing our bandwidth costs. For this reason, this method is also known as bandwidth theft.

So how do we prevent it? The same method used in the last situations - look at the referrer, and if it is not ours, show a forbidden message.


RewriteCond %{HTTP_REFERER} !^$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www\.our-domaincom/\.org [NC]
RewriteCond %{HTTP_REFERER} !^http://our-domain\.com/\.org [NC]
RewriteRule ^.*$ /denied.html [F]

Using Different Files for Different Browsers

As all good web designers know, different browsers have different ways of parsing the same CSS file. So your masterpiece in IE will look like something the cat brought in Firefox. One simple way of solving this problem is to use mod_rewrite and provide a different css file based on the visitor's browsers. Lets say we have a CSS file called 'style.css'. But for IE, we have created a special CSS file called 'style_ie.css'. For firefox, we have yet another CSS file called 'style_ff.css'. Our pages uses the HTML code...

<link href="style.css" type="text/css" rel="stylesheet" />

Now to provide different files based on the user agent of the visitor...


RewriteCond %{HTTP_USER_AGENT} ^Mozilla/(.*)MSIE
RewriteRule (.*)style.css$ $1style_ie.css [L]

RewriteCond %{HTTP_USER_AGENT} ^Mozilla/(.*)Firefox
RewriteRule (.*)style.css$ $1style_ff.css [L]

For more solutions to situations like this, see the URL Rewriting Guide from Apache Docs.

Read More...

mod_rewrite Directives - RewriteCond and RewriteRule

In the last post on mod_rewrite, I used a basic example from http://del.icio.us to explain the working of the mod_rewrite module. Now I will try to explain the various options available in mod_rewrite.

RewriteEngine

This directive turns the rewrite engine on or off.
Syntax : RewriteEngine (on|off)
Example: RewriteEngine on

If you wish to disable rewriting, use RewriteEngine off instead of commenting out all the other lines. Since the rewrite engine is off by default, you have to turn it on every time you wish to use the mod_rewrite module. So the first line will be always...

RewriteEngine on

RewriteCond

The 'if' statement of mod_rewrite. The commands given below a RewriteCond line will be evaluated only if this returns a true value.
Syntax : RewriteCond TestString ConditionPattern [Flags]
Example: RewriteCond %{HTTP_REFERER} ^http://www.google.com [NC]

The RewriteCond has two arguments plus an optional third one.

TestString

There are three main types of strings that can be used in TestString part of the directive.

RewriteRule Regular Expression Captures - $N

Here N is a number between 0 and 9. If you use the string $1 in the TestString part of the RewriteCond directive, it will be replaced by the first capture from the regular expression for the corresponding RewriteRule - ie. the RewriteRule that will follow this condition.

RewriteCond Regular Expression Captures - %N

For this string, N is a number between 1 and 9. If you use the $1 in the TestString part of the RewriteCond directive, it will be replaced by the first capture from the regular expression for the corresponding RewriteCond - ie. the RewriteCond above this condition.

Server Variables

This are given in the format...

%{VARIABLE_NAME}

The most commonly used Server variables are given below. To see the full list of available server variables, see the apache manual page on mod_rewrite.

HTTP_USER_AGENT
A string containing the name of the browser the visitor is using. Eg 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8) Gecko/20051111 Firefox/1.5'
HTTP_REFERER
The URL of the page from where the current visitor came form.
REMOTE_ADDR
The IP of the visitor.
REMOTE_HOST
The visitor's host name.
SCRIPT_FILENAME
The filename of the page that was requested.
QUERY_STRING
The queries that was passed to the page.
REQUEST_URI
The called URI
REQUEST_FILENAME
The path of the file - ie. the URL of the page without the domain.

CondPattern

CondPattern is a regular expression - with some extra features...

!
You can prefix the '!' operator to any condition pattern to make RewriteCond return true if the pattern does NOT match.
<CondPattern
Compares the two string and return true if the TestString is lexically lower than the given pattern
>CondPattern
Return true if the TestString is lexically greater than the given pattern.
=CondPattern
Return true if the TestString and pattern are equal.
-d
Return true if TestString is a directory(folder)
-f
Return true if TestString is a file

Flags

Flags are given inside squire brackets([FLAGS]). Two flags are available for RewriteCond...
NC
No Case - the case is ignored in matching.
OR
Use this to combine two consecutive RewriteCond with a logical OR - if this is not given, an AND condition is implied

RewriteRule

Provides the rules for rewriting URLs.
Syntax : RewriteRule Pattern Substitution [Flags]
Example: RewriteRule ^/user/(.*) get_data.php?user=$1 [NC]

This is were the URL rewriting actually happens. This directive has two arguments plus an optional third one.

Pattern

The pattern is a perl compactable regular expression used to match the current URL. You can capture this by using the parenthesis ie. '(' and ')'. All text between these will be captured and could be used in the Substitution part of RewriteRule.

Substitution

The actual URL that is to be called is given here. This involves the path of the script and the parameters that should be given to it. This supports all the special features of TestString(like $N, %N and Server variables) besides plain text. It also supports the '!','<','>' and '=' prefix operators as we saw in the CondPattern.

Flags

Flats are the third argument to the RewriteRule directive. This should be given inside square brackets([FLAGS]). Flags is a comma-separated list of these flags...

R - Redirect
The URL in the address bar will change if this flag is used - as the server will use the HTTP response of 302 (MOVED TEMPORARILY) when redirecting the page.
F - Forbidden
Using this flag immediately sends a HTTP response of 403 (FORBIDDEN). Use this flag with appropriate RewriteConds to conditionally block some URLs - for example image hot linking from external sites.
G - Gone
Sends a HTTP response header of 410 (GONE). This flag is used to mark pages which no longer exist as gone.
L - Last
Stop the rewriting process in this rule and don't apply any more rules. Think Perl's last command or the break command of C.
NC - No Case
Makes the Pattern case-insensitive.
QSA - Query String Append
This flag will append the query string from the current URL to the substitution string.

Eg.

RewriteRule ^/user/(.*?)/ get_data.php?user=$1 [NC,QSA]

Please keep in mind that this is just the most commonly used Flags - for the full list, go to the apache manual page on mod_rewrite.

Happy rewriting...

Read More...

mod_rewrite module for Apache

Along with the ability to password protect folders on the web server, another major use of the .htaccess file is the ability to 'rewrite' the URL. This will let you create more structured and easy to remember URLs. This module will redirect the user to one page while showing another URL in the address bar.

Application of mod_rewrite

Used in del.icio.us

This method is used to great effect in sites like Wikipedia and Del.icio.us. For example let us take a del.icio.us URL...

http://del.icio.us/binblog/javascript+ajax

This does not mean that there is a folder called binblog in the root of del.icio.us site. Nor does this mean that there is a file with the name 'javascript+ajax'. This trick is done using URL manipulation. In this example, the URL can be split into three parts....

http://del.icio.us/binblog/javascript+ajax
         ^^^         ^^^          ^^^           
      Site URL     User ID        Tags
    del.icio.us    binblog    javascript and ajax

The actual URL being called may be something like...

http://del.icio.us/show_bookmarks.php?format=html&user=binblog&tags=javascript+ajax

So how do the user see one URL and the server use another? That is the subtle art of URL manipulation. Before we see the details of this method, a small warning. You may not be able to get the concept at the first glance - it may be sometime before you understand mod_rewrite completely. So - don't give up, grasshopper. As one person puts it...

Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo.
Brian Moore

Before going any further, let me also warn you that you must know regular expression to understand how this works. OK, now we can go further.

Using mod_rewrite

First we need a regular expression to extract the necessary elements from the URL. We will ignore the site URL(http://del.icio.us/) part. The URL is

http://del.icio.us/binblog/javascript+ajax

The Regualar Expression is...

^([^\/]+)\/([^\/]+)$

The extracted strings will be...

$1 = binblog (First Match)
$2 = javascript+ajax (Second Match)

To make this effect using the mod_rewrite module, open the .htaccess file your favorite editor and type in the following lines...

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^([^\/]+)\/([^\/]*)$ show_bookmarks.php?format=html&user=$1&tags=$2
</IfModule>

Now to test this, create a file called 'show_bookmarks.php' in the document root of your web server. I hope that I don't have to tell you that you need a LAMP setup to do this. You will need atleast Apache and PHP to do this.

After creating the 'show_bookmarks.php' file, enter the following code into it...

<pre><?php print_r($_GET); ?></pre>

Since this is just a test, I did not bother with all the HTML tags like <html>,<body> etc. But if you are a sticker for the rules, go ahead and make the full document.

Next, open this URL in the browser...

http://localhost/show_bookmarks.php?format=html&user=binblog&tags=javascript+ajax

You should get this result - the contests of the GET request...

Array
(
    [format] => html
    [user] => binblog
    [tags] => javascript ajax
)

Now try it with the URL...

http://localhost/binblog/javascript+ajax

If everything went well, this also should have the same output - that is...

Array
(
    [format] => html
    [user] => binblog
    [tags] => javascript ajax
)

Explanation

IfModule

<IfModule mod_rewrite.c>

This is an if condition - the code inside these tags will only be executed if the mod_rewrite module is loaded with apache.

RewriteEngine

RewriteEngine On

The 'RewriteEngine' directive enables or disables runtime rewriting engine. Here we are turning on the re-write Engine. Use the value 'off' if you want to turn of all rewriting.

RewriteRule

RewriteRule ^([^\/]+)\/([^\/]*)$ show_bookmarks.php?format=html&user=$1&tags=$2

This is the important statement. The proper syntax for RewriteRule directive is given below...

RewriteRule Pattern Substitution

The Pattern is a perl compactable regular expression.

Substitution part of the rewriting rule is the string which replaces the original URL for which Pattern has matched. You can use $n to insert regular expression captured strings - $1 is the first capture, $2 will be the second and so on.

One than one line of RewriteRule can be used. The order of useage is important as the second line will use the result of the first substitution as its input

</IfModule>

End of the if condition we started earlier.

Conditions

Some of you must have already seen a big problem in this approach. To see this problem, create a folder called, say, 'data' in your document root. Now create a file called 'something.txt' in this folder. Then try to access this folder from a browser using the URL.

http://localhost/data/

Now you see the problem, don't you? The above URL will result in the output...

Array
(
    [format] => html
    [user] => data
    [tags] => 
)

Our mod_rewrite rules have captured the URL of a valid file along with the other URLs. To solve this problem, we will use a feature of mod_rewrite called Conditions. Insert these lines in the .htaccess file.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\/]+)\/([^\/]*)$ show_bookmarks.php?format=html&user=$1&tags=$2
</IfModule>

See the line RewriteCond %{REQUEST_FILENAME} !-d? This will make sure that the requested file is not a directory. The line RewriteCond %{REQUEST_FILENAME} !-f will prevent files from being caught by the rewrite rule. The algorithm of these statements will look something like this...

if( 'Requested Filename' IS NOT Directory ) {
 if( 'Requested Filename' IS NOT File ) {
  Rewrite the URL.
 }
}

I hope you got the logic behind this - it took me a while to understand. Anyway, as I said earlier, don't be dissappointed if you don't get it at the first try - there is a lot of black magic involved.

Now try to access the file we created a little while back...

http://localhost/data/something.txt

You will see that it works perfectly(hopefully). Now try...

http://localhost/data/

Again the folder is being accessed. Now try a URL that must be re-written...

http://localhost/binblog/javascript+ajax

If all goes well, this URL will be caught by our system and will be redirected to the show_bookmarks.php file.

More about mod_rewrite in the next post(mod_rewrite Directives - RewriteCond and RewriteRule).

Read More...

New Blog - BinnyVA

After much waiting I finally have a blog in WordPress. So currently I have two blogs - Bin-Blog and BinnyVA. I plan to use this blog(Blogger) as a professional blog and the other one(WordPress) as a more personal one. That blog will have a lower post frequency - around one per week. So from now on, all post that would have been tagged with 'Personal' will be kept in the opther blog - this blog will be used exclusively for professional content.

Another plus side of using that blog is that I can get an opertunity to sudy Wordpress - one of the most succesful PHP project of these times. Knowing what makes it tick will do me much good - I will be able to port my many programs as WordPress plugins. I actually plan to do this with Online Sudoku.

So this post will be the last post in this blog to be tagged with 'personal'. If you want more posts of that genre, go over to my new blog.

Filed Under...

Read More...

Football Vs JavaScript

The Stars

Football

  • Zinedine Zidane
  • Ronaldo
  • Wayne Rooney
  • Christano Ronaldo
  • Thierry Henry
  • And more...

JavaScript

The Teams

Football

  • Real Madrid
  • Manchester United
  • ...

JavaScript

  • Yahoo
  • Google
  • ...

Why Football is better than JavaScript

Football has a fixed number of Referees and Lines men.
In JavaScript, we get a new referee every time a new browser is made and a new lines man every time a new version is released.

In football, if the referee calls a goal, it is a goal and if he calls it a foul it is a foul.
In JavaScript, one referee will call an event a goal while another will call the same event a foul.

In football, if you made a foul, the referee will send you out.
In JavaScript, if that was the case, document.write and eval would be a thing of the past.

In football, if some players are playing a standard game, no referee will go around trying to make their lives a living hell.
In JavaScript, IE.

Ronaldo makes more money and more fans than PPK can ever hope for.

Why JavaScript is better than Football

Anyone who knows JavaScript can compete in the World Wide Web cup.
Anyone who knows Football can dream of compeating in the World cup.

In football, the referees will only check how you play - they don't help you.
In JavaScript, Firefox with some extensions to help you to 'play' better.

Using libraries in JavaScript is like having Robotic legs in football. Using these you can run faster, shoot straighter and more accurately than you could hope for using your natural limbs. And most of the referee will stay happy as long as you use these robotic legs.

Filed Under...

Read More...

Password protecting a folder using .htaccess

The password protection feature of '.htaccess' can be used to secure entire folders or files on your web server. This is much easier than having to code the entire authentication system by hand.

This feature had been a life saver for me on several occasions. One time a project I was working on was overdue and I still had to do the admin side of the system. I did not have the time to create an authentication system at that stage. So I made a .htaccess file and used it to password protect the whole admin folder. What would have take me hours was over in a few seconds. .htaccess saves the day. Afterwards, I had to code the authentication system myself in PHP because the project needed some features like multiple admins, password retrieval etc. Anyway, it saved me from work the first day.

Try it out...

Let's say that we are trying to protect the '/var/www/htdocs/top_secret' folder. We will make this folder inaccessible to all but our user 'james_bond'. He will access it using the highly secure and unguessable password 'secret'.

  • Username : james_bond
  • Password : secret

First we go to the folder we are protecting(ie '/var/www/htdocs/top_secret') and create the .htaccess file in this directory. Put these lines in the .htaccess file...

AuthUserFile /var/www/safe/.htpasswd
AuthGroupFile /dev/null
AuthName TopSecret
AuthType Basic

require user james_bond

Open the location /var/www/safe/(create this folder if it doesn't exist) and create a file called '.htpasswd' with this line...

james_bond:tbuUG6kXINUbo

Fire up your favorite browser(it should be Firefox - anything less is sacrilege) and point it to the location http://127.0.0.1/top_secret. If all went well, you should see a Username/Password prompt. You will only be allowed in if you provide the valid username and password(james_bond/secret).

Explanation

.htaccess

AuthUserFile /var/www/safe/.htpasswd
AuthGroupFile /dev/null
AuthName TopSecret
AuthType Basic

require user james_bond

The first line says the location of the file with the username and password. For security reasons, this file is kept outside the document root. We don't want any yahoos with a web browser accessing our .htpasswd file. You will have to change this to the location where you kept your .htpasswd file.

The second line is the full path of a text file containing the list of user groups that should be allowed in. This line is not relevent in our context as we don't have any groups - we are just pointing it to a null file.

The third line 'AuthName TopSecret' is the name of the area you are protecting. You can change this as you see fit. This text will appear in the prompt for the username and password - like this...

Enter username and password for "TopSecret" at ...

The fourth line 'AuthType Basic' is used because we are using the basic authentication scheme.

The last line 'require user james_bond' says that only user 'james_bond' can enter. If you have multiple users in the .htpasswd file, you can use the line...

require valid-user

Now any user in the .htpasswd file can enter.

.htpasswd

This file is a list of all users in the format... <USERNAME>:<PASSWORD>

The username is given in plain text while the password is encrypted using the 'crypt' function. You can generate this password using the 'htpasswd' command in linux. For example running the command...

htpasswd -c .htpasswd james_bond

will ask for a password. Once the password is provided, the program will create the file '.htpasswd' in the current folder with the user 'james_bond' and the given password.

If you are not on linux or if you are afraid of typing commands in the console, you can create the password using one of the many online password generators out there...

Or if you want to create the password yourself, the PHP code is given below...

$username = 'binny';
$password = '';

//Create a random salt
$chars = str_shuffle( "012456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+=-`[];',./\{}:\"<>?|" );
$salt  = $chars[rand(0,strlen($chars))] . $chars[rand(0,strlen($chars))];

//Print the username:password pair
print $username . ':' . crypt($password,$salt);

If you don't understand the above code, just use this...

crypt('password');

This will return the encrypted password. For more information, see the PHP manual entry on crypt.

Problems

No matter what you do, you can't get the username/password prompt. You just go to the page directly. This is because your apache server is not reading the .htaccess file. Open the server configuration file(usually /etc/httpd/conf/httpd.conf). Search for the text 'AllowOverride'. Find the AllowOverride setting for the document root folder(something like /var/www/htdocs). Change this line to...

AllowOverride All

This setting will make sure that the apache server reads and uses the .htaccess file. After making this change, restart the server with the command 'service httpd restart'.

For more information, see the apache documentation.

Filed Under...

Read More...

Status Update

Since it has been some time since the last update, I am thinking that I would post another status update. I plan to do this once every six months. This is basically the current status of my various sites and projects.

Before I start, I want to congratulate Jansan on his new blog - Techno WeBlog. I am hoping that this will encourage Gladwin to update his site. His site has been around for some time now - but the meaning of the word 'content' is still foreign to him.

Sites

Bin-Co.com

This is my site about Web Development and Scripting Languages. The primary languages of intrest are...

I plan to add other languages like Ruby and Python soon.

OpenJS

This site has not picked up yet. I still have a lot of time to fill it up with content. I recently posted a published a new version of jx Ajax library there. Be sure to check out the explanation page - I put a lot of work into it.

Bin-Blog

Going steady at around 50 unique visits per day. Not much improvement over the last two months. May be because the posting frequency went down. I try to post once every three days.

BinnyVA.com

My new site - I plan to use this as a personal site. I will be porting the BinnyVA site to it. I will be able to make some subdomains for all the sub sites. Also, I plan to implement my old idea of moving to WordPress here - I am thinking about using a WordPress blog at, say, http://blog.binnyva.com/(don't exist right now). My plan is to use it for more personal blogging - about my life, Kerala, etc.

The Oldies

The old sites like my geocities and tripod sites still exists. The geocities site still gets a lot of traffic - most of the google SERPs are still pointing to these old pages.

Filed Under...

Read More...

Subscribe to : Posts