2010年 12月 31日

gerry++

gerry++

2010年 12月 30日

tscreen 使うときのメモ

ネットだとよく tscreen を screen の alias にする的な方法が書かれているけど、あれだと、screen -X を直接実行して screen にコマンド送ったりするツールがのきなみダメになるので、

#!/bin/sh
exec tscreen ${@+"$@"}
screens=$(which -a screen | grep -v $0 | head -n 1)
exec $screens ${@+"$@"}

とか書いてパスが通ったところに screen として保存するようにしました。

2010年 12月 28日

iTerm2 にしたり、tscreen にしたりしていたら 256color 環境ができあがっていたので、256color で開発するようにした。リモートのコンピュータで terminfo がなくて困ったけど ncurses っぽいパッケージを適当にいくつか入れたらなおった。

エディタの色も変えた

JavaScript の BigInt ライブラリ

探してみると、実装自体はあるんだけど、インターフェイスやらライセンスやらで好みのがなくて困った。弾さんが最近書いていたりしたけど、ライセンスが GPL なので、一部の用途にはちょっと使うのに躊躇するしという感じなので、Public Domain で公開されている www.leemon.com/crypto/BigInt.js のラッパを書いてしのぐことにした。

パフォーマンスは計ってないけど、今回の自分の用途だとそんなにパフォーマンスいらないのでまぁいいやという気分。負数に対応してないけど使わないので深追いしてない。

2010年 12月 27日

gerry++

2010年 12月 21日

Apache2 + mod_perl2 の仕様と正しく mod_perl2 を使うための方法

Plack::Handler::Apache2 をちょっと使ってみているのですが、本格的に使おうとすると挙動がおかしいところがあって最近手を入れています (Plack にクソパッチを送ったりして申し分けない気分にはなりますが、背に腹は変えれないので、恥を忍んで送りまくってます……)。その間に気付いたこととかをいくつかメモ書きしておきます。

Apache2::RequestRec (以下 $r) の path_info は全く信用できない

$r->unparsed_uri から作りましょう。

この path_info とかいうやつは Apache がパースしたあとの値が入っているので、いろいろおかしいことになっていることがあります。例えば

とかがあります。この $r->path_info から変なことになってない状態に復元することは不可能なので、$r->unparsed_uri から作るしかありません。基本的には以下のように

URI->new($r->unparsed_uri)->path

で PATH_INFO 相当になります。$r->uri というのあって "The path portion of the URI" と書かれているので、これも上記と同じ動作をするはずですが、信用できないので自力で unparsed_uri をパースしたほうが懸命な気がしています (遅いだろうけど、正しく動かないと早いも遅いもない)。

とはいえ、これで PATH_INFO 相当になるのは <Location /> で PerlHandler をしかけている場合に限っています。例えば /foo とかに PerlHandler をしかけたら、SCRIPT_NAME 相当のものは /foo で PATH_INFO は残りの部分になってほしいわけですが、上記のままではそうなりません (unparsed_uri を使って自力でやってるので当然です)。

SCRIPT_NAME を期待通りとる確実な方法がない

$r->unparsed_uri と $r->location から頑張って作りましょう。

subprocess_env でとれる SCRIPT_NAME は PATH_INFO と同様、ファイルシステムの影響 (よくわからず再現できなかったけど他の何かの影響をうけていることもある気がする) をうけるので信用なりません。 (SCRIPT_NAME と PATH_INFO は御互い重複する部分がないという性質があるので、一方が変わったら一方も変わります ref. RFC3875)

CGI とかの場合ファイルシステムを実際見るのはたぶん正しいと思いますが、mod_perl のように実際にファイルがあるかとかは関係なく Location を使ってハンドリングする場合、Location の位置を SCRIPT_NAME とし、残りの部分を PATH_INFO を扱ってくれるのというのが一番混乱しない仕様でしょう (まぁだいたい / にしか PerlHandler 書かないと思いますけど……)。

Location ディレクティブの引数は $r->location でとれるので、これを SCRIPT_NAME として扱えばだいたいいいんですが、ややこしいことに LocationMatch ディレクティブというのもあって、こちらは正規表現が使え、これも $r->location で取得できます。すなわち $r->location は正規表現の場合があります。といっても Location と LocationMatch を区別する方法はないようなので、どっちを使っているかは推測する必要があります。(実際のところ、こんなことしないだろという気はするので、汎用的にしないなら決めうちでどうにかしてしまうべきでしょう……)

で、もろもろ解決するため、テストを追加しつつだいたい動くであろう以下のようなコードを書きました。

    my $path_info = URI->new($r->unparsed_uri)->path;
    my $location = $r->location;

    if ($path_info =~ s{^($location)/?}{/}) {
        $env->{SCRIPT_NAME} = $1 || '';
    }

location がただの文字列の場合に大変心苦しい感じがするので、もっと完璧な方法があったら教えてほしいです。

まとめ

文章に書きくだしてみるとそんなに大したことはやらなくていい気もするんですが、知らないと大変困る仕様がいくつかあってハマりまくりました。「なんとなく動いている」というのが一番怖いので、ホント勘弁して欲しいところです。まだなんかありそうで怖いです。

これらの BK を知らなくても安心して使いたいわけなので、P::H::Apache2 を完璧にしたいですね…… mod_perl に詳しい人に助言を頂きたいものです

2010年 12月 19日

gerry++

2010年 12月 17日

gerry++

2010年 12月 16日