mod_rewriteの無限ループを止めるパッチを書いてみた

自分で書く.htaccessファイルであれば気を付けるだけで良いのですが、
人様に作っていただいたりした.htaccessファイルで無限ループが発生することもあります。

apacheにはLimitInternalRecursionという一見すると再起的に行われる内部処理に制限を掛けてくれそうなディレクティブがあります。

http://httpd.apache.org/docs/2.0/ja/mod/core.html#limitinternalrecursion

ただ残念ながらこれはmod_rewriteの処理で生じるループを制限するものではないようです。

という独り言はさておき、困った例がこちら。
諸事情でいろいろ削り落としていった結果この記述は無限ループを起こすようだ、と推測しました。

まず.htaccess

1
2
3
RewriteEngine on
RewriteBase /
RewriteRule "^(\S*) +(\S* .*)$" $1-$2 [N,NE]

困ったことになるURLはたったのこれだけ。

http://localhost/%20/%20/

あ、アクセスする前にhttpd.confには下記記述を追加しておくことをお勧めします。

1
2
RewriteLog logs/rewrite.log
RewriteLogLevel 9

では、アクセス。

1
curl -i http://localhost/%20/%20/

私の手元だと数十秒待っても応答が返ってきません。

その時のプロセス状態は、、、

1
2
3
4
5
6
7
8
9
10
11
root     32442  0.0  0.0  99688   716 ?        Ss   00:13   0:00 /usr/sbin/httpd
48 32444 0.0 0.0 100916 24 ? S 00:13 0:00 \_ /usr/sbin/httpd
48 32445 0.0 0.0 1632244 28 ? Sl 00:13 0:00 \_ /usr/sbin/httpd
48 32708 1.3 23.6 5493980 3845076 ? Sl 00:13 0:04 \_ /usr/sbin/httpd
48 543 0.0 0.0 1566708 104 ? Sl 00:13 0:00 \_ /usr/sbin/httpd
48 544 0.0 0.0 1566708 28 ? Sl 00:13 0:00 \_ /usr/sbin/httpd
48 545 0.0 0.0 1566708 28 ? Sl 00:13 0:00 \_ /usr/sbin/httpd
48 546 0.0 0.0 1566708 28 ? Sl 00:13 0:00 \_ /usr/sbin/httpd
48 2179 0.0 0.0 1501172 28 ? Sl 00:17 0:00 \_ /usr/sbin/httpd
48 2344 0.0 0.0 1501172 400 ? Sl 00:18 0:00 \_ /usr/sbin/httpd
48 2573 0.0 0.0 1501172 6144 ? Sl 00:19 0:00 \_ /usr/sbin/httpd

1プロセスだけ狂ったようにメモリを喰い続けます。
ここいらで該当プロセスをkillしないとやがてメモリを喰い潰し・・・oom-killerさんが殺しにきます。

怖いですね。

さて、このとき rewrite.log どうなっているのか?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/  -> /home/rhykw/public_html/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] strip per-dir prefix: /home/rhykw/public_html/ / -> /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] applying pattern '^(\\S*) +(\\S* .*)$' to uri ' / '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (2) [perdir /home/rhykw/public_html/] rewrite ' / ' -> '-/ '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add per-dir prefix: -/ -> /home/rhykw/public_html/-/
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/-/ -> /home/rhykw/public_html/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] strip per-dir prefix: /home/rhykw/public_html/-/ / -> -/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] applying pattern '^(\\S*) +(\\S* .*)$' to uri '-/ / '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (2) [perdir /home/rhykw/public_html/] rewrite '-/ / ' -> '-/-/ '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add per-dir prefix: -/-/ -> /home/rhykw/public_html/-/-/
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/-/-/ -> /home/rhykw/public_html/-/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] strip per-dir prefix: /home/rhykw/public_html/-/-/ / -> -/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] applying pattern '^(\\S*) +(\\S* .*)$' to uri '-/-/ / '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (2) [perdir /home/rhykw/public_html/] rewrite '-/-/ / ' -> '-/-/-/ '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add per-dir prefix: -/-/-/ -> /home/rhykw/public_html/-/-/-/
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/-/-/-/ -> /home/rhykw/public_html/-/-/-/ /

