Hatena::Groupsubtech

NaN days

ブログを移転しています。最新の記事は motemen.hatenablog.com へどうぞ

2012-09-20

コード中から簡単に plackup できるモジュールを書いた

| 19:50 | コード中から簡単に plackup できるモジュールを書いた - NaN days を含むブックマーク はてなブックマーク - コード中から簡単に plackup できるモジュールを書いた - NaN days


[2013-10-15] shipit しました。P が大文字になっています。


https://github.com/motemen/AnyEvent-plackup

使い方は簡単で、

use AnyEvent::plackup;
my $server = plackup(app => \&psgi_app, port => $port);
say $server; # => 'http://0.0.0.0:8290' # 文字列化すると URL に

とするだけです。ポートを指定しないと適当に空いているポートが選ばれます。

で、これだけだとただの Twiggy のラッパーなのですが、これが便利なのは app を指定せずに起動することができる点です。

my $server = plackup();

こういうことができるわけです。この使い方をした場合、呼び出し側でよしなにリクエストを捌く必要があります。

my $req = $server->recv;
$req->respond([ 200, [], [ 'OK' ] ]);

$server->recv を呼ぶと、リクエストが来るまでそこで処理がストップします (AnyEvent のループが回りはじめます)。やってくるリクエストオブジェクトは Plack::Request に respond というメソッドが生えたもので、これに raw PSGI response を返してやることで、クライアントにレスポンスを返すことができます。

これが何に使えるのかというと、OAuth アプリを書いてる際など、コールバックをとりあえず受け取るためだけのサーバを立てたいときに便利です。

my $plackup = plackup(port => 4000);
   $plackup->host('localhost'); # 0.0.0.0 だとリダイレクト先として許されないので…
my $client = Net::OAuth2::Client->new(
    $client_id,
    $client_secret,
    site               => 'https://accounts.google.com',
    authorize_path     => '/o/oauth2/auth',
    access_token_path  => '/o/oauth2/token',
    scope              => 'https://www.googleapis.com/auth/drive.readonly',
    access_token_param => 'oauth_token',
)->web_server(
    redirect_uri => "$plackup/oauth2callback",
);

system 'open', $client->authorize_url; # ここでブラウザが開く

my $code = $plackup->recv->parameters->{code}; # ブラウザで承認してリダイレクトされるとここに到達
my $token = $client->get_access_token($code);

ブラウザを勝手に開いちゃえばあとはリダイレクトで何とかしてくれる、という感じです。PIN みたいなのを手で入れたりする必要がないので便利です。