/usr/share/perl5/Catalyst/Request/Upload.pm is in libcatalyst-perl 5.90115-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 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | package Catalyst::Request::Upload;
use Moose;
with 'MooseX::Emulate::Class::Accessor::Fast';
use Catalyst::Exception;
use File::Copy ();
use IO::File ();
use File::Spec::Unix;
use namespace::clean -except => 'meta';
has filename => (is => 'rw');
has headers => (is => 'rw');
has size => (is => 'rw');
has tempname => (is => 'rw');
has type => (is => 'rw');
has basename => (is => 'ro', lazy_build => 1);
has raw_basename => (is => 'ro', lazy_build => 1);
has charset => (is=>'ro', predicate=>'has_charset');
has fh => (
is => 'rw',
required => 1,
lazy => 1,
default => sub {
my $self = shift;
my $fh = IO::File->new($self->tempname, IO::File::O_RDONLY);
unless ( defined $fh ) {
my $filename = $self->tempname;
Catalyst::Exception->throw(
message => qq/Can't open '$filename': '$!'/ );
}
return $fh;
},
);
sub _build_basename {
my $basename = shift->raw_basename;
$basename =~ s|[^\w\.-]+|_|g;
return $basename;
}
sub _build_raw_basename {
my $self = shift;
my $basename = $self->filename;
$basename =~ s|\\|/|g;
$basename = ( File::Spec::Unix->splitpath($basename) )[2];
return $basename;
}
no Moose;
=for stopwords uploadtmp
=head1 NAME
Catalyst::Request::Upload - handles file upload requests
=head1 SYNOPSIS
my $upload = $c->req->upload('field');
$upload->basename;
$upload->copy_to;
$upload->fh;
$upload->decoded_fh
$upload->filename;
$upload->headers;
$upload->link_to;
$upload->size;
$upload->slurp;
$upload->decoded_slurp;
$upload->tempname;
$upload->type;
$upload->charset;
To specify where Catalyst should put the temporary files, set the 'uploadtmp'
option in the Catalyst config. If unset, Catalyst will use the system temp dir.
__PACKAGE__->config( uploadtmp => '/path/to/tmpdir' );
See also L<Catalyst>.
=head1 DESCRIPTION
This class provides accessors and methods to handle client upload requests.
=head1 METHODS
=head2 $upload->new
Simple constructor.
=head2 $upload->copy_to
Copies the temporary file using L<File::Copy>. Returns true for success,
false for failure.
$upload->copy_to('/path/to/target');
Please note the filename used for the copy target is the 'tempname' that
is the actual filename on the filesystem, NOT the 'filename' that was
part of the upload headers. This might seem counter intuitive but at this
point this behavior is so established that its not something we can change.
You can always create your own copy routine that munges the target path
as you wish.
=cut
sub copy_to {
my $self = shift;
return File::Copy::copy( $self->tempname, @_ );
}
=head2 $upload->is_utf8_encoded
Returns true of the upload defines a character set at that value is 'UTF-8'.
This does not try to inspect your upload and make any guesses if the Content
Type charset is undefined.
=cut
sub is_utf8_encoded {
my $self = shift;
if(my $charset = $self->charset) {
return $charset eq 'UTF-8' ? 1 : 0;
}
return 0;
}
=head2 $upload->fh
Opens a temporary file (see tempname below) and returns an L<IO::File> handle.
This is a filehandle that is opened with no additional IO Layers.
=head2 $upload->decoded_fh(?$encoding)
Returns a filehandle that has binmode set to UTF-8 if a UTF-8 character set
is found. This also accepts an override encoding value that you can use to
force a particular L<PerlIO> layer. If neither are found the filehandle is
set to :raw.
This is useful if you are pulling the file into code and inspecting bits and
maybe then sending those bits back as the response. (Please note this is not
a suitable filehandle to set in the body; use C<fh> if you are doing that).
Please note that using this method sets the underlying filehandle IO layer
so once you use this method if you go back and use the C<fh> method you
still get the IO layer applied.
=cut
sub decoded_fh {
my ($self, $layer) = @_;
my $fh = $self->fh;
$layer = ":encoding(UTF-8)" if !$layer && $self->is_utf8_encoded;
$layer = ':raw' unless $layer;
binmode($fh, $layer);
return $fh;
}
=head2 $upload->filename
Returns the client-supplied filename.
=head2 $upload->headers
Returns an L<HTTP::Headers> object for the request.
=head2 $upload->link_to
Creates a hard link to the temporary file. Returns true for success,
false for failure.
$upload->link_to('/path/to/target');
=cut
sub link_to {
my ( $self, $target ) = @_;
return CORE::link( $self->tempname, $target );
}
=head2 $upload->size
Returns the size of the uploaded file in bytes.
=head2 $upload->slurp(?$encoding)
Optionally accepts an argument to define an IO Layer (which is applied to
the filehandle via binmode; if no layer is defined the default is set to
":raw".
Returns a scalar containing the contents of the temporary file.
Note that this will cause the filehandle pointed to by C<< $upload->fh >> to
be reset to the start of the file using seek and the file handle to be put
into whatever encoding mode is applied.
=cut
sub slurp {
my ( $self, $layer ) = @_;
unless ($layer) {
$layer = ':raw';
}
my $content = undef;
my $handle = $self->fh;
binmode( $handle, $layer );
$handle->seek(0, IO::File::SEEK_SET);
while ( $handle->sysread( my $buffer, 8192 ) ) {
$content .= $buffer;
}
$handle->seek(0, IO::File::SEEK_SET);
return $content;
}
=head2 $upload->decoded_slurp(?$encoding)
Works just like C<slurp> except we use C<decoded_fh> instead of C<fh> to
open a filehandle to slurp. This means if your upload charset is UTF8
we binmode the filehandle to that encoding.
=cut
sub decoded_slurp {
my ( $self, $layer ) = @_;
my $handle = $self->decoded_fh($layer);
my $content = undef;
$handle->seek(0, IO::File::SEEK_SET);
while ( $handle->sysread( my $buffer, 8192 ) ) {
$content .= $buffer;
}
$handle->seek(0, IO::File::SEEK_SET);
return $content;
}
=head2 $upload->basename
Returns basename for C<filename>. This filters the name through a regexp
C<basename =~ s|[^\w\.-]+|_|g> to make it safe for filesystems that don't
like advanced characters. This will of course filter UTF8 characters.
If you need the exact basename unfiltered use C<raw_basename>.
=head2 $upload->raw_basename
Just like C<basename> but without filtering the filename for characters that
don't always write to a filesystem.
=head2 $upload->tempname
Returns the path to the temporary file.
=head2 $upload->type
Returns the client-supplied Content-Type.
=head2 $upload->charset
The character set information part of the content type, if any. Useful if you
need to figure out any encodings on the file upload.
=head2 meta
Provided by Moose
=head1 AUTHORS
Catalyst Contributors, see Catalyst.pm
=head1 COPYRIGHT
This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
__PACKAGE__->meta->make_immutable;
1;
|