Coro::LWPで/etc/hostsを使う
本番環境と同じドメインでアクセスできるストレージ環境があって、
/etc/hostsのIPアドレスを書き換えて開発のチェックをしてたりします。
で、Coro::LWP使ったscriptでアクセスしてみたら本番の方に行ってしまいハマったのでメモ書き。
まずMacOSXだから/etc/hostsを読んでくれてないのかと思いだいぶハマりました。
Linuxでやっても同じように本番の方に行ってしまったので「あれ?おかしいな」と。
で、試しに/etc/hostsに
127.0.0.1 www.google.co.jp
と書き、LWP::UserAgent使って
perl -MLWP::UserAgent -e 'warn LWP::UserAgent->new->get("http://www.google.jp")->code'
を実行してみると
403 at -e line 1.
ちゃんとエラーになる。
次にCoro::LWPを使って
perl -MLWP::UserAgent -MCoro::LWP -e 'warn LWP::UserAgent->new->get("http://www.google.jp")->code'
を実行してみると
200 at -e line 1.
200正常が返って来て/etc/hostsを見てくれてないことがわかった。
こっから色々ググって何か方法ないかと探してみたのだけどなかなか見当たらず。
で、Coro::LWPの中を覗いてみて
Coro::Util::inet_aton
ってのが使われてて、Coro::Utilを覗いてみると
AnyEvent::Socket::inet_aton
ってのが使われてて、さらにAnyEvent::Socketを覗いてみると
require AnyEvent::DNS;
ってなってて、「コレっぽいかな?」と当てを付けてみたのだけど、そこから先に進めず。
「わからないことがあれば#perl-casualで聞くといいよ!」
ってのを色んな発表で聞いていたので良い機会だと思い試しに聞いてみました。
monmon Coro::LWPについて分かる方いたら教えて欲しいのですが、 monmon Coro::LWPで/etc/hostsの内容を読んでくれる方法ってありますか? monmon 例えば、 monmon [13:50@www5206u]% grep google /etc/hosts [/tmp]127.0.0.1 www.google.co.jp monmon と、hostsに書いておいて、 monmon 普通にLWPを使った場合は monmon [13:50@www5206u]% perl -MLWP::UserAgent -e 'warn LWP::UserAgent->new->get("http://www.google.jp")->code' monmon 403 at -e line 1. mobitaro Google [text/html; charset=UTF-8] monmon hosts見てくれるのですけど、 monmon Coro::LWP使うと monmon [13:51@www5206u]% perl -MLWP::UserAgent -MCoro::LWP -e 'warn LWP::UserAgent->new->get("http://www.google.jp")->code' monmon 200 at -e line 1. mobitaro Google [text/html; charset=UTF-8] monmon DNSを見ちゃう kazuho AnyEvent::DNS? なのでそうですね monmon Coro::LWPの中で、Coro::Util::inet_atonを使ってて、Coro::Utilが monmon あ、そです tokuhirom4 うん monmon AnyEvent::DNS使ってるようなので monmon どうにかやる方法がないのかなと tokuhirom4 AnyEvent::DNS に hosts を見る機能がないから monmon 思い。 monmon そうすると/etc/hosts見るようにするには自分でCoro::LWPに似たようなものを作るしかないですかね? tokuhirom4 自分だったら、どっかをフックして、/etc/hosts をよんでよしなにするけど kazuho とりあえずなおせりゃいいなら Coro::Util::inet_aton をフックするのがいいかなと kazuho /etc/hosts をちゃんと読むのめんどくさそう tokuhirom4 そういう CPAN module とか tokuhirom4 ありそうだけどw tokuhirom4 つーかまあ tokuhirom4 シリアスな用途じゃないなら tokuhirom4 Coro::LWP を use する前に tokuhirom4 Socket::inet_aton を保存しておいて tokuhirom4 use Coro::LWP してから restore するとかでも tokuhirom4 いいとおもうけど。 tokuhirom4 DNS が block するのが問題なければ。 tokuhirom4 カジュアル用途ならそれで十分とおもう。 tokuhirom4 なにかいてるのかしらんけど! monmon なるほどなるほど。ドメインを同じにしてあるステージング環境のステータスコードチェックしたいだけなので monmon その方法調べてみます。 monmon ありがとございます
ということで説明する前に理解してもらって速攻で道筋を教えてもらえました。
出来上がったのが以下のような感じ。
Socket::inet_atonを上書きしてみたのだけどCoro::Utilの中でも使っていたので
Coro::Util::inet_atonごと上書きしました。
#!/usr/bin/env perl use strict; use warnings; use LWP::UserAgent; use Socket; use Data::Dumper; BEGIN { *inet_aton = \&Socket::inet_aton; } use Coro::LWP; #*Socket::inet_aton = \&inet_aton; *Coro::Util::inet_aton = \&inet_aton; my $url = shift || "http://www.google.co.jp"; print LWP::UserAgent->new->get($url)->code;
https://gist.github.com/751157
「上手くいったーやったー。」と思って#perl-casualにありがとうありがとうの報告をしようと見てみたら
mash_ dnsmasqって/etc/hostsを見てくれるDNSサーバをローカルにたてたりしてます
という続きがあったのでそっちもやってみました。
dnsmasqのインストールと設定と起動
homebrewにあったのでそのままinstall
sudo brew install dnsmasq
名前解決で自分を見るように/etc/resolv.confに以下を追加
nameserver 127.0.0.1
あとは起動
/usr/local/sbin/dnsmasq
/etc/hostsを見ているか確認
% nslookup www.google.co.jp Server: 127.0.0.1 Address: 127.0.0.1#53 Name: www.google.co.jp Address: 127.0.0.1
おぉぉ!上手くいってる様子。
超楽だ。これは便利。
IRC使ったことなくて聞くの躊躇してたんだけど今日聞いておいて良かった。
ありがとうありがとう。