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

I've "discovered" the many variants of fileupload.cgi unfortunetly it just lets a users choose a file and upload it - not what I'd like. I need a script that handles 3 fields; a TITLE (text field), a CATEGORY (text field), and the "choose-file-to-upload" field. Simultaneously I would hope that the 2 text fields are parsed and written to a text file and the choosen file gets uploaded to it's place. I've tried looking at the various scripts to see my options in adapting the script. Unfortunetly I'm not really at the level to understand everything that is going on or at least the more critical components. I understand I could just have two forms but then I wouldn't be able to link CATEGORY and TITLE to what the user would upload later. Is it impossible to send binary data+text values to a script and have the script parse it OK? Am I'm missing something...? Well, besides more Perl knowledge :)

Replies are listed 'Best First'.
Re: File Upload + recording
by btrott (Parson) on Mar 05, 2000 at 11:22 UTC
    Yeah, sending a file from the same form as some "text values" works fine. Have you investigated CGI.pm? You should.

    You can use it to create the form for uploading the file (the form "enctype" has to be "multipart/form-data"). And then you can use it to proces the file upload, the title, and the description.

    use CGI; my $query = new CGI; my $fh = $query->upload('uploaded_file'); open OUTPUT, ">/foo/save" or die "Can't open: $!"; while (<$fh>) { print OUTPUT; } close OUTPUT or die "Can't close: $!"; my $title = $query->param('title'); my $description = $query->param('description'); # now write them to a file...
    CGI.pm also lets you access some metadata about the file, using the "uploadInfo" method. For more info, take a look at the CGI.pm docs.
      Should perhaps be:
      < my $fh = $query->upload('upload_file'); > my $fh = $query->param('uploaded_file'); # file input control is named "uploaded_file" and < open OUTPUT, "/foo/save" or die "Can't open: $!"; > open OUTPUT, "> /foo/save" or die "Can't open: $!";
      One problem I've found is that when uploading files larger than around ~60-70k, I get a problem in trying to instantiate CGI.pm. (Apache flips me the bird and takes me to an error screen). Is this a known problem? Has anyone else struck this?
        You're right about the open on the OUPUT filehandle. I think we're both right on the first thing (param vs. upload), though. :) As the CGI.pm docs say this:
        To be safe, use the upload() function (new in version 2.47). When called with the name of an upload field, upload() returns a filehandle, or undef if the parameter is not a valid filehandle. $fh = $query->upload('uploaded_file');
        Calling param on an uploaded file field gives you a thing that's both a string and a filehandle. Using upload just makes sure you get a filehandle, as it's less of a security risk.

        As to your question re: big uploads: do you get any out of memory errors? 60-70k doesn't seem like *that* big a value. Could it be a POST limitation?

Re: File Upload + recording
by plaid (Chaplain) on Mar 06, 2000 at 02:35 UTC
    The main difference between file uploading and normal forms lies in the way the form values are passed. When a file is uploaded, the target cgi has to expect multipart form data, which is different than the key1=value1&key2=value2 format you may be used to. For an understanding of what multipart data looks like, you might want to scan through the rfc. After you look at the examples though, I'm pretty sure you'll decide that it's not worth it to take the time to parse it yourself. As posted above, CGI.pm has a very clean interface to handling file uploads, and is a great way to go. This post is probably only useful if you care to find out any of the behind-the-scenes working of file upload.