Показаны сообщения с ярлыком redirect. Показать все сообщения
Показаны сообщения с ярлыком redirect. Показать все сообщения

понедельник, 3 марта 2014 г.

htaccess redirect и кириллические пути

Допустим, надо сделать редирект с
http://сайт.рф/каталог/новый
в
http://сайт.рф/новый-каталог

Шаг 0, обязательный! Убеждаемся, что у нас кодировка у файла .htaccess UTF-8, без этого работать не будет!

записи будут такие
RewriteEngine On
RewriteCond %{REQUEST_URI} /каталог/новый [NC]
RewriteRule .* /новый-каталог [L,R=301]

Начальные слэши обязательны, без них будет путь на сервере.
А вот если надо на другой русский домен, сам домен надо за-punycode-ить, например на https://www.reg.ru/whois/punycode
для сайт2.рф будет 
RewriteRule .* http://xn--2-7sb1a4ah.xn--p1ai/новый-каталог [L,R=301]

Можно попробовать объединить строки в 1
RewriteRule /каталог/новый /новый-каталог [L,R=301]

И пара полезных линков "по теме"
20+ правил .htaccess, которые должен знать каждый разработчик
Директива RewriteCond

воскресенье, 3 марта 2013 г.

apache+nginx, появление внутреннего порта в адресе

Связка apache+nginx, появление внутреннего порта в адресе.
Проблема была замечена исключительно с debian: при обращении к странице вида site.ru/about и внутренним редиректом на site.ru/about/ (добавление слэша в конец) вдруг появляется внутренный порт, и адрес становится например site.ru:8080/about/
Есть предположения о причинах, но если проблема не в основных настройках системы (уже было описано тут: http://dragonflybsd.blogspot.ru/2011/08/apachenginx.html), то наиболее простой фикс: в nginx правим переменную $host
proxy_set_header Host $host:80;
при этом должен стоять mod_rpaf (без выставленного X-Forvarded-for), с правильным RPAFproxy_ips.

Также был замечен вариант с
proxy_set_header X-Server-Address $server_addr;
но мной не проверялось.

помним про proxy_redirect

понедельник, 2 июля 2012 г.

nginx: regex в server_name

Штатно есть весьма удобный функционал с регэкспами в server_name (далее блок), позволяющий весьма интересные трюки. (дока) Но проблема в том, что использование таких регэкспов таит много подводных камней.
Например, если мы определили .site.ru, регулярки на отдельный блок, даже если оно помещено выше главного блока, работать не будут. Вот такой прикол.
Причина в том, что у регулярок приоритет минимален и выбираются они, когда остался только блок по умолчанию (что неявно и описано в доке выше).

Для примера возьмём задачу редиректа с доменов вида www.sub.site.ru на sub.site.ru (где поддоменов sub может быть десятки и сотни). Правильнее всего вынести домены, с которых нужен редирект, в отдельный блок. Но вроде простая задача "в лоб" не решается, см. описание выше. Поэтому придуманы варианты (в порядке возрастания извращений, но не быстродействия):
0) передать заботу редиректов фронтенду. Тому же апачу.

1) в главный блок пихать
if ($host ~* ^www\.(w+\.site\.ru)$) {
set $newdomain $1;
rewrite ^(.*)$ http://$newdomain$1 permanent;
}
Но... IfIsEvil

2) улучшенный 1). Подключить встроенный перл и им обрабатывать $host

3) для каждого поддомена www.(sub).site.ru сделать отдельный блок и там return 301 sub.site.ru. Идеальный вариант, если поддоменов 1-10 и-или их количество расти не будет. Задача частично может решиться скриптами автогенерации блоков. Для нагруженных серверов пожалуй оптимальный вариант.

4) Пропихнуть в nginx патчи для поднятия приоритета регэкспам.

Но есть вариант проще, тоже вполне рабочий.
server {
    server_name ~^www\.(\w+\.site\.ru)$;
    return 301 http://$1$request_uri;
}

server {
    server_name site.ru www.site.ru ~^\w+\.site\.ru$;
    ....
}

!!! В таком описании указывать *.site.ru или .site.ru недопустимо! Отвалится первый блок.

Для облегчения работы можно в первом блоке сделать именованную переменную (иначе при первом же регэкспе во всяких там location потеряем значение), тогда будет так:
server_name ~^www\.(?<domain>.+\.site\.ru)$;
и работаем с $domain
или потом в коде установить переменную
set $newdomain $1;

четверг, 25 августа 2011 г.

apache+nginx: убираем порт из адреса при редиректе

Столкнулся на одном проекте с багой: после 301 редиректа адрес становился вида site.ru:8080/newaddr

Оказалось, в данном случае в конфиге был прописан
UseCanonicalName On

Закомментировал - заработало как надо.
Если что - есть вариант прописать в конфиге апача после VirtualHost
Port 80

"Появление порта 8080 в адреса вызвано работой модуля Apache mod_dir. Правильное решение проблемы - добавление Port 80 в конфигурацию Apache.
Установка же header в nginx не всегда решает проблему - некоторые сайты генерируют адрес с использованием директивы Port, которая, если её не выставить, остаётся 8080."
http://forum.nic.ru/archive/index.php/t-197.html

ЗЫ
Не забываем проверить и остальные части конфигов, они такие:
nginx:
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
#proxy_redirect http://${SITENAME}:${PORT}/ http://${SITENAME}/;
...

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

apache - mod_rpaf:
LoadModule rpaf_module libexec/apache22/mod_rpaf.so
RPAFproxy_ips 127.0.0.1 1.2.3.4
RPAFEnable On
RPAFheader X-Forwarded-For
#RPAFsethostname On

Не могу упомянуть занятную статью
http://greenmice.info/ru/node/116

понедельник, 28 марта 2011 г.

Редирект с http на https

Через .htaccess

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

отсюда
В комментах тоже много интересного.
ещё
и даже такое...

На PHP
function redirectToHTTPS() {
if($_SERVER['HTTPS']!=="on") {
$redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location:$redirect");
}
}

Nginx
Прописываем в нужный server код:
location / {
rewrite ^/(.*) https://$host/$1 permanent;
}
Это не проверял. В теории должно работать. (вариант: https://$host$1 permanent).
!!! Для новых версий предпочтительно использовать новую конструкцию:
return 301 https://freebsd.ru$request_uri;

Вообще, для nginx правильнее определить отдельный конфиг для таких редиректов (опция server_name максимально соответствует нужному домену, прописан listen под нужный порт, и весь конфиг - сам server_name и return 301, этот вариант самый быстрый)

perl
$q = new CGI;
print $q->redirect(“http://www.new-url.com/”);

Линки
http://nginx.org/en/docs/http/converting_rewrite_rules.html
http://wiki.nginx.org/IfIsEvil
http://devaka.ru/articles/redirect-301