[已解决:见下面的解决方案。]
我在编写RewriteMap
程序时遇到问题(使用Python)。我有一个RewriteMap
指令指向Python脚本,该脚本确定是否需要将请求的URL重定向到其他位置。
当脚本输出以换行符终止的字符串时,Apache会相应地重定向。但是,当脚本输出NULL
(没有换行符)时,Apache挂起并且后续的HTTP请求被有效忽略。
错误日志显示没有错误。重写日志仅在成功时显示pass through
后跟redirect
,在脚本返回pass through
时仅显示NULL
。后续请求也只显示pass through
。
此外,将stdout
替换为os.fdopen(sys.stdout.fileno(), 'w', 0)
以将缓冲区长度设置为零也无济于事。
非常感谢任何帮助。提前谢谢。
[...]
RewriteLock /tmp/apache_rewrite.lock
<VirtualHost *:80>
[...]
RewriteEngine on
RewriteLogLevel 1
RewriteLog /var/www/logs/rewrite.log
RewriteMap remap prg:/var/www/remap.py
[...]
</VirtualHost>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*_.*) /${remap:$1} [R=301]
#!/usr/bin/python
import sys
def getRedirect(str):
new_url = None
# if url needs to be redirected, put this value in new_url
# otherwise new_url remains None
return new_url
while True:
request = sys.stdin.readline().strip()
response = getRedirect(request)
if response:
sys.stdout.write(response + '\n')
else:
sys.stdout.write('NULL')
sys.stdout.flush()
答案 0 :(得分:6)
你必须返回一个换行符,而不是'NULL'。
Apache等待换行符知道要重写的URL何时结束。如果您的脚本没有发送换行符,Apache将永远等待。
所以只需将return ('NULL')
更改为return ('NULL\n')
,然后重定向到/。如果您不希望发生这种情况,请让程序在地图中没有匹配时返回您想要的URL。
如果你想在没有匹配时不重定向,我会:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond (${remap:$1}) !NULL
RewriteRule (.*_.*) /%1 [R=301]
在RewriteCond中使用匹配(当然,这也适用于 NULL )。但考虑到你的问题,这看起来是正确的解决方案。
答案 1 :(得分:3)
到目前为止,我提出的最佳解决方案是让RewriteMap脚本返回新的url或'__NULL__\n'
如果不需要重定向,并将此值存储在ENV变量中。然后,检查ENV变量!__NULL__
并重定向。请参阅下面的.htaccess
文件。
此外,如果有人计划做类似的事情,在Python脚本中我将相当数量的它包装在try / except块中以防止脚本死亡(在我的情况下,由于文件/数据库失败)读取)和后续查询被忽略。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ - [E=REMAP_RESULT:${remap:$1},NS]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{ENV:REMAP_RESULT} !^__NULL__$
RewriteRule ^(.+)$ /%{ENV:REMAP_RESULT} [R=301,L]
#!/usr/bin/python
import sys
def getRedirect(str):
try: # to prevent the script from dying on any errors
new_url = str
# if url needs to be redirected, put this value in new_url
# otherwise new_url remains None
if new_url == str: new_url = '__NULL__'
return new_url
except:
return '__NULL__'
while True:
request = sys.stdin.readline().strip()
response = getRedirect(request)
sys.stdout.write(response + '\n')
sys.stdout.flush()
Vinko,你肯定帮我解决了这个问题。如果我对stackoverflow
有更多经验,您会收到我^
。谢谢。
我希望这篇文章可以帮助将来处理类似问题的人。
干杯, 安德鲁