Apache2 + RewriteMap + Python - 当返回'NULL'时,apache挂起

时间:2009-10-16 22:47:33

标签: python apache2 rewrite apache

[已解决:见下面的解决方案。]

我在编写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)以将缓冲区长度设置为零也无济于事。

非常感谢任何帮助。提前谢谢。

/etc/apache2/httpd.conf

[...]
RewriteLock /tmp/apache_rewrite.lock

的/ etc / apache2的/位点可用/默认

<VirtualHost *:80>
  [...]
  RewriteEngine on
  RewriteLogLevel 1
  RewriteLog /var/www/logs/rewrite.log
  RewriteMap remap prg:/var/www/remap.py
  [...]
</VirtualHost>

/var/www/webroot/.htaccess

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*_.*) /${remap:$1} [R=301]

/var/www/remap.py

#!/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()

2 个答案:

答案 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块中以防止脚本死亡(在我的情况下,由于文件/数据库失败)读取)和后续查询被忽略。

/var/www/webroot/.htaccess

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]

/var/www/remap.py

#!/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有更多经验,您会收到我^。谢谢。

我希望这篇文章可以帮助将来处理类似问题的人。

干杯, 安德鲁