Weblog Navigation

First Previous Index Next Last

Uploading Files Over HTTP From Perl

Saturday, March 3rd, 2012

So it turns out that uploading files over HTTP from a perl script using LWP isn't as obvious and straightforward as you might expect it to be. This stuff should be plainly documented, and it's not. All the examples I could find online for how to do it are about ten years old and each of them is slightly wrong, in various different ways!

So first off, yes, the right way to do this is probably WWW::Mechanize. But if you really want to use LWP::UserAgent and do things manually, here are the undocumented secrets:

# You MUST specify the boundary explicitly here. You can use whatever
# unique string you like here, and it will do the right thing.
my @headers=('Content-type'=>'multipart/form-data; boundary=xYzZY');

# Notice that we're passing an arrayref, not a hashref,
# even though the contents look like a hash.
my $request=new HTTP::Request('POST'=>$url,\@headers);

# If you have other form fields you need to submit in addition
# to the file you're uploading, here's how you attach them. This is
# equivalent to:
# <input name="field1" value="value1">
$request->add_part(new HTTP::Message([
  'Content-disposition'=>'form-data; name="field1"'
],'value1'));

# Finally, to upload your file:
$request->add_part(new HTTP::Message([
  'Content-disposition'=>'form-data; name="myfile"; filename="upload.csv"',
  'Content-type'=>'text/csv',
],$filecontents));

# Finally, submit the query:: my $response=$ua->request($request);

Obviously you should choose the right MIME type for the type of file you're uploading, only use valid characters for the filename, and that sort of thing. I actually haven't tested this with binary data; I assume it works but it's possible there may be some escaping required somewhere that I've skipped here. Please let me know if you notice something I've missed, but this is working for me!


Weblog Navigation

First Previous Index Next Last