[plack] response body を変更する Middleware の試作
Web アプリケーションが見事にコードリファレンス一つに抽象化されている PSGI では、あるアプリケーションに前処理・後処理を追加して、動作をちょっと変更する Middleware という仕組みがあって、それで色々と面白いことができそうなので、試しにくだらないものを作ってみました。
今回作ったのは、実用性皆無ですが、後処理を追加することで、出力をすべて大文字にしてくれる Middleware です。
必要なモジュール: Plack, Twiggy
使い方: plackup -s Twiggy app.psgi で動かして、http://localhost:5000/stream などを見てみる。
hiratara さんの記事 PSGI 1.03のMiddlewareを書いてみる を参考にしながら作ってみたのですが、Plack::Component::response_cb の定義をよく見ると、body_filter として返すコードリファレンスの内容は、return undef をすると $res->[2] に無駄な undef が入るので、return () の方を使うこのコードの方がよいと思います。
今回作ったのは、実用性皆無ですが、後処理を追加することで、出力をすべて大文字にしてくれる Middleware です。
必要なモジュール: Plack, Twiggy
使い方: plackup -s Twiggy app.psgi で動かして、http://localhost:5000/stream などを見てみる。
package Plack::Middleware::UpperCase;
use strict;
use warnings;
use parent qw(Plack::Middleware);
sub call {
my ($self, $env) = @_;
my $res = $self->app->($env);
return $self->response_cb($res, sub {
my $res = shift;
return sub {
my $body_chunk = shift;
if (defined $body_chunk) {
return uc $body_chunk;
} else {
return;
}
};
});
}
package main;
use strict;
use warnings;
use AnyEvent;
use Plack::Builder;
use Plack::Response;
builder {
# enable 'Plack::Middleware::UpperCase';
enable sub { Plack::Middleware::UpperCase->wrap(@_) };
mount '/static' => sub {
my $env = shift;
my $res = Plack::Response->new(200);
$res->content_type('text/plain');
$res->body("static response");
return $res->finalize;
};
mount '/handle' => sub {
my $env = shift;
my $res = Plack::Response->new(200);
$res->content_type('text/plain');
open my $io, '<', \'body handle';
$res->body($io);
return $res->finalize;
};
mount '/stream' => sub {
my $env = shift;
return sub {
my ($write) = @_;
my $writer = $write->([
200,
[
'Content-Type' => 'text/plain',
],
]);
my $count = 0;
my $t; $t = AE::timer 0, 0.5, sub {
$writer->write("date:@{[ scalar localtime ]}, count:@{[ $count++ ]}\n");
if ($count > 10) {
undef $t;
$writer->close;
}
};
};
};
};
hiratara さんの記事 PSGI 1.03のMiddlewareを書いてみる を参考にしながら作ってみたのですが、Plack::Component::response_cb の定義をよく見ると、body_filter として返すコードリファレンスの内容は、return undef をすると $res->[2] に無駄な undef が入るので、return () の方を使うこのコードの方がよいと思います。
コメント
コメントを投稿