Showing with 193 additions and 115 deletions.
  1. +4 −0 Changes
  2. +68 −25 lib/Catalyst/Plugin/Static/Simple.pm
  3. +33 −33 t/04static.t
  4. +32 −12 t/11serve_static.t
  5. +56 −45 t/lib/TestApp/Controller/Root.pm
4 changes: 4 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Revision history for Perl extension Catalyst::Plugin::Static::Simple

0.30 2010-08-06
- Added ability to override file extention and content type
with tests and pod patches closes RT#60053 -- ECARROLL

0.29 2010-02-01 18:45:00
- Switch from override to around, because really, wtf

Expand Down
93 changes: 68 additions & 25 deletions lib/Catalyst/Plugin/Static/Simple.pm
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,24 @@ sub _locate_static_file {
}

sub _serve_static {
my $c = shift;
my ( $c, $file_info ) = @_;

my $full_path = defined $file_info->{full_path}
? $file_info->{full_path}
: $c->_static_file
;

my $type = $file_info->{content_type};
unless ( defined $type ) {
if ( defined $file_info->{ext} ) {
$type = $c->_ext_to_type({ ext => $file_info->{ext} })
}
else {
$type = $c->_ext_to_type({ full_path => $full_path })
}
}

my $full_path = shift || $c->_static_file;
my $type = $c->_ext_to_type( $full_path );
my $stat = stat $full_path;
my $stat = stat $full_path;

$c->res->headers->content_type( $type );
$c->res->headers->content_length( $stat->size );
Expand All @@ -195,7 +208,7 @@ sub _serve_static {
}

sub serve_static_file {
my ( $c, $full_path ) = @_;
my ( $c, $full_path, $args ) = @_;

my $config = $c->config->{static} ||= {};

Expand All @@ -211,34 +224,44 @@ sub serve_static_file {
return;
}

$c->_serve_static( $full_path );
$args->{full_path} = $full_path unless defined $args->{full_path};

$c->_serve_static( $args );
}

# looks up the correct MIME type for the current file extension
sub _ext_to_type {
my ( $c, $full_path ) = @_;
my ( $c, $args ) = @_;

my $config = $c->config->{static};

if ( $full_path =~ /.*\.(\S{1,})$/xms ) {
my $ext = $1;
my $type = $config->{mime_types}{$ext}
|| $config->{mime_types_obj}->mimeTypeOf( $ext );
if ( $type ) {
$c->_debug_msg( "as $type" ) if $config->{debug};
return ( ref $type ) ? $type->type : $type;
}
else {
$c->_debug_msg( "as text/plain (unknown extension $ext)" )
if $config->{debug};
return 'text/plain';
}
## figure out extention
my $ext = $args->{ext};
unless ( defined $ext ) {
if ( $args->{full_path} =~ /.*\.(\S{1,})$/xms ) {
$ext = $1;
}
else {
$c->_debug_msg( 'as text/plain (no extension)' )
if $config->{debug}
;
return 'text/plain';
}
}

## Get it from mime db
my $type = $config->{mime_types}{$ext}
|| $config->{mime_types_obj}->mimeTypeOf( $ext );
if ( $type ) {
$c->_debug_msg( "as $type" ) if $config->{debug};
return ( ref $type ) ? $type->type : $type;
}
else {
$c->_debug_msg( 'as text/plain (no extension)' )
$c->_debug_msg( "as text/plain (unknown extension $ext)" )
if $config->{debug};
return 'text/plain';
}

}

sub _debug_msg {
Expand Down Expand Up @@ -280,12 +303,13 @@ The Static::Simple plugin is designed to make serving static content in
your application during development quick and easy, without requiring a
single line of code from you.
This plugin detects static files by looking at the file extension in the
This plugin can detect static files by looking at the file extension in the
URL (such as B<.css> or B<.png> or B<.js>). The plugin uses the
lightweight L<MIME::Types> module to map file extensions to
IANA-registered MIME types, and will serve your static files with the
correct MIME type directly to the browser, without being processed
through Catalyst.
through Catalyst. Alternatively, this plugin can accept the content type
in a seperate argument hash.
Note that actions mapped to paths using periods (.) will still operate
properly.
Expand Down Expand Up @@ -450,6 +474,9 @@ module, you may enter your own extension to MIME type mapping.
},
);
There is also the ability to override extentions and content_types using the
C<serve_static> method
=head2 Compatibility with other plugins
Since version 0.12, Static::Simple plays nice with other plugins. It no
Expand Down Expand Up @@ -510,7 +537,7 @@ L<Catalyst::Engine::Apache2::MP20>.
=head1 PUBLIC METHODS
=head2 serve_static_file $file_path
=head2 serve_static_file $file_path $arg_hash
Will serve the file located in $file_path statically. This is useful when
you need to autogenerate them if they don't exist, or they are stored in a model.
Expand All @@ -520,9 +547,23 @@ you need to autogenerate them if they don't exist, or they are stored in a mode
sub curr_user_thumb : PathPart("my_thumbnail.png") {
my ( $self, $c ) = @_;
my $file_path = $c->user->picture_thumbnail_path;
$c->serve_static_file($file_path);
$c->serve_static_file( $file_path );
}
This method also takes an optional C<$arg_hash> which can be used to
override the normal inference of content_type by extention:
sub curr_user_thumb : PathPart("my_leads.adf") {
my ( $self, $c ) = @_;
my $file_path = $c->stash->{leads};
$c->serve_static_file( $file_path, { content_type => 'text/xml' } );
}
Valid keys for the argument hash are C<content_type>, C<ext>, and,
C<full_path>. The key C<ext> simply serves the file but infers the files
extention on the basis of an extention it doesn't have. This might be useful if
you're serving up files named by hashes.
=head1 INTERNAL EXTENDED METHODS
Static::Simple extends the following steps in the Catalyst process.
Expand Down Expand Up @@ -572,6 +613,8 @@ Justin Wheeler (dnm)
Matt S Trout, <mst@shadowcat.co.uk>
Evan Carroll, <me@evancarroll.com>
=head1 THANKS
The authors of Catalyst::Plugin::Static:
Expand Down
66 changes: 33 additions & 33 deletions t/04static.t
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
#!perl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";

# Module::Build craps out on files with spaces so it's not included in the dist
my $has_space_file = -e "$FindBin::Bin/lib/TestApp/root/files/space file.txt";

use Test::More;
#!perl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";

# Module::Build craps out on files with spaces so it's not included in the dist
my $has_space_file = -e "$FindBin::Bin/lib/TestApp/root/files/space file.txt";

use Test::More;
plan tests => ($has_space_file) ? 12 : 9;
use Catalyst::Test 'TestApp';

# test getting a css file
ok( my $res = request('http://localhost/files/static.css'), 'request ok' );
is( $res->content_type, 'text/css', 'content-type text/css ok' );
like( $res->content, qr/background/, 'content of css ok' );

# test a file with spaces
if ( $has_space_file ) {
ok( $res = request('http://localhost/files/space file.txt'), 'request ok' );
is( $res->content_type, 'text/plain', 'content-type text/plain ok' );
like( $res->content, qr/background/, 'content of space file ok' );
}

# test a non-existent file
ok( $res = request('http://localhost/files/404.txt'), 'request ok' );
is( $res->content, 'default', 'default handler for non-existent content ok' );

# test unknown extension
ok( $res = request('http://localhost/files/err.omg'), 'request ok' );
is( $res->content_type, 'text/plain', 'unknown extension as text/plain ok' );
use Catalyst::Test 'TestApp';

# test getting a css file
ok( my $res = request('http://localhost/files/static.css'), 'request ok' );
is( $res->content_type, 'text/css', 'content-type text/css ok' );
like( $res->content, qr/background/, 'content of css ok' );

# test a file with spaces
if ( $has_space_file ) {
ok( $res = request('http://localhost/files/space file.txt'), 'request ok' );
is( $res->content_type, 'text/plain', 'content-type text/plain ok' );
like( $res->content, qr/background/, 'content of space file ok' );
}

# test a non-existent file
ok( $res = request('http://localhost/files/404.txt'), 'request ok' );
is( $res->content, 'default', 'default handler for non-existent content ok' );

# test unknown extension
ok( $res = request('http://localhost/files/err.omg'), 'request ok' );
is( $res->content_type, 'text/plain', 'unknown extension as text/plain ok' );

ok( $res = request('http://localhost/files/empty.txt'), 'request ok' );
is( $res->content, '', 'empty files result in an empty response' );
44 changes: 32 additions & 12 deletions t/11serve_static.t
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
#!perl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";

use Test::More tests => 6;
use Test::More tests => 14;
use Catalyst::Test 'TestApp';

# test getting a file via serve_static_file
ok( my $res = request('http://localhost/serve_static'), 'request ok' );
is( $res->code, 200, '200 ok' );
# .pm can be both application/x-pagemaker or text/x-perl, so only check for a slash
like( $res->content_type, qr{/}, 'content-type ok' );
like( $res->content, qr/package TestApp/, 'content of serve_static ok' );
my $res;

{
# test getting a file via serve_static_file
ok( $res = request('http://localhost/serve_static'), 'request ok' );
is( $res->code, 200, '200 ok' );
# .pm can be both application/x-pagemaker or text/x-perl, so only check for a slash
like( $res->content_type, qr{/}, 'content-type ok' );
like( $res->content, qr/package TestApp/, 'content of serve_static ok' );
}

{
# test getting a file via serve_static_file with custom filetype
ok( $res = request('http://localhost/serve_static/foobared'), 'request ok' );
is( $res->code, 200, '200 ok' );
like( $res->content_type, qr{foobared}, 'content-type ok' );
like( $res->content, qr/package TestApp/, 'content of serve_static ok' );
}

{
# test getting a file via serve_static_file with custom extention
ok( $res = request('http://localhost/serve_static_ext_jpg'), 'request ok' );
is( $res->code, 200, '200 ok' );
like( $res->content_type, qr{image/jpeg}, 'content-type ok' );
like( $res->content, qr/package TestApp/, 'content of serve_static ok' );
}

# test getting a non-existant file via serve_static_file
ok( $res = request('http://localhost/serve_static_404'), 'request ok' );
is( $res->code, 404, '404 ok' );
{
# test getting a non-existant file via serve_static_file
ok( $res = request('http://localhost/serve_static_404'), 'request ok' );
is( $res->code, 404, '404 ok' );
}
Loading