1 package Catalyst::Plugin::Static::Simple::Middleware;
5 use parent qw/Plack::Middleware/;
7 use Plack::Util::Accessor qw/content_type config cat_app/;
12 my ( $self, $env ) = @_;
14 #wrap everything in an eval so if something goes wrong the user
15 #gets an "internal server error" message, and we get a warning
16 #instead of the user getting the warning and us getting nothing
20 if(! $self->_check_static_simple_path( $env ) ) {
21 return $self->app->($env)
24 my @ipaths = @{$self->config->{include_path}};
25 while ( my $ipath = shift @ipaths ) {
27 if ( ref($ipath) eq 'CODE' ) {
28 $c ||= $self->cat_app->prepare(env => $env, response_cb => sub {});
29 my $paths = $ipath->( $c );
31 unshift @ipaths, @{$paths};
37 if(! -f $root . $env->{PATH_INFO} ) {
41 my $file = Plack::App::File->new( {
43 content_type => $self->content_type
45 $res = $file->call($env);
47 if( $res && ($res->[0] != 404) ) {
52 if(! scalar ( @{$self->config->{dirs}})) {
53 $self->_debug( "Forwarding to Catalyst (or other middleware).", $env );
54 return $self->app->($env);
57 $self->_debug( "404: file not found: " . $env->{PATH_INFO}, $env );
58 return $self->return_404;
62 if($env->{'psgix.logger'} && ref($env->{'psgix.logger'}) eq 'CODE') {
63 $env->{'psgix.logger'}->({ level => 'error', message => $@ });
67 return $self->return_500;
73 sub _check_static_simple_path {
74 my ( $self, $env ) = @_;
75 my $path = $env->{PATH_INFO};
77 for my $ignore_ext ( @{ $self->config->{ignore_extensions} } ) {
78 if ( $path =~ /.*\.${ignore_ext}$/ixms ) {
79 $self->_debug ( "Ignoring extension `$ignore_ext`", $env );
84 for my $ignore ( @{ $self->config->{ignore_dirs} } ) {
85 $ignore =~ s{(/|\\)$}{};
87 if ( $path =~ /^\/$ignore(\/|\\)/ ) {
88 $self->_debug( "Ignoring directory `$ignore`", $env );
93 #we serve everything if it exists and dirs is not set
94 #we check if it exists in the middleware, once we've built the include paths
95 return 1 if ( !scalar(@{$self->config->{dirs}}) );
97 if( $self->_path_matches_dirs($path, $self->config->{dirs}) ) {
104 sub _path_matches_dirs {
105 my ( $self, $path, $dirs ) = @_;
107 $path =~ s!^/!!; #Remove leading slashes
109 foreach my $dir ( @$dirs ) {
111 if (ref($dir) eq 'Regexp') {
113 } elsif ( $dir =~ m{^qr/}xms ) {
117 die( "Error compiling static dir regex '$dir': $@" );
120 my $dir_re = quotemeta $dir;
122 $re = qr{^${dir_re}/};
134 my ( $self, $msg, $env ) = @_;
136 if($env && $env->{'psgix.logger'} && ref($env->{'psgix.logger'}) eq 'CODE') {
137 $env->{'psgix.logger'}->({ level => 'error', message => $@ });
139 warn "Static::Simple: $msg\n" if $self->config->{debug};
144 #for backcompat we can't use the one in Plack::App::File as it has the content-type of plain
145 return [404, ['Content-Type' => 'text/html', 'Content-Length' => 9], ['not found']];
149 return [500, ['Content-Type' => 'text/pain', 'Content-Length' => 9], ['internal server error']];