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

Hi monks, I am trying to upload a user-submitted image into my cgi. The problem is that when I try to dispay the image, strange characters appear (ascii ??) e.g. GIF87a@@@@@@@@@@@@@.... The code I am using is;
my $image = $query->param('image'); $image =~ m/^.*(\\|\/)(.*)/; while (<$image>) { print STDOUT $_; }
Can anyone show me where i'm going wrong? thanks

Replies are listed 'Best First'.
Re: uploading images into cgi's
by rob_au (Abbot) on Dec 16, 2002 at 12:32 UTC
    The problem here is that the client browser is expecting a data stream of type text/html, text/plain or alike and as such, when your script sends the content of the uploaded image, this content is inappropriately displayed.

    To effectively address this problem, an alternate content type header, appropriate to the image data type which follows, such as image/gif, needs to be sent in place of the current header information. The appropriate content type header can be determined through use of the File::MMagic module (or the CGI::Upload module which encompasses File::MMagic in conjunction with CGI.pm to facilitate an easy interface for handling uploads).

    It may be worth posting a larger snippet of your code if you would like further suggestions about how to address this problem.

     

    perl -le 'print+unpack("N",pack("B32","00000000000000000000000111111100"))'

Re: uploading images into cgi's
by dingus (Friar) on Dec 16, 2002 at 12:37 UTC
    You need to print out the appropriate content header so that its an image. i.e.
    my $image = $query->param('image'); $image =~ m/^.*(\\|\/)(.*)/; print header('image/gif'); while (<$image>) { print STDOUT $_; }

    Dingus


    Enter any 47-digit prime number to continue.
Re: uploading images into cgi's
by iburrell (Chaplain) on Dec 16, 2002 at 17:25 UTC
    Other people mentioned setting the Content-Type to image/gif or whatever it should be. I don't see where you are opening the file. You should explicity open the file instead of using the implicit filehandle. Your regexp doesn't do anything since you don't use $1. If you are going to parse the path, use File::Basename.

    I will mention that you shouldn't read the binary file like it is a text file. You definitely should set binmode on the filehandle, otherwise you will run into problems if you ever run the program on a machine with different line endings.

    You also shouldn't read the binary file by lines. Either slurp the whole file into a scalar in if you know they won't be too large.

    my $data = do { local $/ = undef; <$image_fh>; };

    Or read and write the file by blocks:

    while (read($image_fh, $buffer, 4096)) { print $buffer; }