Which headers for file upload in Perl?

2019-07-29 09:55发布

I've been stuck on this for quite a couple of hours and I haven't been able to find a solution for it by researching.

The following HTML code will work for what I require:

<form action="uploader.php" method="POST" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="Filedata" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>

However, the following Perl code does not work. I assume this is because I'm not sending the headers required.

my @headers  = ('Content-Disposition' => 'form-data; name="Filedata"; filename="test.txt"',
                'Content-Type'        => 'text/plain',
                'Content'             => 'File content goes here.');

my $browser  = LWP::UserAgent->new;
my $response = $browser->post('uploader.php', undef, @headers);

If anyone can point out the reason it doesn't work I would be grateful. Thank you!

2条回答
▲ chillily
2楼-- · 2019-07-29 10:19

You're providing a Content-Type of text/plain, which is obviously wrong — you need to be sending a multipart/form-data MIME message with the file as a text/plain enclosure. You could do this by hand with a MIME module, but as jpalecek points out, HTTP::Request::Common already knows how to do it for you. A request like this should work:

my $response = $browser->request(
    POST "http://somewhere/uploader.php",
        Content_Type => 'form-data',
        Content => [
            Filedata => [ 
                undef,
                "test.txt",
                Content_Type => "text/plain",
                Content => "file content goes here"
            ]
        ]
);

Or if test.txt actually exists on disk:

my $response = $browser->request(
    POST "http://somewhere/uploader.php",
        Content_Type => 'form-data',
        Content => [
            Filedata => [ "/path/to/test.txt" ]
        ]
);

will be enough. In either case, just make sure to add use HTTP::Request::Common; to your code.

查看更多
来,给爷笑一个
3楼-- · 2019-07-29 10:41
my $response = $ua->post('http://.../uploader.php',
   Content_Type => 'form-data',
   Content => [
      Filedata => [ undef, 'test.txt',
         Content_Type => 'text/plain',
         Content      => "Hello, World!\n",
      ],
      submit => 'Submit',
   ],
);

The args for ->post are the same args for HTTP::Request::Common's POST sub.

It's also capable of reading the file from disk for you if that's what you actually want to do.

my $response = $ua->post('http://.../uploader.php',
   Content_Type => 'form-data',
   Content => [
      Filedata => [ 'test.txt', 'test.txt',
         Content_Type => 'text/plain',
      ],
      submit => 'Submit',
   ],
);
查看更多
登录 后发表回答