Fork me on GitHub

2012/01/27


このエントリーをはてなブックマークに追加
こんにちわ。昨今、ウェブ開発の進化はすざましいですね。PythonやPerlやJava、色んな言語で書かれていると思います。
もちろん編集にはVimを使っているかと思います。
でも編集だけ?

違うよね!
Vim scriptはウェブアプリケーション記述言語なんだよ!

Plack::App::Vim
package Plack::App::Vim;
use strict;
use warnings;
use parent qw/Plack::Component/;
use Plack::Request;
use Encode;
use JSON::PP;

sub prepare_app {
    my $self = shift;
    $self->{vim} ||= 'vim';
    if (!$self->{server}) {
        open(my $f"vim --serverlist|");
        my $server = <$f>;
        close($f);
        chomp $server;
        $self->{server} = $server;
    }
    if (!$self->{encoding}) {
        open(my $fsprintf("%s --servername %s --remote-expr \"&encoding\"|",
            $self->{vim}$self->{server}));
        my $encoding = <$f>;
        close($f);
        chomp $encoding;
        $self->{encoding} = $encoding;
    }
    $self;
}

sub call {
    my ($self$env) = @_;
    my $req = Plack::Request->new($env);
    my $json = JSON::PP->new->ascii
        ->allow_singlequote->allow_blessed->allow_nonref;
    my $str = $json->encode({
        uri => $env->{PATH_INFO}||'',
        method => $req->method,
        headers => [split/\n/$req->headers->as_string)],
        content => $req->content,
    });
    $str =~ s!"!\\x22!g;

    my $command;
    if ($^O eq 'MSWin32') {
        $command = sprintf(
            '%s --servername %s --remote-expr "vimplack#handle("""%s""")"',
            $self->{vim}$self->{server},
            encode($self->{encoding} || 'utf8'$str));
    } else {
        $command = sprintf(
            "%s --servername %s --remote-expr 'vimplack#handle(\"%s\")'",
            $self->{vim}$self->{server},
            encode($self->{encoding} || 'utf8'$str));
    }
    open(my $f"$command|");
    binmode $f':utf8';
    my $out = <$f>;
    close $f;
    my $res = $json->decode($out);
    $res->[2][0] = encode_utf8 $res->[2][0] if $res;
    $res || [500, ['Content-Type' => 'text/plain'], ['Internal Server Error']];
}

1;

__END__

=head1 NAME

Plack::App::Vim - The Vim App in Plack

=head1 SYNOPSIS

  use Plack::Builder;
  use Plack::App::Vim;

  builder {
    mount "/" => Plack::App::Vim->new(server => 'VIM');
  };

=head1 DESCRIPTION

Plack::App::Vim allows you to write web application with Vim script.

=head1 AUTHOR

Yasuhiro Matsumoto

=head1 SEE ALSO

L<Plack>

=cut
Plack::Appのアプリケーションハンドラを書いたよ。これを起動するpsgiファイルを用意するよ!

app.psgi
#!perl
use lib qw/lib/;
use Plack::Builder;
use Plack::App::Vim;

builder {
    mount "/" => Plack::App::Vim->new(server => 'VIM');
};
引数のserverにはclientserver機能が使えるVimを立ち上げ、そのサーバIDを指定しておく必要があるよ!
そしてVim側にハンドラを書くよ!

autoload/vimplack.vim
scriptencoding utf-8

function! vimplack#handle(req)
  let req = json#decode(a:req)
  let res = [200, {}, ["hello world"]]
  return json#encode(res)
endfunction
PSGIプロトコルそのままですね!便利!

起動しよう!
# plackup app.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
ブラウザでhttp://localhost:5000を開こう!
Vim on PSGI
やたー!
あとはアプリケーション書き放題ですね!
試しに掲示板書いてみるよ!

autoload/vimplack.vim
scriptencoding utf-8

let s:comments = get(s:, 'comments', [])

