Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

CGI.pm and filehandle woes

by Elijah (Hermit)
on Mar 27, 2007 at 19:01 UTC ( [id://606837]=perlquestion: print w/replies, xml ) Need Help??

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

It seems that CGI.pm has a nice little bug that gets in the way of normal filehandle processing. I was trying to write a simple perl/cgi file upload script to upload binary files as blobs into MySQL and ran into this nifty little issue.

The problem seems to be that cgi.pm messes with the filehandle to make it more "lightweight/nonusable". I built a simple html form using an input type of of file and a enctype of multipart/form-data. Using the input "file" type browse button to select a file off the local filesystem and submitting the form renders this output in my browser:

Filename => dos_performance.xls Size => 106496 Content-Type: text/html; charset=ISO-8859-1 Undefined subroutine Fh::s +eek at /usr/lib/perl5/site_perl/5.8.6/File/MimeInfo/Magic.pm line 97
Here is the subroutine I have the form send to:
sub upload { my ($obj, $db) = @_; my $project_id = $PTS::QUERY_STRING{'pid'}; my $user_id = $PTS::QUERY_STRING{'uid'}; my $fname = $PTS::QUERY_STRING{'fname'}; my $filehandle = $PTS::CGI->upload('fname'); my $size = -s $filehandle; print $PTS::CGI->header(); print "Filename => $fname\n<br>"; print "Size => $size\n<br>"; push @Fh::ISA, 'IO::Seekable' unless $filehandle->isa('IO::Seekabl +e'); push @Fh::ISA, 'IO::Handle' unless $filehandle->isa('IO::Handle'); print "Mime Type => ".File::MimeInfo::Magic->magic($filehandle)."\ +n<br>"; #show($obj, $db); }
It seems that File::MimeInfo::Magic has a problem with the filehandle that is returned by CGI.pm. As you can see I have tried to re-add some of the missing parent objects but this still fails. AM I not doing this correctly? How would one go about checking the mimetype of data in buffer without having to write out a tmp file just to get the mimetype. I am not storing the file on the filesystem, but in a database so the intermediate step if writing the file out would waste cycles being written and then waste cycles having to be deleted.

Anyone have any ideas on how to get this working?

Replies are listed 'Best First'.
Re: CGI.pm and filehandle woes
by Sidhekin (Priest) on Mar 27, 2007 at 19:12 UTC

    Anyone have any ideas on how to get this working?

    As I said in the CB, I've worked around CGI's lightweight, crippled, overloaded file handle by making it inherit from the necessary classes. Assuming the classes are already loaded:

    push @Fh::ISA, 'IO::Seekable' unless Fh->isa('IO::Seekable'); push @Fh::ISA, 'IO::Handle' unless Fh->isa('IO::Handle'); my $mimetype = File::MMagic->new->checktype_filehandle($filehandle);

    As long as the $filehandle provided by CGI is a globref, blessed to the Fh class, and sysopened on the tempfile (as it is today), this works. Plenty hacky, but it works, at least for File::MMagic.

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

      Actually, it appears I owe you an apology, I was trying to use your method with File::MimeInfo::Magic which does a seek on the filehandle and it did not work, I installed File::MMagic and used your suggestion and it seems to work fine. The weird thing is that File::MMagic does a seek on the filehandle also.
      Yeah from our conversation in CB, I have tried your suggestion and still get the error.

        Yeah from our conversation in CB, I have tried your suggestion and still get the error.

        Okay, I have installed your choice of module, and it works here. I'm beginning to suspect that you have not loaded the necessary modules. Try adding these lines before the mess above:

        require IO::Seekable; require IO::Handle;

        (If you still get the same error, something else is messing with inheritence.)

        print "Just another Perl ${\(trickster and hacker)},"
        The Sidhekin proves Sidhe did it!

      If this works well, have you considered getting patch into CGI.pm that does the same thing? Your solution seems like it would work to me.
Re: CGI.pm and filehandle woes
by sgifford (Prior) on Mar 27, 2007 at 19:16 UTC
    In general, if a filehandle isn't seekable, it's not enough to add classes to its @ISA list. You have to find a way to avoid seeking, or else write to a temporary file and then re-open that (using, for example, File::Temp).

    Non-seekable filehandles often come from pipes or network reads. In these cases, it's simply not possible to seek forwards and backwards in the file: once the data is read, it is gone.

    I'm not sure of the details of how CGI handles uploaded files, but hopefully that will get you pointed in the right direction.

Re: CGI.pm and filehandle woes
by Zaxo (Archbishop) on Mar 27, 2007 at 19:24 UTC

    CGI::uploadInfo() should return a hashref to all the uploaded file's headers. I don't think there is anything unusual about the filehandle returned by upload(). I'm suspicious of shoving your handle into IO::Seekable if it isn't already, but the buffer should be seekable so I don't think that's contrubuting anything to the real problem.

    You appear to have a lot of external variables in your sub. Are these always doing what you expect? Consider the effect of closures. Using strict may help sort things out.

    After Compline,
    Zaxo

      I always use strict and warnings, I am not sure what you mean by "external variables". This sub is just full of debug code right now to show me what CGI is ending me. I am simply assigning CGI passed params to local variables and using those, that is the strict way. :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://606837]
Approved by Joost
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (6)
As of 2024-04-19 14:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found