http://qs1969.pair.com?node_id=219314

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

Hi monks, I am trying to convert a lovely perl script into a CGI. The perl script reads in a tab-delimited file, splits it into elements of an array etc so it is easy to manage... However, when the user submit's a file for the CGI to upload, the tab-delimited format of the original file is not preserved when you read it in line by line. This makes it impossible for the script i have written to work. My question is, how can I preserve the format of the contents of a file when it is submitted to a CGI (file upload)?? thanks

Replies are listed 'Best First'.
Re: why do CGI's mess everything up???
by mce (Curate) on Dec 12, 2002 at 14:16 UTC
    Hi,
    Do you use the filefield method in CGI, f.e. (from the CGI docs)
    print $query->filefield(-name=>'uploaded_file', -default=>'starting value', -size=>50, -maxlength=>80);
    -or-
    print $query->filefield('uploaded_file','starting value', 50,80);
    This will not change the contents of the file.

    You can read the file by

    $filename = $query->param('uploaded_file'); while (<$filename>) { print; }
    Note: this is just copy-n-paste from CGI.
    ---------------------------
    Dr. Mark Ceulemans
    Senior Consultant
    IT Masters, Belgium
Re: why do CGI's mess everything up???
by blokhead (Monsignor) on Dec 12, 2002 at 13:25 UTC
    Sounds strange. What exactly does happen to the data? Can your script print it out or save it to a temp file to verify that it's in the correct format? My hunch is that the uploaded file isn't any different from the files you've been testing with in the non-CGI environment, with the possible exception of end-of-line characters. However, I don't think you'll be able to get much more than stabs in the dark from the monks here unless you can post the relevant file-parsing code from your CGI script.

    blokhead

      Hi, i'm still battling this one.
      THE CGI bit #! usr/bin/perl -w use CGI; print STDOUT $query->header(); print STDOUT $query->start_html( -title=> "results"; -BGCOLOR=>"#ccddff"); # Get the file from the html form $file_contents = $query->param('file'); # read the file in line by line while (defined ($line = <$file_contents>)) { $info = $info.$line; } # prints the file contents but loses all tab-delimited formatting. print STDOUT "$info<P>"; # slurp file into scalar variable $data = do { local $/; <$info>; }; # the following does nothing print STDOUT "$data";
      Is there another way that i can read in the file but preserve the file format?? Also, why doesn't printing  $data work?? cheers
        Hi there anonymonk, thanks for posting the code. A few comments for you:

        • You seem to read in the file just fine. I'm willing to bet the farm that the tab-delimited formatting is still in your $info variable. However, when you print the variable to the browser, it won't display the tabs properly. Your browser should treat all whitespace characters as just spaces, so tab alignment won't work. You can verify this by viewing the source of the output in your browser -- the HTML source should show the tab alignment. I'm sure that if you printed out <pre> tags around the data, it would appear better in the browser output.
        • You have a problem when you try to slurp the file contents into $data. More specifically, you try to use the diamond <> operator on a string ($info), which won't work. You can only use this operator on filehandles. This is why nothing was showing up. If you had warnings turned on, you would have seen an error to this effect.
        Otherwise, your code looks good. Of course, I would be remiss if I didn't strongly encourage you to use strict and warnings! This is Perl Monks after all!

        blokhead

Re: why do CGI's mess everything up???
by earthboundmisfit (Chaplain) on Dec 12, 2002 at 15:28 UTC
    Just a guess, but are you using this script on a Windows box? Some browsers insert "\r" as the newline for uploaded data and this subsequently messes up homegrown parsing routines. The way I've gotten around this is to filter for "\r" when saving the data. Here's a sub from a script I'm working on. I'm still working out the taint checking and have a ways to go, but perhaps this will help you out despite still being in its infancy:
    sub write_file() { my $filehandle = shift; my $type = uploadInfo($filehandle)->{'Content-Type'}; die "text files only at this point" unless ($type eq 'text/plain' or +$type eq 'text/html'); print "file: $filehandle of type $type\n\n <PRE>"; open (FH, ">d:/inetpub/wwwroot/repnet/docs/$filehandle") or die "cannot create file: $!"; while (<$filehandle>) { $_ =~ s/\r//g; print; print FH; } print "</PRE>"; close(FH); }
    ---- I am what I read
Re: why do CGI's mess everything up???
by vek (Prior) on Dec 12, 2002 at 13:48 UTC
    Welcome to the Monastery AM. I'm sure there will be someone who can help you out. Unfortunately without any code to look at it's going to be a little difficult to work out what's happening. As blokhead suggests, please post some code.

    -- vek --