X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine%2FHTTP%2FDaemon.pm;h=00daf22454918583ad5f0755ca9ada046e573ca7;hb=ebfde331f96f61128105df0b2c4904cc0d5593e5;hp=8d13fe832eed562fee6953f9f1d2ed95fc8eaccf;hpb=73ad976960bcb5dc1f66f5f6ffff0f2d0f482de3;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine/HTTP/Daemon.pm b/lib/Catalyst/Engine/HTTP/Daemon.pm index 8d13fe8..00daf22 100644 --- a/lib/Catalyst/Engine/HTTP/Daemon.pm +++ b/lib/Catalyst/Engine/HTTP/Daemon.pm @@ -3,27 +3,30 @@ package Catalyst::Engine::HTTP::Daemon; use strict; use base 'Catalyst::Engine::HTTP::Base'; +use Catalyst::Exception; use IO::Select; +use IO::Socket; BEGIN { if ( $^O eq 'MSWin32' ) { - *EINPROGRESS = sub { 10036 }; - *EWOULDBLOCK = sub { 10035 }; - *F_GETFL = sub { 0 }; - *F_SETFL = sub { 0 }; - - *IO::Socket::blocking = sub { - my ( $self, $blocking ) = @_; - my $nonblocking = $blocking ? 0 : 1; - ioctl( $self, 0x8004667e, \$nonblocking ); - }; + *EINTR = sub { 10004 }; + *EINPROGRESS = sub { 10036 }; + *EWOULDBLOCK = sub { 10035 }; + *F_GETFL = sub { 0 }; + *F_SETFL = sub { 0 }; + + *IO::Socket::blocking = sub { + my ( $self, $blocking ) = @_; + my $nonblocking = $blocking ? 0 : 1; + ioctl( $self, 0x8004667e, \$nonblocking ); + }; } else { Errno->require; - Errno->import( qw[EWOULDBLOCK EINPROGRESS] ); + Errno->import( qw[EWOULDBLOCK EINPROGRESS EINTR] ); } } @@ -86,14 +89,17 @@ sub run { $SIG{'PIPE'} = 'IGNORE'; my $daemon = Catalyst::Engine::HTTP::Daemon::Catalyst->new( - Listen => 1, + Listen => SOMAXCONN, LocalPort => $port, ReuseAddr => 1, Timeout => 5 ); unless ( defined $daemon ) { - die(qq/Failed to create daemon. Reason: '$!'/); + + Catalyst::Exception->throw( + message => qq/Failed to create daemon. Reason: '$!'/ + ); } my $base = URI->new( $daemon->url )->canonical; @@ -119,7 +125,11 @@ sub run { my $nread = $client->sysread( my $buf, 4096 ); - unless ( defined($nread) && length($buf) ) { + unless ( $nread ) { + + next if $! == EWOULDBLOCK; + next if $! == EINPROGRESS; + next if $! == EINTR; $select->remove($client); $client->close; @@ -162,7 +172,21 @@ sub run { next unless $client->response; unless ( $client->response_buffer ) { - $client->response_buffer = $client->response->as_string; + + $client->response->header( Server => $daemon->product_tokens ); + + my $connection = $client->request->header('Connection') || ''; + + if ( $connection =~ /Keep-Alive/i ) { + $client->response->header( 'Connection' => 'Keep-Alive' ); + $client->response->header( 'Keep-Alive' => 'timeout=60, max=100' ); + } + + if ( $connection =~ /close/i ) { + $client->response->header( 'Connection' => 'close' ); + } + + $client->response_buffer = $client->response->as_string("\x0D\x0A"); $client->response_offset = 0; } @@ -170,7 +194,11 @@ sub run { $client->response_length, $client->response_offset ); - unless ( defined($nwrite) ) { + unless ( $nwrite ) { + + next if $! == EWOULDBLOCK; + next if $! == EINPROGRESS; + next if $! == EINTR; $select->remove($client); $client->close; @@ -182,9 +210,19 @@ sub run { if ( $client->response_offset == $client->response_length ) { - my $connection = $client->request->header('Connection'); + my $connection = $client->request->header('Connection') || ''; + my $protocol = $client->request->protocol; + my $persistent = 0; + + if ( $protocol eq 'HTTP/1.1' && $connection !~ /close/i ) { + $persistent++; + } + + if ( $protocol ne 'HTTP/1.1' && $connection =~ /Keep-Alive/i ) { + $persistent++; + } - unless ( $connection && $connection =~ /Keep-Alive/i ) { + unless ( $persistent ) { $select->remove($client); $client->close; }