line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyrights 1999-2022 by [Mark Overmeer ]. |
2
|
|
|
|
|
|
|
# For other contributors see ChangeLog. |
3
|
|
|
|
|
|
|
# See the manual pages for details on the licensing terms. |
4
|
|
|
|
|
|
|
# Pod stripped from pm file by OODoc 2.03. |
5
|
|
|
|
|
|
|
# This code is part of distribution MIME::Types. Meta-POD processed with |
6
|
|
|
|
|
|
|
# OODoc into POD and HTML manual-pages. See README.md |
7
|
|
|
|
|
|
|
# Copyright Mark Overmeer. Licensed under the same terms as Perl itself. |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package MIME::Types; |
10
|
4
|
|
|
4
|
|
281935
|
use vars '$VERSION'; |
|
4
|
|
|
|
|
47
|
|
|
4
|
|
|
|
|
244
|
|
11
|
|
|
|
|
|
|
$VERSION = '2.23'; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
14
|
4
|
|
|
4
|
|
23
|
use strict; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
75
|
|
15
|
|
|
|
|
|
|
|
16
|
4
|
|
|
4
|
|
1489
|
use MIME::Type (); |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
83
|
|
17
|
4
|
|
|
4
|
|
26
|
use File::Spec (); |
|
4
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
73
|
|
18
|
4
|
|
|
4
|
|
19
|
use File::Basename qw(dirname); |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
428
|
|
19
|
4
|
|
|
4
|
|
29
|
use List::Util qw(first); |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
7457
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my %typedb; |
23
|
4
|
|
|
4
|
1
|
262
|
sub new(@) { (bless {}, shift)->init( {@_} ) } |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub init($) |
26
|
4
|
|
|
4
|
0
|
12
|
{ my ($self, $args) = @_; |
27
|
4
|
50
|
|
|
|
28
|
keys %typedb or $self->_read_db($args); |
28
|
4
|
|
|
|
|
35
|
$self; |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub _read_db($) |
32
|
4
|
|
|
4
|
|
12
|
{ my ($self, $args) = @_; |
33
|
4
|
|
|
|
|
10
|
my $skip_extensions = $args->{skip_extensions}; |
34
|
4
|
|
|
|
|
8
|
my $only_complete = $args->{only_complete}; |
35
|
4
|
|
|
|
|
9
|
my $only_iana = $args->{only_iana}; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
my $db = $ENV{PERL_MIME_TYPE_DB} |
38
|
|
|
|
|
|
|
|| $args->{db_file} |
39
|
4
|
|
33
|
|
|
359
|
|| File::Spec->catfile(dirname(__FILE__), 'types.db'); |
40
|
|
|
|
|
|
|
|
41
|
4
|
|
|
|
|
20
|
local *DB; |
42
|
4
|
50
|
|
4
|
|
24
|
open DB, '<:encoding(utf8)', $db |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
21
|
|
|
4
|
|
|
|
|
112
|
|
43
|
|
|
|
|
|
|
or die "cannot open type database in $db: $!\n"; |
44
|
|
|
|
|
|
|
|
45
|
4
|
|
|
|
|
47862
|
while(1) |
46
|
192
|
|
|
|
|
517
|
{ my $header = ; |
47
|
192
|
100
|
|
|
|
383
|
defined $header or last; |
48
|
188
|
|
|
|
|
250
|
chomp $header; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# This logic is entangled with the bin/collect_types script |
51
|
188
|
|
|
|
|
757
|
my ($count, $major, $is_iana, $has_ext) = split /\:/, $header; |
52
|
188
|
100
|
33
|
|
|
929
|
my $skip_section = $major eq 'EXTENSIONS' ? $skip_extensions |
53
|
|
|
|
|
|
|
: (($only_iana && !$is_iana) || ($only_complete && !$has_ext)); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
#warn "Skipping section $header\n" if $skip_section; |
56
|
188
|
|
|
|
|
431
|
(my $section = $major) =~ s/^x-//; |
57
|
188
|
100
|
|
|
|
316
|
if($major eq 'EXTENSIONS') |
58
|
4
|
|
|
|
|
7
|
{ local $_; |
59
|
4
|
|
|
|
|
19
|
while() |
60
|
9016
|
100
|
|
|
|
20512
|
{ last if m/^$/; |
61
|
9012
|
50
|
|
|
|
11384
|
next if $skip_section; |
62
|
9012
|
|
|
|
|
9617
|
chomp; |
63
|
9012
|
50
|
|
|
|
59245
|
$typedb{$section}{$1} = $2 if m/(.*);(.*)/; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
else |
67
|
184
|
|
|
|
|
204
|
{ local $_; |
68
|
184
|
|
|
|
|
454
|
while() |
69
|
12456
|
100
|
|
|
|
28603
|
{ last if m/^$/; |
70
|
12272
|
50
|
|
|
|
15528
|
next if $skip_section; |
71
|
12272
|
|
|
|
|
13204
|
chomp; |
72
|
12272
|
50
|
|
|
|
81460
|
$typedb{$section}{$1} = "$major/$_" if m/^(?:x-)?([^;]+)/; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
4
|
|
|
|
|
128
|
close DB; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Catalyst-Plugin-Static-Simple uses it :( |
81
|
|
|
|
0
|
0
|
|
sub create_type_index {} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
#------------------------------------------- |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub type($) |
86
|
4157
|
|
|
4157
|
1
|
10796
|
{ my $spec = lc $_[1]; |
87
|
4157
|
50
|
|
|
|
6969
|
$spec = 'text/plain' if $spec eq 'text'; # old mailers |
88
|
|
|
|
|
|
|
|
89
|
4157
|
50
|
|
|
|
15338
|
$spec =~ m!^(?:x\-)?([^/]+)/(?:x-)?(.*)! |
90
|
|
|
|
|
|
|
or return; |
91
|
|
|
|
|
|
|
|
92
|
4157
|
50
|
|
|
|
10644
|
my $section = $typedb{$1} or return; |
93
|
4157
|
50
|
|
|
|
10963
|
my $record = $section->{$2} or return; |
94
|
4157
|
100
|
|
|
|
8957
|
return $record if ref $record; # already extended |
95
|
|
|
|
|
|
|
|
96
|
2078
|
|
|
|
|
3026
|
my $simple = $2; |
97
|
2078
|
|
|
|
|
6323
|
my ($type, $ext, $enc) = split m/\;/, $record; |
98
|
2078
|
|
|
|
|
3169
|
my $os = undef; # XXX TODO |
99
|
|
|
|
|
|
|
|
100
|
2078
|
|
|
|
|
6618
|
$section->{$simple} = MIME::Type->new |
101
|
|
|
|
|
|
|
( type => $type |
102
|
|
|
|
|
|
|
, extensions => [split /\,/, $ext] |
103
|
|
|
|
|
|
|
, encoding => $enc |
104
|
|
|
|
|
|
|
, system => $os |
105
|
|
|
|
|
|
|
); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub mimeTypeOf($) |
110
|
25
|
|
|
25
|
1
|
863
|
{ my ($self, $name) = @_; |
111
|
25
|
|
|
|
|
127
|
(my $ext = lc $name) =~ s/.*\.//; |
112
|
25
|
100
|
|
|
|
89
|
my $type = $typedb{EXTENSIONS}{$ext} or return; |
113
|
23
|
|
|
|
|
58
|
$self->type($type); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub addType(@) |
118
|
3
|
|
|
3
|
1
|
61
|
{ my $self = shift; |
119
|
|
|
|
|
|
|
|
120
|
3
|
|
|
|
|
7
|
foreach my $type (@_) |
121
|
3
|
|
|
|
|
5
|
{ my ($major, $minor) = split m!/!, $type->simplified; |
122
|
3
|
|
|
|
|
9
|
$typedb{$major}{$minor} = $type; |
123
|
3
|
|
|
|
|
5
|
$typedb{EXTENSIONS}{$_} = $type for $type->extensions; |
124
|
|
|
|
|
|
|
} |
125
|
3
|
|
|
|
|
11
|
$self; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
sub types() |
130
|
0
|
|
|
0
|
1
|
0
|
{ my $self = shift; |
131
|
0
|
|
|
|
|
0
|
my @types; |
132
|
0
|
|
|
|
|
0
|
foreach my $section (keys %typedb) |
133
|
0
|
0
|
|
|
|
0
|
{ next if $section eq 'EXTENSIONS'; |
134
|
|
|
|
|
|
|
push @types, map $_->type("$section/$_"), |
135
|
0
|
|
|
|
|
0
|
sort keys %{$typedb{$section}}; |
|
0
|
|
|
|
|
0
|
|
136
|
|
|
|
|
|
|
} |
137
|
0
|
|
|
|
|
0
|
@types; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub listTypes() |
142
|
6
|
|
|
6
|
1
|
13
|
{ my $self = shift; |
143
|
6
|
|
|
|
|
11
|
my @types; |
144
|
6
|
|
|
|
|
56
|
foreach my $section (keys %typedb) |
145
|
138
|
100
|
|
|
|
276
|
{ next if $section eq 'EXTENSIONS'; |
146
|
132
|
|
|
|
|
162
|
foreach my $sub (sort keys %{$typedb{$section}}) |
|
132
|
|
|
|
|
13908
|
|
147
|
18246
|
|
|
|
|
34337
|
{ my $record = $typedb{$section}{$sub}; |
148
|
18246
|
50
|
|
|
|
50874
|
push @types, ref $record ? $record->type |
|
|
100
|
|
|
|
|
|
149
|
|
|
|
|
|
|
: $record =~ m/^([^;]+)/ ? $1 : die; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
} |
152
|
6
|
|
|
|
|
21809
|
@types; |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
|
156
|
0
|
|
|
0
|
1
|
0
|
sub extensions { keys %{$typedb{EXTENSIONS}} } |
|
0
|
|
|
|
|
0
|
|
157
|
0
|
|
|
0
|
|
0
|
sub _MojoExtTable() {$typedb{EXTENSIONS}} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
#------------- |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub httpAccept($) |
162
|
7
|
|
|
7
|
1
|
3732
|
{ my $self = shift; |
163
|
7
|
|
|
|
|
12
|
my @listed; |
164
|
|
|
|
|
|
|
|
165
|
7
|
|
|
|
|
40
|
foreach (split /\,\s*/, shift) |
166
|
|
|
|
|
|
|
{ |
167
|
17
|
50
|
|
|
|
89
|
m!^ ([a-zA-Z0-9-]+ | \*) / ( [a-zA-Z0-9+-]+ | \* ) |
168
|
|
|
|
|
|
|
\s* (?: \;\s*q\=\s* ([0-9]+(?:\.[0-9]*)?) \s* )? |
169
|
|
|
|
|
|
|
(\;.* | ) |
170
|
|
|
|
|
|
|
$ !x or next; |
171
|
|
|
|
|
|
|
|
172
|
17
|
|
|
|
|
52
|
my $mime = "$1/$2$4"; |
173
|
17
|
100
|
|
|
|
35
|
my $q = defined $3 ? $3 : 1; # q, default=1 |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# most complex first |
176
|
17
|
100
|
|
|
|
59
|
$q += $4 ? +0.01 : $1 eq '*' ? -0.02 : $2 eq '*' ? -0.01 : 0; |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# keep order |
179
|
17
|
|
|
|
|
31
|
$q -= @listed*0.0001; |
180
|
|
|
|
|
|
|
|
181
|
17
|
|
|
|
|
55
|
push @listed, [ $mime => $q ]; |
182
|
|
|
|
|
|
|
} |
183
|
7
|
|
|
|
|
36
|
map $_->[0], sort {$b->[1] <=> $a->[1]} @listed; |
|
15
|
|
|
|
|
60
|
|
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub httpAcceptBest($@) |
188
|
8
|
|
|
8
|
1
|
1244
|
{ my $self = shift; |
189
|
8
|
100
|
|
|
|
26
|
my @accept = ref $_[0] eq 'ARRAY' ? @{(shift)} : $self->httpAccept(shift); |
|
4
|
|
|
|
|
9
|
|
190
|
8
|
|
|
|
|
9
|
my $match; |
191
|
|
|
|
|
|
|
|
192
|
8
|
|
|
|
|
14
|
foreach my $acc (@accept) |
193
|
10
|
|
|
|
|
17
|
{ $acc =~ s/\s*\;.*//; # remove attributes |
194
|
17
|
|
|
17
|
|
38
|
my $m = $acc !~ s#/\*$## ? first { $_->equals($acc) } @_ |
195
|
|
|
|
|
|
|
: $acc eq '*' ? $_[0] # $acc eq */* |
196
|
10
|
0
|
|
0
|
|
58
|
: first { $_->mediaType eq $acc } @_; |
|
0
|
50
|
|
|
|
0
|
|
197
|
10
|
100
|
|
|
|
52
|
return $m if defined $m; |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
1
|
|
|
|
|
3
|
(); |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
sub httpAcceptSelect($@) |
205
|
4
|
|
|
4
|
1
|
10
|
{ my ($self, $accept) = (shift, shift); |
206
|
4
|
50
|
|
|
|
17
|
my $fns = !@_ ? return () : ref $_[0] eq 'ARRAY' ? shift : [@_]; |
|
|
50
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
4
|
100
|
|
|
|
11
|
unless(defined $accept) |
209
|
1
|
|
|
|
|
3
|
{ my $fn = $fns->[0]; |
210
|
1
|
|
|
|
|
3
|
return ($fn, $self->mimeTypeOf($fn)); |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# create mapping type -> filename |
214
|
3
|
|
|
|
|
4
|
my (%have, @have); |
215
|
3
|
|
|
|
|
7
|
foreach my $fn (@$fns) |
216
|
6
|
50
|
|
|
|
11
|
{ my $type = $self->mimeTypeOf($fn) or next; |
217
|
6
|
|
|
|
|
14
|
$have{$type->simplified} = $fn; |
218
|
6
|
|
|
|
|
14
|
push @have, $type; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
3
|
|
|
|
|
12
|
my $type = $self->httpAcceptBest($accept, @have); |
222
|
3
|
100
|
|
|
|
13
|
defined $type ? ($have{$type}, $type) : (); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
#------------------------------------------- |
226
|
|
|
|
|
|
|
# OLD INTERFACE (version 0.06 and lower) |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
|
229
|
4
|
|
|
4
|
|
43
|
use base 'Exporter'; |
|
4
|
|
|
|
|
18
|
|
|
4
|
|
|
|
|
1949
|
|
230
|
|
|
|
|
|
|
our @EXPORT_OK = qw(by_suffix by_mediatype import_mime_types); |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
my $mime_types; |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub by_suffix($) |
236
|
7
|
|
|
7
|
1
|
6063
|
{ my $filename = shift; |
237
|
7
|
|
66
|
|
|
28
|
$mime_types ||= MIME::Types->new; |
238
|
7
|
|
|
|
|
22
|
my $mime = $mime_types->mimeTypeOf($filename); |
239
|
|
|
|
|
|
|
|
240
|
7
|
100
|
|
|
|
27
|
my @data = defined $mime ? ($mime->type, $mime->encoding) : ('',''); |
241
|
7
|
100
|
|
|
|
28
|
wantarray ? @data : \@data; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub by_mediatype($) |
246
|
8
|
|
|
8
|
1
|
14435
|
{ my $type = shift; |
247
|
8
|
|
33
|
|
|
27
|
$mime_types ||= MIME::Types->new; |
248
|
|
|
|
|
|
|
|
249
|
8
|
|
|
|
|
14
|
my @found; |
250
|
8
|
100
|
100
|
|
|
55
|
if(!ref $type && index($type, '/') >= 0) |
251
|
2
|
|
|
|
|
6
|
{ my $mime = $mime_types->type($type); |
252
|
2
|
50
|
|
|
|
7
|
@found = $mime if $mime; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
else |
255
|
6
|
100
|
|
|
|
111
|
{ my $search = ref $type eq 'Regexp' ? $type : qr/$type/i; |
256
|
6
|
|
|
|
|
25
|
@found = map $mime_types->type($_), |
257
|
|
|
|
|
|
|
grep $_ =~ $search, |
258
|
|
|
|
|
|
|
$mime_types->listTypes; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
8
|
|
|
|
|
930
|
my @data; |
262
|
8
|
|
|
|
|
25
|
foreach my $mime (@found) |
263
|
4126
|
|
|
|
|
7078
|
{ push @data, map [$_, $mime->type, $mime->encoding], |
264
|
|
|
|
|
|
|
$mime->extensions; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
8
|
100
|
|
|
|
1126
|
wantarray ? @data : \@data; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub import_mime_types($) |
272
|
0
|
|
|
0
|
1
|
|
{ my $filename = shift; |
273
|
4
|
|
|
4
|
|
29
|
use Carp; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
410
|
|
274
|
0
|
|
|
|
|
|
croak <<'CROAK'; |
275
|
|
|
|
|
|
|
import_mime_types is not supported anymore: if you have types to add |
276
|
|
|
|
|
|
|
please send them to the author. |
277
|
|
|
|
|
|
|
CROAK |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
1; |