Apache RewriteMap с URL-адресами, содержащими пробелы, не работает

На самом деле я использую директиву RewriteMap внутри своего виртуального хоста для перенаправления списка из 800 URL. Он работает нормально:

RewriteEngine On
RewriteMap redirects dbm=db:/data/apps/project/current/configuration/etc/httpd/conf/redirects.db
RewriteCond ${redirects:$1} !=""
RewriteRule ^(.*)$ ${redirects:$1} [redirect=permanent,last]

Я использую файл redirect.txt , содержащий отображение. Затем он преобразуется в файл базы данных:

httxt2dbm -f db -i /data/apps/project/current/configuration/etc/httpd/conf/redirects.txt -o /data/apps/project/current/configuration/etc/httpd/conf/redirects.db

Например, для этого типа URL-адреса все в порядке:

/associations/old_index.php /

Но когда URL-адрес содержит пробелы, он не работает: (я полагаю, что то же самое будет и с другими специальными символов)

/Universités%20direct   /

Как поступить в этом случае?

3
задан 29 September 2016 в 16:42
3 ответа

Обходным путем может быть внутреннее переписывание URL, содержащих пробел в дефис (замените пробел дефисом) и включение дефисованного URL в карту переписывания вместо него.

Если у вас есть только некоторые URL, которые содержат один пробел внутри URL, то вы можете использовать что-то вроде следующей директивы перед существующими директивами:

RewriteRule ^(.+)\s(.+)$ $1-$2

А затем использовать следующее в карте перезаписи:

/Universités-direct /

UPDATE: Если у вас есть URL, которые содержат два пробела (например, /пробуждение силой), а некоторые с одним пробелом, то вы можете добавить дополнительное правило:

RewriteRule ^(.+)\s(.+)\s(.+)$ $1-$2
RewriteRule ^(.+)\s(.+)$ $1-$2

Эти правила предполагают, что у вас нет URL, которые заканчиваются пробелом. И ни один URL не имеет более одного смежного пробела.

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

RewriteRule ^(.+)\s(.+)\s(.+)\s(.+)$ $1-$2

Я бы предпочел сделать это с помощью нескольких (простых) правил, а не с помощью общего "преобразования всего в одно правило", если только вам это специально не нужно. Общее правило будет выполняться рекурсивно, сокращая несколько пробелов до одного символа. Вам также, скорее всего, понадобятся дополнительные флаги (например, DPI), чтобы предотвратить известную ошибку перезаписи в Apache.

.
1
ответ дан 3 December 2019 в 05:11

Это можно решить, извлекая кодированный URI из переменной %{THE_REQUEST} и используя его для поиска. Конечно же, вам нужно поместить кодированные URI в карту. Что-то вроде следующего:

RewriteEngine On
RewriteMap redirects dbm=db:/data/apps/project/current/configuration/etc/httpd/conf/redirects.db
RewriteCond %{THE_REQUEST} "\w+ ([^ ]+)"
RewriteRule ^ - [E=MYVAR:%1]

RewriteCond ${redirects:%{ENV:MYVAR}} !=""
RewriteRule ^ ${redirects:%{ENV:MYVAR}} [redirect=permanent,last] [B]

Я тестировал его только с текстовой картой, а не с картой, основанной на БД. Скорее всего, это нужно будет модифицировать, если вам придется иметь дело с URL, содержащими строки запроса.

.
3
ответ дан 3 December 2019 в 05:11

Вы можете использовать вторую карту перезаписи, внутренняя функция escape превращает пробелы в% 20:

RewriteMap ec int:escape

RewriteMap redirects dbm=db:/data/apps/project/current/configuration/etc/httpd/conf/redirects.db

RewriteCond ${redirects:${ec:$1}} !=""

RewriteRule ^(.*)$ ${redirects:${ec:$1}} [redirect=permanent,last]

Затем в вашей собственной базе данных перезаписи карты вы можете иметь:

/Universités-direct%20/

Это должно затем сопоставьте.

3
ответ дан 3 December 2019 в 05:11

Теги

Похожие вопросы