Apache mod_rewrite дважды кодирует строку запроса при перенаправлении

13

Мы столкнулись со странной проблемой (возможно, ошибкой?) В поведении Apache mod_rewrite при прохождении через строки запроса.

Для воспроизведения мы настроили чистую установку Ubuntu (oneiric) со стандартной конфигурацией Apache. Мы включили mod_rewrite и в конфигурацию сайта по умолчанию добавили следующее:

RewriteEngine on
RewriteRule ^/(.*)$ /r/$1 [R]

Для тестирования мы используем curl:

curl -I 'http://[ubuntu-machine]/a/b%20c?a%20b'

Соответствующий вывод:

HTTP/1.1 302 Found
Server: Apache/2.2.20 (Ubuntu)
Location: http://[ubuntu-machine]/r/a/b%20c?a%2520b

Как видите, строка запроса экранирована двойным образом, что неверно. У кого-нибудь есть идеи, как мы могли бы это исправить? Мы попробовали пару вещей:

  • Добавление [NE]. Это дает нам правильную строку запроса, но путь не экранирован, что приводит к новым проблемам.
  • Добавление [NE, B]. Кажется, это работает, но приводит к тому, что /между aи bчастями пути экранируется.
  • Отключение строки запроса вручную.

    RewriteCond %{QUERY_STRING} .*
    RewriteMap unescape int:unescape  
    RewriteRule ^(.*)$          $1?${unescape:%{QUERY_STRING}}
    

    Однако это означает, что мы не можем различить, скажем, от &и экранированный &в строке запроса.

Обновить:

Этот отчет об ошибке описывает ту же проблему. Первый комментарий связан с коммитом, по-видимому, исправляющим проблему, но, как говорит Питер ниже, не похоже, что он на самом деле исправлен.

Эрик Хесселинк
источник

Ответы:

7

Кажется, это ошибка в Apache. Этот отчет об ошибке немного грязный, но точно описывает вашу проблему:

https://issues.apache.org/bugzilla/show_bug.cgi?id=34602

Похоже, они знают о проблеме. Хотя ошибка утверждает, что они исправлены, я проверил это с Apache 2.3.15, и проблема все еще, кажется, там. Также обратите внимание, что Apache 2.3 является бета-версией, поэтому она бесполезна для вас, даже если она и исправит ее, пока не выйдет Apache 2.4.

Pieter
источник
Кажется, что Apache 2.4.10 все еще делает это, хотя это должно было быть исправлено в 2.4.1 .
Арьян
1
Я все еще вижу проблему в 2.4.7
Франсуа