>>>>> Gisle Aas <gi...@aas.no> writes: >>>>> Ivan Shmakov <i...@main.uusia.org> 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
### 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
pgp3I0BPTVpFX.pgp
Description: PGP signature