# Never ever remove this, it would result in random length output
# streams if STDIN eq STDOUT (like in the HTTP engine)
- $c->request->handle->blocking(1);
+ *STDIN->blocking(1);
return $self->NEXT::finalize_read($c);
}
my ( $self, $c ) = @_;
# Set the input handle to non-blocking
- $c->request->handle->blocking(0);
+ *STDIN->blocking(0);
return $self->NEXT::prepare_read($c);
}
my $c = shift;
# support for non-blocking IO
- my $handle = $c->request->handle;
- my $rin = '';
- vec( $rin, $handle->fileno, 1 ) = 1;
+ my $rin = '';
+ vec( $rin, *STDIN->fileno, 1 ) = 1;
READ:
{
select( $rin, undef, undef, undef );
- my $rc = $handle->sysread(@_);
+ my $rc = *STDIN->sysread(@_);
if ( defined $rc ) {
return $rc;
}
# A very very simple HTTP server that initializes a CGI environment
sub run {
- my ( $self, $class, $port, $host, $fork ) = @_;
+ my ( $self, $class, $port, $host, $options ) = @_;
+
+ $options ||= {};
our $GOT_HUP;
local $GOT_HUP = 0;
local $SIG{HUP} = sub { $GOT_HUP = 1; };
-
local $SIG{CHLD} = 'IGNORE';
+ my $allowed = $options->{allowed} || { '127.0.0.1' => '255.255.255.255' };
+
# Handle requests
# Setup socket
$host = $host ? inet_aton($host) : INADDR_ANY;
- socket( HTTPDaemon, PF_INET, SOCK_STREAM, getprotobyname('tcp') );
- setsockopt( HTTPDaemon, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) );
- bind( HTTPDaemon, sockaddr_in( $port, $host ) );
- listen( HTTPDaemon, SOMAXCONN );
+ socket( HTTPDaemon, PF_INET, SOCK_STREAM, getprotobyname('tcp') )
+ || die "Couldn't assign TCP socket: $!";
+ setsockopt( HTTPDaemon, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) )
+ || die "Couldn't set TCP socket options: $!";
+ bind( HTTPDaemon, sockaddr_in( $port, $host ) )
+ || die "Couldn't bind socket to $port on $host: $!";
+ listen( HTTPDaemon, SOMAXCONN )
+ || die "Couldn't listen to socket on $port on $host: $!";
my $url = 'http://';
if ( $host eq INADDR_ANY ) {
require Sys::Hostname;
while ( accept( Remote, HTTPDaemon ) ) {
# Fork
- if ($fork) { next if $pid = fork }
+ if ( $options->{fork} ) { next if $pid = fork }
close HTTPDaemon if defined $pid;
# Ignore broken pipes as an HTTP server should
local $SIG{PIPE} = sub { close Remote };
- local $SIG{HUP} = (defined $pid ? 'IGNORE' : $SIG{HUP});
+ local $SIG{HUP} = ( defined $pid ? 'IGNORE' : $SIG{HUP} );
local *STDIN = \*Remote;
local *STDOUT = \*Remote;
}
}
}
+ unless ( uc($method) eq 'KILL' ) {
- # Pass flow control to Catalyst
- $class->handle_request;
+ # Pass flow control to Catalyst
+ $class->handle_request;
+ }
+ else {
+ my $ipaddr = _inet_addr($peeraddr);
+ my $ready = 0;
+ while ( my ( $ip, $mask ) = each %$allowed and not $ready ) {
+ $ready = ( $ipaddr & _inet_addr($mask) ) == _inet_addr($ip);
+ }
+ if ($ready) {
+ $GOT_HUP = 1;
+ last;
+ }
+ }
exit if defined $pid;
}
continue {
close Remote;
}
close HTTPDaemon;
- exec {$0}( ( ( -x $0 ) ? () : ($^X) ), $0, @ARGV ) if $GOT_HUP;
+
+ if ($GOT_HUP) {
+ $SIG{CHLD} = 'DEFAULT';
+ wait;
+ exec $^X . ' "' . $0 . '" ' . join( ' ', @{ $options->{argv} } );
+ }
}
sub _get_line {
return $line;
}
+sub _inet_addr { unpack "N*", inet_aton( $_[0] ) }
+
=back
=head1 SEE ALSO