File Coverage

blib/lib/CGI/Application/Plugin/Stream.pm
Criterion Covered Total %
statement 55 56 98.2
branch 14 20 70.0
condition 13 16 81.2
subroutine 7 7 100.0
pod 1 1 100.0
total 90 100 90.0


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::Stream;
2              
3 1     1   48657 use 5.006;
  1         5  
  1         188  
4 1     1   6 use strict;
  1         2  
  1         133  
5 1     1   5 use warnings;
  1         7  
  1         49  
6              
7 1     1   2353 use CGI::Application 3.21;
  1         32433  
  1         38  
8 1     1   15 use File::Basename;
  1         2  
  1         172  
9             require Exporter;
10 1     1   7 use vars (qw/@ISA @EXPORT_OK/);
  1         2  
  1         622  
11             @ISA = qw(Exporter);
12              
13             @EXPORT_OK = qw(stream_file);
14              
15             our $VERSION = '2.11';
16              
17             sub stream_file {
18 10     10 1 13168 my ( $self, $file_or_fh, $bytes ) = @_;
19 10   100     58 $bytes ||= 1024;
20 10         14 my ($fh, $basename);
21 10         169 my $size = (stat( $file_or_fh ))[7];
22              
23             # If we have a file path
24 10 100       45 if ( ref( \$file_or_fh ) eq 'SCALAR' ) {
25             # They passed along a scalar, pointing to the path of the file
26             # So we need to open the file
27 2 50       102 open($fh,"<$file_or_fh" ) || return 0;
28             # Now let's go binmode (Thanks, William!)
29 2         8 binmode $fh;
30 2         122 $basename = basename( $file_or_fh );
31             }
32             # We have a file handle.
33             else {
34 8         11 $fh = $file_or_fh;
35 8         17 $basename = 'FILE';
36             }
37              
38             # Use FileHandle to make File::MMagic happy;
39             # bless the filehandle into the FileHandle package to make File::MMagic happy
40 10         1109 require FileHandle;
41 10         15261 bless $fh, "FileHandle";
42              
43             # Check what headers the user has already set and
44             # don't override them.
45 10         44 my %existing_headers = $self->header_props();
46              
47             # Check for a existing type header set with or without a hyphen
48 10 100 100     238 unless ( $existing_headers{'-type'} || $existing_headers{'type'} ) {
49 8         17 my $mime_type;
50              
51 8         13 eval {
52 8         1203 require File::MMagic;
53 8         12144 my $magic = File::MMagic->new();
54 8         4048 $mime_type = $magic->checktype_filehandle($fh);
55             };
56 8 50       203451 warn "Failed to load File::MMagic module to determine mime type: $@" if $@;
57              
58             # Set Default
59 8   50     35 $mime_type ||= 'application/octet-stream';
60              
61 8         71 $self->header_add('-type' => $mime_type);
62             }
63              
64              
65 10 100 66     512 unless ( $existing_headers{'Content_Length'}
66             || $existing_headers{'-Content_Length'}
67             ) {
68 8         27 $self->header_add('-Content_Length' => $size);
69             }
70              
71 10 100 100     385 unless ( $existing_headers{'-attachment'}
      66        
72             || $existing_headers{'attachment'}
73             || grep( /-?content-disposition/i, keys %existing_headers )
74             ) {
75 8         28 $self->header_add('-attachment' => $basename);
76             }
77              
78 10 50       371 unless ( $ENV{'CGI_APP_RETURN_ONLY'} ) {
79 10         31 $self->header_type( 'none' );
80 10         193 print $self->query->header( $self->header_props() );
81             }
82              
83             # This reads in the file in $byte size chunks
84             # File::MMagic may have read some of the file, so seek back to the beginning
85 10         31313 my $output = "";
86 10         79 seek($fh,0,0);
87 10         172 while ( read( $fh, my $buffer, $bytes ) ) {
88 10 50       38 if ( $ENV{'CGI_APP_RETURN_ONLY'} ) {
89 0         0 $output .= $buffer;
90             } else {
91 10         30 print $buffer;
92             }
93             }
94              
95 10 50       119 print '' unless $ENV{'CGI_APP_RETURN_ONLY'}; # print a null string at the end
96 10         268 close ( $fh );
97 10 50       101 return $ENV{'CGI_APP_RETURN_ONLY'} ? \$output : 1;
98             }
99              
100             1;
101             __END__