【问题标题】:Perl LWP Post form-data with my boundaryPerl LWP 用我的边界发布表单数据
【发布时间】:2017-12-05 05:56:32
【问题描述】:

我想发布内容类型为multipart/form-data的数据:

use strict;
use warnings;

use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
$ua->post (
    'http://127.0.0.1:12555',
    'Content-Type' => 'form-data',
    Content => {
        'data1' => rand,
        'data2' => rand,
    }
);

并且我测试了提交的数据:

use strict;
use warnings;
use IO::Socket::INET;
use Socket qw ( inet_aton );

my $sock_listen = new IO::Socket::INET (
    LocalHost => '127.0.0.1',
    LocalPort => '12555',
    Proto => 'tcp',
    Listen => 3,
    Reuse => 1,
);
$sock_listen->autoflush ();

my $sock;
while ( $sock = $sock_listen->accept ( ) )
{
    my $data = '';
    $sock->recv ( $data, 4096 );
    print $data . "\n";
}

测试 #1 结果:

POST / HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: 127.0.0.1:12555
User-Agent: libwww-perl/6.05
Content-Length: 162
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="data2"

0.876556396484375
--xYzZY
Content-Disposition: form-data; name="data1"

0.62921142578125
--xYzZY--

测试#2结果:

POST / HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: 127.0.0.1:12555
User-Agent: libwww-perl/6.05
Content-Length: 163
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="data2"

0.896942138671875
--xYzZY
Content-Disposition: form-data; name="data1"

0.041656494140625
--xYzZY--

我添加了一条数据:

        'data3' => '--xYzZY'

得到:

POST / HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: 127.0.0.1:12555
User-Agent: libwww-perl/6.05
Content-Length: 221
Content-Type: multipart/form-data; boundary=Tegj

--Tegj
Content-Disposition: form-data; name="data2"

0.34613037109375
--Tegj
Content-Disposition: form-data; name="data3"

--xYzZY
--Tegj
Content-Disposition: form-data; name="data1"

0.678955078125
--Tegj--

问题是如何使用LWP 手动将boundary 设置为32 个字符的字符串,例如浏览器的----WebKitFormBoundary[...]

或者可以只使用IO::Socket

【问题讨论】:

  • 我只是注意到 Chrome 和 IE 创建了不同的边界格式。
  • 这是一个非常好的帖子,IMO。但是:为什么要设置特定的边界?首先,它的目的是分隔消息部分,因此唯一的问题是它不存在于消息中的任何位置。它不必与任何其他“相同”(并且您无法确保,因为没有一个可以保证保持不变)。此外,将其设置为任何固定值都是不好的——如果该字符串出现在消息中怎么办?
  • 我将从阅读 LWP 的源代码开始。它可能会将您带到 HTTP::Message。在那里,您将看到边界是如何设置的。您可能可以覆盖它、附加一些东西或伸手去改变它。但我同意你为什么要这样做是有问题的。
  • @simbabque 它是从HTTP::Request::Common 使用的,并且代码强烈暗示它甚至不可能设置它(没有严重违反模块)。
  • @zdim 我现在无法使用计算机,所以我做了一个有根据的猜测。有可能以某种方式进行子类化。我猜它会修补它。 Class::Method::Modifiers 作为猴子补丁替代品可以工作。但是我应该先看代码,我不会在手机上搜索它。 ;-)

标签: perl http post multipartform-data lwp


【解决方案1】:

LWP 允许您在执行multipart/form-data 请求时手动设置边界。遗憾的是,此功能根本没有记录。

但是,您必须明确地multipart。您可以通过将 boundary 附加为Content-Type 的附加字段来设置自己的边界。它将是converted to a header appropriately by HTTP::Request::Common

my $ua = LWP::UserAgent->new;
$ua->post(
    'http://127.0.0.1:12555',
    'Content-Type' => 
        'multipart/form-data;boundary=Nobody-has-the-intention-to-erect-a-wall',
         # ^^^^^^^           ^^^^^^^^

    Content => {
        data1 => rand,
        data2 => rand,
    },
);

使用您的侦听器,这将产生以下输出。

POST / HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: 127.0.0.1:12555
User-Agent: libwww-perl/6.15
Content-Length: 269
Content-Type: multipart/form-data; boundary=Nobody-has-the-intention-to-erect-a-wall

--Nobody-has-the-intention-to-erect-a-wall
Content-Disposition: form-data; name="data2"

0.0575856828104122
--Nobody-has-the-intention-to-erect-a-wall
Content-Disposition: form-data; name="data1"

0.677908250902878
--Nobody-has-the-intention-to-erect-a-wall--

请注意,如果 HTTP::Request::Common 在任何部分的正文中找到边界字符串,它将用随机字符串替换您的边界。它不仅会在您的边界上添加一个数字。

【讨论】:

    【解决方案2】:

    边界的唯一目的是分隔消息部分,唯一的要求是它不会出现在消息的任何地方。我认为没有充分的理由尝试将其设置为与其他任何内容“相同”。此外,没有任何工具可以保证它总是使用同一个。

    更重要的是,将其设置为固定字符串(不考虑消息)是危险的:有人怎么知道这样的字符串可能不在消息中?

    最后,我认为不可能这样做,正是因为必须检查边界以确保它确实不在消息中;所以任何工具都不应该提供将其设置为预定义字符串的方法。

    看看HTTP::Request::Common's source。看看子 boundary() 如何严重破坏要返回的字符串,以及在其他地方有多少工作进入边界。如果不够好,CHECK_BOUNDARY: 块会进一步更改它。这显然不是要设置在外面的。

    LWP::UserAgentpost 方法作为此模块的快捷方式存在。


    注意simbabque found a way 设置边界,然后也进行检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多