File Coverage

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


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::Stream;
2              
3 1     1   19576 use 5.006;
  1         3  
  1         31  
4 1     1   5 use strict;
  1         1  
  1         34  
5 1     1   6 use warnings;
  1         16  
  1         57  
6              
7 1     1   744 use CGI::Application 3.21;
  1         7644  
  1         30  
8 1     1   9 use File::Basename;
  1         1  
  1         97  
9             require Exporter;
10 1     1   6 use vars (qw/@ISA @EXPORT_OK/);
  1         2  
  1         489  
11             @ISA = qw(Exporter);
12              
13             @EXPORT_OK = qw(stream_file);
14              
15             our $VERSION = '2.12';
16              
17             sub stream_file {
18 11     11 1 15244 my ( $self, $file_or_fh, $bytes ) = @_;
19 11   100     68 $bytes ||= 1024;
20 11         33 my ($fh, $basename);
21 11         172 my $size = (stat( $file_or_fh ))[7];
22              
23             # If we have a file path
24 11 100       61 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       105 open($fh,"<$file_or_fh" ) || return 0;
28             # Now let's go binmode (Thanks, William!)
29 2         9 binmode $fh;
30 2         120 $basename = basename( $file_or_fh );
31             }
32             # We have a file handle.
33             else {
34 9         17 $fh = $file_or_fh;
35 9         21 $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 11         857 require FileHandle;
41 11         12052 bless $fh, "FileHandle";
42              
43             # Check what headers the user has already set and
44             # don't override them.
45 11         52 my %existing_headers = $self->header_props();
46              
47             # Check for a existing type header set with or without a hyphen
48 11 100 100     284 unless ( $existing_headers{'-type'} || $existing_headers{'type'} ) {
49 9         11 my $mime_type;
50              
51 9         17 eval {
52 9         911 require File::MMagic;
53 9         6282 my $magic = File::MMagic->new();
54 9         4260 $mime_type = $magic->checktype_filehandle($fh);
55             };
56 9 50       204950 warn "Failed to load File::MMagic module to determine mime type: $@" if $@;
57              
58             # Set Default
59 9   50     39 $mime_type ||= 'application/octet-stream';
60              
61 9         70 $self->header_add('-type' => $mime_type);
62             }
63              
64              
65 11 100 66     668 unless ( $existing_headers{'Content_Length'}
66             || $existing_headers{'-Content_Length'}
67             ) {
68 9         34 $self->header_add('-Content_Length' => $size);
69             }
70              
71 11 100 100     454 unless ( $existing_headers{'-attachment'}
      100        
72             || $existing_headers{'attachment'}
73             || grep( /-?content(-|_)disposition/i, keys %existing_headers )
74             ) {
75 8         31 $self->header_add('-attachment' => $basename);
76             }
77              
78 11 50       317 unless ( $ENV{'CGI_APP_RETURN_ONLY'} ) {
79 11         33 $self->header_type( 'none' );
80 11         216 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 11         29844 my $output = "";
86 11         67 seek($fh,0,0);
87 11         174 while ( read( $fh, my $buffer, $bytes ) ) {
88 11 50       45 if ( $ENV{'CGI_APP_RETURN_ONLY'} ) {
89 0         0 $output .= $buffer;
90             } else {
91 11         71 print $buffer;
92             }
93             }
94              
95 11 50       135 print '' unless $ENV{'CGI_APP_RETURN_ONLY'}; # print a null string at the end
96 11         287 close ( $fh );
97 11 50       131 return $ENV{'CGI_APP_RETURN_ONLY'} ? \$output : 1;
98             }
99              
100             1;
101             __END__