Skip to content
This repository

Use alternatives instead of Plack::MIME #361

Merged
merged 3 commits into from about 1 year ago

2 participants

Oliver Paukstadt Tatsuhiko Miyagawa
Oliver Paukstadt

I am a little unhappy with Plack::MIME content-types, especially when using Plack::Middleware::Static. Sometimes I want a improved MIME-type detection, like File::MimeInfo::Magic.

I added a content_type attribute to Plack::Middleware::Static, which can be a sub like
content_type => sub { mimetype($_[0]) },

The content_type is now handed to Plack::App::File, which is extended to evaluate the CODE reference if content_type is one. For the primary use of Plack::App::File it might be not necessary to handle code references for content_type, but I think it is the best place to deal with it and to provide this feature to other components reusing Plack::App::File.

Oliver Paukstadt add handling of content_type code reference in App/File (readable cha…
…nge)

add attribute content_type to Middleware/Static which can be an callback
9036e90
Tatsuhiko Miyagawa
Owner

Can you add a documentation and test about it?

added some commits January 05, 2013
Oliver Paukstadt provide tests for content_type callback for Plack::App::File and Plac…
…k::Middleware::Static.

Using Plack::MIME with added mimetype and modify the returned mimetype to make sure it is not the Plack::MIME fallback which was called. This was done not to have a dependency to a different mimetype checker.
4ec9e77
Oliver Paukstadt Documentation update c0ddf94
Tatsuhiko Miyagawa miyagawa merged commit 7b1ee71 into from January 31, 2013
Tatsuhiko Miyagawa miyagawa closed this January 31, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 3 unique commits by 1 author.

Jan 04, 2013
Oliver Paukstadt add handling of content_type code reference in App/File (readable cha…
…nge)

add attribute content_type to Middleware/Static which can be an callback
9036e90
Jan 05, 2013
Oliver Paukstadt provide tests for content_type callback for Plack::App::File and Plac…
…k::Middleware::Static.

Using Plack::MIME with added mimetype and modify the returned mimetype to make sure it is not the Plack::MIME fallback which was called. This was done not to have a dependency to a different mimetype checker.
4ec9e77
Oliver Paukstadt Documentation update c0ddf94
This page is out of date. Refresh to see the latest.
6  lib/Plack/App/File.pm
@@ -86,6 +86,10 @@ sub serve_path {
86 86
     my $content_type = $self->content_type || Plack::MIME->mime_type($file)
87 87
                        || 'text/plain';
88 88
 
  89
+    if ("CODE" eq ref $content_type) {
  90
+		$content_type = $content_type->($file);
  91
+    }
  92
+
89 93
     if ($content_type =~ m!^text/!) {
90 94
         $content_type .= "; charset=" . ($self->encoding || "utf-8");
91 95
     }
@@ -174,6 +178,8 @@ Set the file encoding for text files. Defaults to C<utf-8>.
174 178
 
175 179
 Set the file content type. If not set L<Plack::MIME> will try to detect it
176 180
 based on the file extension or fall back to C<text/plain>.
  181
+Can be set to a callback which should work on $_[0] to check full path file 
  182
+name.
177 183
 
178 184
 =back
179 185
 
15  lib/Plack/Middleware/Static.pm
@@ -4,7 +4,7 @@ use warnings;
4 4
 use parent qw/Plack::Middleware/;
5 5
 use Plack::App::File;
6 6
 
7  
-use Plack::Util::Accessor qw( path root encoding pass_through );
  7
+use Plack::Util::Accessor qw( path root encoding pass_through content_type );
8 8
 
9 9
 sub call {
10 10
     my $self = shift;
@@ -29,7 +29,7 @@ sub _handle_static {
29 29
         return unless $matched;
30 30
     }
31 31
 
32  
-    $self->{file} ||= Plack::App::File->new({ root => $self->root || '.', encoding => $self->encoding });
  32
+    $self->{file} ||= Plack::App::File->new({ root => $self->root || '.', encoding => $self->encoding, content_type => $self->content_type });
33 33
     local $env->{PATH_INFO} = $path; # rewrite PATH
34 34
     return $self->{file}->call($env);
35 35
 }
@@ -67,7 +67,7 @@ If the requested document is not within the C<root> or the file is there but
67 67
 not readable, this middleware will return a 403 Forbidden response.
68 68
 
69 69
 The content type returned will be determined from the file extension by using
70  
-L<Plack::MIME>.
  70
+L<Plack::MIME> or using C<content_type>.
71 71
 
72 72
 =head1 CONFIGURATIONS
73 73
 
@@ -111,6 +111,15 @@ When this option is set to a true value, then this middleware will never
111 111
 return a 404 if it cannot find a matching file. Instead, it will simply pass
112 112
 the request on to the application it is wrapping.
113 113
 
  114
+=item content_type
  115
+
  116
+The C<content_type> option can be used to provide access to a different MIME 
  117
+database than L<Plack::MIME>.
  118
+L<Plack::MIME> works fast and good for a list of well known file endings, 
  119
+but if you need a more accurate content based checking you can use modules
  120
+like L<File::MimeInfo> or L<File::MMagic> for example.
  121
+The callback should work on $_[0] which is the filename of the file.
  122
+
114 123
 =back
115 124
 
116 125
 =head1 AUTHOR
1  t/Plack-Middleware/static.foo
... ...
@@ -0,0 +1 @@
  1
+bar
10  t/Plack-Middleware/static.t
@@ -11,6 +11,8 @@ use Plack::Test;
11 11
 
12 12
 my $base = cwd;
13 13
 
  14
+Plack::MIME->add_type(".foo" => "text/x-fooo");
  15
+
14 16
 my $handler = builder {
15 17
     enable "Plack::Middleware::Static",
16 18
         path => sub { s!^/share/!!}, root => "share";
@@ -18,6 +20,9 @@ my $handler = builder {
18 20
         path => sub { s!^/share-pass/!!}, root => "share", pass_through => 1;
19 21
     enable "Plack::Middleware::Static",
20 22
         path => qr{\.(t|PL|txt)$}i, root => '.';
  23
+    enable "Plack::Middleware::Static",
  24
+        path => qr{\.foo$}i, root => '.', 
  25
+        content_type => sub { substr Plack::MIME->mime_type($_[0]),0,-1  } ;
21 26
     sub {
22 27
         [200, ['Content-Type' => 'text/plain', 'Content-Length' => 2], ['ok']]
23 28
     };
@@ -70,6 +75,11 @@ my %test = (
70 75
             my($ct, $charset) = $res->content_type;
71 76
             is $charset, 'charset=utf-8';
72 77
         }
  78
+
  79
+        {
  80
+            my $res = $cb->(GET "http://localhost/t/Plack-Middleware/static.foo");
  81
+            is $res->content_type, 'text/x-foo';
  82
+        }
73 83
 },
74 84
     app => $handler,
75 85
 );
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.