2009-11-05 5 views
1

Я использую RewriteRule, чтобы заменить все пробела (AKA% 20) в моей URL, подчеркивание:Apache: RewriteRule приводит к сегментации

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 (заметьте, что последний пространство было преобразовано, но ни один еще).

Есть ли у кого-нибудь идея, почему RewriteRule так неудачно не работает, работая над существующими файлами?

Update: выдаёт ошибку сегментации происходит только, если есть дополнительный "/" в запрашиваемом URI, как

/virtual-directory/This is an example.html 

Update 2: Там нет нет RewriteCond в этом заявлении. По-моему, это должно работать без. Вопрос в том, почему это не так. Htaccess:

RewriteEngine On 
RewriteBase /test/ 

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

Update 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 слишком велики, чтобы вставить. Один запрос заполняет файл 13 МБ данных. Вот дайджест:

(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: «Добавить информацию о пути postfix».

+0

Как и где определить ваш '/ virtual-directory' (или это'/test')? –

+0

и каков ваш [ErrorDocument] [1], действующий в '/ virtual-directory'? [1]: http://httpd.apache.org/docs/2.0/mod/core.html#errordocument –

+0

Я обновил вопрос соответствующим образом. ErrorDocument определен только для 404s, это перенаправление на index.php в том же каталоге, что и файл .htaccess. «/ Virtual-directory» в действительности использует префикс языка (например, «/ en /» или «/ de /»), который я использую для различения запрошенного языка. – Boldewyn

ответ

2

UPDATE

глядя на ваш обновления 3 (полезно, спасибо), еще 2 идеи приходят мне на ум:

  1. есть проблема с apache: mod_rewrite adds path info postfix after a substitution occured, которая похожа на вашу. это было fixed in 2.2.12 с введением discardpathinfo|DPI RewriteRule flag. попробуйте добавить этот флаг вашей RewriteRule:

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

    и посмотреть, если это решит проблему. требуется apache 2.2.12.

  2. у вас есть mod_dir включительно DirectorySlashOn? попробуйте отключить его.

UPDATE END

ваша установка:

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

работает для меня (http://localhost/test/This is an example.html, переписать правила в VirtualHost конфигурации, Apache 2.2.14). вот мой RewriteLogRewriteLogLevel 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] 

когда D:/var/www/test/This_is_an_example.html не существует, я получаю 404 - но не Segfault.

не могли бы вы разместить свой RewriteLog? где вы ставите свои правила перезаписи? в .htaccess? есть ли у вас какие-либо директивы (AliasMatch и т. д.), которые также работают на вашем URL-адресе?

+0

Он тоже работает для меня, когда я добавляю RewriteCond. Однако возникает вопрос, зачем вообще нужен RewriteCond? Если вы посмотрите на мой RewriteRule в вопросе, он должен округлить круг и до тех пор, пока не останется свободного места, и что без необходимости RewriteCond. Мой вопрос: почему он этого не делает. – Boldewyn

+0

он также работает здесь без 'RewriteCond' (тот же' RewriteLog'). так что: как выглядит ваш 'RewriteLog', являются ли ваши правила перезаписи в' .htaccess' и/или существуют ли другие директивы, соответствующие соответствующему URL? –

+0

Правила перезаписи находятся в файле .htaccess. Обратите внимание на мое первое обновление в вопросе, segfault возникает только, если перед правилом есть компонент, подобный папке. Я вложу немного журнала перезаписи выше в вопрос. – Boldewyn

0

Попробуйте абсолютную замену:

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

Нет, это не работает, тот же результат. Теперь я обхожу его с условием: «RewriteCond% {REQUEST_FILENAME}. * [\]. *' – Boldewyn

+0

@Boldewyn: Он работает для меня таким образом. – Gumbo

0

По большому счету, разработчики Apache серьезно воспримут SIGSEGV в httpd, если будут представлены повторяющиеся тестовые примеры. Тем более, если вы присоедините отладчик и захватите обратную трассировку.

+0

segfault, вероятно, может быть отключен с помощью LimitInternalRecursion (Apache 2.0.47+) или RewriteOptions MaxRedirects (2.0.45-46) –

Смежные вопросы