Perlbal::Plugin::ProxyPass
Perlbal で Vpaths プラグインをつかって、
LOAD vpaths CREATE POOL apache POOL apache ADD 127.0.0.1 CREATE SERVICE apache_proxy SET role = reverse_proxy SET pool = apache ENABLE apache_proxy CREATE SERVICE selector SET listen = 0.0.0.0:8080 SET role = selector SET plugins = vpaths VPATH /apache = apache_proxy ENABLE selector
みたいな設定をすると、
http://localhost:8080/apache -> http://localhost:80/apache
といった形でプロキシしてくれるんだけど、これを
http://localhost:8080/apache -> http://localhost:80/
としたくてプラグイン書いてみた。もしかしてプラグイン書かなくてもできるかもしれないけど、やり方がわからなかったのと、プラグインを書く練習ってことで。プラグイン名は Apache mod_proxy の ProxyPass ディレクティブにちなんでます。
package Perlbal::Plugin::ProxyPass; use strict; use warnings; sub load { my $class = shift; Perlbal::register_global_hook('manage_command.proxypass', sub { my $mc = shift->parse(qr/proxypass\s+(?:(\w+)\s+)?(\S+)\s*=\s*(\S+)$/, "usage: ProxyPass [<service>] <source path> = <dest path>"); my ($selname, $source, $target) = $mc->args; unless ($selname ||= $mc->{ctx}{last_created}) { return $mc->err("omitted service name not implied from context"); } my $ss = Perlbal->service($selname); return $mc->err("Service '$selname' is not a reverse_proxy service") unless $ss && $ss->{role} eq "reverse_proxy"; $ss->{extra_config}->{_proxypass} ||= []; push @{$ss->{extra_config}->{_proxypass}}, [ $source, $target ]; return $mc->ok; }); return 1; } sub register { my ($class, $svc) = @_; unless ($svc && $svc->{role} eq "reverse_proxy") { die "You can't load the proxypass plugin on a service not of role reverse_proxy.\n"; } $svc->register_hook( 'ProxyPass' => 'start_proxy_request', sub { my Perlbal::ClientProxy $client = shift; for my $proxypass ( @{ $svc->{extra_config}->{_proxypass} } ) { my $source = $proxypass->[0]; my $target = $proxypass->[1]; $client->{req_headers}->{uri} =~ s/$source/$target/; $client->{req_headers}->{uri} =~ s!//!/!; } return 0; } ); return 1; } 1;
設定はこんな感じ。
LOAD vpaths LOAD ProxyPass CREATE POOL apache POOL apache ADD 127.0.0.1 CREATE SERVICE apache_proxy SET role = reverse_proxy SET pool = apache SET plugins = ProxyPass ProxyPass /apache = / ENABLE apache_proxy CREATE SERVICE selector SET listen = 0.0.0.0:8080 SET role = selector SET plugins = vpaths VPATH /apache = apache_proxy ENABLE selector
