package EnsEMBL::Web::Apache::Static;
#############################################################
## mod_perl static files handler
#############################################################
use strict;
# use Apache::File ();
# use Apache::Log ();
use MIME::Types ();
use Compress::Zlib ();
use HTTP::Date ();
use Data::Dumper;
use Apache2::Const qw(:common :methods :http);
use Apache2::Util ();
use SiteDefs qw(:ALL);
use EnsEMBL::Web::RegObj;
use EnsEMBL::Web::Root;
use EnsEMBL::Web::RegObj;
use EnsEMBL::Web::Cache;
our $MEMD = EnsEMBL::Web::Cache->new;
our $MIME = MIME::Types->new();
our @HTDOCS_TRANS_DIRS;
BEGIN {
foreach my $dir( @SiteDefs::ENSEMBL_HTDOCS_DIRS ){
if( -d $dir ) {
if( -r $dir ) {
push( @HTDOCS_TRANS_DIRS, "$dir/%s" );
} else {
warn "ENSEMBL_HTDOCS_DIR $dir is not readable\n";
}
} else {
warn "ENSEMBL_HTDOCS_DIR $dir does not exist\n";
}
}
};
## TODO:
## cahrset + utf8
## Not modified!
## restrictions
## error pages!
## PLUGINS!!!!!!!!!!!!
sub handler {
my $r = shift;
my $uri = $r->uri;
my $content = $MEMD && $MEMD->get($uri) || undef;
if ($content) {
$r->headers_out->set('X-MEMCACHED' => 'yes');
$r->headers_out->set('Accept-Ranges' => 'bytes');
$r->headers_out->set('Content-Length' => length($content));
$r->headers_out->set('Cache-Control' => 'max-age=' . 60*60*24*30);
$r->headers_out->set('Expires' => HTTP::Date::time2str( time + 60*60*24*30 ));
$r->content_type(mime_type($uri));
$r->print($content);
return OK;
} else {
my $file = $uri;
return FORBIDDEN if $file =~ /\.\./;
## Not temporary static files are pluggable:
unless ($file =~ s/^$ENSEMBL_TMP_URL_IMG/$ENSEMBL_TMP_DIR_IMG/g + $file =~ s/^$ENSEMBL_TMP_URL/$ENSEMBL_TMP_DIR/g) {
## walk through plugins tree and search for the file in all htdocs dirs
foreach my $dir (@HTDOCS_TRANS_DIRS) {
my $f = sprintf( $dir, $file );
if (-d $f or -r $f) {
$file = $f;
last;
}
}
}
## /
if (-e $file) {
{
local $/=undef;
open FILE, $file or die "Couldn't open file: $!";
$content = <FILE>;
close FILE;
}
$MEMD->set($uri, $content) if $MEMD;
my @file_info = stat($file);
$r->headers_out->set('Last-Modified' => HTTP::Date::time2str( $file_info[9] ));
$r->headers_out->set('Accept-Ranges' => 'bytes');
$r->headers_out->set('Content-Length' => length($content));
$r->headers_out->set('Cache-Control' => 'max-age=' . 60*60*24*30);
$r->headers_out->set('Expires' => HTTP::Date::time2str( time + 60*60*24*30 ));
$r->content_type(mime_type($uri));
$r->print($content);
return OK;
}
}
return DECLINED;
} # end of handler
sub mime_type {
my $file = shift;
my $mimeobj = $MIME->mimeTypeOf($file);
return $mimeobj ? $mimeobj->type : 'text/plain';
}
1;