Ovid has asked for the wisdom of the Perl Monks concerning the following question:

The problem: users will be uploading images that will be stored in a database. I have no control over whether they are sending gifs, bmps, jpgs, etc., I need an accurate method of determining the mime type of the incoming file so I can serve the image correctly.

Using CGI.pm, I could try this:

$type = $query->uploadInfo($filename)->{'Content-Type'};
However, browsers like to play "MIMEtype roulette", so this is not an optimal solution.

I've also found File::MMagic, but I have no idea how reliable this is. Has anyone used it before? If so, what are your impressions?

What I have works so far (we're only using jpegs, so that makes it easier), but once I let users at it, I need this to be as accurate as possible.

Any suggestions, or am I taking an entirely wrong approach to this?

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just go the the link and check out our stats.

Replies are listed 'Best First'.
Re: Opinions on determining mime type
by lhoward (Vicar) on Sep 21, 2000 at 03:56 UTC
    I've used Image::Magick to do this before. In my installation I used it to identify the format, convert certain formats to others (for instance, I had it convert all non-animanted GIF's with no transparent colors to PNG's). It is also good for making sure it is a valid image (not some person uploading a word document where they should be uploading a graphic). I also used it to automatically scale the images to a certain maximum allowable size for the site in question. Image::Magic can bia bit heavy, but it is the swiss-army knife of perl image manipulation modules and can handle all common and manu not-so-common image formats.
Re: Opinions on determining mime type
by Fastolfe (Vicar) on Sep 21, 2000 at 17:42 UTC
    It's a pity that browsers/systems cannot agree on what are supposed to be "standard" MIME types. You are correct that sometimes this MIME type will be accurate and other times it will be something generic like "application/octet-stream" even though the browser and its OS know exactly what type of file it is.

    File::MMagic works exactly like the 'file' Unix command. It uses a "magic" file that has identifying characteristics of tons of different file formats and can very accurately determine the type of file.

    What I would do is give preference either to the browser's MIME type (if it's non-generic) or use something like File::MMagic (or perhaps both). Failing either of those, fall back to the extension and do some hard-coded mappings.

(Ovid - update) Re: Opinions on determining mime type
by Ovid (Cardinal) on Sep 21, 2000 at 01:45 UTC
    Update: Because the only users who will be using this functionality will be those with "Administrator" priveleges, they are required to use IE5.x. Does IE5.x always supply the correct mime type, or do I need to consider alternatives?

    In response to ncw: this is being run on NT4, service pack 6 with IIS (yuck!).

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just go the the link and check out our stats.

RE: Opinions on determining mime type
by geektron (Curate) on Sep 21, 2000 at 02:06 UTC
    if what you have works now, i'd suggest beating it up a bit more ( throw some GIFs at it, or some BMPs ) and see if it reliably handles those. then goof up the suffix and see if it handles that.

    if you wanted to try File::MMagic, i'd suggest the same routine of testing to see it's reliability. or, read through the source to see what it's doing differently than you are.

Re: Opinions on determining mime type
by ncw (Friar) on Sep 21, 2000 at 01:46 UTC
    If your server is unix then you could try the file command. I've found this very reliable.

    From the man page :-

    NAME
           file - determine file type
    
    SYNOPSIS
           file  [  -bcnsvzL ] [ -f namefile ] [ -m magicfiles ] file
           ...
    
    DESCRIPTION
           This manual page documents version 3.27 of the  file  com<AD>
           mand.   File tests each argument in an attempt to classify
           it.  There are three sets  of  tests,  performed  in  this
           order:  filesystem tests, magic number tests, and language
           tests.  The first test that succeeds causes the file  type
           to be printed.
    
    Maybe File::MMagic is based on the same technology.