Porbo
view release on metacpan or search on metacpan
lib/Porbo/Server.pm view on Meta::CPAN
$$listen_port_r = $port;
$self->{server_ready}->({
host => $host,
port => $port,
server_software => 'Porbo',
}) if $self->{server_ready};
return $self->{backlog} || 0;
};
}
sub _accept_handler {
my ($self, $app, $listen_host_r, $listen_port_r, $ssl) = @_;
$app = Plack::Middleware::ContentLength->wrap($app);
return sub {
my ( $sock, $peer_host, $peer_port ) = @_;
DEBUG && warn "$sock Accepted connection from $peer_host:$peer_port\n";
return unless $sock;
$self->{exit_guard}->begin;
if ( $self->{no_delay} ) {
setsockopt($sock, IPPROTO_TCP, TCP_NODELAY, 1)
or die "setsockopt(TCP_NODELAY) failed:$!";
}
my %args;
if ($ssl) {
$args{tls} = 'accept';
$args{tls_ctx} = {
key_file => $self->{ssl_key_file},
cert_file => $self->{ssl_cert_file},
};
}
my $handle; $handle = AnyEvent::Handle->new(
fh => $sock,
on_error => sub {
if ($handle) {
$handle->destroy;
$self->{exit_guard}->end;
}
},
%args,
);
$handle->push_read(line => "\015\012\015\012", sub {
my ($hdl, $header) = @_;
my $env = {
SERVER_NAME => $$listen_host_r,
SERVER_PORT => $$listen_port_r,
SCRIPT_NAME => '',
REMOTE_ADDR => $peer_host,
'psgi.version' => [ 1, 0 ],
'psgi.errors' => *STDERR,
'psgi.url_scheme' => $ssl ? 'https' : 'http',
'psgi.nonblocking' => Plack::Util::TRUE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.run_once' => Plack::Util::FALSE,
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => Plack::Util::FALSE,
'psgi.input' => undef, # will be set by _run_app()
'psgix.io' => $hdl->fh,
'psgix.input.buffered' => Plack::Util::TRUE,
};
my $reqlen = parse_http_request($header."\015\012\015\012", $env);
if ($reqlen < 0) {
return $self->_bad_request($handle, 0);
}
unless ( eval {
$self->_run_app($app, $env, $handle);
1;
}) {
my $disconnected = ($@ =~ /^client disconnected/);
$self->_bad_request($handle, $disconnected);
}
undef $handle;
});
};
}
sub _run_app {
my ($self, $app, $env, $handle) = @_;
unless ($env->{'psgi.input'}) {
if ($env->{CONTENT_LENGTH}) {
my $body;
$handle->on_read(sub {
$body .= $_[0]->rbuf;
$_[0]->rbuf = "";
if ($env->{CONTENT_LENGTH} <= length $body) {
open my $input, '<', \$body;
$env->{'psgi.input'} = $input;
$self->_run_app($app, $env, $handle);
}
});
return;
} else {
$env->{'psgi.input'} = $null_io;
}
}
my $res = Plack::Util::run_app $app, $env;
if ( ref $res eq 'ARRAY' ) {
$self->_write_psgi_response($handle, $res);
} elsif (ref $res eq 'CODE') {
$res->(sub {
$self->_write_psgi_response($handle, $_[0]);
});
} else {
croak("Unknown response type: $res");
}
}
sub _bad_request {
( run in 0.849 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )