Arriba
view release on metacpan or search on metacpan
lib/Arriba/Server.pm view on Meta::CPAN
my $self = shift;
srand();
if ($self->{options}->{psgi_app_builder}) {
$self->{app} = $self->{options}->{psgi_app_builder}->();
}
$0 = "arriba worker " . join(" ", @{$self->{options}{argv} || []});
}
sub post_accept_hook {
my $self = shift;
$self->{client} = { };
}
sub process_request {
my $self = shift;
my $client = $self->{server}->{client};
# Is this an SSL connection?
my $ssl = $client->NS_proto eq 'SSL';
if ($ssl && $client->next_proto_negotiated &&
$client->next_proto_negotiated eq 'spdy/3')
{
# SPDY connection
require Arriba::Connection::SPDY;
$self->{client}->{connection} =
Arriba::Connection::SPDY->new($client);
}
else {
# HTTP(S) connection
require Arriba::Connection::HTTP;
$self->{client}->{connection} =
Arriba::Connection::HTTP->new($client, ssl => $ssl,
chunk_size => CHUNKSIZE);
}
my $connection = $self->{client}->{connection};
while (my $req = $connection->read_request) {
my $env;
my $conn_header;
if ($req->{env}) {
# Headers already parsed
$env = $req->{env};
}
else {
$env = {
REMOTE_ADDR => $self->{server}->{peeraddr},
REMOTE_HOST => $self->{server}->{peerhost} || $self->{server}->{peeraddr},
REMOTE_PORT => $self->{server}->{peerport} || 0,
SERVER_NAME => $self->{server}->{sockaddr} || 0, # XXX: needs to be resolved?
SERVER_PORT => $self->{server}->{sockport} || 0,
SCRIPT_NAME => '',
'psgi.version' => [ 1, 1 ],
'psgi.errors' => *STDERR,
'psgi.url_scheme' => $req->{scheme},
'psgi.nonblocking' => Plack::Util::FALSE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.run_once' => Plack::Util::FALSE,
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => Plack::Util::TRUE,
'psgix.io' => $client,
'psgix.input.buffered' => Plack::Util::TRUE,
'psgix.harakiri' => Plack::Util::TRUE,
};
my $reqlen = parse_http_request($req->{headers}, $env);
if ($reqlen < 0) {
# Bad request
$self->_http_error($req, 400);
last;
}
$conn_header = delete $env->{HTTP_CONNECTION};
my $proto = $env->{SERVER_PROTOCOL};
if ($proto && $proto eq 'HTTP/1.0' ) {
if ($conn_header && $conn_header =~ /^keep-alive$/i) {
# Keep-alive only with explicit header in HTTP/1.0
$connection->{_keepalive} = 1;
}
else {
$connection->{_keepalive} = 0;
}
}
elsif ($proto && $proto eq 'HTTP/1.1') {
if ($conn_header && $conn_header =~ /^close$/i ) {
$connection->{_keepalive} = 0;
}
else {
# Keep-alive assumed in HTTP/1.1
$connection->{_keepalive} = 1;
}
# Do we need to send 100 Continue?
if ($env->{HTTP_EXPECT}) {
if ($env->{HTTP_EXPECT} eq '100-continue') {
# FIXME:
#syswrite $client, 'HTTP/1.1 100 Continue' . $CRLF . $CRLF;
}
else {
$self->_http_error(417, $env);
last;
}
}
unless ($env->{HTTP_HOST}) {
# No host, bad request
$self->_http_error(400, $env);
last;
}
}
unless ($self->{options}->{keepalive}) {
$connection->{_keepalive} = 0;
}
( run in 1.746 second using v1.01-cache-2.11-cpan-140bd7fdf52 )