source: main/trunk/greenstone2/perllib/cpan/LWP/MediaTypes.pm@ 27183

Last change on this file since 27183 was 27183, checked in by davidb, 11 years ago

Changing to using installed version of LWP that comes from libwww-perl, which is more self-contained than v6.x

File size: 6.8 KB
Line 
1package LWP::MediaTypes;
2
3require 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 = "5.835";
8
9use strict;
10
11# note: These hashes will also be filled with the entries found in
12# the 'media.types' file.
13
14my %suffixType = (
15 'txt' => 'text/plain',
16 'html' => 'text/html',
17 'gif' => 'image/gif',
18 'jpg' => 'image/jpeg',
19 'xml' => 'text/xml',
20);
21
22my %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.
31my %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
40read_media_types();
41
42
43
44sub _dump {
45 require Data::Dumper;
46 Data::Dumper->new([\%suffixType, \%suffixExt, \%suffixEncoding],
47 [qw(*suffixType *suffixExt *suffixEncoding)])->Dump;
48}
49
50
51sub guess_media_type
52{
53 my($file, $header) = @_;
54 return undef unless defined $file;
55
56 my $fullname;
57 if (ref($file)) {
58 # assume URI object
59 $file = $file->path;
60 #XXX should handle non http:, file: or ftp: URIs differently
61 }
62 else {
63 $fullname = $file; # enable peek at actual file
64 }
65
66 my @encoding = ();
67 my $ct = undef;
68 for (file_exts($file)) {
69 # first check this dot part as encoding spec
70 if (exists $suffixEncoding{$_}) {
71 unshift(@encoding, $suffixEncoding{$_});
72 next;
73 }
74 if (exists $suffixEncoding{lc $_}) {
75 unshift(@encoding, $suffixEncoding{lc $_});
76 next;
77 }
78
79 # check content-type
80 if (exists $suffixType{$_}) {
81 $ct = $suffixType{$_};
82 last;
83 }
84 if (exists $suffixType{lc $_}) {
85 $ct = $suffixType{lc $_};
86 last;
87 }
88
89 # don't know nothing about this dot part, bail out
90 last;
91 }
92 unless (defined $ct) {
93 # Take a look at the file
94 if (defined $fullname) {
95 $ct = (-T $fullname) ? "text/plain" : "application/octet-stream";
96 }
97 else {
98 $ct = "application/octet-stream";
99 }
100 }
101
102 if ($header) {
103 $header->header('Content-Type' => $ct);
104 $header->header('Content-Encoding' => \@encoding) if @encoding;
105 }
106
107 wantarray ? ($ct, @encoding) : $ct;
108}
109
110
111sub media_suffix {
112 if (!wantarray && @_ == 1 && $_[0] !~ /\*/) {
113 return $suffixExt{lc $_[0]};
114 }
115 my(@type) = @_;
116 my(@suffix, $ext, $type);
117 foreach (@type) {
118 if (s/\*/.*/) {
119 while(($ext,$type) = each(%suffixType)) {
120 push(@suffix, $ext) if $type =~ /^$_$/i;
121 }
122 }
123 else {
124 my $ltype = lc $_;
125 while(($ext,$type) = each(%suffixType)) {
126 push(@suffix, $ext) if lc $type eq $ltype;
127 }
128 }
129 }
130 wantarray ? @suffix : $suffix[0];
131}
132
133
134sub file_exts
135{
136 require File::Basename;
137 my @parts = reverse split(/\./, File::Basename::basename($_[0]));
138 pop(@parts); # never consider first part
139 @parts;
140}
141
142
143sub add_type
144{
145 my($type, @exts) = @_;
146 for my $ext (@exts) {
147 $ext =~ s/^\.//;
148 $suffixType{$ext} = $type;
149 }
150 $suffixExt{lc $type} = $exts[0] if @exts;
151}
152
153
154sub add_encoding
155{
156 my($type, @exts) = @_;
157 for my $ext (@exts) {
158 $ext =~ s/^\.//;
159 $suffixEncoding{$ext} = $type;
160 }
161}
162
163
164sub read_media_types
165{
166 my(@files) = @_;
167
168 local($/, $_) = ("\n", undef); # ensure correct $INPUT_RECORD_SEPARATOR
169
170 my @priv_files = ();
171 if($^O eq "MacOS") {
172 push(@priv_files, "$ENV{HOME}:media.types", "$ENV{HOME}:mime.types")
173 if defined $ENV{HOME}; # Some does not have a home (for instance Win32)
174 }
175 else {
176 push(@priv_files, "$ENV{HOME}/.media.types", "$ENV{HOME}/.mime.types")
177 if defined $ENV{HOME}; # Some doesn't have a home (for instance Win32)
178 }
179
180 # Try to locate "media.types" file, and initialize %suffixType from it
181 my $typefile;
182 unless (@files) {
183 if($^O eq "MacOS") {
184 @files = map {$_."LWP:media.types"} @INC;
185 }
186 else {
187 @files = map {"$_/LWP/media.types"} @INC;
188 }
189 push @files, @priv_files;
190 }
191 for $typefile (@files) {
192 local(*TYPE);
193 open(TYPE, $typefile) || next;
194 while (<TYPE>) {
195 next if /^\s*#/; # comment line
196 next if /^\s*$/; # blank line
197 s/#.*//; # remove end-of-line comments
198 my($type, @exts) = split(' ', $_);
199 add_type($type, @exts);
200 }
201 close(TYPE);
202 }
203}
204
2051;
206
207
208__END__
209
210=head1 NAME
211
212LWP::MediaTypes - guess media type for a file or a URL
213
214=head1 SYNOPSIS
215
216 use LWP::MediaTypes qw(guess_media_type);
217 $type = guess_media_type("/tmp/foo.gif");
218
219=head1 DESCRIPTION
220
221This module provides functions for handling media (also known as
222MIME) types and encodings. The mapping from file extensions to media
223types is defined by the F<media.types> file. If the F<~/.media.types>
224file exists it is used instead.
225For backwards compatibility we will also look for F<~/.mime.types>.
226
227The following functions are exported by default:
228
229=over 4
230
231=item guess_media_type( $filename )
232
233=item guess_media_type( $uri )
234
235=item guess_media_type( $filename_or_uri, $header_to_modify )
236
237This function tries to guess media type and encoding for a file or a URI.
238It returns the content type, which is a string like C<"text/html">.
239In array context it also returns any content encodings applied (in the
240order used to encode the file). You can pass a URI object
241reference, instead of the file name.
242
243If the type can not be deduced from looking at the file name,
244then guess_media_type() will let the C<-T> Perl operator take a look.
245If this works (and C<-T> returns a TRUE value) then we return
246I<text/plain> as the type, otherwise we return
247I<application/octet-stream> as the type.
248
249The optional second argument should be a reference to a HTTP::Headers
250object or any object that implements the $obj->header method in a
251similar way. When it is present the values of the
252'Content-Type' and 'Content-Encoding' will be set for this header.
253
254=item media_suffix( $type, ... )
255
256This function will return all suffixes that can be used to denote the
257specified media type(s). Wildcard types can be used. In a scalar
258context it will return the first suffix found. Examples:
259
260 @suffixes = media_suffix('image/*', 'audio/basic');
261 $suffix = media_suffix('text/html');
262
263=back
264
265The following functions are only exported by explicit request:
266
267=over 4
268
269=item add_type( $type, @exts )
270
271Associate a list of file extensions with the given media type.
272Example:
273
274 add_type("x-world/x-vrml" => qw(wrl vrml));
275
276=item add_encoding( $type, @ext )
277
278Associate a list of file extensions with an encoding type.
279Example:
280
281 add_encoding("x-gzip" => "gz");
282
283=item read_media_types( @files )
284
285Parse media types files and add the type mappings found there.
286Example:
287
288 read_media_types("conf/mime.types");
289
290=back
291
292=head1 COPYRIGHT
293
294Copyright 1995-1999 Gisle Aas.
295
296This library is free software; you can redistribute it and/or
297modify it under the same terms as Perl itself.
298
Note: See TracBrowser for help on using the repository browser.