Catalyst-Engine-HTTP-Prefork
view release on metacpan or search on metacpan
lib/Catalyst/Engine/HTTP/Prefork.pm view on Meta::CPAN
print "You can connect to your server at $url\n";
}
# The below methods run in the child process
sub post_accept_hook {
my $self = shift;
$self->{client} = {
headerbuf => '',
inputbuf => '',
keepalive => 1,
};
}
sub process_request {
my $self = shift;
my $conn = $self->{server}->{client};
while ( $self->{client}->{keepalive} ) {
last if !$conn->connected;
# Read until we see all headers
last if !$self->_read_headers;
# Parse headers
my $h = HTTP::HeaderParser::XS->new( \delete $self->{client}->{headerbuf} );
if ( !$h ) {
# Bad request
DEBUG && warn "[$$] Bad request\n";
$self->_http_error(400);
last;
}
# Initialize CGI environment
my $uri = $h->request_uri();
my ( $path, $query_string ) = split /\?/, $uri, 2;
my $version = $h->version_number();
my $proto = sprintf( "HTTP/%d.%d", int( $version / 1000 ), $version % 1000 );
local %ENV = (
PATH_INFO => $path || '',
QUERY_STRING => $query_string || '',
REMOTE_ADDR => $self->{server}->{peeraddr},
REMOTE_HOST => $self->{server}->{peerhost} || $self->{server}->{peeraddr},
REQUEST_METHOD => $h->request_method() || '',
SERVER_NAME => $self->{server}->{sockaddr}, # XXX: needs to be resolved?
SERVER_PORT => $self->{server}->{port}->[0],
SERVER_PROTOCOL => $proto,
%{ $self->{env} },
);
# Add headers
my $headers = $h->getHeaders();
$self->{client}->{headers} = $headers;
# prepare_connection and prepare_path need a few headers in %ENV
$ENV{HTTP_X_FORWARDED_FOR} = $headers->{'X-Forwarded-For'}
if $headers->{'X-Forwarded-For'};
$ENV{HTTP_X_FORWARDED_HOST} = $headers->{'X-Forwarded-Host'}
if $headers->{'X-Forwarded-Host'};
# Determine whether we will keep the connection open after the request
my $connection = $headers->{Connection};
if ( $proto && $proto eq 'HTTP/1.0' ) {
if ( $connection && $connection =~ /^keep-alive$/i ) {
# Keep-alive only with explicit header in HTTP/1.0
$self->{client}->{keepalive} = 1;
}
else {
$self->{client}->{keepalive} = 0;
}
}
elsif ( $proto && $proto eq 'HTTP/1.1' ) {
if ( $connection && $connection =~ /^close$/i ) {
$self->{client}->{keepalive} = 0;
}
else {
# Keep-alive assumed in HTTP/1.1
$self->{client}->{keepalive} = 1;
}
# Do we need to send 100 Continue?
if ( $headers->{Expect} ) {
if ( $headers->{Expect} eq '100-continue' ) {
syswrite STDOUT, 'HTTP/1.1 100 Continue' . $CRLF . $CRLF;
DEBUG && warn "[$$] Sent 100 Continue response\n";
}
else {
DEBUG && warn "[$$] Invalid Expect header, returning 417\n";
$self->_http_error( 417, 'HTTP/1.1' );
last;
}
}
# Check for an absolute request and determine the proper Host value
if ( $ENV{PATH_INFO} =~ /^http/i ) {
my ($host, $path) = $ENV{PATH_INFO} =~ m{^http://([^/]+)(/.+)}i;
$ENV{HTTP_HOST} = $host;
$ENV{PATH_INFO} = $path;
DEBUG && warn "[$$] Absolute path request, host: $host, path: $path\n";
}
elsif ( $headers->{Host} ) {
$ENV{HTTP_HOST} = $headers->{Host};
}
else {
# No host, bad request
DEBUG && warn "[$$] Bad request, HTTP/1.1 without Host header\n";
$self->_http_error( 400, 'HTTP/1.1' );
last;
}
}
# Pass flow control to Catalyst
$self->{appclass}->handle_request( $self->{client} );
DEBUG && warn "[$$] Request done\n";
if ( $self->{client}->{keepalive} ) {
( run in 1.061 second using v1.01-cache-2.11-cpan-39bf76dae61 )