こういう行が延々と続き、、、

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/  -> /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] strip per-dir prefix: /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ / -> -/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] applying pattern '^(\\S*) +(\\S* .*)$' to uri '-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ / '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (2) [perdir /home/rhykw/public_html/] rewrite '-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ / ' -> '-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add per-dir prefix: -/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ -> /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ -> /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] strip per-dir prefix: /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ / -> -/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ /
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] applying pattern '^(\\S*) +(\\S* .*)$' to uri '-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ / '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (2) [perdir /home/rhykw/public_html/] rewrite '-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ / ' -> '-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ '
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add per-dir prefix: -/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ -> /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
127.0.0.1 - - [15/Oct/2015:12:23:51 +0900] [localhost/sid#17bd580][rid#7f2e7c002970/initial] (3) [perdir /home/rhykw/public_html/] add path info postfix: /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ -> /home/rhykw/public_html/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ /

こうなる始末。
これは何かヒントになりそうです。

僕はとりあえずどんな.htaccessをもらっても事故に遭いたくないのでapacheのソースから無限ループの出処はどこだーと探します。
諸事情により今回は2.2系apacheの最新から1つだけ古いバージョン、httpd-2.2.29で確認。

1
2
[rhykw@builder httpd-2.2.29]$ grep -Fnr "add path info postfix: " .
./modules/mappers/mod_rewrite.c:3823: rewritelog((r, 3, ctx->perdir, "add path info postfix: %s -> %s%s",

ふむふむ。

modules/mappers/mod_rewrite.c:3823 は、 apply_rewrite_rule 関数。
apply_rewrite_rule は、modules/mappers/mod_rewrite.c:4082 で呼ばれている。

なんか近い場所に loop: goto loop; って書いてあります。
安易な発想で恐縮ですが、適当な回数ループが回ったら処理をブッチすれば良さそう。

雑ですがパッチはこんな感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ diff -u ./modules/mappers/mod_rewrite.c.orig ./modules/mappers/mod_rewrite.c
--- ./modules/mappers/mod_rewrite.c.orig 2015-10-15 13:28:26.143001755 +0900
+++ ./modules/mappers/mod_rewrite.c 2015-10-15 13:52:19.307001869 +0900
@@ -193,6 +193,8 @@
#define LEFT_CURLY '{'
#define RIGHT_CURLY '}'

+#define REWRITE_MAX_LOOPS 64
+
/*
* expansion result items on the stack to save some cycles
*
@@ -4050,6 +4052,7 @@
int rc;
int s;
rewrite_ctx *ctx;
+ int loops = 0;

ctx = apr_palloc(r->pool, sizeof(*ctx));
ctx->perdir = perdir;
@@ -4061,6 +4064,7 @@
entries = (rewriterule_entry *)rewriterules->elts;
changed = 0;
loop:
+ loops ++;
for (i = 0; i < rewriterules->nelts; i++) {
p = &entries[i];

@@ -4133,6 +4137,10 @@
* the rewriting ruleset again.
*/
if (p->flags & RULEFLAG_NEWROUND) {
+ if (loops > REWRITE_MAX_LOOPS) {
+ rewritelog((r, 2, perdir, "loops is over than REWRITE_MAX_LOOPS: %d/%d",loops,REWRITE_MAX_LOOPS));
+ break;
+ }
goto loop;
}

ひとまず困った.htaccessを置いてしまっても泣かずにすむようになりました。
やったー。

今回はとりあえず、雑なパッチを自己満足で書いてみましたが、本当はapacheの設定で回避できる、とか既に綺麗なパッチがあるよ、とかそういう情報があれば知りたいです。

ではおやすみなさい。

追記。
2.4系のapache(2.4.8以降)では、Nフラッグのオプションでループ回数に上限を設定できるようになっています。
https://httpd.apache.org/docs/current/rewrite/flags.html#flag_n

In 2.4.8 and later, this module returns an error after 32,000 iterations to protect against unintended looping. An alternative maximum number of iterations can be specified by adding to the N flag.

1
2
3
4
# Be willing to replace 1 character in each pass of the loop
RewriteRule "(.+)[><;]$" "$1" [N=64000]
# ... or, give up if after 10 loops
RewriteRule "(.+)[><;]$" "$1" [N=10]