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 に投げてみようかな.