From: Christian Garbs Date: Sun, 28 Dec 2008 12:52:17 +0000 (+0100) Subject: Merge branch 'plugin' into domainsocket X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=commitdiff_plain;h=0f554556c26c3484792f09621e6a19118dbce4c4;hp=59f5a45fea0697fc63d7cbc7dc4ac60c52dc9ddb;p=xmlrtorrent.git Merge branch 'plugin' into domainsocket --- diff --git a/xmlrtorrent/SocketTalker.pm b/xmlrtorrent/SocketTalker.pm new file mode 100644 index 0000000..14b6590 --- /dev/null +++ b/xmlrtorrent/SocketTalker.pm @@ -0,0 +1,94 @@ +# Talker using SCGI over Unix Domain Socket +# +# (c) 2008 by Christian Garbs +# licensed under GNU GPL v2 + +package xmlrtorrent::SocketTalker; +use xmlrtorrent::TalkerBase; +@ISA = qw(xmlrtorrent::TalkerBase); + +use RPC::XML; +use RPC::XML::Parser; +use IO::Socket::UNIX; +use strict; + +sub new { + my $class = shift; + my $self = $class->SUPER::new(); + + $self->{'NAME'} = 'socket'; + $self->{'DESC'} = 'talker using SCGI over Unix Domain Socket'; + $self->{'_PARAMS'} = { + 'SOCKET' => ['', 'filename of socket'], + }; + $self->{'__RPCXMLPARSER'} = RPC::XML::Parser->new(); + + bless($self, $class); + + $self->_prepare_parameters(); + + return $self; +} + +sub _create_netstring($$) { + my $self = shift; + my $string = shift; + my $len = length $string; + return "$len:$string,"; +} + +sub _create_scgi_header($$$) { + my $self = shift; + my ($name, $value) = (@_); + return "$name\0$value\0"; +} + +sub send_request { + my $self = shift; + my (@params) = (@_); + + my $socketfile = $self->_getval('SOCKET'); + + unless (defined $socketfile and $socketfile ne '') { + return 'socket talker: SOCKET not set'; + } + + # prepare socket + my $socket = IO::Socket::UNIX->new( + 'Type' => SOCK_STREAM, + 'Peer' => $socketfile, + ) + or return "socket talker: cannot connect to SOCKET: $!"; + $socket->autoflush(1); # default since 1.18, but be sure + + # prepare XML RPC request + my $rpc_request = RPC::XML::request->new(@params)->as_string(); + + # prpepare SCGI request + my $scgi_request = + $self->_create_netstring( + $self->_create_scgi_header('CONTENT_LENGTH', length $rpc_request) + . + $self->_create_scgi_header('SCGI', '1') + ) + . + $rpc_request; + + # write to socket + $socket->print($scgi_request); + + # read from socket + while (my $line = <$socket>) { + last if ($line =~ /^\s*$/); # munch headers + } + my $ret = ''; + while (my $line = <$socket>) { + $ret .= $line; + } + + $socket->close() or return "socket talker: cannot close SOCKET: $!"; + + return $self->{'__RPCXMLPARSER'}->parse($ret); +} + +1;