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.583 second using v1.01-cache-2.11-cpan-df04353d9ac )