HTTP 客户端的 Perl 顺序请求-响应
Perl sequential requets-responds for HTTP client
伙计们!
目前我需要维护一些脚本。现在我需要从类似 HTTP 的服务器执行顺序请求-响应操作。原始脚本是一个单一的请求-响应任务,所以完全没有问题。但是现在我需要发出 3 个不同的请求,解析响应并将它们存储到 PostgreSQL。但是,例如,假设我们将处理 google。
$socket = IO::Socket::INET->new(PeerAddr => "google.com:80", KeepAlive => 1);
$socket->write("GET / HTTP/1.1" . $EOL);
$socket->write("Connection: keep-alive" . $EOL);
$socket->write($EOL);
$socket->flush();
while($sockbuff = $socket->getline)
{
print ("$sockbuff");
$recvbuff = $recvbuff.$sockbuff;
}
print("- REQUEST 1 -\n");
$socket->write("GET / HTTP/1.1" . $EOL);
while($sockbuff = $socket->getline)
{
print ("$sockbuff");
$recvbuff = $recvbuff.$sockbuff;
}
但是,由于指定了 Connection: keep-alive,进程永远不会从第一个 while(read) 循环中退出,因此永远不会发送第二个请求,并且会一直等到线程被外部终止(我需要轮询大约 350 个这样的服务器,因此,整个过程是线程化的)。
另一方面,如果我强制套接字以非阻塞模式运行,我只会得到第一行。
任何人都可以建议我如何在 Perl 中进行顺序读写操作,记住,这是类似于 HTTP 的协议。
根据评论,我建议你这样做比较困难。 Perl 带有一个可爱的库,叫做 LWP::UserAgent
- 它可以让你做 'web stuff'。
使用 LWP::UserAgent
你的代码如下所示:
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
my $agent = LWP::UserAgent->new( keep_alive => 1 );
my $response = $agent->get('http://www.google.com');
if ( $response->is_success ) {
print $response ->content();
}
else {
print "Failed: ", $response->status_line(), "\n";
}
而且您可以非常简单地扩展到多个 URL,我敢肯定 :)。
Can anybody suggest how I can make a sequential write-read operations in Perl keeping in mind, that this is HTTP-like protocol.
使用 LWP::UserAgent、Mojo::UserAgent 或类似模块。
如果你真的想自己动手:
- 阅读标准,例如RFC 2616(或更新的 RFC7230..7235)。
- 了解 body 的长度是如何定义的。注意
Content-Length
和 Transfer-Encoding: chunked
。
- 读取 body 直到响应中定义的结束,而不是直到连接结束或停止。然后发送下一个请求,但要注意
Connection
header 中表示连接将被关闭的任何信息。
But for example, lets think we will tackle google.
更难,因为你必须在这里处理 HTTPS,所以 IO::Socket::INET 不会帮助你。在这种情况下,您需要 IO::Socket::SSL.
伙计们! 目前我需要维护一些脚本。现在我需要从类似 HTTP 的服务器执行顺序请求-响应操作。原始脚本是一个单一的请求-响应任务,所以完全没有问题。但是现在我需要发出 3 个不同的请求,解析响应并将它们存储到 PostgreSQL。但是,例如,假设我们将处理 google。
$socket = IO::Socket::INET->new(PeerAddr => "google.com:80", KeepAlive => 1);
$socket->write("GET / HTTP/1.1" . $EOL);
$socket->write("Connection: keep-alive" . $EOL);
$socket->write($EOL);
$socket->flush();
while($sockbuff = $socket->getline)
{
print ("$sockbuff");
$recvbuff = $recvbuff.$sockbuff;
}
print("- REQUEST 1 -\n");
$socket->write("GET / HTTP/1.1" . $EOL);
while($sockbuff = $socket->getline)
{
print ("$sockbuff");
$recvbuff = $recvbuff.$sockbuff;
}
但是,由于指定了 Connection: keep-alive,进程永远不会从第一个 while(read) 循环中退出,因此永远不会发送第二个请求,并且会一直等到线程被外部终止(我需要轮询大约 350 个这样的服务器,因此,整个过程是线程化的)。 另一方面,如果我强制套接字以非阻塞模式运行,我只会得到第一行。 任何人都可以建议我如何在 Perl 中进行顺序读写操作,记住,这是类似于 HTTP 的协议。
根据评论,我建议你这样做比较困难。 Perl 带有一个可爱的库,叫做 LWP::UserAgent
- 它可以让你做 'web stuff'。
使用 LWP::UserAgent
你的代码如下所示:
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
my $agent = LWP::UserAgent->new( keep_alive => 1 );
my $response = $agent->get('http://www.google.com');
if ( $response->is_success ) {
print $response ->content();
}
else {
print "Failed: ", $response->status_line(), "\n";
}
而且您可以非常简单地扩展到多个 URL,我敢肯定 :)。
Can anybody suggest how I can make a sequential write-read operations in Perl keeping in mind, that this is HTTP-like protocol.
使用 LWP::UserAgent、Mojo::UserAgent 或类似模块。
如果你真的想自己动手:
- 阅读标准,例如RFC 2616(或更新的 RFC7230..7235)。
- 了解 body 的长度是如何定义的。注意
Content-Length
和Transfer-Encoding: chunked
。 - 读取 body 直到响应中定义的结束,而不是直到连接结束或停止。然后发送下一个请求,但要注意
Connection
header 中表示连接将被关闭的任何信息。
But for example, lets think we will tackle google.
更难,因为你必须在这里处理 HTTPS,所以 IO::Socket::INET 不会帮助你。在这种情况下,您需要 IO::Socket::SSL.