You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by ma...@sergeant.org on 2006/08/09 04:38:00 UTC

[SVN] [62] mime plugins

Revision: 62
Author:   matt
Date:     2006-08-09 02:37:33 +0000 (Wed, 09 Aug 2006)

Log Message:
-----------
mime plugins

Modified Paths:
--------------
    trunk/lib/AxKit2/Client.pm
    trunk/lib/AxKit2/Connection.pm
    trunk/lib/AxKit2/HTTPHeaders.pm
    trunk/lib/AxKit2/Plugin.pm

Added Paths:
-----------
    trunk/plugins/fast_mime_map
    trunk/plugins/magic_mime_map

Modified: trunk/lib/AxKit2/Client.pm
===================================================================
--- trunk/lib/AxKit2/Client.pm	2006-08-07 21:50:51 UTC (rev 61)
+++ trunk/lib/AxKit2/Client.pm	2006-08-09 02:37:33 UTC (rev 62)
@@ -224,4 +224,18 @@
     }
 }
 
-1;
\ No newline at end of file
+sub hook_mime_map {
+    my $self = shift;
+    my ($ret, $out) = $self->run_hooks('mime_map', @_);
+    if ($ret == DECLINED) {
+        return 1;
+    }
+    elsif ($ret == OK) {
+        return 1;
+    }
+    else {
+        # TODO: output error stuff?
+    }
+}
+
+1;

Modified: trunk/lib/AxKit2/Connection.pm
===================================================================
--- trunk/lib/AxKit2/Connection.pm	2006-08-07 21:50:51 UTC (rev 61)
+++ trunk/lib/AxKit2/Connection.pm	2006-08-09 02:37:33 UTC (rev 62)
@@ -165,6 +165,8 @@
     
     $self->hook_uri_to_file($hd, $hd->request_uri)
     &&
+    $self->hook_mime_map($hd, $hd->filename);
+    &&
     $self->hook_access_control($hd)
     &&
     $self->hook_authentication($hd)
@@ -268,4 +270,4 @@
     $_->close("Timeout") foreach @to_close;
 }
 
-1;
\ No newline at end of file
+1;

Modified: trunk/lib/AxKit2/HTTPHeaders.pm
===================================================================
--- trunk/lib/AxKit2/HTTPHeaders.pm	2006-08-07 21:50:51 UTC (rev 61)
+++ trunk/lib/AxKit2/HTTPHeaders.pm	2006-08-09 02:37:33 UTC (rev 62)
@@ -16,6 +16,7 @@
             'uri',          # scalar; request URI (if GET request)
             'file',         # scalar; request File
             'querystring',  # scalar: request querystring
+            'mime_type',    # scalar: request file mime type
             'params',       # parsed params
             'paramkeys',    # all parsed param keys
             'type',         # 'res' or 'req'
@@ -319,6 +320,12 @@
     return $self->{file};
 }
 
+sub mime_type {
+    my AxKit2::HTTPHeaders $self = shift;
+    @_ and $self->{mime_type} = shift;
+    return $self->{mime_type};
+}
+
 sub version_number {
     my AxKit2::HTTPHeaders $self = shift;
     @_ and $self->{vernum} = shift;
@@ -538,4 +545,4 @@
 }
 
 
-1;
\ No newline at end of file
+1;

Modified: trunk/lib/AxKit2/Plugin.pm
===================================================================
--- trunk/lib/AxKit2/Plugin.pm	2006-08-07 21:50:51 UTC (rev 61)
+++ trunk/lib/AxKit2/Plugin.pm	2006-08-09 02:37:33 UTC (rev 62)
@@ -10,7 +10,7 @@
 our @hooks = qw(
     logging config pre-connection connect post_read_request
     body_data uri_translation access_control authentication authorization
-    fixup xmlresponse response disconnect error
+    fixup mime_map xmlresponse response disconnect error
 );
 our %hooks = map { $_ => 1 } @hooks;
 
@@ -133,4 +133,4 @@
     die "eval $@" if $@;
 }
 
-1;
\ No newline at end of file
+1;

