【问题标题】:HTTP::Request->parse does not work as expectedHTTP::Request->parse 没有按预期工作
【发布时间】:2014-02-06 02:26:41
【问题描述】:

我正在尝试使用 HTTP::Request->parse 方法解析 HTTP 请求字符串,

GET / HTTP/1.1
Host: www.google.com
Referer: www.google.com
Cookies: A=B

(在它的末尾还有另一个“\r\n”,但我不能在不破坏语法高亮的情况下追加它..)

上面的字符串在我用nc www.google.com 80 < request发送时有效

现在我尝试解析并通过 LWP 发送:

use warnings;
use strict;
use File::Slurp qw/read_file/;
use HTTP::Request;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->parse (read_file ('/run/shm/request'));
print Dumper ($request);

my $r = $ua->request ($request);
if ($r->is_success)
{
    print $r->decoded_content;
}
else
{
    print $r->status_line;
}

我得到:

$VAR1 = bless( {
                 '_headers' => bless( {}, 'HTTP::Headers' ),
                 '_content' => '',
                 '_protocol' => 'HTTP/1.1',
                 '_method' => 'GET',
                 '_uri' => bless( do{\(my $o = '/')}, 'URI::_generic' )
               }, 'HTTP::Request' );
400 URL must be absolute

所以解析器不起作用,它无法解析 URI 和标头。

有什么想法吗?

【问题讨论】:

  • 总是 use strictuse warnings每个 Perl 程序的顶部,尤其是当您寻求帮助时。
  • @Borodin 我做了,只是在粘贴中删除了它,是的,没有来自 Perl 的抱怨 ;-)
  • 最好发布您的完整代码,或展示相同不当行为的简化版本。这个特殊问题不太可能是由 strictwarnings 发现的任何东西引起的,但更常见的是会有额外的和不必要的反复要求你添加它们并显示结果。
  • 哦,我明白你的意思了,我会在这里和下次将它们包括在内,谢谢@Borodin

标签: perl lwp


【解决方案1】:

我真的不喜欢File::Slurp。它主要是成语的替代品

my $contents = do {
  open my $fh, '<', 'myfile' or die $!;
  local $/;
  <$fh>;
};

或者,如果您在命令行中传递文件名

my $contents = do {
  local $/;
  <>;
};

这并不难使用,并且清楚地说明了正在发生的事情。

这里,File::Slurp 是您的问题的原因,因为当在列表上下文中调用时(以及子例程调用的参数应用列表上下文),它会返回文件中的 list 行整个文件的单个标量值。

因为HTTP::Request-&gt;parse 只查看传递的第一个参数,所以它只查看GET 行,并产生一个没有标头的请求。

你可以通过写作来修复它

my $request = read_file ('/run/shm/request');
$request = HTTP::Request->parse($request);

或者你可能更喜欢

my $request = HTTP::Request->parse(scalar read_file ('/run/shm/request'));

但我会写一些类似的东西

use autodie;

my $request = do {
  open my $fh, '<', '/run/shm/request';
  local $/;
  my $contents = <$fh>;
  HTTP::Request->parse($contents);
};

 


更新

顺便说一句,查看HTTP::Message 的HTTP 消息的更好方法。为您构建的是使用print $message-&gt;as_string。使用Data::Dumper 会显示很多不相关的数据和对象内部使用的上下文,并且无法知道它的哪些部分是相关的。

在您上面的程序的情况下,使用的更正版本

print $request->as_string

这个输出的结果

GET / HTTP/1.1
Host: www.google.com
Referer: www.google.com
Cookies: A=B

这正是您的输入文件所包含的内容,并且希望是您所期望的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    • 2014-11-15
    • 1970-01-01
    • 2012-07-02
    • 2011-09-07
    相关资源
    最近更新 更多