http://qs321.pair.com?node_id=21924

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

Your exellence, greatest monks and not so greate. I'm asking to help me in one problem. I'm just the beginner in Perl wisdom and surely have some problems.. It is in CGI. When I want to transmit some files from form, I use "enctype=multipart/form-data" and "method=post". In script:
read(STDIN,$form_data,$ENV{'CONTENT_LENGTH'}); open (FILE,""something.log"); print $form_data; close(FILE);
Doing all that and then checking have this: in file "something.log": ------------- 1234567890 #(just some --- and some numbers Maybe something wrong... I couldn't make anything myself. I really need a wisdom advise...

Replies are listed 'Best First'.
RE: Asking for help from anyone...
by le (Friar) on Jul 11, 2000 at 11:53 UTC
    You are strongly advised to use the CGI.pm module whenever you want to do something in CGI.
RE: Asking for help from anyone...
by davorg (Chancellor) on Jul 11, 2000 at 12:08 UTC

    a) Please post code examples between <code>...</code> tags so that we can read them.

    b) File uploading is really very easy using CGI.pm. There's no good reason not to use it.

    --
    <http://www.dave.org.uk>

    European Perl Conference - Sept 22/24 2000, ICA, London
    <http://www.yapc.org/Europe/>
RE: Asking for help from anyone...
by c-era (Curate) on Jul 11, 2000 at 15:16 UTC
    Original code:
    read(STDIN,$form_data,$ENV{'CONTENT_LENGTH'}); open (FILE,""something.log"); print $form_data; close(FILE);
    First, you are not doing anything with the file. Second, if you want to send html back you need to print "Content-type: text/html\n\n"
    # Get form information if ($ENV{'REQUEST_METHOD'} eq "GET") { # GET Method $form_data = $ENV{'QUERY_STRING'}; } elsif ( $ENV{'CONTENT_LENGTH'} > 0 ) { # POST Methond read(STDIN, $form_data, $ENV{'CONTENT_LENGTH'}); } else { exit; } # Error handling # To print the form info to a file open (FILE,">>something.log"); # Open the file in append mode flock (FILE,2); # Exclusive lock print FILE $form_data; # Print the form to the file # To print the file as a responce open (FILE,"<something.log"); # Open the file in read mode flock (FILE,1); # Sharded lock print "Content-type: text/html\n\n"; # Print HTTP header print <FILE>; # Print file close(FILE); # Close and unlock the file
    Hope that helps.

    PS Not everyone can use CGI.pm. Some places do not like extra moduals to deal with, so it is always helpful to know the raw way of doing something.

      I thought CGI.pm is part of the standard Perl distribution?!

        It is. And has been since 5.004_04. Anyone still using a version of Perl earlier than that is beyond help.

        And besides, I'd rather deal with extra modules than a dozen programmers each implementing their own CGI parameter parsing routine - each with its own little bugs.

        --
        <http://www.dave.org.uk>

        European Perl Conference - Sept 22/24 2000, ICA, London
        <http://www.yapc.org/Europe/>
      This is incorrect. What this will do is print into the file the exact thing that the poster got: a bunch of hyphens followed by a bunch of numbers/letters. Multipart form data does not work by reading in the CONTENT_LENGTH amount of bytes. Check out rfc 1867 for a description.
Re: Asking for help from anyone...
by plaid (Chaplain) on Jul 11, 2000 at 23:53 UTC
    While I agree that using CGI.pm is the way to go for this, especially for parsing multipart data, a bit of theory may help. For a better description of this, you'd probably want to check out rfc 1867.

    Once you start using multipart data, the normal reading from STDIN and grabbing $ENV{CONTENT_LENGTH} bytes doesn't work any more. Multipart data instead uses the idea of a boundary to delimit the different fields on a form. A boundary looks like you described, a series of hyphens followed by a unique string of numbers and letters. If you do read in just the CONTENT_LENGTH amount of bytes, you'll just get this boundary.

    If you really want to get a look at what the data looks like, you'll want to do something like

    read(STDIN, $form_data, 10000000); #just get everything
    Once you get a look at what the actual multipart data looks like, I'm sure you'll reach the same conclusion I did when I considered writing a CGI parser to handle this type of thing a while back: it's really not worth it.