Re: an HTTP client upon a buffer-based IO, please?
Ivan Shmakov <[email protected]> Sun, 09 May 2010 00:08:51 +0700
| Newsgroups | gmane.comp.lang.perl.modules.lwp |
|---|---|
| Message-ID | <[email protected]> |
>>>>> Gisle Aas <[email protected]> writes: >>>>> Ivan Shmakov <[email protected]> wrote: >> 1. The questions >> Do I understand it correctly that the most of the libwww HTTP >> implementation is tied together by the means of the >> LWP::Protocol::http module, while LWP::UserAgent just invokes >> scheme-specific protocol handlers? > That's right. >> I need for the libwww HTTP client to use two scalar values as the >> read and write buffers for communication instead of a, say, >> IO::Socket::INET6 instance. Do I understand it correctly that in >> order to do that I will have to: > There are many ways to hook into the protocol machinery. I tried to > set it up just by creating my own http-handler and ::Socket package > that subclass Net::HTTP::Methods, and then just filled in the missing > methods that I found my test program invoked. I then ended up with > the attached script. I hope you find it instructive. Impressive, thanks! I've already started to write my own Net::HTTP::Custom package (MIME-d), but somehow reasoned that I need to subclass the whole Net::HTTP (or rather ::NB) package instead of just the ::Methods one. However, that means that all that LWP::Protocol::http and Net::HTTP do by themselves is the tracking of socket-related issues, like, say, timeouts? BTW, may it make sense to include such a package into libwww? At the very least, it may prove to be useful for debugging purposes. (Doesn't the other thread here demand just the same feature?) Also, wouldn't it be nice to have “localized” (i. e., scope-local, just like the ‘local’ variables) scheme handlers? Any insight on how it may be done? -- FSF associate member #7257
(unnamed)
(text/x-perl, 2.3 KB)
### Custom.pm --- Net::HTTP::Custom, a custom IO for HTTP -*- Perl -*-
package Net::HTTP::Custom;
use strict;
use vars qw ($VERSION @ISA $DEFAULT_NEW_CONNECTION);
$VERSION = "0.01";
unless ($DEFAULT_NEW_CONNECTION) {
eval { require IO::Socket::INET } || require IO::Socket;
$DEFAULT_NEW_CONNECTION = sub {
IO::Socket::INET->new (@_);
};
}
require Carp;
require Net::HTTP::NB;
@ISA = qw (Net::HTTP::NB);
sub new {
my $class = shift;
Carp::croak ("No Host option provided")
unless @_;
unshift (@_, "Host")
if @_ == 1;
my %cnf = @_;
## a custom version of IO::Socket::INET->new ()
my $newconn = delete ($cnf {custom_newconn});
$newconn = $DEFAULT_NEW_CONNECTION
unless $newconn;
# my $self = $class->SUPER::new (%cnf);
## FIXME: mostly a copy of Net::HTTP::Methods::new ()
require Symbol;
my $self = bless Symbol::gensym(), $class;
warn ("XXX");
warn ("XXX: " . $self);
${*$self}{_httpcustom_newconn} = $newconn;
warn ("XXX: " . join (", ", sort keys (%{*$self})));
## .
return $self->http_configure (\%cnf);
}
sub http_connect {
my ($self, $cnf) = @_;
warn ("XXX: " . $self);
warn ("XXX: " . join (", ", sort keys (%{*$self})));
my $newconn = ${*$self}{_httpcustom_newconn}
or Carp::croak ("No newconn field");
my $sock = &$newconn (%$cnf)
or Carp::croak ("Cannot create connection object");
${*$self}{_httpcustom_sock} = $sock;
## .
$self;
}
sub print {
warn ("print (): " . join (", ", @_, "(END)"));
my $self = shift;
${*$self}{_httpcustom_sock}->print (@_);
## .
$_[0];
}
sub _httpcustom_sysread {
my $self = shift;
${*$self}{_httpcustom_sock}->sysread (@_);
## .
$_[0];
}
sub sysread {
warn ("sysread (): " . join (", ", @_, "(END)"));
## FIXME: mostly a copy of Net::HTTP::NB::sysread ()
my $self = $_[0];
if (${*$self}{'httpnb_read_count'}++) {
${*$self}{'http_buf'} = ${*$self}{'httpnb_save'};
die "Multi-read\n";
}
my $buf;
my $offset = $_[3] || 0;
my $n = $self->_httpcustom_sysread ($_[1], $_[2], $offset);
${*$self}{'httpnb_save'} .= substr($_[1], $offset);
## .
return $n;
}
1;
__END__
## Local variables:
## indent-tabs-mode: nil
## End:
### Custom.pm ends here
signature.asc
(application/pgp-signature, 196 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkvlmqUACgkQ+MvqjYjLOAyOYgCfQ1mg+cg4Dfq/Acm3u6osN4rT QYoAoIso8Jdjve6Fy1mNj7hk+fSDBphL =OORi -----END PGP SIGNATURE-----