Arriba
view release on metacpan or search on metacpan
lib/Arriba/Connection/HTTP.pm view on Meta::CPAN
my $class = shift;
my $self = $class->SUPER::new(@_);
if ($self->{client}->NS_proto eq 'TCP') {
setsockopt($self->{client}, IPPROTO_TCP, TCP_NODELAY, 1)
or die $!;
}
$self->{_inputbuf} = '';
$self->{_current_req} = undef;
$self->{_keepalive} = 1;
return $self;
}
sub read_request {
my $self = shift;
my $req;
if ($req = $self->{_current_req}) {
lib/Arriba/Connection/HTTP.pm view on Meta::CPAN
last unless $read && $read > 0;
}
$req->{content_length} = $length;
}
$req->{complete} = 1;
$self->{_current_req} = undef;
}
elsif ($self->{_keepalive}) {
# New request
$req = Arriba::Request->new($self);
$req->{scheme} = $self->{ssl} ? 'https' : 'http';
while (1) {
last if defined $self->{_inputbuf} &&
$self->{_inputbuf} =~ /$CRLF$CRLF/s;
my $read = sysread $self->{client}, my $buf, $self->{chunk_size};
lib/Arriba/Connection/HTTP.pm view on Meta::CPAN
}
}
elsif (my $te = $headers{'transfer-encoding'}) {
if ($te eq 'chunked') {
$chunked = 1;
}
}
}
else {
if (!exists $headers{'transfer-encoding'}) {
$self->{_keepalive} = 0;
}
}
if ($self->{_keepalive}) {
push @header_lines, 'Connection: keep-alive';
}
else {
push @header_lines, 'Connection: close';
}
syswrite $self->{client}, join($CRLF, @header_lines, '') . $CRLF;
if (defined $res->[2]) {
Plack::Util::foreach($res->[2], sub {
my $buffer = $_[0];
lib/Arriba/Server.pm view on Meta::CPAN
}
if ($options->{daemonize}) {
$extra{setsid} = $extra{background} = 1;
}
if ($options->{ssl_cert}) {
$extra{SSL_cert_file} = $options->{ssl_cert};
}
if ($options->{ssl_key}) {
$extra{SSL_key_file} = $options->{ssl_key};
}
if (!exists $options->{keepalive}) {
$options->{keepalive} = 1;
}
if (!exists $options->{keepalive_timeout}) {
$options->{keepalive_timeout} = 1;
}
my @port;
for my $listen (@{$options->{listen} || [ "$options->{host}:$options->{port}" ]}) {
my %listen;
if ($listen =~ /:/) {
my($h, $p, $opt) = split /:/, $listen, 3;
$listen{host} = $h if $h;
$listen{port} = $p;
$listen{proto} = 'ssl' if 'ssl' eq lc $opt;
lib/Arriba/Server.pm view on Meta::CPAN
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);
lib/Arriba/Server.pm view on Meta::CPAN
}
}
unless ($env->{HTTP_HOST}) {
# No host, bad request
$self->_http_error(400, $env);
last;
}
}
unless ($self->{options}->{keepalive}) {
$connection->{_keepalive} = 0;
}
$req->{env} = $env;
}
# Process this request later if it's not ready yet
next if !$req->{complete};
if ($req->{body_stream}) {
$env->{'psgi.input'} = $req->{body_stream}->rewind;
lib/Arriba/Server.pm view on Meta::CPAN
my $res = Plack::Util::run_app($self->{app}, $env);
if (ref $res eq 'CODE') {
$res->(sub { $connection->write_response($req, $_[0]) });
}
else {
$connection->write_response($req, $res);
}
my $sel = IO::Select->new($client);
last unless $sel->can_read($self->{options}->{keepalive_timeout});
}
}
sub _http_error {
my ($self, $req, $code) = @_;
my $status = $code || 500;
my $msg = status_message($status);
my $res = [
$status,
[ 'Content-Type' => 'text/plain', 'Content-Length' => length($msg) ],
[ $msg ],
];
$self->{client}->{connection}->{_keepalive} = 0;
$self->{client}->{connection}->write_response($req, $res);
}
1;
( run in 0.788 second using v1.01-cache-2.11-cpan-df04353d9ac )