/usr/share/perl5/Mojolicious/Plugin/RenderFile.pm is in libmojolicious-plugin-renderfile-perl 0.12-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | package Mojolicious::Plugin::RenderFile;
use Mojo::Base 'Mojolicious::Plugin';
use strict;
use warnings;
use File::Basename;
use Encode qw( encode decode_utf8 );
use Mojo::Util 'quote';
our $VERSION = '0.12';
sub register {
my ( $self, $app ) = @_;
$app->helper( 'render_file' => sub {
my $c = shift;
my %args = @_;
utf8::decode($args{filename}) if $args{filename} && !utf8::is_utf8($args{filename});
utf8::decode($args{filepath}) if $args{filepath} && !utf8::is_utf8($args{filepath});
my $filename = $args{filename};
my $status = $args{status} || 200;
my $content_disposition = $args{content_disposition} || 'attachment';
my $cleanup = $args{cleanup} // 0;
# Content type based on format
if ($args{format} && $args{content_type}) {
$c->app->log->error('You cannot provide both "format" and "content_type" option');
return;
}
my $content_type = $args{content_type};
$content_type ||= $c->app->types->type( $args{format} ) if $args{format};
$content_type ||= 'application/x-download';
# Create asset
my $asset;
if ( my $filepath = $args{filepath} ) {
unless ( -f $filepath && -r $filepath ) {
$c->app->log->error("Cannot read file [$filepath]. error [$!]");
return;
}
$filename ||= fileparse($filepath);
$asset = Mojo::Asset::File->new( path => $filepath );
$asset->cleanup($cleanup);
} elsif ( $args{data} ) {
$filename ||= $c->req->url->path->parts->[-1] || 'download';
$asset = Mojo::Asset::Memory->new();
$asset->add_chunk( $args{data} );
} else {
$c->app->log->error('You must provide "data" or "filepath" option');
return;
}
# Set response headers
my $headers = $c->res->content->headers();
$filename = quote($filename); # quote the filename, per RFC 5987
$filename = encode("UTF-8", $filename);
$headers->add( 'Content-Type', $content_type . ';name=' . $filename );
$headers->add( 'Content-Disposition', $content_disposition . ';filename=' . $filename );
# Range
# Partially based on Mojolicious::Static
if ( my $range = $c->req->headers->range ) {
my $start = 0;
my $size = $asset->size;
my $end = $size - 1 >= 0 ? $size - 1 : 0;
# Check range
if ( $range =~ m/^bytes=(\d+)-(\d+)?/ && $1 <= $end ) {
$start = $1;
$end = $2 if defined $2 && $2 <= $end;
$status = 206;
$headers->add( 'Content-Length' => $end - $start + 1 );
$headers->add( 'Content-Range' => "bytes $start-$end/$size" );
} else {
# Not satisfiable
return $c->rendered(416);
}
# Set range for asset
$asset->start_range($start)->end_range($end);
} else {
$headers->add( 'Content-Length' => $asset->size );
}
# Stream content directly from file
$c->res->content->asset($asset);
return $c->rendered($status);
} );
}
1;
=head1 NAME
Mojolicious::Plugin::RenderFile - "render_file" helper for Mojolicious
=head1 SYNOPSIS
# Mojolicious
$self->plugin('RenderFile');
# Mojolicious::Lite
plugin 'RenderFile';
# In controller
$self->render_file('filepath' => '/tmp/files/file.pdf'); # file name will be "file.pdf"
# Provide any file name
$self->render_file('filepath' => '/tmp/files/file.pdf', 'filename' => 'report.pdf');
# Render data from memory as file
$self->render_file('data' => 'some data here', 'filename' => 'report.pdf');
# Open file in browser(do not show save dialog)
$self->render_file(
'filepath' => '/tmp/files/file.pdf',
'format' => 'pdf', # will change Content-Type "application/x-download" to "application/pdf"
'content_disposition' => 'inline', # will change Content-Disposition from "attachment" to "inline"
'cleanup' => 1, # delete file after completed
);
=head1 DESCRIPTION
L<Mojolicious::Plugin::RenderFile> is a L<Mojolicious> plugin that adds "render_file" helper. It does not read file in memory and just streaming it to a client.
=head1 HELPERS
=head2 C<render_file>
$self->render_file(filepath => '/tmp/files/file.pdf', 'filename' => 'report.pdf' );
With this helper you can easily provide files for download. By default "Content-Type" header is "application/x-download" and "content_disposition" option value is "attachment".
Therefore, a browser will ask where to save file. You can provide "format" option to change "Content-Type" header.
=head3 Supported Options:
=over
=item C<filepath>
Path on the filesystem to the file. You must always pass "filepath" or "data" option
=item C<data>
Binary content which will be transferred to browser. You must always pass "filepath" or "data" option
=item C<filename> (optional)
Browser will use this name for saving the file
=item C<format> (optional)
The "Content-Type" header is based on the MIME type mapping of the "format" option value. These mappings can be easily extended or changed with L<Mojolicious/"types">.
By default "Content-Type" header is "application/x-download"
=item C<content_disposition> (optional)
Tells browser how to present the file.
"attachment" (default) - is for dowloading
"inline" - is for showing file inline
=item C<cleanup> (optional)
Indicates if the file should be deleted when rendering is complete
=back
This plugin respects HTTP Range headers.
=head1 AUTHOR
Viktor Turskyi <koorchik@cpan.org>
=head1 CONTRIBUTORS
Nils Diewald (Akron)
Danil Greben (SDSWanderer)
=head1 BUGS
Please report any bugs or feature requests to Github L<https://github.com/koorchik/Mojolicious-Plugin-RenderFile>
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
Copyright 2011 Viktor Turskyi
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
=cut
|