From 184c290a8eedc44e92a8b22671a6911388875407 Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Fri, 6 Aug 2010 11:09:34 -0500 Subject: [PATCH 1/2] removed carriage returns --- t/04static.t | 66 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/t/04static.t b/t/04static.t index bae2922..b301341 100644 --- a/t/04static.t +++ b/t/04static.t @@ -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' ); From 793a70075985b6493868db34452cae069caeb32f Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Fri, 6 Aug 2010 11:52:41 -0500 Subject: [PATCH 2/2] added the ability to override a files content_type, and extention in the serve_static function --- Changes | 4 ++ lib/Catalyst/Plugin/Static/Simple.pm | 93 +++++++++++++++++------- t/11serve_static.t | 44 ++++++++---- t/lib/TestApp/Controller/Root.pm | 101 +++++++++++++++------------ 4 files changed, 160 insertions(+), 82 deletions(-) diff --git a/Changes b/Changes index aea5423..3df541d 100644 --- a/Changes +++ b/Changes @@ -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 diff --git a/lib/Catalyst/Plugin/Static/Simple.pm b/lib/Catalyst/Plugin/Static/Simple.pm index ca3412c..bea0962 100644 --- a/lib/Catalyst/Plugin/Static/Simple.pm +++ b/lib/Catalyst/Plugin/Static/Simple.pm @@ -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 ); @@ -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} ||= {}; @@ -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 { @@ -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 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. @@ -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 method + =head2 Compatibility with other plugins Since version 0.12, Static::Simple plays nice with other plugins. It no @@ -510,7 +537,7 @@ L. =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. @@ -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, C, and, +C. The key C 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. @@ -572,6 +613,8 @@ Justin Wheeler (dnm) Matt S Trout, +Evan Carroll, + =head1 THANKS The authors of Catalyst::Plugin::Static: diff --git a/t/11serve_static.t b/t/11serve_static.t index f98760f..36859aa 100644 --- a/t/11serve_static.t +++ b/t/11serve_static.t @@ -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' ); +} diff --git a/t/lib/TestApp/Controller/Root.pm b/t/lib/TestApp/Controller/Root.pm index d3dc5ee..e045e05 100644 --- a/t/lib/TestApp/Controller/Root.pm +++ b/t/lib/TestApp/Controller/Root.pm @@ -1,45 +1,56 @@ -package TestApp::Controller::Root; - -use strict; -use warnings; -use File::Spec::Functions; - -use base qw/Catalyst::Controller/; - -__PACKAGE__->config(namespace => ''); - -sub default : Private { - my ( $self, $c ) = @_; - - $c->res->output( 'default' ); -} - -sub subtest : Local { - my ( $self, $c ) = @_; - - $c->res->output( $c->subreq('/subtest2') ); -} - -sub subtest2 : Local { - my ( $self, $c ) = @_; - - $c->res->output( 'subtest2 ok' ); -} - -sub serve_static : Local { - my ( $self, $c ) = @_; - - my $file = catfile( $FindBin::Bin, 'lib', 'TestApp.pm' ); - - $c->serve_static_file( $file ); -} - -sub serve_static_404 : Local { - my ( $self, $c ) = @_; - - my $file = catfile( $FindBin::Bin, 'lib', 'foo.pm' ); - - $c->serve_static_file( $file ); -} - -1; +package TestApp::Controller::Root; + +use strict; +use warnings; +use File::Spec::Functions; + +use base qw/Catalyst::Controller/; + +__PACKAGE__->config(namespace => ''); + +sub default : Private { + my ( $self, $c ) = @_; + + $c->res->output( 'default' ); +} + +sub subtest : Local { + my ( $self, $c ) = @_; + + $c->res->output( $c->subreq('/subtest2') ); +} + +sub subtest2 : Local { + my ( $self, $c ) = @_; + + $c->res->output( 'subtest2 ok' ); +} + +sub serve_static : Local { + my ( $self, $c, $ct ) = @_; + + my $file = catfile( $FindBin::Bin, 'lib', 'TestApp.pm' ); + + my %args; + $args{content_type} = $ct if defined $ct; + + $c->serve_static_file( $file, \%args ); +} + +sub serve_static_ext_jpg : Local { + my ( $self, $c, $ct ) = @_; + + my $file = catfile( $FindBin::Bin, 'lib', 'TestApp.pm' ); + + $c->serve_static_file( $file, {ext=>'jpg'} ); +} + +sub serve_static_404 : Local { + my ( $self, $c ) = @_; + + my $file = catfile( $FindBin::Bin, 'lib', 'foo.pm' ); + + $c->serve_static_file( $file ); +} + +1;