Created
May 13, 2011 08:16
-
-
Save dolmen/970190 to your computer and use it in GitHub Desktop.
Discovering PSGI: A proof of concept of a proxy that switches Google and Bing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# vim:set ft=perl: | |
use strict; | |
use warnings; | |
# plackup --port 8079 -s Twiggy -a GoogleBingProxy.psgi | |
# http_proxy=http://0.0.0.0:8079/ curl -i http://www.google.fr/ | |
# Les lignes suivantes ne sont pas néccessaires, mais ça permet de | |
# spécifier plus clairement les dépendances pour ceux qui voudraient faire | |
# tourner l'exemple | |
require Twiggy; | |
require AnyEvent::HTTP; | |
require Plack::App::Proxy; | |
BEGIN { $ENV{PLACK_PROXY_BACKEND} = 'AnyEvent::HTTP' } | |
package Plack::Middleware::ClearCookies; | |
$INC{'Plack/Middleware/ClearCookies.pm'} = __FILE__; | |
use parent 'Plack::Middleware'; | |
require Plack::Util; | |
sub call | |
{ | |
my ($self, $env) = @_; | |
delete $env->{HTTP_COOKIE}; | |
my $res = $self->app->($env); | |
Plack::Util::response_cb($res, sub { | |
my $res = shift; | |
my $headers = $res->[1]; | |
for(my $i = $#{ $headers }-1; $i > 0; $i--) { | |
next unless $headers->[$i] =~ /^Set-Cookie$/i; | |
splice @$headers, $i, 2; | |
} | |
}) | |
} | |
package Plack::Middleware::PrintCookies; | |
$INC{'Plack/Middleware/PrintCookies.pm'} = __FILE__; | |
use parent 'Plack::Middleware'; | |
require Plack::Util; | |
sub call | |
{ | |
my ($self, $env) = @_; | |
if (exists $env->{HTTP_COOKIE}) { | |
foreach my $cookie (split /\s*;\s*/, $env->{HTTP_COOKIE}) { | |
print "-> $cookie\n"; | |
} | |
} | |
Plack::Util::response_cb($self->app->($env), sub { | |
my $res = shift; | |
my $headers = $res->[1]; | |
for(my $i = $#{ $headers }-1; $i > 0; $i--) { | |
next unless $headers->[$i] =~ /^Set-Cookie$/i; | |
foreach my $cookie (split /\s*,\s*/, $headers->[$i+1]) { | |
print "<- $cookie\n"; | |
} | |
} | |
}) | |
} | |
package Plack::Middleware::BingGoogleProxy; | |
$INC{'Plack/Middleware/BingGoogleProxy.pm'} = __FILE__; | |
use parent 'Plack::Middleware'; | |
sub call | |
{ | |
my ($self, $env) = @_; | |
#print join(',', keys(%$env)), "\n"; | |
print "Host: $env->{HTTP_HOST}\n" if exists $env->{HTTP_HOST}; | |
print "URI: $env->{REQUEST_URI}\n"; | |
my ($host, $path) = ($env->{REQUEST_URI} =~ m!http://([^/]*)(/?.*)$!); | |
my $host_orig = $host; | |
if ($host eq 'www.google.fr') { | |
$host = 'www.bing.com'; | |
} elsif ($host eq 'www.bing.com') { | |
$host = 'www.google.fr'; | |
} | |
if ($host ne $host_orig) { | |
$env->{HTTP_HOST} = $host; | |
$env->{REQUEST_URI} = 'http://'.$host.$path; | |
Plack::Middleware::ClearCookies->wrap($self->app)->($env); | |
} else { | |
$self->app->($env); | |
} | |
} | |
package Plack::App::BingGoogleProxy; | |
use Plack::App::Proxy; | |
my $proxy = Plack::App::Proxy->new->to_app; | |
my $app = sub($) { | |
my $env = shift; | |
# Forward | |
# TODO drop CONNECT, and non-http:// | |
$env->{'plack.proxy.url'} = $env->{REQUEST_URI}; | |
$env->{REQUEST_URI} =~ s!^http://[^/]*!!; | |
$proxy->($env) | |
}; | |
use Plack::Builder; | |
builder { | |
enable 'Plack::Middleware::PrintCookies'; | |
enable 'Plack::Middleware::BingGoogleProxy'; | |
$app | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment