Perl 使用LWP发送普通字符串请求

Perl 使用LWP发送普通字符串请求,perl,http,lwp,lwp-useragent,Perl,Http,Lwp,Lwp Useragent,要从某个网站获得响应,我必须给出一个确切的请求字符串,HTTP/1.1。我用telnet尝试了那个,它给了我想要的响应(重定向,但我需要它) 但是当我尝试将相同的请求字符串赋予HTTP::request->parse()时,我只得到消息400 URL必须是绝对的 我不确定是网站还是LWP给了我这个信息,因为正如我所说的,回复是通过telnet进行的 代码如下: my $req = "GET / HTTP/1.1\n". "Host: www.example-site.de\n". "Us

要从某个网站获得响应,我必须给出一个确切的请求字符串,HTTP/1.1。我用
telnet
尝试了那个,它给了我想要的响应(重定向,但我需要它)

但是当我尝试将相同的请求字符串赋予
HTTP::request->parse()
时,我只得到消息
400 URL必须是绝对的

我不确定是网站还是LWP给了我这个信息,因为正如我所说的,回复是通过telnet进行的

代码如下:

my $req = "GET / HTTP/1.1\n".
  "Host: www.example-site.de\n".
  "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1\n".
  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n".
  "Accept-Language: en-us,en;q=0.5\n".
  "Accept-Encoding: gzip, deflate\n".
  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n".
  "Keep-Alive: 115\n".
  "Connection: keep-alive\n";

# Gives correct request string
print HTTP::Request->parse($req)->as_string;

my $ua = LWP::UserAgent->new( cookie_jar => {}, agent => '' );
my $response = $ua->request(HTTP::Request->parse($req));

# 400 error
print $response->as_string,"\n";

有人能帮我吗?

在我看来,解析请求并不是100%往返安全的,这意味着您无法将响应反馈到请求中

乍一看似乎是个bug,但是这个模块已经运行了很长时间了……另一方面,我甚至不知道你可以使用这个模块来解析请求,所以可能它没有经过很好的测试

下面的测试用例应该向您指出问题所在,那就是URL没有正确地组装起来,无法提供给
$req->request
方法

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use Test::More;

my $host = 'www.example.com';
my $url = '/bla.html';

my $req = <<"EOS";
GET $url HTTP/1.1
Host: $host
EOS

# (1) parse the request
my $reqo = HTTP::Request->parse($req);
isa_ok $reqo, 'HTTP::Request';
diag explain $reqo;
diag $reqo->as_string;

# (2) construct the request
my $reqo2 = HTTP::Request->new( GET => "http://$host$url" );
isa_ok $reqo2, 'HTTP::Request';
diag explain $reqo2;
diag $reqo2->as_string;

is $reqo->uri, $reqo2->uri, 'both URLs are identical';

my $ua = LWP::UserAgent->new( cookie_jar => {}, agent => '' );
for ( $reqo, $reqo2 ) {
    my $response = $ua->request( $_ );
    diag $response->as_string,"\n";
}

done_testing;
使用严格;
使用警告;
使用LWP::UserAgent;
使用HTTP::请求;
使用测试::更多;
my$host='www.example.com';
我的$url='/bla.html';
my$req=作为字符串;
#(2)构造请求
我的$reqo2=HTTP::Request->new(GET=>“HTTP://$host$url”);
isa_ok$reqo2,‘HTTP::Request’;
diag解释$reqo2;
诊断$REQUO2->as_字符串;
是$reqo->uri,$reqo2->uri,'两个URL都是相同的';
我的$ua=LWP::UserAgent->new(cookie\u jar=>{},agent=>'';
对于($reqo,$reqo2){
我的$response=$ua->request($\ux);
diag$response->as_字符串“\n”;
}
完成测试;
如果请求中未指定架构,则会导致出现错误。它可能需要它来正确地使用它

因此,要使其工作,您需要为您的请求指定完整的url:

my $req_str = "GET http://www.example.de/\n".
  "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1\n".
  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n".
  "Accept-Language: en-us,en;q=0.5\n".
  "Accept-Encoding: gzip, deflate\n".
  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n".
  "Keep-Alive: 115\n".
  "Connection: keep-alive\n";

好的,我是用插座做的。毕竟,我有HTTP请求,希望得到简单的响应。以下是感兴趣的人的代码:

use IO::Sockets;

my $sock = IO::Socket::INET->new(
    PeerAddr => 'www.example-site.de',
    PeerPort => 80, 
    Proto => 'Tcp',
);
die "Could not create socket: $!\n" unless $sock;

print $sock, $req;

while(<$sock>) {
    # Look for stuff I need
}

close $sock;
使用IO::Sockets;
my$sock=IO::Socket::INET->new(
PeerAddr=>“www.example-site.de”,
皮尔波特=>80,
Proto=>“Tcp”,
);
die“无法创建套接字:$!\n”,除非$sock;
打印$sock,$req;
while(){
#寻找我需要的东西
}
关闭$sock;

重要的是要记住,在
时保留
,因为HTTP响应不会以
EOF
结束,但我不能,因为服务器不会接受我的请求。它只接受我上面给出的形状的请求。@Scán-如果服务器如此不灵活,可能唯一的方法就是直接通过套接字或类似@Scán的东西进行低级通信:你怎么知道服务器不会接受请求?如果
parse()
没有问题,它应该是正确的。@reinierpost:我告诉过你,我用telnet给出了确切的请求,并得到了我需要的响应。我发送了一个经过解析的
LWP
请求,得到了403响应。@Scán:它确实有效,我刚刚测试过。(将
$req_str
替换为
$req
,并在bvr的代码中插入正确的URL。)