今回は、phpのpdo_sqliteの話。
今朝方までmake出来なかったのは、まぁ、仕方ない。

konata.netのFreeBSDの移行が大方済んだので、ログのチェックなどしてみると、
臨時用2ch串の書き込みログがなんだか妙な感じ。

具体的には、在日がどうとかそういうおんなじ文章をマルチポストするようなのが出てくるのだけれど、
書き込みログの間隔が、1分弱と妙に短い。
確か、設定だと300秒にしてあったはずなのだけれど……
ちなみに、リモートホストは丸の内OCN。

取り急ぎ、リモートでメンテ中にして、原因の調査。
Apacheの過去ログを遡ると、書き込み待ち時間を経過していない場合のエラーになる割合が酷く少ない。
これはいくら何でも不自然なので、なにかしらバグがあると踏んだ。

普段、自分が使う時は特権IPなのでそっちのルートには流れないんだよなぁ……

で、一時的に特権を外して、VIPの!ninjaスレを2つ見つけて連続書き込み。
両方に書き込みできてしまった。
連投規制外れてれば、そりゃ水遁されるわけだわ。
あんまり言葉狩りはしたくないので、NGワードを緩めにしてたのも裏目に出た。

が、今ひとつ状況がつかめない。
sqliteのクエリログでも取れれば良いのだけれど、生憎みつけられなかったので、
sqlite3を直に叩いて、同じはずのクエリを投げてみる。

肝心のクエリはこんな感じ。

$query = “SELECT COUNT(ip) FROM allowlist WHERE posttime + ? < ? AND ip = ?;";
$stmt = $pdo->prepare( $query );
$stmt->execute( array( $wait, $now, $ip ) );

以前、投稿した時刻を記録しておいて、
「1つ前の投稿した時刻+待ち時間 < 現在時刻 かつ IPが一致したもの」
の件数を取り出すというもの。
sqlite3で、直にDBを弄ると正しい結果が得られるのだけれど、PODから実行すると、
必ず1件のレコードが該当するような動作をする。

が、原因が判らない。
案外、寝ぼけてるだけかもしれないけれど。

仕方が無いので、DBに計算させるのはやめることにした。
修正後のクエリはこう。

$query = “SELECT posttime FROM allowlist WHERE ip = ?;”;

IPから投稿時刻だけ取ってくる、後はphp側で同じ比較をすれば完了。

なんだかよくわからないけど、これで想定通りの動作をするようになったので、良しとする。
ただ、今まで連投規制なしで書いてた人からは不満が出るかもしれないなぁ……

前回のあらまし

1、Apacheの mod_ext_filter でPOSTデータにsidを追加する。
2、POSTデータにsidを追加するApacheモジュールを新規に組む。
の案が出ていて、1についてはどうやらApacheがサポートしていないということが判明した。

というわけで、2の実現に取り掛かる。
結論から言うとこっちもダメでした。
POSTデータにsidを付与するApacheモジュールは組めたのだけれど、Proxy経由で動作しない問題が発生。
どうやら、Proxyを介するときはContent-Lengthヘッダも書き換えねばならないらしい。
Content-Lengthヘッダを消してしまえばよいのかと思い、 RequestHeader unset を試してみるものの効果なし。
このあたりはフィルタの処理順序に由来するものだろう。
さらっと書いてるけど、不慣れなApacheモジュールを作るのに2日、さらにProxy経由で動かない原因特定に1日かかっている。
Content-LengthはHTTPのヘッダ部なので、書き換えはさらに面倒であることが予想された。

というわけで、第3の選択肢の登場。
3、test/bbs.cgiへの書き込みアクセスを、mod_rewriteで書き換えて、ローカルのphpで受け、phpでsidを付与した書き込み要求を行う。

具体的には、以下のディレクティブを書いた。

RewriteEngine on
RewriteRule ^/2ch/([0-9A-Za-z]+)/test/bbs.cgi /post.php?saba=$1 [L]

これで、post.phpは、GET変数に鯖名を、POST変数にユーザーの送信データを得ることが出来る。
後は、このPHPでsidを取ってきてPOST変数に付与してやれば良い。
SIDは別のphpスクリプトでcronをまわして定期更新させるようにしておく。
これで、原理的にはOKとなる。

実際は、SIDの渡し方ではまったり、Cookieの設定を送信する必要があったりして、さらに時間を食うことになるのだけれど、とにかく何とかリリースにこぎつけた。

あぁ、めんどくさかった……