File Coverage

blib/lib/LWP/MediaTypes.pm
Criterion Covered Total %
statement 72 77 93.5
branch 34 46 73.9
condition 4 6 66.6
subroutine 7 7 100.0
pod 5 6 83.3
total 122 142 85.9


line stmt bran cond sub pod time code
1             package LWP::MediaTypes;
2              
3             require Exporter;
4             @ISA = qw(Exporter);
5             @EXPORT = qw(guess_media_type media_suffix);
6             @EXPORT_OK = qw(add_type add_encoding read_media_types);
7             $VERSION = "6.02";
8              
9 1     1   5865 use strict;
  1         3  
  1         1130  
10              
11             # note: These hashes will also be filled with the entries found in
12             # the 'media.types' file.
13              
14             my %suffixType = (
15             'txt' => 'text/plain',
16             'html' => 'text/html',
17             'gif' => 'image/gif',
18             'jpg' => 'image/jpeg',
19             'xml' => 'text/xml',
20             );
21              
22             my %suffixExt = (
23             'text/plain' => 'txt',
24             'text/html' => 'html',
25             'image/gif' => 'gif',
26             'image/jpeg' => 'jpg',
27             'text/xml' => 'xml',
28             );
29              
30             #XXX: there should be some way to define this in the media.types files.
31             my %suffixEncoding = (
32             'Z' => 'compress',
33             'gz' => 'gzip',
34             'hqx' => 'x-hqx',
35             'uu' => 'x-uuencode',
36             'z' => 'x-pack',
37             'bz2' => 'x-bzip2',
38             );
39              
40             read_media_types();
41              
42              
43              
44             sub guess_media_type
45             {
46 24     24 1 7677 my($file, $header) = @_;
47 24 50       55 return undef unless defined $file;
48              
49 24         23 my $fullname;
50 24 100       47 if (ref($file)) {
51             # assume URI object
52 4         11 $file = $file->path;
53             #XXX should handle non http:, file: or ftp: URIs differently
54             }
55             else {
56 20         25 $fullname = $file; # enable peek at actual file
57             }
58              
59 24         63 my @encoding = ();
60 24         26 my $ct = undef;
61 24         43 for (file_exts($file)) {
62             # first check this dot part as encoding spec
63 28 100       63 if (exists $suffixEncoding{$_}) {
64 10         20 unshift(@encoding, $suffixEncoding{$_});
65 10         14 next;
66             }
67 18 100       37 if (exists $suffixEncoding{lc $_}) {
68 2         7 unshift(@encoding, $suffixEncoding{lc $_});
69 2         5 next;
70             }
71              
72             # check content-type
73 16 100       39 if (exists $suffixType{$_}) {
74 14         25 $ct = $suffixType{$_};
75 14         18 last;
76             }
77 2 50       6 if (exists $suffixType{lc $_}) {
78 0         0 $ct = $suffixType{lc $_};
79 0         0 last;
80             }
81              
82             # don't know nothing about this dot part, bail out
83 2         3 last;
84             }
85 24 100       53 unless (defined $ct) {
86             # Take a look at the file
87 10 100       19 if (defined $fullname) {
88 8 100       233 $ct = (-T $fullname) ? "text/plain" : "application/octet-stream";
89             }
90             else {
91 2         4 $ct = "application/octet-stream";
92             }
93             }
94              
95 24 100       53 if ($header) {
96 1         5 $header->header('Content-Type' => $ct);
97 1 50       15 $header->header('Content-Encoding' => \@encoding) if @encoding;
98             }
99              
100 24 100       94 wantarray ? ($ct, @encoding) : $ct;
101             }
102              
103              
104             sub media_suffix {
105 3 50 66 3 1 1359 if (!wantarray && @_ == 1 && $_[0] !~ /\*/) {
      66        
106 1         7 return $suffixExt{lc $_[0]};
107             }
108 2         5 my(@type) = @_;
109 2         2 my(@suffix, $ext, $type);
110 2         24 foreach (@type) {
111 2 50       12 if (s/\*/.*/) {
112 2         10 while(($ext,$type) = each(%suffixType)) {
113 1766 100       8621 push(@suffix, $ext) if $type =~ /^$_$/i;
114             }
115             }
116             else {
117 0         0 my $ltype = lc $_;
118 0         0 while(($ext,$type) = each(%suffixType)) {
119 0 0       0 push(@suffix, $ext) if lc $type eq $ltype;
120             }
121             }
122             }
123 2 50       52 wantarray ? @suffix : $suffix[0];
124             }
125              
126              
127             sub file_exts
128             {
129 24     24 0 115 require File::Basename;
130 24         656 my @parts = reverse split(/\./, File::Basename::basename($_[0]));
131 24         37 pop(@parts); # never consider first part
132 24         71 @parts;
133             }
134              
135              
136             sub add_type
137             {
138 2065     2065 1 3338 my($type, @exts) = @_;
139 2065         2804 for my $ext (@exts) {
140 2651         2878 $ext =~ s/^\.//;
141 2651         6082 $suffixType{$ext} = $type;
142             }
143 2065 50       12812 $suffixExt{lc $type} = $exts[0] if @exts;
144             }
145              
146              
147             sub add_encoding
148             {
149 2     2 1 5 my($type, @exts) = @_;
150 2         4 for my $ext (@exts) {
151 2         3 $ext =~ s/^\.//;
152 2         8 $suffixEncoding{$ext} = $type;
153             }
154             }
155              
156              
157             sub read_media_types
158             {
159 1     1 1 2 my(@files) = @_;
160              
161 1         6 local($/, $_) = ("\n", undef); # ensure correct $INPUT_RECORD_SEPARATOR
162              
163 1         2 my @priv_files = ();
164 1 50       7 push(@priv_files, "$ENV{HOME}/.media.types", "$ENV{HOME}/.mime.types")
165             if defined $ENV{HOME}; # Some doesn't have a home (for instance Win32)
166              
167             # Try to locate "media.types" file, and initialize %suffixType from it
168 1         2 my $typefile;
169 1 50       4 unless (@files) {
170 1         2 @files = map {"$_/LWP/media.types"} @INC;
  11         23  
171 1         3 push @files, @priv_files;
172             }
173 1         3 for $typefile (@files) {
174 13         28 local(*TYPE);
175 13 100       448 open(TYPE, $typefile) || next;
176 3         98 while () {
177 4437 100       15324 next if /^\s*#/; # comment line
178 2064 50       5106 next if /^\s*$/; # blank line
179 2064         2480 s/#.*//; # remove end-of-line comments
180 2064         5561 my($type, @exts) = split(' ', $_);
181 2064         12523 add_type($type, @exts);
182             }
183 3         63 close(TYPE);
184             }
185             }
186              
187             1;
188              
189              
190             __END__