Apache:重写规则导致segfault
我使用重写规则将URL中的所有空格(又名%20)替换为下划线:Apache:重写规则导致segfault,apache,mod-rewrite,Apache,Mod Rewrite,我使用重写规则将URL中的所有空格(又名%20)替换为下划线: RewriteRule (.*)[\ ](.*) $1_$2 [N] [N]标志再次开始重写过程,直到没有剩余空间为止(希望如此)。现在,当有文件在另一端等待时,一切正常,即请求: /This is an example.html 和文件: This_is_an_example.html 但是,当没有匹配的文件时,Apache将退出,并出现500个内部错误。错误日志说明一个segfault,重写日志显示重写引擎在试图重定向到时
RewriteRule (.*)[\ ](.*) $1_$2 [N]
[N]标志再次开始重写过程,直到没有剩余空间为止(希望如此)。现在,当有文件在另一端等待时,一切正常,即请求:
/This is an example.html
和文件:
This_is_an_example.html
但是,当没有匹配的文件时,Apache将退出,并出现500个内部错误。错误日志说明一个segfault,重写日志显示重写引擎在试图重定向到时发疯
/This is an_example.html/This is an_example.html/This is an_example.html/...
以此类推,直到segfault(请注意,最后一个空间已转换,但没有其他空间)
有人知道为什么重写规则在处理现有文件时失败得如此惨重吗
更新:只有在请求的URI中有一个额外的“/”时,才会出现segfault,如
/virtual-directory/This is an example.html
更新2:此语句中没有重写条件。在我看来,它应该在没有任何限制的情况下起作用。问题是,为什么不呢。Htaccess:
RewriteEngine On
RewriteBase /test/
RewriteRule (.*)[\ ](.*) $1_$2 [N]
更新3:有问题的.htaccess文件:
AddType application/xhtml+xml .xhtml
AddEncoding x-gzip .gz
ExpiresActive On
ExpiresByType application/xhtml+xml "access plus 1 year"
ErrorDocument 404 /test/index.php?error=404
RewriteEngine On
RewriteBase /test/
# replace spaces with underscores
RewriteCond %{REQUEST_FILENAME} .*[\ ].*
RewriteRule (.*)[\ ](.*) $1_$2 [N]
# the index.php
RewriteRule ^index.php - [L]
# language tag
RewriteRule ^([a-z]{2})$ index.php?lang=$1&url= [L,QSA]
RewriteRule ^$ en [R=301,L]
# add .xhtml
RewriteCond %{REQUEST_FILENAME}.xhtml -s [OR]
RewriteCond %{REQUEST_FILENAME}.xhtml.gz -s
RewriteRule ^(.+) $1.xhtml
# add .gz
RewriteCond %{HTTP:Accept-Encoding} .*gzip.*
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+) $1.gz
# send correct mime type
#RewriteCond %{REQUEST_FILENAME} -s
RewriteRule \.xhtml\.gz$ - [L,T=application/xhtml+xml]
rewriteLog语句太大,无法粘贴。一个请求就用13MB的数据填充文件。以下是摘要:
(IP) - - [date] [host] (3) [perdir /htdocs/test/] add path info postfix: /htdocs/test/de -> /htdocs/test/de/This is a test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] strip per-dir prefix: /htdocs/test/de/This is a test -> de/This is a test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] applying pattern '(.*)[\ ](.*)' to uri 'de/This is a test'
(IP) - - [date] [host] (2) [perdir /htdocs/test/] rewrite 'de/This is a test' -> 'de/This is a_test'
(IP) - - [date] [host] (3) [perdir /htdocs/test/] add per-dir prefix: de/This is a_test -> /htdocs/test/de/This is a_test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] add path info postfix: /htdocs/test/de/This is a_test -> /htdocs/test/de/This is a_test/This is a test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] strip per-dir prefix: /htdocs/test/de/This is a_test/This is a test -> de/This is a_test/This is a test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] applying pattern '(.*)[\ ](.*)' to uri 'de/This is a_test/This is a test'
(IP) - - [date] [host] (2) [perdir /htdocs/test/] rewrite 'de/This is a_test/This is a test' -> 'de/This is a_test/This is a_test'
(IP) - - [date] [host] (3) [perdir /htdocs/test/] add per-dir prefix: de/This is a_test/This is a_test -> /htdocs/test/de/This is a_test/This is a_test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] add path info postfix: /htdocs/test/de/This is a_test/This is a_test -> /htdocs/test/de/This is a_test/This is a_test/This is a test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] strip per-dir prefix: /htdocs/test/de/This is a_test/This is a_test/This is a test -> de/This is a_test/This is a_test/This is a test
(IP) - - [date] [host] (3) [perdir /htdocs/test/] applying pattern '(.*)[\ ](.*)' to uri 'de/This is a_test/This is a_test/This is a test'
(IP) - - [date] [host] (2) [perdir /htdocs/test/] rewrite 'de/This is a_test/This is a_test/This is a test' -> 'de/This is a_test/This is a_test/This is a_test'
(IP) - - [date] [host] (3) [perdir /htdocs/test/] add per-dir prefix: de/This is a_test/This is a_test/This is a_test -> /htdocs/test/de/This is a_test/This is a_test/This is a_test
... and so on ad infinitum
坏家伙是第6行:“添加路径信息后缀”。尝试绝对替换:
RewriteRule ^([^\ ]*)\ (.*) /$1_$2 [N]
更新 看到你的更新3(很有帮助,谢谢),我又想到了两个主意:
重写规则中
:
RewriteRule (.*)[\ ](.*) $1_$2 [N,DPI]
看看这能否解决问题。需要Apache2.2.12?尝试禁用它
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} .*[\ ].*
RewriteRule (.*)[\ ](.*) $1_$2 [N]
适合我(http://localhost/test/This 是一个示例.html
,重写VirtualHost
config中的规则,apache 2.2.14)。这是我的RewriteLog
(带有rewriteloglevel2
):
当D:/var/www/test/This\u是一个示例。html
不存在时,我得到一个404
-但没有segfault
你能发布你的
重写日志吗?你把重写规则放在哪里?进入.htaccess
?您是否有任何指令(AliasMatch
等)也适用于您的url?总体而言,如果提供可重复的测试用例,Apache开发人员将非常认真地对待httpd中的SIGSEGV。如果附加调试器并捕获回溯跟踪,则情况更糟。不,这不起作用,结果相同。我现在用一个条件来绕过它:RewriteCond%{REQUEST\u FILENAME}.*[\].
当我添加RewriteCond时,它也适用于我。但问题是,为什么我需要重写?如果你看一下我在问题中的重写规则,它应该一圈一圈地循环,直到没有剩余的空间,而不需要重写。我的问题是,它为什么不这样做。它在这里也可以工作,而不使用RewriteCond
(相同的RewriteLog
)。那么:您的重写日志
看起来像什么,您的重写规则在.htaccess
中,和/或是否有其他指令与所讨论的url匹配?重写规则在.htaccess文件中。请注意我在问题中的第一次更新,SEGFULT仅在规则之前存在类似文件夹的组件时发生。我将把上面的重写日志粘贴到问题中。哇,谢谢你找出了这个bug。看起来真的是我的问题。不幸的是,我还有2.2.11,但我会在赏金到期之前尝试设置2.2.12来验证这一点。现在我要把这个问题打印出来,框起来,贴在墙上。最后,有多少mod_重写问题以“这不是你的错,这是mod_重写中的错误”?;-)如何定义您的/virtual directory
(或者它是/test
)以及您的[ErrorDocument][1]在/virtual directory
中的作用是什么?[1] :我相应地更新了问题。ErrorDocument仅为404定义,它是指向与.htaccess文件位于同一目录中的index.php的重定向。“/virtual directory”在现实生活中是我用来区分请求语言的语言前缀(如“/en/”或“/de/”)。segfault可能会被LimitInternalRecursion(Apache 2.0.47+)或RewriteOptions MaxRedirects(2.0.45-46)禁用
init rewrite engine with requested uri /test/This is an example.html
rewrite '/test/This is an example.html' -> '/test/This is an_example.html'
rewrite '/test/This is an_example.html' -> '/test/This is_an_example.html'
rewrite '/test/This is_an_example.html' -> '/test/This_is_an_example.html'
local path result: /test/This_is_an_example.html
prefixed with document_root to D:/var/www/test/This_is_an_example.html
go-ahead with D:/var/www/test/This_is_an_example.html [OK]