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

I have a form that allows the user to upload a file and then a cgi script that deals with saving the file and emailing it. I am running into a peculiar problem that I can't seem to even figure out how to query for. The form submits just fine when I use Firefox, but if I try to use IE, I get the following error:
Can't use an undefined value as a HASH reference at ../cgisubs.conf line 32.
And that line is
 my $mime = uploadInfo($filename)->{'Content-Type'};

My hash understanding is very novice, but I'm mostly confused that it works in one browser and not the other. I've never encountered a script problem that was actually because of the browser. Well, I guess there is obviously something wrong with my script, but I'm puzzled at what to look for since it works in one instance and not another.
  • Comment on IE vs. Firefox : Can't use an undefined value as a HASH reference error
  • Download Code

Replies are listed 'Best First'.
Re: IE vs. Firefox : Can't use an undefined value as a HASH reference error
by cbrandtbuffalo (Deacon) on Feb 24, 2005 at 17:15 UTC
    Don't know if I have enough information to nail down your problem, but I can offer a known difference between the two browsers. If you have a form and the submit button has a name, IE won't send the button name if the user just hits 'Return' rather than clicking the button. Firefox will. So maybe the button param isn't getting passed and that's tripping up your 'uploadInfo'?

    Can you post the uploadInfo code?

      Here's the subroutine for storing the file:
      #stores uploaded files sub storeFiles{ my($filename, $directory, $mime) = @_; #name subroutine variables my $data; my $mime = uploadInfo($filename)->{'Content-Type'}; open (STORAGE, ">$directory/$filename") or die "Error: $directory/ +$filename: $!\n"; if($mime !~ /text/){ binmode ($filename); binmode (STORAGE); } while( read($filename, $data, 1024) ){ print STORAGE $data;} close STORAGE; }
      I'm using the following subroutine to get the filename from the form:
      sub Get_File_Name{ if($ENV{HTTP_USER_AGENT} =~ /win/i){ fileparse_set_fstype("MSWin32"); #changed from MSDOS to try a +nd fix the A:\ problem } elsif($ENV{HTTP_USER_AGENT} =~ /mac/i) { fileparse_set_fstype("MacOS"); } my $full_name = shift; $full_name = basename($full_name); $full_name =~ s!\s!\_!g; # Replace whitespace with _ return($full_name); }
      As for the submit button. It just has a generic name of 'submit' which is not used by the script in any way to identify anything.
Re: IE vs. Firefox : Can't use an undefined value as a HASH reference error
by gellyfish (Monsignor) on Feb 24, 2005 at 17:46 UTC

    I'd take a guess that Firefox is setting the content-type of the form to 'multipart/form-data' when it sees the upload field whereas IE is not - you should put the enctype attribute of the form element ie.:

    <form method="post" action="whatever" enctype="multipart/form-data" +>

    /J\

      The form is already set that way. Thanks for the suggestion.
Re: IE vs. Firefox : Can't use an undefined value as a HASH reference error
by Roy Johnson (Monsignor) on Feb 24, 2005 at 18:20 UTC
    In case it's not clear to you, uploadInfo is returning undef -- that's the undefined value the error message is talking about. So the question becomes why is uploadInfo returning undef? And we'd need to see the source of uploadInfo and know what the value of $filename is to answer that.

    Caution: Contents may have been coded under pressure.
      I'm playing my novice card here, but when you ask for the source of uploadInfo, what are you asking for? The code for that function? uploadInfo is from CGI.pm, so you want the source from the CGI module?

      In the form, the field for the file to upload is
      <input type="FILE" name="filename">
      The script then gets the filename:
      $File_Name = Get_File_Name(param('filename')); sub Get_File_Name{ if($ENV{HTTP_USER_AGENT} =~ /win/i){ fileparse_set_fstype("MSWin32"); #changed from MSDOS to try a +nd fix the A:\ problem } elsif($ENV{HTTP_USER_AGENT} =~ /mac/i) { fileparse_set_fstype("MacOS"); } my $full_name = shift; $full_name = basename($full_name); $full_name =~ s!\s!\_!g; # Replace whitespace with _ return($full_name); }
      and calls sub to store the file ($Directory is a path and is already defined):
      storeFiles($File_Name, $Directory); #stores uploaded files sub storeFiles{ my($filename, $directory) = @_; #name subroutine variables my $data; my $mime = uploadInfo($filename)->{'Content-Type'}; open (STORAGE, ">$directory/$filename") or die "Error: $directory/ +$filename: $!\n"; if($mime !~ /text/){ binmode ($filename); binmode (STORAGE); } while( read($filename, $data, 1024) ){ print STORAGE $data;} close STORAGE; }
      I'm guessing the content-type isn't being passed correctly from IE, but I'm not what to change since I've already set the form type as a multipart-form.
        uploadInfo is from CGI.pm, so you want the source from the CGI module?
        That would be the relevant code, yes. Not being a frequent CGI programmer, myself, I didn't recognize that it was a CGI function. So here's the source:
        sub uploadInfo { my($self,$filename) = self_or_default(@_); return $self->{'.tmpfiles'}->{$filename}->{info}; }
        It's a method, and you're calling it as an ordinary sub.

        Update: as dragonchild points out, that's not the problem. So the critical issue looks like: what is the value of $filename? It may require some exploration and dumping of data to see what value it should have in order to work.


        Caution: Contents may have been coded under pressure.
Re: IE vs. Firefox : Can't use an undefined value as a HASH reference error
by dragonchild (Archbishop) on Feb 24, 2005 at 17:15 UTC
    Verify that $filename is in the case you expect it to be. Win32 is case-insensitive while Unix (which I'm assuming you're running this on) is case-sensitive.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.