Twiggy

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Perl extension Twiggy

0.1026  2021-01-20 23:01:13 PST
        - Improved documentation

0.1025  2015-01-04 07:00:16 JST
        - Fix a bug where Twiggy's run loop exits after a streaming request is cut off (hoelzro) #41

0.1024  2013-10-12 11:35:35 PDT
        - Fix a bug where exit_guard is not correctly decremented when writing header failed (maedama) #37

0.1023  2013-06-15 01:51:22 PDT
        - Move the bin directory (moznion) #35

0.1022  2013-06-12 12:36:16 PDT
        - convert to use Milla
        - Fix dependency for LWP

Changes  view on Meta::CPAN

        - Support listening on multiple sockets and UNIX sockets
        - Implemented psgix.io and psgix.input.buffered
        - Removed undocumented poll_cb on writer

0.03  Wed Nov 11 21:33:16 PST 2009
        - Merged nothingmuch's fork to make the socket handling much faster (twice as fast!)
        - Fixed poll_cb and writer shutdown
        - Implemented graceful exit on SIGQUIT (nothingmuch)

0.02  Thu Oct 29 12:38:15 PDT 2009
        - Support psgi.streaming and condvar response for delayed response (nothingmuch)
        - Improved error handling, memory usage and performance by not using AnyEvent::Handle (nothingmuch)

0.01  Mon Oct 12 23:31:52 2009
        - original version

MANIFEST  view on Meta::CPAN

eg/chat-websocket/templates/test.js
lib/AnyEvent/Server/PSGI.pm
lib/Plack/Handler/Twiggy.pm
lib/Twiggy.pm
lib/Twiggy/Server.pm
lib/Twiggy/Server/SS.pm
script/twiggy
t/00_compile.t
t/anyevent.t
t/anyevent_closed_connection.t
t/anyevent_closed_streaming.t
t/anyevent_extensions.t
t/anyevent_manyconnections.t
t/anyevent_server_starter.t
t/anyevent_slow_post.t
t/author-pod-syntax.t
t/deflater.t
t/disconnect.t

README  view on Meta::CPAN

      AE::cv->recv;

DESCRIPTION

    Twiggy is a lightweight and fast HTTP server with unique features such
    as:

    PSGI

      Can run any PSGI applications. Fully supports psgi.nonblocking and
      psgi.streaming interfaces.

    AnyEvent

      This server uses AnyEvent and runs in a non-blocking event loop, so
      it's best to run event-driven web applications that runs I/O bound
      jobs or delayed responses such as long-poll, WebSocket or streaming
      content (server push).

      This software used to be called Plack::Server::AnyEvent but was
      renamed to Twiggy.

    Fast header parser

      Uses XS/C based HTTP header parser for the best performance.
      (optional, install the HTTP::Parser::XS module to enable it; see also
      Plack::HTTPParser for more information).

lib/Twiggy.pm  view on Meta::CPAN

=head1 DESCRIPTION

Twiggy is a lightweight and fast HTTP server with unique features such
as:

=over 4

=item PSGI

Can run any PSGI applications. Fully supports I<psgi.nonblocking> and
I<psgi.streaming> interfaces.

=item AnyEvent

This server uses AnyEvent and runs in a non-blocking event loop, so
it's best to run event-driven web applications that runs I/O bound
jobs or delayed responses such as long-poll, WebSocket or streaming
content (server push).

This software used to be called Plack::Server::AnyEvent but was
renamed to Twiggy.

=item Fast header parser

Uses XS/C based HTTP header parser for the best performance. (optional,
install the L<HTTP::Parser::XS> module to enable it; see also
L<Plack::HTTPParser> for more information).

lib/Twiggy/Server.pm  view on Meta::CPAN

            if ( $self->_try_read_headers($sock, $headers) ) {
                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'   => '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'          => $sock,
                    'psgix.input.buffered' => Plack::Util::TRUE,
                };

                my $reqlen = parse_http_request($headers, $env);
                DEBUG && warn "$sock Parsed HTTP headers: request length=$reqlen\n";

lib/Twiggy/Server.pm  view on Meta::CPAN

        } else {
            $env->{'psgi.input'} = $null_io;
        }
    }

    my $res = Plack::Util::run_app $app, $env;

    if ( ref $res eq 'ARRAY' ) {
        $self->_write_psgi_response($sock, $res);
    } elsif ( blessed($res) and $res->isa("AnyEvent::CondVar") ) {
        Carp::carp("Returning AnyEvent condvar is deprecated and will be removed in the next release of Twiggy. Use the streaming callback interface intstead.");
        $res->cb(sub { $self->_write_psgi_response($sock, shift->recv) });
    } elsif ( ref $res eq 'CODE' ) {
        my $created_writer;

        $res->(
            sub {
                my $res = shift;

                if ( @$res < 2 ) {
                    croak "Insufficient arguments";

t/anyevent_closed_streaming.t  view on Meta::CPAN

use warnings;

use Test::Requires qw(AnyEvent::HTTP);
use AnyEvent::HTTP;
use Test::More;
use Test::TCP;
use Plack::Loader;
use POSIX ();
use Time::HiRes qw(usleep);

sub do_streaming_request {
    my ( $url, $callback ) = @_;

    local $Test::Builder::Level = $Test::Builder::Level + 1;

    my $cond = AnyEvent->condvar;

    http_get $url, timeout => 3, want_body_handle => 1, sub {
        my ( $h, $headers ) = @_;

        is $headers->{'Status'}, 200, 'streaming response should succeed';

        $h->on_read(sub {
            $h->push_read(line => sub {
                my ( undef, $line ) = @_;

                my $stop = $callback->($line, $cond);
                if($stop) {
                    $h->destroy;
                    $cond->send;
                }

t/anyevent_closed_streaming.t  view on Meta::CPAN

my $server = Test::TCP->new(
    code => sub {
        my ( $port ) = @_;

        my $server = Plack::Loader->load('Twiggy', port => $port, host => '127.0.0.1');
        $server->run($app);
        exit;
    },
);

do_streaming_request('http://127.0.0.1:' . $server->port, sub {
    my ( $line, $cond ) = @_;

    if($line == 5) {
        return 1;
    }
    return;
});

sleep 1; # give the process a bit to clean up, if it died

t/anyevent_extensions.t  view on Meta::CPAN


                $write->([
                    200,
                    [ 'Content-Type' => 'text/plain', ],
                    [ 'Hello, ' . $env->{QUERY_STRING} ],
                ]);
            }
        },
    ],
    [
        'coderef streaming',
        sub {
            my $cb = shift;
            my $res = $cb->(GET "http://127.0.0.1/?name=miyagawa");
            is $res->code, 200;
            is $res->header('content_type'), 'text/plain';
            is $res->content, 'Hello, name=miyagawa';
        },
        sub {
            my $env = shift;



( run in 0.908 second using v1.01-cache-2.11-cpan-4d50c553e7e )