apache

Rewriting URLs to use www with permanent redirect

The following rewrite rule enables all requests to a site to go through via its www URL, theoretically improving search engine 'optimization' (if there is such a thing).

The important thing here is that any file or directory request following the url is kept during the redirect (I've seen poor rewrites on sites that just redirect from http://whatever.com to the front page and the user loses their path to the link they clicked on once already).


RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^.*$ http://www.example.com%{REQUEST_URI} [R=permanent,L]

Perl script to check website with regex, alert if failure

Wrote this script today using the WWW::Curl::Easy example.

Background: Recently eaccelerator screwed up a dev server so that while Apache didn't die, php scripts weren't parsing, and I got no alerts.

This script parses a php script using curl, which contains a basic 'hello()' function that prints hello out.

The perl script checks the output for 'hello' and if it doesn't find it, it sends me an e-mail (it also sends me an SMS using our Clickatell account, but I'm not giving you the credentials, silly.)

#!/usr/bin/perl
#
# Checks a php script using curl and if there is a
# problem, e-mail me
#
use strict;
use WWW::Curl::Easy;
my $url = "http://localhost/test.php";
# Init the curl session
my $curl= WWW::Curl::Easy->new() or die "curl init failed!\n";
# Give curl the URL to use
$curl->setopt(CURLOPT_URL, $url);
# a subroutine which is called for each 'chunk' as the
# file is received.
sub body_callback {
    my ($chunk,$context)=@_;
    # add the chunk we received to the end of the array we've been given
    push @{$context}, $chunk;
    return length($chunk); # OK
}
# configure which subroutine to call when some data comes in
$curl->setopt(CURLOPT_WRITEFUNCTION, \&body_callback);
my @body;
# tell the subroutine which array to put the data into
$curl->setopt(CURLOPT_FILE, \@body);
if ($curl->perform() != 0) {
    print "Failed ::".$curl->errbuf."\n";
};
my $output = join("",@body);
# Check if we got 'hello' out of the php script. If we did, ignore it
if ($output=~ m/hello/i) {
}
else {
        #sms me, incidentally this is done with curl too, so I create another instance of WWW::Curl::Easy
        my $alert_url = "http://the-clickatell-api-command-to-sms-me";
        my $curl_alert= WWW::Curl::Easy->new() or die "curl init failed!\n";
        $curl_alert->setopt(CURLOPT_URL, $alert_url);
        $curl_alert->setopt(CURLOPT_WRITEFUNCTION, \&body_callback);
        $curl_alert->setopt(CURLOPT_FILE, \@body);
        if ($curl_alert->perform() != 0) {
            print "Failed ::".$curl_alert->errbuf."\n";
        };
        # send me an e-mail now, using Sendmail
        unless(open (MAIL, "|/usr/sbin/sendmail -t")) {
                print "error.\n";
                warn "Error starting sendmail: $!";
        }
        else {
                print MAIL "From: web\@the-server.com\n";
                print MAIL "To: miguel\@example.com\n";
                print MAIL "Subject: PHP problem on the server\n\n";
                print MAIL "The server has stopped parsing php! Panic! Panic!";
                close(MAIL) || warn "Error closing mail: $!";
        }
}

Debian, Apache, SSL, Multiple Virtual Hosts

After much trial and grief, I've finally nailed how to have multiple SSL virtual hosts running on Apache on our Debian servers alongside non-SSL hosts.

In the 'default' apache config, put:


NameVirtualHost *:80
NameVirtualHost *:443

Then for each virtual host config that you ever create, the opening VirtualHost tag MUST include the relevant port as follows:


< VirtualHost *:443 > (for SSL site)
< VirtualHost *:80 > (for standard site)

Note that I have added a space between the < > tags due to Drupal attempting to format as HTML. Remove the spaces in your config file.

You must then have the ServerName specified inside each Virtual Host.

Somehow it didn't seem that easy at the start!