开发者

Apache: RewriteRule leads to segfault

I use a RewriteRule to replace all spaces (aka %20) in my URLs by underscores:

RewriteRule (.*)[\ ](.*) $1_$2 [N]

The [N] flag starts the rewrite process again, until no space is left (hopefully). Now, all is well, when there is a file waiting at the other side, i.e. request:

/This is an example.html

and file:

This_is_an_example.html

But when there is no matching file, Apache exits with a 500 Internal Error. The error log states a segfault, and the rewrite log shows, that the rewrite engine goes mad trying to redirect to

/This is an_example.html/This is an_example.html/This is an_example.html/...

and so on until the segfault (note, that the last space was converted, but none else).

Has anyone an idea, why the RewriteRule fails so miserably, while working for existing files?

Update: The segfault only occurs, if there is an additional "/" in the requested URI, like

/virtual-directory/This is an example.html

Update 2: There is no RewriteCond in this statement. In my opinion it should work without. The question is, why doesn't it. Htaccess:

RewriteEngine On
RewriteBase /test/

RewriteRule (.*)[\ ](.*) $1_$2 [N]

Update 3: The .htaccess file in question:

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]
RewriteCo开发者_StackOverflownd %{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]

The rewriteLog statements are too large to paste. A single request fills the file with 13MB of data. Here is the digest:

(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

The bad guy is line 6: "add path info postfix".


UPDATE

looking at your update 3 (helpful, thanks), 2 more ideas come to my mind:

  1. there is an apache issue: mod_rewrite adds path info postfix after a substitution occured, that looks similar to yours. this was fixed in 2.2.12 with the introduction of the discardpathinfo|DPI RewriteRule flag. try adding this flag to your RewriteRule:

    RewriteRule (.*)[\ ](.*) $1_$2 [N,DPI]
    

    and see if that solves the issue. needs apache 2.2.12.

  2. do you happen to have mod_dir enabled an DirectorySlashOn? try disabling it.

UPDATE END

your setup:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} .*[\ ].*
RewriteRule (.*)[\ ](.*) $1_$2 [N]

works for me (http://localhost/test/This is an example.html, rewrite rules in VirtualHost config, apache 2.2.14). here is my RewriteLog (with RewriteLogLevel 2):

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]

when D:/var/www/test/This_is_an_example.html does not exist, i get a 404 - but no segfault.

could you post your RewriteLog? where do you put your rewrite rules? into an .htaccess? do you have any directives (AliasMatch etc.) that also work on your url?


Try an absolute replacement:

RewriteRule ^([^\ ]*)\ (.*) /$1_$2 [N]


By and large, the Apache developers will take a SIGSEGV in httpd quite seriously if presented with a repeatable test case. Even more so if you attach a debugger and capture a backtrace.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