如何使用Perl通过套接字发送逐字请求?

如何使用Perl通过套接字发送逐字请求?,perl,http,httprequest,Perl,Http,Httprequest,我需要发送格式完全符合我指定的请求,包括空格。实现这一目标的最佳方式是什么 我要发送的请求类型示例: GET / key=val Host:example.com 该协议是一个简单的请求-响应协议,如HTTP。我希望尽可能利用LWP的现有代码。也许您可以使用该模块。下面是使用它的一点简短说明: #!/usr/bin/perl use IO::Socket; my $host = '127.0.0.1'; # an example obviously my $remote = IO::Socke

我需要发送格式完全符合我指定的请求,包括空格。实现这一目标的最佳方式是什么

我要发送的请求类型示例:

GET
/
key=val
Host:example.com
该协议是一个简单的请求-响应协议,如HTTP。我希望尽可能利用LWP的现有代码。

也许您可以使用该模块。下面是使用它的一点简短说明:

#!/usr/bin/perl
use IO::Socket;
my $host = '127.0.0.1'; # an example obviously
my $remote = IO::Socket::INET->new( 
   Proto     => "tcp",
   PeerAddr  => $host,
   PeerPort  => "http(80)",
);

my $message = <<MSG;
GET
/
key=val
Host:example.com
MSG
unless ($remote) { die "cannot connect to http daemon on $host" }
$remote->autoflush(1);
print $remote $message;
while ( <$remote> ) { print }
close $remote;
#/usr/bin/perl
使用IO::Socket;
my$host='127.0.0.1'#这显然是一个例子
my$remote=IO::Socket::INET->new(
Proto=>“tcp”,
PeerAddr=>$host,
PeerPort=>“http(80)”,
);

我的$message=我认为使用LWP是可以实现的。老实说,这是一点工作

我看了一下,您需要实际实现自己的协议(请参见
LWP::protocol
),因为实际请求就是在那里创建的。之后,您需要作为http(或https)的实现者启用该协议:

例如,看一下
LWP::Protocol::GHTTP
code

简单地说,您需要创建一个实现
request
方法的包。在该方法中,您需要组装请求、打开连接、发送请求并接收响应


下面是一个简单的工作示例

MyFunkyProto.pm:

package MyFunkyProto;

use LWP::Protocol;
@ISA = qw/LWP::Protocol/;

use HTTP::Response;
use IO::Socket;
use Carp qw/croak/;

sub request
{
    my ($self, $request, $proxy, $arg, $size, $timeout) = @_;

    my $remote = IO::Socket::INET->new(
        Proto     => "tcp",
        PeerAddr  => "example.com",
        PeerPort  => "http(80)"
    ) or croak('unable to connect');

    my $message = <<EOF;
GET
/
key=val
Host:example.com
EOF

    $remote->print($message);
    $remote->flush();

    local $/;
    my $resp = HTTP::Response->parse(<$remote>);

    $remote->close();

    return $resp;
};

1;

请注意,您实际上需要从
$request
对象构造请求(并获取主机和端口)。或者,如果您很懒,只需将其存储在该对象中的某个位置。

@raina77ow是否有任何方法可以使用LWP而不将HTTP::Request子类化?您尝试了什么?那么反应呢?你是想自己处理这些问题,还是想要一个模块来帮你处理这些问题?@MichałGórny:我已经搜索了CPAN。我想我可以打开自己的套接字,或者编辑LWP源代码,但我觉得有一种更简单的方法我没有。@MichałGórny:我唯一需要自己做的就是请求格式。例如,我对LWP的超时处理和所有这些都很满意。我需要发送一个特定的请求并读取响应。@Andreas So IO::Socket系列也不相关吗?
package MyFunkyProto;

use LWP::Protocol;
@ISA = qw/LWP::Protocol/;

use HTTP::Response;
use IO::Socket;
use Carp qw/croak/;

sub request
{
    my ($self, $request, $proxy, $arg, $size, $timeout) = @_;

    my $remote = IO::Socket::INET->new(
        Proto     => "tcp",
        PeerAddr  => "example.com",
        PeerPort  => "http(80)"
    ) or croak('unable to connect');

    my $message = <<EOF;
GET
/
key=val
Host:example.com
EOF

    $remote->print($message);
    $remote->flush();

    local $/;
    my $resp = HTTP::Response->parse(<$remote>);

    $remote->close();

    return $resp;
};

1;
#!/usr/bin/env perl

use strict;
use warnings;
use lib '.';

use MyFunkyProto;
use LWP::Protocol;
use LWP::UserAgent;

LWP::Protocol::implementor('http', 'MyFunkyProto');

my $fr = HTTP::Request->new('GET', 'http://www.example.com/');
my $ua = LWP::UserAgent->new();

my $r = $ua->request($fr);
print $r->as_string();