2 # $Id: MediaTypes.pm,v 1.1.1.1 2003/08/02 23:39:53 takezoe Exp $
4 package LWP::MediaTypes;
8 LWP::MediaTypes - guess media type for a file or a URL
12 use LWP::MediaTypes qw(guess_media_type);
13 $type = guess_media_type("/tmp/foo.gif");
17 This module provides functions for handling media (also known as
18 MIME) types and encodings. The mapping from file extentions to media
19 types is defined by the F<media.types> file. If the F<~/.media.types>
20 file exists it is used instead.
21 For backwards compatability we will also look for F<~/.mime.types>.
23 The following functions are exported by default:
29 ####################################################################
33 @EXPORT = qw(guess_media_type media_suffix);
34 @EXPORT_OK = qw(add_type add_encoding read_media_types);
35 $VERSION = sprintf("%d.%02d", q$Revision: 1.1.1.1 $ =~ /(\d+)\.(\d+)/);
40 # note: These hashes will also be filled with the entries found in
41 # the 'media.types' file.
44 'txt' => 'text/plain',
45 'html' => 'text/html',
47 'jpg' => 'image/jpeg',
51 'text/plain' => 'txt',
52 'text/html' => 'html',
54 'image/jpeg' => 'jpg',
57 #XXX: there should be some way to define this in the media.types files.
58 my %suffixEncoding = (
69 Data::Dumper->new([\%suffixType, \%suffixExt, \%suffixEncoding],
70 [qw(*suffixType *suffixExt *suffixEncoding)])->Dump;
77 =item guess_media_type($filename_or_url, [$header_to_modify])
79 This function tries to guess media type and encoding for a file or url.
80 It returns the content-type, which is a string like C<"text/html">.
81 In array context it also returns any content-encodings applied (in the
82 order used to encode the file). You can pass a URI object
83 reference, instead of the file name.
85 If the type can not be deduced from looking at the file name,
86 then guess_media_type() will let the C<-T> Perl operator take a look.
87 If this works (and C<-T> returns a TRUE value) then we return
88 I<text/plain> as the type, otherwise we return
89 I<application/octet-stream> as the type.
91 The optional second argument should be a reference to a HTTP::Headers
92 object or any object that implements the $obj->header method in a
93 similar way. When it is present the values of the
94 'Content-Type' and 'Content-Encoding' will be set for this header.
100 my($file, $header) = @_;
101 return undef unless defined $file;
107 #XXX should handle non http:, file: or ftp: URIs differently
109 $fullname = $file; # enable peek at actual file
114 for (file_exts($file)) {
115 # first check this dot part as encoding spec
116 if (exists $suffixEncoding{$_}) {
117 unshift(@encoding, $suffixEncoding{$_});
120 if (exists $suffixEncoding{lc $_}) {
121 unshift(@encoding, $suffixEncoding{lc $_});
126 if (exists $suffixType{$_}) {
127 $ct = $suffixType{$_};
130 if (exists $suffixType{lc $_}) {
131 $ct = $suffixType{lc $_};
135 # don't know nothing about this dot part, bail out
138 unless (defined $ct) {
139 # Take a look at the file
140 if (defined $fullname) {
141 $ct = (-T $fullname) ? "text/plain" : "application/octet-stream";
143 $ct = "application/octet-stream";
148 $header->header('Content-Type' => $ct);
149 $header->header('Content-Encoding' => \@encoding) if @encoding;
152 wantarray ? ($ct, @encoding) : $ct;
156 =item media_suffix($type,...)
158 This function will return all suffixes that can be used to denote the
159 specified media type(s). Wildcard types can be used. In a scalar
160 context it will return the first suffix found.
164 @suffixes = media_suffix('image/*', 'audio/basic');
165 $suffix = media_suffix('text/html');
170 if (!wantarray && @_ == 1 && $_[0] !~ /\*/) {
171 return $suffixExt{$_[0]};
174 my(@suffix, $ext, $type);
177 while(($ext,$type) = each(%suffixType)) {
178 push(@suffix, $ext) if $type =~ /^$_$/;
181 while(($ext,$type) = each(%suffixType)) {
182 push(@suffix, $ext) if $type eq $_;
186 wantarray ? @suffix : $suffix[0];
192 require File::Basename;
193 my @parts = reverse split(/\./, File::Basename::basename($_[0]));
194 pop(@parts); # never consider first part
201 The following functions are only exported by explict request:
205 =item add_type($type, @exts)
207 Associate a list of file extensions with the given media type.
211 add_type("x-world/x-vrml" => qw(wrl vrml));
217 my($type, @exts) = @_;
218 for my $ext (@exts) {
220 $suffixType{$ext} = $type;
222 $suffixExt{$type} = $exts[0] if @exts;
226 =item add_encoding($type, @ext)
228 Associate a list of file extensions with an encoding type.
232 add_encoding("x-gzip" => "gz");
238 my($type, @exts) = @_;
239 for my $ext (@exts) {
241 $suffixEncoding{$ext} = $type;
246 =item read_media_types(@files)
248 Parse media types files and add the type mappings found there.
252 read_media_types("conf/mime.types");
260 local($/, $_) = ("\n", undef); # ensure correct $INPUT_RECORD_SEPARATOR
264 push(@priv_files, "$ENV{HOME}:media.types", "$ENV{HOME}:mime.types")
265 if defined $ENV{HOME}; # Some does not have a home (for instance Win32)
267 push(@priv_files, "$ENV{HOME}/.media.types", "$ENV{HOME}/.mime.types")
268 if defined $ENV{HOME}; # Some doesn't have a home (for instance Win32)
271 # Try to locate "media.types" file, and initialize %suffixType from it
275 @files = map {$_."LWP:media.types"} @INC;
277 @files = map {"$_/LWP/media.types"} @INC;
279 push @files, @priv_files;
281 for $typefile (@files) {
283 open(TYPE, $typefile) || next;
284 LWP::Debug::debug("Reading media types from $typefile");
286 next if /^\s*#/; # comment line
287 next if /^\s*$/; # blank line
288 s/#.*//; # remove end-of-line comments
289 my($type, @exts) = split(' ', $_);
290 add_type($type, @exts);
302 Copyright 1995-1999 Gisle Aas.
304 This library is free software; you can redistribute it and/or
305 modify it under the same terms as Perl itself.