Added: trunk/plugins/fast_mime_map
===================================================================
--- trunk/plugins/fast_mime_map	2006-08-07 21:50:51 UTC (rev 61)
+++ trunk/plugins/fast_mime_map	2006-08-09 02:37:33 UTC (rev 62)
@@ -0,0 +1,111 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+fast_mime_map - File extension to MIME type mapping
+
+=head1 SYNOPSIS
+
+    Plugin fast_mime_map
+    
+    # Optionally:
+    MimeMap   .foo   application/foo
+
+=head1 DESCRIPTION
+
+This module attempts to map filenames to MIME types without doing any I/O. It
+is purely based on file extensions. If you need to introspect the contents of
+the file to get the MIME type then use the magic_mime_map plugin.
+
+There is a default mapping. Best to view the source to find out what it is.
+Anything specified in the C<MimeMap> config directives overrides the default
+mappings.
+
+The default MIME type is B<text/html> (in case an extension cannot be found in
+your custom mappings nor the default mappings). To override the default mapping:
+
+    MimeMap   #default   application/octet-stream
+
+(Or whatever default you would prefer).
+
+=cut
+
+sub init {
+    my $self = shift;
+    
+    $self->register_config('MimeMap', sub { $self->add_mime_map(@_) });
+}
+
+sub add_mime_map {
+    my ($self, $conf, $ext, $type) = @_;
+    
+    my $key = $self->plugin_name . '::mime_map';
+    my $map = $conf->notes($key) || {};
+    $map->{$ext} = $type;
+    $conf->notes($key, $map);
+}
+
+sub mime_map {
+    my $self = shift;
+    my $conf = $self->config;
+    my $key = $self->plugin_name . '::mime_map';
+    return $conf->notes($key) || {};
+}
+
+my %default_types = (
+        '.html'     => 'text/html',
+        '.htm'      => 'text/html',
+        '.txt'      => 'text/plain',
+        '.gif'      => 'image/gif',
+        '.jpeg'     => 'image/jpeg',
+        '.jpg'      => 'image/jpeg',
+        '.png'      => 'image/png',
+        '.tiff'     => 'image/tiff',
+        '.css'      => 'text/css',
+        '.csv'      => 'text/csv',
+        '.rtf'      => 'text/rtf',
+        '.xml'      => 'text/xml',
+        '.mpg'      => 'video/mpeg',
+        '.avi'      => 'application/octet-stream',
+        '.eml'      => 'message/rfc822',
+        '.mp2'      => 'audio/mpeg',
+        '.mp3'      => 'audio/mpeg',
+        '.mp4'      => 'audio/mp4',
+        '.js'       => 'application/ecmascript',
+        '.doc'      => 'application/msword',
+        '.gz'       => 'application/octet-stream',
+        '.xhtml'    => 'application/xhtml+xml',
+        '.dtd'      => 'application/xml-dtd',
+        '.xls'      => 'application/ms-excel',
+        '.ppt'      => 'application/ms-powerpoint',
+        '.pps'      => 'application/ms-powerpoint',
+        '.rpm'      => 'application/octet-stream',
+        '.pdf'      => 'application/pdf',
+        '.ps'       => 'application/postscript',
+        '.rdf'      => 'application/rdf+xml',
+        '.smil'     => 'application/smil+xml',
+        '#default'  => 'text/html',
+    );
+
+sub hook_mime_map {
+    my ($self, $hd, $filename) = @_;
+    
+    my $custom_map = $self->mime_map;
+    
+    $filename =~ s/.*\///;
+    my @parts = split(/\./, $filename);
+    while (@parts) {
+        my $name = join('.', @parts);
+        if (exists($custom_map->{$name})) {
+            $hd->mime_type($custom_map->{$name});
+            return OK;
+        }
+        if (exists($default_types{$name})) {
+            $hd->mime_type($default_types{$name});
+            return OK;
+        }
+        shift @parts;
+    }
+    $hd->mime_type($custom_map->{'#default'} || $default_types{'#default'});
+    return DECLINED;
+}

Added: trunk/plugins/magic_mime_map
===================================================================
--- trunk/plugins/magic_mime_map	2006-08-07 21:50:51 UTC (rev 61)
+++ trunk/plugins/magic_mime_map	2006-08-09 02:37:33 UTC (rev 62)
@@ -0,0 +1,33 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+magic_mime_map - Use File::MMagic to set MIME type
+
+=head1 SYNOPSIS
+
+    Plugin magic_mime_map
+
+=head1 DESCRIPTION
+
+This plugin uses C<File::MMagic> to set the MIME type of the request. This has
+the potential to open the file and be a synchronous action, so use with
+caution.
+
+=cut
+
+use File::MMagic;
+
+my $mm = File::MMagic->new();
+
+sub hook_mime_map {
+    my ($self, $hd, $filename) = @_;
+    
+    my $ct = $mm->checktype_filename($file) || return DECLINED;
+    $hd->mime_type($ct);
+    
+    # we return DECLINED here, even though we have definitively set the MIME
+    # type because another MIME plugin may wish to read this value and set
+    # it to something else.
+    return DECLINED;
+}