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

Hello, I've read various posts regarding HTTP posting and I even have a nice working example (below). The problem I am having may be on the cgi side of things but I'm unsure. The server accepts the HTTP post and even sends back a message in the result stating that the file I've uploaded is now available for download and gives the URL. However, the getting the URL returns 404. I am suspicious that maybe I'm uploading the filename path, but not the actual file data hence fooling the cgi engine serverside. For the curious, I'm uploading a file to have it digitally signed, and then presented for download post signing. Does my code have any glaring issues?
#!/usr/bin/perl # file: uploadafile.pl # call me like this: # uploadafile.pl --url=http://www.x.com/cgi-bin/upload.pl --uploadfile +=c:/temp/who.gif --sig=3rdparty|latest # use strict; use LWP::UserAgent; use HTTP::Request::Common; use Getopt::Long; use File::Basename; my ( $o_url, $o_fqn, $o_sver ); GetOptions( "url=s" => \$o_url, "uploadfile=s" => \$o_fqn, "sig=s" => \$o_sver, ); # mandatory arguments: url &usage unless ( $o_url && $o_fqn && $o_sver ); my $url = $o_url; my $fname = $o_fqn; my $sign = $o_sver; binmode $fname; open FILE, $fname or die $!; binmode FILE; my $buffer; read(FILE, $buffer, 20, 0); binmode $buffer; close(FILE); foreach (split(//, $buffer)) { printf("%02x ", ord($_)); print "\n" if $_ eq "\n"; } #my ($buf, $data, $n); #while (($n = read FILE, $data, 4) != 0) { # print "$n bytes read\n"; # $buf .= $data; #} # put timeouts, proxy etc into the useragent if needed my $ua = LWP::UserAgent->new(); my $req = POST $url, ENCTYPE => 'multipart/form-data', Content => [ submit => 'Sign', widget_bundle => [$fname], email_address => 'harish.krishnamurthy@nokia.com', signer_version => $sign, ]; my $response = $ua->request($req); close(FILE); if ($response->is_success()) { print "OK: ", $response->content; } else { print $response->as_string; } exit; sub usage { printf "usage: %s --url=%s --uploadfile=%s\\n", basename($0),'http://....','c:/data/myfile.jpg','3rdparty|late +st'; exit }

Replies are listed 'Best First'.
Re: Am I HTTP posting a file correctly?
by locked_user sundialsvc4 (Abbot) on Nov 24, 2010 at 19:03 UTC

    Without taking it upon myself to delve into your code ... you should approach solving this problem in this way:

    1. Use a web-data sniffer to observe the actual HTTP transmission that is taking place.
    2. On the server, check for the existence of the file and its actual file-name, which may well be case-sensitive on a Unix/Linux host.   You know exactly what has been sent; you should see exactly the same file-contents there.   Security on the file should be such that the server can reach it.   If you use a utility like md5sum to compare the files on the various computers, the hash-signatures should exactly match.
    3. Examine server logs to see how the server responded to the request to retrieve the file.   The server generally won’t tell you in-detail why it could not “find” the file, but it will tell the log.

      Hello,

      Thanks sundialsvc4 for your reply. Unfortunately, I can't get inside the server at hand. I was however able to take your advice about the packet sniffer.

      Note: I can do the method post using java and it works fine, but in not working in perl.
      Using the packet sniffer:
      1) the perl script only posts a few hundred bytes seen in the Content-Length: header vs the Java app which posts about 5K.
      2) I don't see any multipart boundaries posted from perl, yet they are present when posted from java.
      Do I need to "open" the file first and store it locally in memory?

      Please help.

      Regards,
      Mike

        So, likely, no, you are not sending the same data as your Java program.

        The LWP::UserAgent (resp. HTTP::Request) modules (and objects) have methods to print themselves as strings. Use these to find out whether you are initializing them wrongly or whether you are not sending all data.

        Also consider looking at WWW::Mechanize or at least HTML::Form to make form submission easier, at least if you have a HTML form that you're trying to automate.