Amon2の流れを掴む - 5
前回の続きから。
今回は lib/sample/Web.pm
の中身を見て行きます。
sample::Web
package sample::Web; use strict; use warnings; use utf8;
おなじみ。
use parent qw/sample Amon2::Web/;
どうやら前回見たsample
に加えて、Amon2::Web
を継承しているようです。
use File::Spec;
OSによるセパレータの違いを吸収してくれるモジュール。
だけど、使ってる様子はないので謎。
# dispatcher use sample::Web::Dispatcher; sub dispatch { return (sample::Web::Dispatcher->dispatch($_[0]) or die "response is not generated"); }
Amon2::Web
を見に行くと分かりますが、dispatch
という抽象メソッドが定義されているので、きっちりdispatch
は用意しなきゃいけないです。
ここでは単に、sample::Web::Dispatcher
で割り振られたコントローラ
でレンダリング
されたページのbody
が返ってきます。
# load plugins __PACKAGE__->load_plugins( 'Web::FillInFormLite', 'Web::JSON', '+sample::Web::Plugin::Session', );
ここではプラグイン
をロードしています。local
以下にあるプラグイン(Amon2
に標準で入っているものやCarton
で入れたもの)を指定する以外にも、lib
以下(自分で追加したもの)を指定したい場合には+
を付けます。
Web::FillInFormLite
はHTML
のform
に対して、値を簡単に挿入したやることが出来る機能を提供します。
any '/' => sub { my ($c) = @_; $c->FillInForm(+{ hoge => "ほげ" }); return $c->render('index.tx'); };
<!doctype html> <html> <head> ... </head> <body> ... <form method="POST" action="/register"> <input name="hoge" type="text"></input> <input type="submit"> </form> ... </body> </html>
こうすると、name="hoge"
のinput要素
に"ほげ"という値が入ります。
また、Web::JSON
はjson_render
という、ハッシュリファレンスを渡すとjson
形式のレスポンスを返してくれる機能を提供してくれます。API
を作る際には非常に重宝します。
3つ目のsample::Web::Plugin::Session
はSession
管理機能を提供してくれます。
# setup view use sample::Web::View; { sub create_view { my $view = sample::Web::View->make_instance(__PACKAGE__); no warnings 'redefine'; *sample::Web::create_view = sub { $view }; # Class cache. $view } }
create_view
もdispatch
と同様にAmon2::Web
で抽象メソッドが定義されているので、実装しなければ行けません。
create_view
は、Text::Xslate
のオブジェクトを返しています。これはsample::Web::View
を見に行けば分かるかと思います。このときにsample::Web
のコンテキストも渡すようになっているので、config
にText::Xslate
という名前のハッシュを用意しておけば、Text::Xslate
をnew
するときに、その設定を読み込んでくれます。
また、コメントにも書いてある通り、内部でメソッド自身を上書きすることで設定をキャッシュしています。これで、毎回オブジェクトを生成しなくて済むようになっています。
# for your security __PACKAGE__->add_trigger( AFTER_DISPATCH => sub { my ( $c, $res ) = @_; # http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx $res->header( 'X-Content-Type-Options' => 'nosniff' ); # http://blog.mozilla.com/security/2010/09/08/x-frame-options/ $res->header( 'X-Frame-Options' => 'DENY' ); # Cache control. $res->header( 'Cache-Control' => 'private' ); }, );
最後にdispatch
後に、httpレスポンス
に対してゴニョゴニョするためのトリガを追加しています。
ここでは主にセキュリティを強固にする設定を行っているようです。
最初のX-Content-Type-Optitons
をnosniff
にしているのは、簡単に言えばXSS対策
です。詳しくは下記参考サイトを参照です。
次のX-Frame-Options
をDENY
にしているのは、クリックジャッキング対策
です。詳しくは下記参考サイトを参照です。
そして最後にCache-Control
をprivate
にしているのは、プロキシキャッシュ対策
です。詳しくは下記参考サイトを参照です。
具体的なhttpレスポンス
は以下のような物です。
Cache-Control private Connection close Content-Length 4987 Content-Type text/html; charset=UTF-8 Date Sun, 06 Jul 2014 21:23:46 GMT Server Plack::Handler::Starlet Set-Cookie hss_session=1404681826%3A1fcfdaff77e8a8eab9fd0003c2466f5%3ABQgDAAAAAQiIAAAAB2NvdW50ZXI%3D%3A35356662613234346636393736656635316561656130323662653937616266393466656332336231; path=/; HttpOnly XSRF-TOKEN=1fcfdaff77e8a8eab9fd0003c2466f5; path=/ X-Content-Type-Options nosniff X-Frame-Options DENY
ここまででAmon2の流れを掴む
は一旦の区切りとしたいと思います。