Permalink
Browse files

initial release

  • Loading branch information...
0 parents commit 0b798572c8495419310cb70505d48a138706adeb @nichtich committed Oct 8, 2012
Showing with 198 additions and 0 deletions.
  1. +18 −0 dist.ini
  2. +116 −0 lib/Plack/Middleware/Static/Combine.pm
  3. +5 −0 t/00_compile.t
  4. +56 −0 t/10_combine.t
  5. +1 −0 t/files/bar.js
  6. +1 −0 t/files/doz.txt
  7. +1 −0 t/files/foo.js
@@ -0,0 +1,18 @@
+name = Plack-Middleware-Static-Combine
+author = Jakob Voß <voss@gbv.de>
+version = 0.01
+license = Perl_5
+copyright_holder = Jakob Voß
+copyright_year = 2012
+
+[@Basic]
+[PkgVersion]
+[MinimumPerl]
+[PodWeaver]
+[AutoPrereqs]
+[PruneFiles]
+filename = dist.ini
+filename = README.md
+
+[GithubMeta]
+issues=1
@@ -0,0 +1,116 @@
+package Plack::Middleware::Static::Combine;
+#ABSTRACT: Serve multiple static files combined
+
+use strict;
+use parent qw(Plack::Middleware::Static);
+
+use Plack::Util;
+use Plack::Util::Accessor qw(files);
+
+sub _handle_static {
+ my ($self, $env) = @_;
+
+ my $path_match = $self->path or return;
+ my $path = $env->{PATH_INFO};
+
+ for ($path) {
+ my $matched = 'CODE' eq ref $path_match ? $path_match->($_) : $_ =~ $path_match;
+ return unless $matched;
+ }
+
+ $self->{file} ||= Plack::App::File->new({ root => $self->root || '.', encoding => $self->encoding });
+
+ # copied from Plack::Middleware::Static up to this line
+
+ my ($res, $type, $lastmod);
+ my $length = 0;
+
+ foreach my $file ( @{ $self->files || [] } ) {
+
+ local $env->{PATH_INFO} = $file;
+ my $got = $self->{file}->call($env);
+ Plack::Util::response_cb($got, sub { $got = shift; });
+
+ return $got unless $got->[0] eq '200';
+
+ if ($res) {
+ if ( $type ne Plack::Util::header_get($got->[1],'Content-Type') ) {
+ $res = [500,['Content-Type'=>'text/plain'],['files must have same type']];
+ $length = length $res->[2]->[0];
+ last;
+ }
+
+ # TODO: better combine by sub?
+ my $body = $res->[2];
+ if (ref $body ne 'ARRAY') {
+ $res->[2] = [ ];
+ Plack::Util::foreach($body,sub { push @{$res->[2]}, shift; });
+ }
+ Plack::Util::foreach($got->[2],sub { push @{$res->[2]}, shift; });
+
+ # TODO: Adjust Last-Modified
+
+ } else {
+ $type = Plack::Util::header_get($got->[1],'Content-Type');
+ $lastmod = Plack::Util::header_get($got->[1],'Last-Modified');
+ $res = $got;
+ }
+
+ $length += Plack::Util::header_get($got->[1],'Content-Length');
+ }
+
+ Plack::Util::header_set($res->[1],'Content-Length',$length) if $res;
+
+ return $res;
+}
+
+1;
+
+=head1 SYNOPSIS
+
+ use Plack::Builder;
+
+ builder {
+ enable 'Static::Combine',
+ path => qr{^/javascript\.js$},
+ files => [ 'foo.js', 'bar.js', 'doz.js' ],
+ root => './htdocs';
+ $app;
+ };
+
+
+=head1 DESCRIPTION
+
+Plack::Middleware::Static::Combine combines multiple static files, as served
+via L<Plack::App::File>. Files must have same content type or HTTP 500 is
+returned.
+
+=head1 CONFIGURATION
+
+=over 4
+
+=item path, root, encoding
+
+URL pattern or callback, document root, and text file encoding, as passed to
+L<Plack::App::Static>.
+
+=item files
+
+A list of files.
+
+=item pass_through
+
+When this option is set to a true value, then this middleware will never return
+an error response. Instead, it will simply pass the request on to the
+application it is wrapping.
+
+=back
+
+=head1 SEE ALSO
+
+L<Plack::Middleware::Static>, L<Plack::Middleware::File>,
+L<Plack::Middleware::Static::Minifier>.
+
+=cut
+
+=encoding utf8
@@ -0,0 +1,5 @@
+use Test::More tests => 1;
+
+BEGIN {
+ use_ok 'Plack::Middleware::Static::Combine';
+};
@@ -0,0 +1,56 @@
+use strict;
+use Test::More;
+use Plack::Test;
+use Plack::Builder;
+use HTTP::Request::Common;
+
+my $app = builder {
+ enable 'Static::Combine',
+ path => qr{^/foo$},
+ root => 't',
+ files => [ '00_compile.t', '10_combine.t' ];
+ sub { [ 500, [], [] ] };
+};
+
+test_psgi $app, sub {
+ my $cb = shift;
+
+ my $res = $cb->(GET 'http://localhost/foo');
+ is $res->code, 200;
+ my @c = ($res->content =~ /^(use Test::More)/mg);
+ is scalar @c, 2, 'two files combined';
+};
+
+my @tests = (
+ {
+ # passed through
+ code => 204
+ },{
+ files => [ 'foo.js', 'baz.js' ],
+ code => 404
+ },{
+ files => [ 'foo.js', 'bar.js' ],
+ code => 200
+ },{
+ files => [ 'foo.js', 'doz.txt' ],
+ code => 500
+ },
+);
+
+foreach my $test (@tests) {
+ $app = builder {
+ enable 'Static::Combine',
+ path => qr{^/$},
+ root => 't/files/',
+ files => $test->{files};
+ sub { [ 204, [], [] ] };
+ };
+
+ test_psgi $app, sub {
+ my $cb = shift;
+ my $res = $cb->(GET 'http://localhost/');
+ is $res->code, $test->{code};
+ };
+}
+
+done_testing;
@@ -0,0 +1 @@
+"bar";
@@ -0,0 +1 @@
+
@@ -0,0 +1 @@
+

0 comments on commit 0b79857

Please sign in to comment.