Nginx → Трансформация и перевод на другие языки web-сайтов на лету при помощи Nginx
Как и в прошлый раз мы будем трансформировать сайт example.com в example.ru. Не буду рассказывать о настройке и установке Nginx (об этом много статей), а лучше расскажу о конкретных полезных настройках.
Мы помним, что картинки оригинального сайта находятся по адресу:
super-cdn.com/img
Однако запустив вышеописанную конфигурацию мы видим, что Nginx оставил все ссылки вида
=http://super-cdn.com/img/*
не проксифицированными. Понятно, что это из-за отличия домена. Так же понятно, что в такой ситуации никакой возможности подсунуть переведенные картинки у нас нет, потому как пользователь забирает их напрямую с CDN минуя нас. Значит требуется магия трансформации!
Открываем example-transform.conf
По умолчанию модуль трансформации не откомпилирован! Нужен параметр:
Компилируем, перзапускаем… Бинго!!! Фанфары!!!
Все работает, все летает, картинки можно подменять на ходу.
Мы радостно добавляем первое правило замены содержимого страницы и … узнаем шокирующую информацию о том, что модуль http_sub_module позволяет выполнить всего одну замену!
О Игорь Сысоев, почему ты скрыл этот чудовищный факт в страничке документации!
sysoev.ru/nginx/docs/http/ngx_http_sub_module.html
Ах если бы мы знали про такой финал в самом начале! Но… Стоп! Эмоции в сторону, потому что русские и китайцы — братья навек! Простой китайский паренек Weibin Yao уже решил нашу проблему и создал модуль substitutions4nginx, который доступен по адресу
code.google.com/p/substitutions4nginx/
Устанавливаем модуль по инструкции, открываем наш конфигурацию трансформации и смело пишем:
subs_filter 'http://super-cdn.com/img/’ 'http://example.ru/img/' g;
subs_filter '<title[^>]*>(.*?)' 'НЛО прилетело сюда и подчинило этот сайт своей воле. Аминь!' oir;
Вместо послесловия
4. В Apache Traffic Server и в Nginx я нашел одинаковый баг. При котором теги с линками типа a href содержащие перенос строки не прокисифцируются. Подозреваю что проблема тянется из библиотеки PCRE.
источник — habrahabr.ru/blogs/nginx/114845/
Глобальная конфигурация — nginx.conf
worker_processes 4; # Поставьте тут столько процессов, сколько у в системе ядер # cat /proc/cpuinfo | grep processor | wc - даст ответ http { resolver 127.0.0.1; # Это очень важная строчка. Без нее никак не удавалось запустить работу reverse proxy. Вместо 127.0.0.1 напишите адрес DNS сервера вашего провайдера. Беда в том, что эта настройка ставится глобально, а все примеры по настройке в мануалах и статьях приводятся для локейшинов. Ошибку отлавливаем по слову resolver в логах. Настройте DNS сразу и потратьте спасенное время на полезные дела! include options.conf; include mime.types; # Мы переводим сайт на английском языке, у которого, по-умолчанию, кодировка iso-8859-1. Писать будем по-русски и, чтобы не страдать перекодировками, выберем UTF-8. charset utf-8; override_charset on; source_charset iso-8859-1; charset_map iso-8859-1 utf-8 { } # Команда charset_map - волшебная, без нее ничего не заработает! Предложенный в документации вариант charset_map iso-8859-1 _ { } у меня не заработал. # Настраиваем проксирование всех запросов. Зачем? А чтоб было в хозяйстве! proxy_cache_path /usr/local/nginx/proxy_temp/ levels=1:2 keys_zone=cache-zone:10m inactive=10m max_size=1000M; # Настраиваем сохранение сайта proxy_store_access user:rw group:rw all:r; # Разница между proxy_caсhe и proxy_store в том что первое создает оптимизированный служебный кэш, а второе создает точную локальную копию удаленного сайта. Такая копия станет незаменимой вещью в процессе дальнейшего ручного перевода сайта. # Опускаем остальные конфигурационные команды и … include example.conf; }
Настройка виртуального сервера — example.conf
server { listen 80; server_name example.ru; access_log logs/example.ru.access.log main; error_log logs/example.ru.error.log; index index.html; root /usr/local/nginx/html/example.ru; # Ничего необычного за исключением: rewrite ^/(/broken_page.*) http://www.example.com/$1 permanent; # Это полезное правило позволяет “починить” линки, которые были сломаны проксификатором Nginx работающим в режиме reverse-proxy. Мы теряем возможность перевода сломанных страниц, так как отсылаем пользователя на оригинальный сайт, но зато освобождаемся от ошибки 404. Так лучше. В моих тестах Nginx ломал Pop-up окно с роликом на флеше. # Переходим к самому интересному! # Создаем локейшин /img/ Название локейшина должно совпадать с URI хранилища картинок оригинального сайта. Пояснения ниже. location ^~ /img/ { # Где же локальное хранилище? Ах вот где, прямо у нас под боком! root /usr/local/nginx/html/example.ru; # Пишем волшебство! try_files $uri $uri/ @static; } # Смысл этой замечательно команды в том, что при запросе пользователя она проверяет есть ли в локальной копии сайта файл с указанными именем и если есть, то отдает файл, а если нет, то передает работу в @static, в котором живет прокси сервер. Таким элегантным способом мы можем накапливать картинки (страницы) с оригинального сайта, и, если нужно, по одной штуке переводить их на русский язык в редакторе. Весь процесс не создает ошибок, абсолютно прозрачен для пользователя и максимально удобен для переводчика-дизайнера. # Доделаем нашу статику: location @static { proxy_pass http://super-cdn.com$uri; # Стоит заметить что в годно сделанном сайте, есть 1-2 отдельных домена хранящие статические файлы. В нашем случае полный путь к ним оказался таким: http://super-cdn.com/img proxy_store /usr/local/nginx/html/${uri}; expires max; # expires max - Это чрезвычайно важная команда, которая превращает обычный кэш в постоянно хранилище файлов. Однажды попав картинка остается в хранилище пока вы не удалите ее руками или не перезапишите ее русифицированной версией. Как только картинка перезаписывается, она мгновенно выдается всем новым запросам. Все кэши ( на сервере, у юзера) во всех местах обновляются как надо если перезапустить nginx -s reload. За этой завораживающей процедурой можно наблюдать прямо в консоли firebug после рефреша страницы в браузере. Это действительно уникальная возможность Nginx. # Отдельный лог не повредит при отладке! access_log logs/2.access.log; error_log logs/2.error.log debug; } # Теперь опишем корневую директорию нашего сервера. location / { include example-transform.conf; # Включаем реверс прокси proxy_pass http://www.example.com; # Всякоразные настройки proxy_redirect off; proxy_cache cache-zone; # Не забыли про описание пула в самом начале? proxy_cache_min_uses 2; proxy_cache_valid 200 1h; # Если хотим чтобы владелец оригинального ресурса мог видеть наши посещения добавляем: proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
Мы помним, что картинки оригинального сайта находятся по адресу:
super-cdn.com/img
Однако запустив вышеописанную конфигурацию мы видим, что Nginx оставил все ссылки вида
=http://super-cdn.com/img/*
не проксифицированными. Понятно, что это из-за отличия домена. Так же понятно, что в такой ситуации никакой возможности подсунуть переведенные картинки у нас нет, потому как пользователь забирает их напрямую с CDN минуя нас. Значит требуется магия трансформации!
Открываем example-transform.conf
sub_filter 'http://super-cdn.com/img/’ 'http://example.ru/img/' ; sub_filter_once off;
По умолчанию модуль трансформации не откомпилирован! Нужен параметр:
./configure --with-http_sub_module
Компилируем, перзапускаем… Бинго!!! Фанфары!!!
Все работает, все летает, картинки можно подменять на ходу.
Мы радостно добавляем первое правило замены содержимого страницы и … узнаем шокирующую информацию о том, что модуль http_sub_module позволяет выполнить всего одну замену!
О Игорь Сысоев, почему ты скрыл этот чудовищный факт в страничке документации!
sysoev.ru/nginx/docs/http/ngx_http_sub_module.html
Ах если бы мы знали про такой финал в самом начале! Но… Стоп! Эмоции в сторону, потому что русские и китайцы — братья навек! Простой китайский паренек Weibin Yao уже решил нашу проблему и создал модуль substitutions4nginx, который доступен по адресу
code.google.com/p/substitutions4nginx/
Устанавливаем модуль по инструкции, открываем наш конфигурацию трансформации и смело пишем:
subs_filter 'http://super-cdn.com/img/’ 'http://example.ru/img/' g;
subs_filter '<title[^>]*>(.*?)' 'НЛО прилетело сюда и подчинило этот сайт своей воле. Аминь!' oir;
Вместо послесловия
- Конфиг писался из рабочего, но по понятным причинам не проверялся вживую. Если возникнут сложности постараюсь помочь.
- Nginx работает в нестандартном малоисследованном режиме. Появляется вот такой баг.
- Модуль substitutions4nginx не обкатан, один баг нашелся сразу и был быстро исправлен. Видимо нужна толпа тестеров.
4. В Apache Traffic Server и в Nginx я нашел одинаковый баг. При котором теги с линками типа a href содержащие перенос строки не прокисифцируются. Подозреваю что проблема тянется из библиотеки PCRE.
источник — habrahabr.ru/blogs/nginx/114845/
- +1
- Diesel
- 03 марта 2011, 22:16
Комментарии (0)
rss свернуть / развернутьТолько авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста.