Skip to content

Commit

Permalink
initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
nichtich committed Oct 8, 2012
0 parents commit 0b79857
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 0 deletions.
18 changes: 18 additions & 0 deletions dist.ini
Original file line number Diff line number Diff line change
@@ -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
116 changes: 116 additions & 0 deletions lib/Plack/Middleware/Static/Combine.pm
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions t/00_compile.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use Test::More tests => 1;

BEGIN {
use_ok 'Plack::Middleware::Static::Combine';
};
56 changes: 56 additions & 0 deletions t/10_combine.t
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions t/files/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"bar";
1 change: 1 addition & 0 deletions t/files/doz.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions t/files/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit 0b79857

Please sign in to comment.