Skip to content

Instantly share code, notes, and snippets.

@nihen
Created October 13, 2009 03:15
Show Gist options
  • Save nihen/208943 to your computer and use it in GitHub Desktop.
Save nihen/208943 to your computer and use it in GitHub Desktop.
package Plaxy;
use strict;
use warnings;
use utf8;
use Plack::Request;
use Plack::Response;
use LWP;
use Coro;
use Coro::Channel;
use IO::Handle::Util qw/io_from_getline/;
sub import {
strict->import;
warnings->import;
utf8->import;
}
sub handler {
\&app;
}
sub app {
my $env = shift;
my $req = Plack::Request->new($env);
my ($res, $io) = _request($req);
my $plack_res = Plack::Response->new($res->code, $res->headers, $io);
select STDOUT;$| = 1;
return $plack_res->finalize;
}
sub _request {
my $req = shift;
my $proxy = shift;
my $ua = LWP::UserAgent->new(max_redirect => 0);
my $ua_req = $req->as_http_request;
$ua_req->uri($req->env->{REQUEST_URI});
if ( $ua_req->header('X_FORWARDED_FOR') ) {
$ua_req->header('X_FORWARDED_FOR' => $ua_req->header('X_FORWARDED_FOR') . "," . $req->address);
}
else {
$ua_req->header('X_FORWARDED_FOR' => $req->address);
}
my $res_q = Coro::Channel->new;
my $content_q = Coro::Channel->new;
my $header_parsed = 0;
async {
my $res = $ua->request($ua_req, sub {
my ( $content, $res ) = @_;
if ( !$header_parsed ) {
$header_parsed = 1;
$res_q->put($res);
}
$content_q->put($content);
cede;
});
$res_q->put($res);
$content_q->put;
}
cede;
my $res = $res_q->get;
return $res, io_from_getline sub {
cede;
return $content_q->get;
};
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment