Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Always use psgi.streaming interface and AnyEvent::HTTP.

AnyEvent::HTTP can just work fine with a blocking server (like
Standalone or mod_perl) if you immediately call ->recv on it.

This branch can be merged once Plack's topic/streaming-blocking branch
is merged and released on CPAN.
  • Loading branch information...
commit 6a113bad74b0e9dc53e5a74dcc9aa965b54d8dc3 1 parent b2cfc03
@miyagawa miyagawa authored
View
1  Makefile.PL
@@ -6,6 +6,5 @@ test_requires 'Test::More';
requires 'Plack' => 0.9021; # for Plack::Component
requires 'Plack::Request';
requires 'AnyEvent::HTTP' => 1.44; # for Host header
-requires 'LWP';
auto_set_repository;
WriteAll;
View
45 lib/Plack/App/Proxy.pm
@@ -5,13 +5,17 @@ use parent 'Plack::Component';
use Plack::Util::Accessor qw/host url preserve_host_header/;
use Plack::Request;
use Try::Tiny;
+use AnyEvent::HTTP;
our $VERSION = '0.06';
sub call {
my ($self, $env) = @_;
- $self->setup($env) unless $self->{proxy};
-
+
+ unless ($env->{'psgi.streaming'}) {
+ die "Plack::App::Proxy only runs with the server with psgi.streaming support";
+ }
+
my $req = Plack::Request->new($env);
my $url;
@@ -45,30 +49,13 @@ sub call {
push @headers, ("Content-Type", $req->content_type,
"Content-Length", $req->content_length);
}
-
- return $self->{proxy}->($env->{REQUEST_METHOD}, $url, \@headers, $content);
-}
-sub setup {
- my ($self, $env) = @_;
- try {
- die "Falling back to blocking client" unless $env->{"psgi.streaming"} && $env->{"psgi.nonblocking"};
- require AnyEvent::HTTP;
- $self->{proxy} = sub {$self->async(@_)};
- } catch {
- require LWP::UserAgent;
- $self->{proxy} = sub {$self->blocking(@_)};
- $self->{ua} = LWP::UserAgent->new;
- }
-}
-
-sub async {
- my ($self, $method, $url, $headers, $content) = @_;
return sub {
my $respond = shift;
+ my $cv = AE::cv;
AnyEvent::HTTP::http_request(
- $method => $url,
- headers => {@$headers},
+ $env->{REQUEST_METHOD} => $url,
+ headers => {@headers},
body => $content,
want_body_handle => 1,
sub {
@@ -82,28 +69,20 @@ sub async {
$handle->on_eof(sub {
$handle->destroy;
$writer->close;
+ $cv->send;
});
$handle->on_error(sub{});
$handle->on_read(sub {
my $data = delete $_[0]->{rbuf};
- $writer->write($data) if $data;
+ $writer->write($data);
});
}
}
);
+ $cv->recv unless $env->{"psgi.nonblocking"};
}
}
-sub blocking {
- my ($self, $method, $url, $headers, $content) = @_;
- my $req = HTTP::Request->new($method => $url, $headers, $content);
- my $res = $self->{ua}->request($req);
- if ($res->code =~ /^5\d+/) {
- return [502, ["Content-Type","text/html"], ["Gateway error"]];
- }
- return [$res->code, [$self->response_headers($res)], [$res->content]];
-}
-
sub response_headers {
my ($self, $headers) = @_;
my @valid_headers = qw/Content-Length Content-Type Content-Encoding ETag
View
1  t/01-request.t
@@ -1,6 +1,7 @@
use Plack::App::Proxy;
use Plack::Test;
use Test::More tests => 5;
+$Plack::Test::Impl = 'Server';
# regular static proxy
test_psgi
View
1  t/02-gzipped.t
@@ -3,6 +3,7 @@ use warnings;
use Plack::App::Proxy;
use Plack::Test;
use Test::More tests => 1;
+$Plack::Test::Impl = 'Server';
test_psgi
app => Plack::App::Proxy->new(host => "http://www.google.com/intl/en"),
View
26 t/03-streaming.t
@@ -1,26 +0,0 @@
-use strict;
-use warnings;
-use Plack::Test;
-use Plack::App::Proxy;
-use Test::More tests => 3;
-
-# Do the test with psgi.streaming
-use AnyEvent;
-$Plack::Test::Impl = 'Server';
-
-test_psgi
- app => Plack::App::Proxy->new(host => "http://www.google.com/intl/en"),
- client => sub {
- my $cb = shift;
- my $req = HTTP::Request->new(GET => "http://localhost/index.html");
-
- my $res = $cb->($req);
-
- ok $res->is_success, "Check the status line.";
- like $res->content,
- qr(<html[^>]*>)sm,
- "Should have a html tag.";
- unlike $res->content,
- qr(<html[^>]*>.*<html[^>]*>)sm,
- "Shouldn't have more than two html tags.";
- };
Please sign in to comment.
Something went wrong with that request. Please try again.