Переписанные URL с длиной параметра> 255 не работают

12

Я использую mod_rewrite, чтобы переписать URL-адреса, как это:

http://example.com/1,2,3,4/foo/

Делая это в .htaccess:

RewriteEngine On
RewriteRule ^([\d,]+)/foo/$ /foo.php?id=$1 [L,QSA]

Он работает нормально, за исключением случаев, когда «1,2,3,4» превращается в строку длиной более 255 символов, Apache возвращает «403 Forbidden».

Нет проблем с foo.php?id=1,2,3,4прямым доступом, даже с очень длинной строкой идентификатора, однако для меня это не вариант.

Есть ли какие-то настройки Apache или другие, которые я должен настроить?

ОБНОВЛЕНИЕ : я включил RewriteLog с RewriteLogLevel 9. С короткой строкой идентификатора, я получаю несколько строк в моем файле журнала. Но когда строка id больше 255 символов, ничего не регистрируется (кажется, что mod_rewrite даже не выполняется?).

Если вы нашли этот вопрос интересным / полезным, пожалуйста, подпишите его.

philfreo
источник
Может ли это быть проблемой регулярного выражения? Вы проверили правильность переписанного запроса для строк длиной более 255 символов? Если нет, возможно, вы могли бы опубликовать запросы до и после перезаписи.
Tomjedrz
3
Включите ведение журнала mod_rewrite, RewriteLogи RewriteLogLevelвы сможете увидеть, что сопоставляется и как оно действительно переписывается. Я бы предположил, что копируется только 255 символов $1, и это в конечном итоге является тем, idчто клиент не имеет права видеть, поэтому Apache возвращает 403. Я не смотрел на код, но может быть, что Apache манипулирует обратная ссылка в фиксированном 256-байтовом буфере (256-й зарезервирован для завершающего NULL).
Джеймс Снерингер
Смотрите обновление в вопросе - ничего не записывается для длинных параметров
philfreo

Ответы:

8

Как вы думаете, вы сталкиваетесь с ограничением файловой системы?

Может быть максимальная длина имени файла составляет 255 байт, и когда apache или правило mod_rewrite проверяет, существует ли файл, операционная система возвращает ошибку в apache.

Если вы добавите какое-то правило в свой файл .htaccess, будет слишком поздно, чтобы обойти эту проблему. Apache уже попытался определить имя файла и выдавшую ошибку файловой системы «(36) слишком длинное имя файла», возвращая ошибку 403.

Может быть, вы могли бы изменить шаблон URL внутри вашего приложения. до 255 символов от слэша до слэша.

РЕДАКТИРОВАТЬ: посмотрите здесь для подробного ответа на этот вопрос. Я позаимствовал мой оттуда.

microspino
источник
Да, в настоящее время это все, что мы можем сделать, но я надеюсь на обходной путь или настройку.
Philfreo
3
Microspino, похоже, что вы вырезали и вставили часть своего ответа из ответа @Jeff Clark здесь: serverfault.com/questions/120397/… . Вы должны дать гиперссылку на этот ответ, чтобы он получил некоторую известность.
Стефан Ласевский
@Stefan lasieswski: ты прав, я добавил ссылку.
микроспино
Итак, вы думаете, что, возможно, Apache пытается определить требуемый файл независимо - я имею в виду, что это может быть единственным способом объяснить, что слишком длинный URL даже не
перехватывается
Да, это моя идея, хотя я думаю, что в целом следует избегать таких длинных URL-адресов и имен файлов по ряду причин. Так что лучший совет, который я мог бы подумать, может быть что-то изменить в шаблоне URL, если имя файла не слишком длинное.
микроспино
2

Есть аналогичный вопрос об этом пределе здесь :

Вы можете столкнуться с ограничением базовой файловой системы

Я не знаю, используете ли вы REQUEST_FILENAME где-то в вашей конфигурации .htaccess, поэтому не знаю, будет ли работать предоставленное решение.

GmonC
источник
Это имеет смысл, но нет, я не. Я отредактировал свой вопрос, чтобы полностью включить файл .htaccess. Другие идеи?
Philfreo
В соответствии с «Техническими подробностями Apache mod_rewrite» по адресу httpd.apache.org/docs/trunk/rewrite/tech.html «Хотя mod_rewrite перезаписывает URL-адреса на URL-адреса, URL-адреса на имена файлов и даже имена файлов на имена файлов, API в настоящее время предоставляет только URL-адреса для -filename hook. " Таким образом, даже если вы не обращаетесь к реальному файлу, возможно, перехват URL для имени файла превышает ограничение ресурсов ОС?
Стефан Ласевский
0

Определенно интересный вопрос. Вы запускаете mod_security и если так, пробовали без него? Возможно, ему просто не нравятся длинные или длинные пути с незашифрованными запятыми в них? ^^

Хотя это инстинктивно больше похоже на ограничение пути URL-адреса или, по крайней мере, отдельных его сегментов или интерпретацию его базовой файловой системой, как писал GmonC. Это также объясняет, почему обычный URL с длинной частью в строке запроса работает нормально.

Я думаю, что старый ASP.NET имел ограничение на путь запроса ~ 260 символов или что-то еще.

Оскар Дювеборн
источник
Смотрите обновление к вопросу. И нет, я не вижу файл mod_security в /usr/include/apache2/или /usr/lib/apache2/modules/(но я вижу там mod_rewrite), поэтому я предполагаю, что он не установлен.
Philfreo
0

Вы готовы сменить http сервер? Тогда рассмотрим nginx вместо apache.

И используйте http://wiki.nginx.org/NginxHttpRewriteModule

JavaRocky
источник
В самом деле? Там нет никакого способа сделать это в Apache?
Philfreo