恥ずかしながらいままでLWP::UserAgentでリクエストを送るときにどう書くのかがいまいち分からず、ずっと毎回検索していました.... 今回検索して LWP::UserAgentでBasic認証サイトにアクセスする方法|blog|たたみラボ を読んで、そのあと HTTP::Request::Common - Construct common HTTP::Request objects - search.cpan.org と見比べて、ようやくいままでの謎が解けました。
use HTTP::Request::Common するとGETやPOST などの名前で HTTP::Request のインスタンスを返す関数がエクスポートされるので、
$ua->request(GET 'http://labs.gmo.jp/blog/ku/');
と書いたりできるようになるのだと知りました.....
use HTTP::Request::Commonしないときは
my $req = HTTP::Request->new(GET => 'http://labs.gmo.jp/blog/ku/' );
$ua->request($req);
と書くので、いつもWebで検索して、書かれているコードスニペットを見て、"requestのあとにある GETやPOSTに => がついてたりついていなかったりするのはどういう仕組みなんだろう.... "と思ってたんですが、こんな単純な仕組みだったんですね.... コードの一部だけだと use HTTP::Request::Common
は含まれていないことが多いのと、たかがリクエストの送信と思ってまじめに読んだことがなかったのでずっと混同していました。これで次回からは何も見なくても書けるようになりそうです。いまさらですけど....
前ふりが長くなりました。本題のBASIC認証付きでリクエストを送る方法に戻ります。
LWP::UserAgentでBasic認証サイトにアクセスする方法|blog|たたみラボ で LWP::UserAgentのcredentials を使って認証する方法はそのうちということになっていたので、このメソッドはどう使うものなのか調べてみました。
自分はtwitterのAPIを使いたくてやり方を調べていたので、まずLWP::UserAgentのcredentialsで認証するのと HTTP::Requestのauthorization_basic で認証するのとどっちが一般的なのか知りたいなと思って Net::Twitter と、Plagger::Plugin::UserAgent::AuthenRequest を見てみました。結果両方とも LWP::UserAgentのcredentialsで認証していたのでこっちを使うことにしました。
LWP::UserAgentのcredentialsで認証しようとすると、認証のrealmを設定しないといけないのと、やや面倒なところです。
一度アクセスしたいページにリクエストを送って、帰ってきたHTTPヘッダの中にある
WWW-Authenticate: Basic realm="Twitter API"
のところを記述します。
最終的なコードは
use HTTP::Request::Common;
use LWP::UserAgent;
my $endpoint = 'http://twitter.com/statuses/update.json';
my $ua = LWP::UserAgent->new;
my $u = URI->new($endpoint);
my $realm = 'Twitter API';
$ua->credentials( $u->host_port , $realm, $username, $password );
my $res = $ua->request(POST $endpoint, [ status => 'hi, yo.' ] );
こんなかんじになります。
関係ないけど $ua->>get()/post() 使ったほうが楽なのではというのは、単純に自分が
$ua->post と書けるのを知りませんでした。LWP::UserAgentのコードを見ると中も
sub post {
require HTTP::Request::Common;
my($self, @parameters) = @_;
my @suff = $self->>_process_colonic_headers(\@parameters,2);
return $self->request( HTTP::Request::Common::POST( @parameters ), @suff );
}
こうなっています。$self->>_process_colonic_headersはLWP::UsrAgentの内部的なヘッダの処理のために呼ばれているだけで全く同じなので次から $ua->>post と書いて楽させてもらいます。
もうひとつ、はじめに自分でrealmを調べてわざわざ書くのはめんどくさいから $ua->get_basic_credentials をオーバーライドするか $req->authorization_basic した方が楽じゃん、という話については LWP::UserAgentでBasic認証サイトにアクセスする方法|blog|たたみラボ のほうでくわしく書かれていたのでいいかなと思って触れていませんでした。
ご指摘いただいた通りrealmなんて普段作る側としても意識していないしめんどくさいだけなので、自分も本当は $req->authorization_basic したかったのですが、はじめに白状したとおり LWP::UserAgent::post とか HTTP::Request::Common::POST とか HTTP::Request::new の引数の POST => とかもろもろ理解していなかったため、たたみラボさんの記事をまねしつつ書いてみたけどPOSTにパラメータをどうやったら渡せるかわかんない!という状態であきらめたというのが真相です....
トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。
http://labs.gmo.jp/mt/mt-tb.cgi/129
comments
はじめまして。HTTP::Request::Common::POSTとauthorization_basicを組み合わせる方法について以下の記事に述べてみましたので、よろしければご参照ください。
http://www.akatsukinishisu.net/itazuragaki/perl/basic_auth_post_by_lwp_useragent.html