Catalyst-Plugin-Static-File
view release on metacpan or search on metacpan
lib/Catalyst/Plugin/Static/File.pm view on Meta::CPAN
package Catalyst::Plugin::Static::File;
use v5.14;
# ABSTRACT: Serve a specific static file
use Moose::Role;
use File::Spec;
use File::stat;
use IO::File;
use Plack::MIME;
use Plack::Util;
use Try::Tiny;
use namespace::autoclean;
our $VERSION = 'v0.2.4';
sub serve_static_file {
my ( $c, $path, $type ) = @_;
my $res = $c->res;
my $abs = File::Spec->rel2abs("$path");
try {
# Ideally we could let the file open fail when a file does not exist, but this seems to cause the process to
# exit in a way that try/catch cannot handle on some systems. We can risk a potential race condition where the
# file disappears between the existence check and opening: the worst case is that it would have the same effect
# as not checking for file existence.
die "No such file or directory" unless -e $abs;
my $fh = IO::File->new( $abs, "r" ) or die $!;
binmode($fh);
Plack::Util::set_io_path( $fh, $abs );
$res->body($fh);
$type //= Plack::MIME->mime_type($abs);
my $headers = $res->headers;
$headers->content_type("$type");
my $stat = stat($fh);
$headers->content_length( $stat->size );
$headers->last_modified( $stat->mtime );
}
catch {
my $error = $_;
Catalyst::Exception->throw("Unable to open ${abs} for reading: ${error}");
};
return 1;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Catalyst::Plugin::Static::File - Serve a specific static file
=head1 VERSION
version v0.2.4
=head1 SYNOPSIS
In your Catalyst class:
use Catalyst qw/
Static::File
/;
In a controller method:
$c->serve_static_file( $absolute_path, $type );
=head1 DESCRIPTION
This plugin provides a simple method for your L<Catalyst> app to send a specific static file.
Unlike L<Catalyst::Plugin::Static::Simple>,
=over
=item *
It only supports serving a single file, not a directory of static files. Use L<Plack::Middleware::Static> if you want to
serve multiple files.
=item *
It assumes that you know what you're doing. If the file does not exist, it will throw an fatal error.
( run in 1.151 second using v1.01-cache-2.11-cpan-39bf76dae61 )