in reply to amelinda's HTTP/MIME/file upload/not-a-cgi-but-a-client/minimal-module/perl problem

And because I am a hardheaded S.O.B., I will still try to prove a point. Here's both the server and client side example of using HTML::Form to upload a file.

Put the first file in your cgi-bin directory, and set it to be executable. A good name would be 'htmlformtest.pl'. Make sure you can get to it with your web browser. Put the second file in your user directory. Change the '$site' variable to point to the script in the cgi-bin directory. Run it. You should find a file in your local directory called 'testfile.text, and a file in /tmp, called 'uploaded.file'. These two files should be indentical in content. It seems to work here.

Some of this code isn't pretty, doesn't do enough error checking, etc. It's demo code.
#!/usr/local/bin/perl -w use strict; use CGI; use IO::File; use POSIX qw (tmpnam); my $finalname = '/tmp/uploaded.file'; { my $tmpnam; my $html = new CGI; print $html->header; if (!defined ($html->param ('uploadname')) || $html->param ('upload +name') eq '') { print while (<DATA>); print $html->end_html; exit; } my $fn = $html->param ('uploadname'); my $fh = $html->upload ('uploadname'); my $fd = ''; if (!defined ($fh)) { print "\$fh is not defined!\n"; print $html->end_html; exit; } while ((length ($fd) <= (64 * 1024)) && read ($fh, my $buffer, 1024 +)) { $fd .= $buffer; } if (length ($fd) == (64 * 1024)) { print "File too big!"; print $html->end_html; exit; } # # Get a temporary file name we know is ours. The loop resolves th +e race condition possibility. # for (;;) { $tmpnam = tmpnam (); sysopen (TMP, $tmpnam, O_RDWR | O_CREAT | O_EXCL) && last; } close (TMP); # # Create the temporary input file for the size-getter and thumbnai +l maker # if (open (SOURCE, ">$tmpnam")) { print SOURCE $fd; close SOURCE; } else { print "Couldn't open $tmpnam for writing: $!"; print $html->end_html; exit; } rename ($tmpnam, $finalname); print "File uploaded OK, saved as $finalname"; exit; } __DATA__ <HTML> <HEAD> <TITLE>File Upload Test</TITLE> </HEAD> <BODY> <FORM METHOD="POST" ENCTYPE="multipart/form-data"> <TABLE BORDER="0" ALIGN="CENTER"> <TR> <TD ALIGN="CENTER"> <P>Select file to upload: <INPUT TYPE="FILE" NAME="uploadn +ame"></P> </TD> </TR> <TR> <TD>&nbsp;</TD> </TR> <TR> <TD ALIGN="CENTER"> <INPUT TYPE="SUBMIT" NAME="sendfile" CHECKED="CHECKED" VAL +UE="Send me that file, Cowboy!"> </TD> </TR> </TABLE> </FORM> </BODY> </HTML>

#!/usr/local/bin/perl -w use strict; use Carp; use LWP::UserAgent; use LWP::Simple; use HTML::Form; my $site = 'http://linux/release/cgi-bin/htmlformtest.pl'; my $testfile = './testfile.txt'; # # # { if (!-e $testfile) { open (FH, ">$testfile") || die $!; print FH "\nThis is a test file.\n"; print FH "It has been uploaded via HTML::Form\n"; print FH "And it has 5 lines in it.\n\n"; close FH; } my $req = get ($site); die "Eeek! Request failed.\n" if !$req; # # # my $form = HTML::Form->parse ($req, $site); if ($form->find_input ('uploadname')) { $form->value ('uploadname', [$testfile => [$testfile]]); my $userAgent = LWP::UserAgent->new; my $res = $userAgent->request ($form->click); die sprintf ("Eeek! Request failed (%s)\n", $res->status_line) u +nless ($res->is_success); print "\n", $res->content, "\n"; print "I seem to have uploaded the file OK!\n\n"; } else { die "Eeek! Whatever page we got, didn't have 'uploadname' as a +field!\n"; } }


--Chris

e-mail jcwren

Replies are listed 'Best First'.
RE: (jcwren) RE: amelinda's problem (I am a hardheaded SOB)
by amelinda (Friar) on Oct 03, 2000 at 03:07 UTC
    Thanks for being persistent! This is exactly the kind of thing I've been looking for as an example!

    I find it kind of interesting that you get around the thing I didn't see in HTML::Form by going and getting the form and then searching it for the right thing and filling it out blindly. I hadn't thought of doing that; it would be good errorchecking - make sure you can get to the site before submitting.

    For reference, here is some code I wrote when I was still trying to use libwww-perl (it didn't work, can you tell me why? (serious query)):

    #!/usr/bin/perl use HTTP::Request::Common; use LWP::UserAgent; use CGI qw(header -no_debug); my $URL = 'https://www.mydomain.com/upload.html'; my $req = POST $URL, Content_Type => 'form-data', Content => [ user => 'username', pass => 'password', FILE => ['./binaryfile'], # this file will be uploaded ]; my $res = LWP::UserAgent->new->request($req); print header, $res->is_success ? $res->content : $res->status_line;

    Yes, yes, Carp, strict, -w and all that. Consider it read, for conciseness' sake. Maybe I'll try it again using HTML::Form.

      Well, it passed the syntax check. Since I don't have a server that's configured to run https, I can't really test it. Perhaps you could describe the error in a little more detail.

      --Chris

      e-mail jcwren