function! vimplack#handle(req)
  let req = json#decode(a:req)
  if req.uri == "/"
    let res = [200{"Content-Type""text/html; charset=utf-8"}, [""
\."<html>"
\."<link rel='shortcut icon' href='/static/favicon.ico'>"
\."<title>comment board</title>"
\."<body>"
\."<form action='/regist' method='post'>"
\."コメント:<input type='text' name='comment' value='' /><br />"
\."<input type='submit' value='登録' />"
\."</form>"
\.join(map(copy(s:comments)'html#encodeEntityReference(v:val)')'<br />')
\."</body>"
\."</html>"
\]]
  elseif req.uri == '/regist' && req.method == 'POST'
    let params = {}
    for _ in map(split(req.content, '&')'split(v:val,"=")')
      let params[_[0]] = iconv(http#decodeURI(_[1])'utf-8', &encoding)
    endfor
    if has_key(params, 'comment')
      call add(s:comments, params['comment'])
    endif
    let res = [302{"Location""/"}, [""]]
  else
    let res = [404{}, ["404 Dan Not Found"]]
  endif
  return json#encode(res)
endfunction
アプリケーションの更新はVimを再起動するかautoload/vimplack.vimを開いている常態なら
:so %
で行けるよ!
Vim on PSGI

知らんかったー
Vim scriptはウェブアプリケーション記述言語やったんやー
mattn/p5-Plack-App-Vim - GitHub

Vim Application Handler for PSGI

https://github.com/mattn/p5-Plack-App-Vim
Posted at 21:00 in ソフトウェア::vim
Tagged as: plack, vim
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip

2011/04/02


このエントリーをはてなブックマークに追加
昔どこぞのパクリブログ対策でやってた奴をPlack::Middlewareで。

mattn/Plack-Middleware-ReplaceToUnko - GitHub

plack middleware for replacing images to shit image that referer from external sites.

https://github.com/mattn/Plack-Middleware-ReplaceToUnko

指定の仕方も簡単で、ウンコ画像のURLを指定するだけ。
use strict;
use warnings;
use utf8;
use lib 'lib';
use Plack::Builder;
use Path::Class qw(file);

my $app = sub { [ 302, [ "Location" => "/index.html" ], [] ] };

builder {
    enable 'ReplaceToUnko'unko_image_url => "/unko.png";
    enable 'Static',
      path     => qr{^/.},
      root     => file(__FILE__)->absolute->dir,
      encoding => 'utf-8';
    $app;
};

こうしておけば
replace-to-unko1
普段はこう見えるけど、リファラが違うドメインで直リンされてる場合は
replace-to-unko2
こうなっちゃう><

いかんせんモジュール名がPlack::Middleware::ReplaceToUnkoなので使いたい人はモジュール名変えて使って下さい。

えっ?自分で変えろ?



やだ!


Posted at 01:09 in ソフトウェア::lang::perl
Tagged as: plack
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip

2009/10/01


このエントリーをはてなブックマークに追加
最近熱いPSGI/Packですが、サーバのStandaloneではかなり高速なパフォーマンスが出ているらしく、試してみようと思った所、Windowsでは動かない箇所があったのでいろいろやった作業履歴。
まず、Standaloneサーバが速いと言われる理由としてsendfile(2)を使っているのですが、Windowsにはsendfile(2)がありません。しかしソケット前提であるならばTransmitFileというAPIがあります。
sendfile(2)と同じようにZeroCopyでファイルから指定ディスクリプタに流し込むAPIです。
Plackが使っているSys::Sendfileに対してこのAPIを使う様にWindowsポーティングしました。
Sys::Sendfileのauthorにもpull requestを送りました。次にPlackにてWindowsで使えないAPIを叩いている部分に対するpatchを書きました。
これで一応、高速化対応は完了。
Plackに付属の画像を返すpsgiアプリケーションを起動してベンチマークを取ってみました。
# plackup -s Standalone -a eg/dot-psgi/image.psgi
ベンチマーク結果は以下の通り。まず高速化対応前。
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done


Server Software:        Plack-Server-Standalone/0.01
Server Hostname:        localhost
Server Port:            8080

Document Path:          /
Document Length:        2397678 bytes

Concurrency Level:      1
Time taken for tests:   1.219 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Total transferred:      23978730 bytes
HTML transferred:       23976780 bytes
Requests per second:    8.21 [#/sec] (mean)
Time per request:       121.876 [ms] (mean)
Time per request:       121.876 [ms] (mean, across all concurrent requests)
Transfer rate:          19213.49 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   4.9      0      16
Processing:   109  119  10.9    125     141
Waiting:        0    5   7.5      0      16
Total:        109  120  12.9    125     141

Percentage of the requests served within a certain time (ms)
  50%    125
  66%    125
  75%    125
  80%    141
  90%    141
  95%    141
  98%    141
  99%    141
 100%    141 (longest request)
そして対応後
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done


Server Software:        Plack-Server-Standalone/0.01
Server Hostname:        localhost
Server Port:            8080

Document Path:          /
Document Length:        2397701 bytes

Concurrency Level:      1
Time taken for tests:   0.578 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Total transferred:      23978960 bytes
HTML transferred:       23977010 bytes
Requests per second:    17.30 [#/sec] (mean)
Time per request:       57.813 [ms] (mean)
Time per request:       57.813 [ms] (mean, across all concurrent requests)
Transfer rate:          40504.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   6.6      0      16
Processing:    31   55  22.4     47      94
Waiting:        0    3   6.6      0      16
Total:         31   58  24.5     47     109

Percentage of the requests served within a certain time (ms)
  50%     47
  66%     47
  75%     63
  80%     94
  90%    109
  95%    109
  98%    109
  99%    109
 100%    109 (longest request)
だいたいRequests perl secondで2倍くらい速くなってます。すばらしい。

miyagawa++ kazuho++ Plack++
Posted at 22:42 in ソフトウェア::lang::perl
Tagged as: perl, plack, psgi, sendfile, windows
Bookmarks: add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip