1package Catalyst::Plugin::Static;
2
3use strict;
4use base 'Class::Data::Inheritable';
5use File::MimeInfo::Magic;
6use File::stat;
7use File::Slurp;
8use File::Spec::Functions qw/catdir no_upwards splitdir/;
9use MRO::Compat;;
10
11our $VERSION = '0.11';
12
13
14=head1 NAME
15
16Catalyst::Plugin::Static - DEPRECATED - Serve static files with Catalyst
17
18=head1 SYNOPSIS
19
20    use Catalyst 'Static';
21
22    # let File::MMagic determine the content type
23    $c->serve_static;
24
25    # or specify explicitly if you know better
26    $c->serve_static('text/css');
27
28=head1 DESCRIPTION
29
30Serve static files from config->{root}. You probably want to use
31use L<Catalyst::Plugin::Static::Simple> rather than this module.
32
33=head2 METHODS
34
35=over 4
36
37=item finalize
38
39This plugin overrides finalize to make sure content is removed on
40redirect.
41
42=cut
43
44sub finalize {
45    my $c = shift;
46    if ( $c->res->status =~ /^(1\d\d|[23]04)$/ ) {
47        $c->res->headers->remove_content_headers;
48        $c->finalize_headers;
49    }
50    return $c->next::method(@_);
51
52}
53
54=item serve_static
55
56Call this method from your action to serve requested path
57as a static file from your root. takes an optional content_type
58parameter
59
60=cut
61
62sub serve_static {
63    my $c    = shift;
64    my $r = eval {
65    my $path = $c->config->{root} . '/' . $c->req->path;
66    $c->serve_static_file( $path, @_ );
67    };
68    warn("serve_static puked $@") if $@;
69    $r;
70}
71
72=item serve_static_file <file>
73
74Serve a specified static file.
75
76=cut
77
78sub serve_static_file {
79    my $c    = shift;
80    my $path = catdir(no_upwards(splitdir( shift )));
81
82    if ( -f $path ) {
83
84        my $stat = stat($path);
85
86        if ( $c->req->headers->header('If-Modified-Since') ) {
87
88            if ( $c->req->headers->if_modified_since == $stat->mtime ) {
89                $c->res->status(304); # Not Modified
90                $c->res->headers->remove_content_headers;
91                return 1;
92            }
93        }
94
95        my $type = shift || mimetype($path);
96        my $content = read_file($path);
97        $c->res->headers->content_type($type);
98        $c->res->headers->content_length( $stat->size );
99        $c->res->headers->last_modified( $stat->mtime );
100        $c->res->output($content);
101        if ( $c->config->{static}->{no_logs} && $c->log->can('abort') ) {
102           $c->log->abort( 1 );
103	}
104        $c->log->debug(qq/Serving file "$path" as "$type"/) if $c->debug;
105        return 1;
106    }
107
108    $c->log->debug(qq/Failed to serve file "$path"/) if $c->debug;
109    $c->res->status(404);
110
111    return 0;
112}
113
114=back
115
116=head1 SEE ALSO
117
118L<Catalyst>.
119
120=head1 CAVEATS
121
122This module is not as optimized for static files as a normal web
123server, and is most useful for stand alone operation and development.
124
125=head1 AUTHOR
126
127Sebastian Riedel, C<sri@cpan.org>
128Christian Hansen <ch@ngmedia.com>
129Marcus Ramberg <mramberg@cpan.org>
130
131=head1 THANK YOU
132
133Torsten Seemann and all the others who've helped.
134
135=head1 COPYRIGHT
136
137This program is free software, you can redistribute it and/or modify it under
138the same terms as Perl itself.
139
140=cut
141
1421;
143