LWP::UserAgent::env_proxy
proxy 通さなきゃいけない環境でも LWP::UA を使うのは結構簡単.適切な環境変数を定義しておき,env_proxy を呼ぶ.すると,あとは LWP::UA がよしなにしてくれる.例えばこんな感じ.
use LWP::UserAgent;
$ENV{HTTP_PROXY} = $ENV{FTP_PROXY} = 'http://user:pass@proxy.example.com:8080';
$ENV{NO_PROXY} = '127.0.0.1, localhost';
my $ua = LWP::UserAgent->new;
$ua->env_proxy;
# or
my $ua = LWP::UserAgent->new(env_proxy => 1);user:pass@ の部分は必要に応じて記述すればよい.user/pass 付きだと,リクエストヘッダに Proxy-Authorization を自動的に付けてくれるのでありがたい.
ちゃんと no_proxy にも対応していて,localhost など proxy を通さなくてもよいホストを $ENV{NO_PROXY} に split /\s*,\s*/ で区切れるように設定しておくと,それらホストへのリクエストの場合は proxy 関連のヘッダを含めないようになる.
ほげほげ_PROXY っていう環境変数が特に無い場合,env_proxy は別に何もしないだけなので,あえて env_proxy を呼んでもたいした損は無い.LWP::UA 使ってモジュール作る場合なんかは,むしろ幸せになれる人のほうが多いかも?
ただ,残念なことに,LWP::UA は 192.168.0.0/24 といった形式の no_proxy には対応していない.Firefox の proxy 設定なんかだと受け付けてくれるのにね.サブネット全般に渡ってアドレスを1個1個設定していくのは萎えてしまう.ということで,サブネット形式でも指定できるパッチを書いた.どうやらパッチ期に入ったらしい.
--- lib/LWP/UserAgent.pm.orig Fri Nov 12 03:12:04 2004
+++ lib/LWP/UserAgent.pm Thu Apr 13 12:37:56 2006
@@ -28,8 +28,8 @@
};
}
+use constant HAS_NET_SUBNETS => eval { require Net::Subnets; 1 } || 0;
-
sub new
{
my($class, %cnf) = @_;
@@ -782,6 +782,20 @@
if ($host =~ /\Q$domain\E$/) {
LWP::Debug::trace("no_proxy configured");
return;
+ }
+
+ # check $host is in $domain subnets,
+ # e.g., $ENV{NO_PROXY} includes '192.168.0.0/24';
+ # $domain is '192.168.0.0/24' and $host is '192.168.0.10'
+ next unless HAS_NET_SUBNETS;
+ my $re = join '\.', ('(?:2(?:[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])') x 4;
+ if ($host =~ /^$re$/ and $domain =~ m!^$re/(?:3[0-2]|[12][0-9]|[1-9])$!) {
+ my $sn = Net::Subnets->new;
+ $sn->subnets([$domain]);
+ if (my $subnetref = $sn->check(\$host)) {
+ LWP::Debug::trace("no_proxy configured");
+ return;
+ }
}
}
}さしあたって,Net::Subnets があるときだけチェックするようにした.このパッチは Gisle に投げてみようかな.