1package Plack::Handler::AnyEvent::ReverseHTTP; 2use strict; 3use 5.008_001; 4our $VERSION = '0.04'; 5 6use AnyEvent::ReverseHTTP; 7use HTTP::Message::PSGI; 8use HTTP::Response; 9use Plack::Util; 10 11sub new { 12 my($class, %args) = @_; 13 bless \%args, $class; 14} 15 16sub register_service { 17 my($self, $app) = @_; 18 $self->{guard} = reverse_http $self->{host}, $self->{token}, sub { 19 my $req = shift; 20 my $env = $req->to_psgi; 21 22 if (my $client = delete $env->{HTTP_REQUESTING_CLIENT}) { 23 @{$env}{qw( REMOTE_ADDR REMOTE_PORT )} = split /:/, $client, 2; 24 } 25 26 $env->{'psgi.nonblocking'} = Plack::Util::TRUE; 27 $env->{'psgi.streaming'} = Plack::Util::TRUE; 28 $env->{'psgi.multithread'} = Plack::Util::FALSE; 29 $env->{'psgi.multiprocess'} = Plack::Util::FALSE; 30 $env->{'psgi.run_once'} = Plack::Util::FALSE; 31 32 my $r = $app->($env); 33 if (ref $r eq 'ARRAY') { 34 return HTTP::Response->from_psgi($r); 35 } elsif (ref $r eq 'CODE') { 36 my $cv = AE::cv; 37 $r->(sub { 38 my $r = shift; 39 40 if (defined $r->[2]) { 41 my $res = HTTP::Response->from_psgi($r); 42 $cv->send($res); 43 } else { 44 my $res = HTTP::Response->from_psgi([ $r->[0], $r->[1], [] ]); # dummy 45 my @body; 46 return Plack::Util::inline_object 47 write => sub { push @body, $_[0] }, 48 close => sub { $res->content(join '', @body); $cv->send($res) }; 49 } 50 }); 51 return $cv; 52 } else { 53 die "Bad response: $r"; 54 } 55 }; 56} 57 58sub run { 59 my $self = shift; 60 $self->register_service(@_); 61 AE::cv->recv; 62} 63 641; 65 66__END__ 67 68=head1 NAME 69 70Plack::Handler::AnyEvent::ReverseHTTP - reversehttp gateway for PSGI application 71 72=head1 SYNOPSIS 73 74 > plackup --server AnyEvent::ReverseHTTP --host rhttplabel --token your-token 75 76=head1 DESCRIPTION 77 78Plack::Handler::AnyEvent::ReverseHTTP is Plack handler that runs your 79PSGI application on L<AnyEvent::ReverseHTTP>. It uses ReverseHTTP 80gateway to access your PSGI application on your desktop or behind the 81firewall from the internet. Just like Ruby's hookout does with Rack 82applications. 83 84=head1 AUTHOR 85 86Tatsuhiko Miyagawa E<lt>miyagawa@bulknews.netE<gt> 87 88=head1 LICENSE 89 90This module is licensed under the same terms as Perl itself. 91 92=head1 SEE ALSO 93 94L<AnyEvent::ReverseHTTP> L<http://github.com/paulj/hookout/tree/master> L<http://www.reversehttp.net/> 95 96=cut 97