Странное взаимодействие между UserDir и RedirectMatch в Apache (перенаправление нескольких слешей)

Вопрос или проблема

У меня есть сервер Apache (версии 2.4.62-1~deb12u2 из Debian 12 «Bookworm», в настоящее время стабильная версия Debian), который обслуживает сайт http://www.example.tld/ с активированной UserDir, так что http://www.example.tld/~myname/ загружает материалы из /home/myname/public_html/ — пока все в порядке.

Теперь по какой-то причине, либо из-за опечатки, либо из-за неправильно обработанной относительной ссылки или еще чего-то, ссылки с несколькими слешами, вида http://www.example.tld/~myname//somestuff, начали существовать в сети. Google не любит это, потому что считает их дубликатами. Поэтому я хотел бы перенаправить любой такой URL на канонический http://www.example.tld/~myname/somestuff. Я использую RedirectMatch, потому что хотел бы избежать сложности mod_rewrite. Так что, естественно, я попробовал следующее:

RedirectMatch permanent ^/~myname//+(.*)$ /~myname/$1

но это не дает эффекта (независимо от того, помещаю я это до или после директивы, включающей UserDir): это как будто директивы и не было. Подумая, что может быть я редактирую неправильный файл или использую неправильный синтаксис regexp, я проверил:

RedirectMatch permanent ^/test//+(.*)$ /~myname/$1     # Работает отлично!

и это действительно перенаправляет http://www.example.tld/test//somestuff на http://www.example.tld/~myname/somestuff, устраняя двойной слеш (в то время как http://www.example.tld/test/somestuff вообще не совпадает и возвращает 404, как и ожидалось) — так что нет сомнений, что файл читается, и мои перенаправления в общем работают. Затем я подумал, может быть, нельзя перенаправлять на userdir вообще, но!

RedirectMatch permanent ^/~test/+(.*)$ /~myname/$1     # Работает отлично!

Этот вариант работает отлично и действительно удаляет несколько слешей, как и должно: http://www.example.tld/~test//somestuff переходит на http://www.example.tld/~myname/somestuff как и требовалось. И это не проблема с существованием ~myname, потому что:

RedirectMatch permanent ^/~test//+(.*)$ /~myname/$1    # Без эффекта!

казалось бы, полностью игнорируется (http://www.example.tld/~test//somestuff возвращает 404, а не перенаправляется, как это было в предыдущем тесте).

В этот момент я думаю, что схожу с ума. Обратите внимание, что я также пробовал перенаправление изнутри файла .htaccess в /home/myname/ без какого-либо успеха.

Теперь, прежде чем я назову это ошибкой Apache, что я хотел бы спросить:

  • Есть ли что-то явно неправильное в том, что я пытаюсь сделать? Зафиксировано ли такое поведение?

  • Может кто-то другой воспроизвести вышеуказанный странный эффект? Моя конфигурация Apache немного сложна (например, я также использую mod_jk — не в том же месте, но вы никогда не узнаете, какие странные взаимодействия могут быть), и я не могу легко создать минимальный рабочий пример. Также мне сложно попробовать разные версии Apache, так что если кто-то сможет подтвердить странность на новых версиях или сказать, что это исчезло, я буду признателен.

  • Может ли быть, что я пропустил другой способ обойти это и все равно получить http://www.example.tld/~myname/somestuff, чтобы перенаправить на http://www.example.tld/~myname/somestuff другим способом? Есть ли такая же проблема у mod_rewrite?

  • Стоит ли мне сообщить об этом как об ошибке? Какие другие тесты мне следует провести заранее?

Ответ или решение

К вопросу о странном взаимодействии между директивами UserDir и RedirectMatch в Apache, особенно в контексте обработки URL с двойными слэшами, следует подходить комплексно. Это поможет понять, почему ваши попытки перенаправления не работают так, как ожидается.

1. Проблемная ситуация

У вас есть веб-сервер Apache, на котором включен UserDir, что позволяет пользователям получать доступ к своим собственным директориям через URL, подобные http://www.example.tld/~myname/. Однако возникает необходимость в редиректе URL с двойными слэшами, такого как http://www.example.tld/~myname//somestuff, на канонический вид http://www.example.tld/~myname/somestuff.

2. Почему RedirectMatch может не работать?

Ваша проблема, когда RedirectMatch не срабатывает на запросы к UserDir, может быть связана с тем, как Apache обрабатывает различные директивы, назначенные для пользовательских директорий.

Пункты проверки:

  • Порядок директив: Убедитесь, что директива RedirectMatch размещена до включения UserDir, чтобы она могла обработать запросы до того, как Apache передаст их в модуль UserDir.
  • Использование / внутри регулярных выражений: Регулярное выражение, которое вы используете, должно соответствовать синтаксису Apache, но может оказаться излишне строгим в отношении структуры URL с двойными слэшами.

3. Альтернативные подходы

  • Использование mod_rewrite: Несмотря на ваши намерения избегать mod_rewrite, это может быть более гибкий и мощный инструмент для ваших нужд. Пример правила перенаправления с использованием mod_rewrite:
    RewriteEngine On
    RewriteCond %{THE_REQUEST} \s/~myname//+(.*) [NC]
    RewriteRule ^/~myname//+(.*)$ /~myname/$1 [R=301,L]

4. Испытания иdebugging

  • Логи Apache: Включите детальное логирование ошибок и запросов. Это может дать понимание того, что именно происходит, когда вы запрашиваете URL с двойными слэшами.
  • Тестирование других версий Apache: Возможно, поведение действительно связано с версии Apache. Попробуйте протестировать на более свежих версиях, если это возможно.

5. О возможности сообщения об ошибке

Если описанные вами эксперименты и тесты не решают проблему, возможно, стоит рассмотреть вопрос о сообщении об ошибке. Перед этим выполните следующие шаги:

  • Проверьте другие модули и конфигурации, которые могут конфликтовать.
  • Соберите дополнительные данные (журналы, конфигурации) для более полного понимания.

Заключение

Ваши наблюдения о несоответствии работы RedirectMatch и UserDir могут быть обоснованными. Перепроверьте порядок применения правил, рассмотрите возможность использования mod_rewrite, а также тщательно изучите логи для выявления дополнительных подсказок. Если после всех ваших усилий проблема останется, целесообразно будет сообщить об этом в соответствующих ресурсах поддержки Apache.

Оцените материал
Добавить комментарий

Капча загружается...