Twiggy
view release on metacpan or search on metacpan
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
- 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
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
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 )