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

时间:2012-08-23 22:20:35

标签: perl http httprequest

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

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

GET
/
key=val
Host:example.com

协议是一种简单的请求 - 响应协议,如HTTP。我希望尽可能利用LWP现有的代码。

2 个答案:

答案 0 :(得分:3)

也许您可以使用IO::Socket::INET模块。这里使用它有点缩短example

#!/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;

换句话说,在协议层次结构中稍低一些。 )

答案 1 :(得分:3)

我认为LWP可以实现。说实话,这是一项工作。

我看一下它,你需要实际实现自己的协议(参见LWP::Protocol),因为这是创建实际请求的地方。之后,您需要启用该协议作为http(或https)的实现者:

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

例如,请查看LWP::Protocol::GHTTP代码。

简单地说,您需要创建一个实现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;

script.pl:

#!/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();

请注意,您实际上希望从$request对象构造请求(并获取主机和端口)。或者,如果你很懒,只需将它存放在该对象的某个地方。