summaryrefslogtreecommitdiff
path: root/lib/XXV/OUTPUT
diff options
context:
space:
mode:
authorAndreas Brachold <vdr07@deltab.de>2008-06-04 17:59:38 +0000
committerAndreas Brachold <vdr07@deltab.de>2008-06-04 17:59:38 +0000
commita6e275f794e1339a2d4002fc911087da844cf515 (patch)
tree58005b2a4822a64661779915ac45b1647693cb29 /lib/XXV/OUTPUT
parent695e2e6bd71f78b4bd52d977091261e856a42348 (diff)
downloadxxv-a6e275f794e1339a2d4002fc911087da844cf515.tar.gz
xxv-a6e275f794e1339a2d4002fc911087da844cf515.tar.bz2
* Add simple proxy mode to relay live stream
* Add option to select method of live stream (playlist, redirect, proxy) * CHANNELS: Dont delete all database entry at import, insert only changed data. * CHANNELS: Better detect new channels.
Diffstat (limited to 'lib/XXV/OUTPUT')
-rw-r--r--lib/XXV/OUTPUT/Html.pm150
1 files changed, 150 insertions, 0 deletions
diff --git a/lib/XXV/OUTPUT/Html.pm b/lib/XXV/OUTPUT/Html.pm
index 254c26d..429ac4e 100644
--- a/lib/XXV/OUTPUT/Html.pm
+++ b/lib/XXV/OUTPUT/Html.pm
@@ -24,6 +24,9 @@ sub module {
# 'Template' => 'Front-end module to the Template Toolkit',
# 'Compress::Zlib' => 'Interface to zlib compression library',
'HTML::TextToHTML' => 'convert plain text file to HTML. ',
+ 'IO::Socket::INET' => 'Object interface for AF_INET domain sockets',
+ 'IO::Select' => 'OO interface to the select system call',
+ 'IO::Handle' => 'Supply object methods for I/O handles'
},
Description => gettext('This receives and sends HTML messages.'),
Version => (split(/ /, '$Revision$'))[1],
@@ -426,6 +429,10 @@ sub statusmsg {
if(exists $s->{$state});
my $arg = {};
+
+ $arg->{'Location'} = $msg
+ if($state == 301);
+
$arg->{'WWW-Authenticate'} = "Basic realm=\"xxvd\""
if($state == 401);
@@ -762,6 +769,149 @@ sub _stream {
return 0;
}
+sub proxy {
+ my $self = shift || return error('No object defined!');
+ my $streamdev_host = shift || return error('No host defined!');
+ my $streamdev_port = shift || return error('No port defined!');
+ my $request = shift || return error('No request defined!');
+ my $mimetyp = shift || return error('No mimetyp defined!');
+
+ if($self->{browser}->{Method} eq 'HEAD') {
+ # Fake response, don't bother streamdev recorder
+ $self->statusmsg(200,'','',$mimetyp);
+# Call streamdev to query channel state with HTTP-Request HEAD
+# if($self->_proxy($handle,$streamdev_host,$streamdev_port,"HEAD " . $request . "\r\n\r\n")) {
+# undef $self->{handle};
+# undef $self->{output};
+# } else {
+# $self->status404($channelid,$!);
+# }
+ return;
+ }
+ # Start proxy
+ my $handle = $self->{handle};
+ my $child = fork();
+ if ($child < 0) {
+ error("Can't create proxy process for streaming : " . $!);
+ return $self->status404($request,$!);
+ }
+ elsif ($child > 0) {
+ debug("Create proxy process for streaming");
+ $self->{'sendbytes'} = 0;
+ }
+ elsif ($child == 0) {
+ $self->{dbh}->{InactiveDestroy} = 1;
+ eval {
+ local $SIG{'__DIE__'};
+ lg(sprintf("Send request %s",$request));
+ unless($self->_proxy($handle,$streamdev_host,$streamdev_port,"GET " . $request . "\r\n\r\n")) {
+ $handle->close();
+ }
+ };
+
+ error($@) if $@;
+ exit 0;
+ }
+
+ undef $self->{handle};
+ undef $self->{output};
+}
+
+sub _proxy {
+ my $self = shift || return error('No object defined!');
+ my $handle = shift;
+ my $streamdev_host = shift;
+ my $streamdev_port = shift;
+ my $request = shift;
+
+ my $r;
+ my $bytes;
+ my $buf="";
+ my $bExit = 0;
+ my $tousage = 0;
+ my $fromusage = 0;
+ my $peer = 0;
+
+ binmode $handle;
+ lg(sprintf("Try to connect %s:%d",$streamdev_host,$streamdev_port));
+ my $streamdev = IO::Socket::INET->new (
+ PeerAddr => $streamdev_host,
+ PeerPort => $streamdev_port);
+ unless($streamdev) {
+ error(sprintf("Could'nt connect to %s:%d",$streamdev_host,$streamdev_port));
+ return 0;
+ }
+ binmode $streamdev;
+
+ $handle->blocking(0);
+ $streamdev->blocking(0);
+
+ my $select = new IO::Select();
+ $select->add($streamdev);
+ $select->add($handle);
+
+ autoflush $streamdev;
+ autoflush $handle;
+
+ # Send HTTP Request to get data from streamdev client
+ print $streamdev $request;
+
+ # Relay data from streamdev to calling host
+ while (my @ready = $select->can_read()) {
+ foreach my $fd (@ready) {
+ $peer = 1;
+ if ($fd == $handle) {
+ do {
+ $r = 0;
+ $bytes = sysread( $handle, $buf, 1500 );
+ if($bytes) {
+ $tousage += $bytes;
+ $peer = $streamdev->peername;
+ $r = $streamdev->send($buf,0,$peer)
+ if($peer);
+ $tousage -= $r if($r);
+ }
+# lg(sprintf("Read host bytes %d (%d)",$bytes,$r));
+ } while $r && $bytes > 0;
+ if (!$peer || $tousage < -100000 || $tousage > 100000) {
+ $bExit = 2;
+ }
+ }
+ elsif ($fd == $streamdev) {
+ do {
+ $r = 0;
+ $bytes = sysread( $streamdev, $buf, 1500 );
+ if($bytes) {
+ $fromusage += $bytes;
+ my $peer = $handle->peername;
+ $r = $handle->send($buf,0,$peer)
+ if($peer);
+ $fromusage -= $r if($r);
+ }
+ } while $r && $bytes > 0;
+ if ($fromusage < -100000 || $fromusage > 100000) {
+ $bExit = 1;
+ }
+ } else {
+ $select->remove($fd);
+ $fd->close();
+ $bExit = 1;
+ }
+ }
+ if($bExit) {
+ lg(sprintf("EOF proxy send data %s:%d (%d)",$streamdev_host,$streamdev_port, $bExit));
+ last;
+ }
+ }
+ lg(sprintf("Exit proxy send data %s:%d",$streamdev_host,$streamdev_port)) unless($bExit);
+ $select->remove($streamdev);
+ $select->remove($handle);
+
+ $streamdev->close();
+ $handle->close();
+ return 1;
+}
+
# ------------------
sub image {
# ------------------