У меня есть URL-адрес, содержащий следующее:
/somepath/morestuff/ohno%25foobar
По какой-то причине apache сообщает о 400 неверных запросах (это как-то связано с% 25). Я использую mod_rewrite, чтобы переписать путь, указывающий на мой экземпляр codeigniter, но он даже не достигает codeigniter, это просто ошибка apache по умолчанию.
Есть идеи?
Я подозреваю, что вы используете PATH_INFO
для обработки запросов CodeIgniter. Следовательно, ваш .htaccess
файл содержит набор правил, который выглядит примерно так:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php/$0 [L]
Когда mod_rewrite
проверяет ваши URL, они уже были декодированы в естественный формат символов, так что в этом случае %25
стало просто %
. Когда вы применяете это правило, обратная ссылка фактически содержит буквальный текст somepath/morestuff/ohno%foobar
, который по умолчанию не перекодирован. Apache не понимает, что делает этот %
в пути запроса к /index.php/somepath/morestuff/ohno%foobar
и задыхается, выдавая эту ошибку.
Если вы используете Apache 2.2, mod_rewrite
добавил для этой цели флаг B
, позволяющий автоматически избегать обратных ссылок, переписанных на ваш URL. Добавление его в список текущих флагов должно решить проблему в этом случае:
RewriteRule ^.*$ index.php/$0 [B,L]
Существует также escape
RewriteMap
который был доступен в качестве внутренней карты в предыдущих версиях Apache mod_rewrite
, но, к сожалению, эта карта должна быть включена на уровне конфигурации сервера или виртуального сервера, поэтому может быть недоступна, если вы запускаете свой сайт на виртуальном хостинге. Это делает то же самое, хотя и немного более целенаправленно.
В конфигурации вашего сервера/виртуального сервера:
RewriteMap escape int:escape
Затем, где бы вы ни определяли свои правила:
RewriteRule ^.*$ index.php/${escape:$0} [L]
Помните, что CodeIgniter не нужно использовать PATH_INFO
для получения информации о запросе, и использование REQUEST_URI
вполне приемлемо, если вы не используете mod_rewrite
для других преобразований (и вообще избежите этой головной боли). Я думаю, что по умолчанию CodeIgniter настроен на получение запроса от AUTO
(если я не перепутал фреймворки), так что просто не переписывать запрос на URL с информацией о пути будет достаточно, чтобы сделать это изменение.