PSGI/Plack勉強会
PSGI/Plack勉強会を開きました(ひとりで)。資料はGitHubにあげてあります。いろいろまとめ書き足りてないのですが、自分的には納得したので満足してしまいました。
以下にもコピペ。
PSGI/Plackとは?
PSGI策定の背景
PSGIプロトコル概略
ref: http://github.com/miyagawa/psgi-specs/blob/master/PSGI.pod
.------------------------------------------------------------. | Application | '------------------------------------------------------------' | .------------------------------------------------------------. | WAF | '------------------------------------------------------------' | passes $app as a coderef .------------------------------------------------------------. | PSGI implementation | '------------------------------------------------------------' | | request as an $env | .------------------. .------------------. .------------------. | mod_perl | | FastCGI | | Pure Perl | '------------------' '------------------' '------------------' | | | .------------------------------------------------------------. | Request | '------------------------------------------------------------'
PSGIにおけるアプリケーションとは
という仕様を満たすコードリファレンス(詳細は後述)。
Plack
Hello World
- ハンドラ = coderefを.psgiファイルに定義する
- plackupを使い、plackを起動する
config/hello_world.psgi
my $handler = sub { return [ 200, [ "Content-Type" => "text/plain", "Content-Length" => 11 ], [ "Hello World" ], ]; };
plackの起動
perl -Imodules/Plack/lib modules/Plack/scripts/plackup -app config/hello_world.psgi
Hello World (2)
plackupの行っていること:
- config/hello_world.psgiをロード。
- Plack::Loaderにより適切なサーバ実装が選択される。
- この場合、Plack::Impl::StandAloneが使われる。plackupへの--implオプションで変更可能。
- 選択されたPlack::Impl::*に$handlerがわたされ、アプリケーションが実行される。
Plackを使ってWAFを作ろう (1)
最低限必要なもの:
Plackを使ってWAFを作ろう (2)
環境変数を受け取り、レスポンスをPSGI形式なコードリファレンスとしてハンドラ。
package MyWAF::Handler::PSGI; use strict; use warnings; use Carp qw(croak); use UNIVERSAL::require; sub handler { my ($class, $app) = @_; qroak qq{no such app: $app} if !$app->use; sub { my $env = shift; $app->run($env); }; } !!1;
Plackを使ってWAFを作ろう (2)
受け取った環境変数(リクエスト)を元に、あれこれする箇所(WAFの勘所)。
package MyWAF; use strict; use warnings; sub run { my ($class, $env) = @_; # $envからリクエストオブジェクトを生成 # どのコントローラ、アクションにdispatchするかを決定 # コントローラ実行 # ビューをレンダリング return $response->result; # レスポンスを以下のような形式の配列リファレンスとして返す # [ # 200, # [ # 'Content-Type' => 'text/html', # # ... # ], # [ 'Hello World' ] # ] } !!1;
Plackを使ってWAFを作ろう (3)
早速使ってみる。MyAppを作成。
package MyApp; use strict; use warnings; use base qw(MyWAF); !!1;
Plackを使ってWAFを作ろう (4)
Plackアプリケーションを起動するためのpsgiファイル。
use MyWAF::Handler::PSGI; my $handler = MyWAF::Handler::PSGI->handler('MyApp');
Plackを使ってWAFを作ろう (5)
MyAppをCGI上で動作させる。
#!/usr/bin/env perl use strict; use warnings; use Plack::Impl::CGI; my $app = do 'config/myapp.psgi'; Plack::Impl::CGI->new->run($app);
Plackを使ってWAFを作ろう (6)
MyAppをmod_perl上で動作させる。
<Locaion /> SetHandler perl-script PerlHandler Plack::Impl::Apache2 PerlSetVar psgi_app /path/to/myapp.psgi </Location>
まとめ
- PSGIの仕様はシンプル。
- Plackという実装もあるので、サーバ実装の差異にまつわる面倒なことをお任せできて、簡単にWAFを作れる。
- お膳立ては整っているので、いけてるWAFにするのはWAF開発者のセンス次第。