mod_rewrite RewriteMap prg仅适用于第一个请求

时间:2011-12-05 21:31:54

标签: python apache mod-rewrite

我正在创建一个简单的IP黑名单。每个请求都根据IP列表进行评估,并在必要时抛出403。我决定在Apache端使用mod_rewrite,它的RewriteMap和简单的python脚本来处理它。

VirtualHost

<VirtualHost *:80>
    ...

    RewriteEngine On

    RewriteMap banip prg:/path/to/script.py
    RewriteCond ${banip:%{REMOTE_ADDR}} !=OK
    RewriteRule ^/.* - [F]
</VirtualHost>

script.py:

#!/usr/bin/python
import sys

sys.stdout.write('OK\n')
sys.stdout.flush()

现在奇怪的部分。重新启动Apache后,只有第一个请求返回200,并且每个后续请求都返回403。我希望所有人都返回200。当我重新启动Apache时,同样会再次发生。

重启Apache后重写日志:

# Very first request
127.0.0.1 - (2) init rewrite engine with requested uri /app_dev.php/
127.0.0.1 - (3) applying pattern '^/.*' to uri '/app_dev.php/'
127.0.0.1 - (5) map lookup OK: map=banip key=127.0.0.1 -> val=OK
127.0.0.1 - (4) RewriteCond: input='OK' pattern='!=OK' => not-matched
127.0.0.1 - (1) pass through /app_dev.php/

...

# Request after that
127.0.0.1 - (2) init rewrite engine with requested uri /static/css/grid.css
127.0.0.1 - (3) applying pattern '^/.*' to uri '/static/css/grid.css'
127.0.0.1 - (5) map lookup OK: map=banip key=127.0.0.1 -> val=
127.0.0.1 - (4) RewriteCond: input='' pattern='!=OK' => matched
127.0.0.1 - (2) forcing responsecode 403 for /static/css/grid.css

第二次刷新时,它不会写任何来重写日志,只是立即抛出403

当我尝试RewriteCond OK !=OKRewriteCond NOTOK !=OK时,它会完美无缺。知道为什么会这样吗?

我使用的是Apache 2.2.20和Python 2.7.2的Xubuntu 11.10。

1 个答案:

答案 0 :(得分:4)

我想你可能想仔细看看RewriteMap documentation。特别是:

  

该程序在Apache服务器启动时启动一次,并且   然后通过其stdin和stdout与重写引擎通信   文件句柄。对于每个映射函数查找,它将接收密钥   在stdin上查找为换行符的字符串。然后它必须给   将查找的值作为stdout上的换行符终止字符串或   如果失败则为四字符串“NULL”(即没有   给定密钥的相应值。)

因此,您的程序启动一次,从Apache接收密钥,生成响应,然后退出。正如您从文档中看到的那样,它将不会重新启动

你的程序应循环,读取一行输入,生成输出,然后等待更多输入。链接的文档包含一个非常简短的示例。