Yaxy -- это proxy-сервер для веб-разработчика, подменяющий запрашиваемые ресурсы, следуя простым правилам.
Если у вас до сих пор не установлен NodeJS, устанавливайте, после чего
npm install -g yaxy
yaxy --config my-yaxy-config.txt --port 9999
Если не указан параметр --config
, то ищется файл yaxy-config.txt в текущей директории. Если не указан --port
, то сервер будет слушать порт 8558
.
Чтобы защитить прокси-сервер паролем, укажите параметр --auth user:password
.
Если необходимо, что Yaxy ходил через другой прокси-сервер (например, у вас доступ в интернет через прокси), то при запуске нужно указать параметр --proxy user:password@proxyhost:3000
.
Для подмены HTTPS-ресурсов, Yaxy запускает HTTPS-сервер, слушающий порт 8559
. Чтобы изменить значение по-умолчанию, используйте параметр --https-port 9998
. Чтобы совсем отключить подмену HTTPS-ресурсов и не занимать лишний порт, используйте параметр --no-https
.
Важно: порт --https-port
нужен только для корректной работы yaxy и меняется в случае, если порт 8559 занят чем-то другим. В браузере для всех протоколов указывается порт --port
.
Конфигурационный файл читается построчно. Пустые строки, строки, начинающиеся на символ #
и строки неопознанного формата игнорируются.
Правила могут объединяться в секции. Начало секции задаётся строкой в квадратных скобках, содержимое строки может быть любым.
# Правила вне секций
[Секция 1]
# Правила секции 1
[Секция 2]
# Правила секции 2
Если имя секции начинается на #
, то все правила в секции игнорируются.
# Правила вне секций
[#Секция 1]
# Правила секции 1
# Будут игнорироваться
[Секция 2]
# Правила секции 2
По-умолчанию Yaxy перехватывает только HTTP-запросы. Чтобы включить перехват HTTPS для какого-нибудь хоста, необходимо в конфиге указать
$UseSSLFor www.yandex.ru
После этого правила для сайта www.yandex.ru начнут срабатывать и при HTTPS-запросах. Однако сертификат у www.yandex.ru станет самоподписанным, поэтому необходимо будет согласиться его принять в браузере.
Yaxy умеет проксировать и перенаправлять WebSocket-ы. Никаких специальных указаний для этого не требуется. Если в правиле не указан протокол, то такое правило будет влиять и на WebSocket-ы. Если по какому-то урлу необходимо подменять только сокеты, а обычные http-соединения не трогать, то в правиле просто нужно указать протокол ws:/wss:.
Правила записываются в виде:
url => replacement
url
-- строка, на которую должен начинаться адрес, чтобы правило сработало. Например, правило www.yandex.ru => ...
будет срабатывать для всех ресурсов в домене www.yandex.ru, а правило yandex.ru/yandsearch => ...
-- только для поиска Яндекса.
Если у адреса в левой части правила не указан протокол, то оно будет срабатывать и для HTTP, и для HTTPS, при условии, что включен перехват HTTPS для данного хоста директивой $UseSSLFor
. Если нужно подменять только загрузку по конкретному протоколу, его необходимо явно указать в правиле.
Иногда требуется точное совпадение с адресом, например, необходимо модифицировать только главную страницу какого-нибудь сайта, а внутренние оставить без изменений. В таких случаях в начале урла нужно указать !
, протокол в начале указывать по прежнему необязательно, если нужно перехватывать и http, и https, а вот завершающие слеши обязательны, т.к. совпадение должно быть точным. Например, подмена только главной страницы Яндекса: !www.yandex.ru/ => ...
.
Если не хватает первых двух вариантов, в левой части правила можно указать регулярное выражение, заключённое между символами /
. Вдруг вам понадобится модифицировать все запросы к доменам в зоне ru: /^http://[^/]+\.ru// => ...
. Обратите внимание, на вход регулярному выражению подаётся весь урл, включая протокол.
В начале строки с правилом можно указать один или несколько методов, на которые будет срабатывать правило, обязательно большими буквами:
GET yandex.ru => ...
PUT|POST yandex.ru => ...
В путях до файлов в конфиге можно использовать знак ~
, вместо которого будет подставляться текущая директория. Изначально это директория, в которой лежит файл с конфигом. Изменить значение тильды можно директивой $SetDocumentRoot
.
$SetDocumentRoot /home/me/projects
site.my => file://~/site.my
# Вместе с правилом выше это аналогично
site.my => file:///home/me/projects/site.my
Точно также можно определить текущую директорию только для конкретной секции.
$SetDocumentRoot /home/me/projects
[site.my]
$SetDocumentRoot ~/site.my
site.my/css => file://~/css-dev
site.my/js => file://~/js-dev
site.my => file://~
Тильду можно использовать в любых правилах наряду с остальной шаблонизацией
site.my/js/my.js => bin: jossy ~/js/my.js
В правой части правил и модификаторов доступна вставка различных паратров запроса.
* `${url}` -- запрашиваемый урл
* `${host}` -- запрашиваемый хост
* `${port}` -- запрашиваемый порт
* `${path}` -- запрашиваемый путь внутри сайта
* `${query}` -- строка параметров
* `${header:Referer}` -- значение http-заголовка `Referer`
* `${param:callback}` -- значение get-параметра `callback`
* `${cookie:sessionId}` -- значение куки `sessionId`
Если необходимо эскейпить вставляемую строку, добавляем символ &
:
# Запрос к www.yandex.ru уйдёт на site.my/proxy?url=http%3A%2F%2Fwww.yandex.ru%2F
www.yandex.ru => site.my/proxy?url=${&url}
Ещё примеры:
# Подменяем jsonp-ответ
site.my/jsonp => data:application/javascript;${param:callback}({foo: 1, bar: 2});
# Достаём реферер в get-параметры
www.yandex.ru => $
$SetRequestParam referer=${header:Referer}
Если в левой части правила находится регулярное выражение, то кроме именованных параметров в шаблон можно вставлять сохранённые группировки регекспа. Например, заменяем все запросы к доменам *.ru на *.com: /^(http://[^/]+\.)ru(/.*)$/ => $1com$2
.
Если в левой части правила находится строка, то правая часть указывает, на что в урле заменить совпавшую левую. Например, правило google.ru => yandex.ru
заменит все запросы к google.ru
на запросы к yandex.ru
, т.е. запрос http://google.ru/
на самом деле уйдёт к http://yandex.ru/
, а запрос http://google.ru/foo/bar
уйдёт к http://yandex.ru/foo/bar
. Более точное правило google.ru/foo => yandex.ru/foo
заменит запрос к http://google.ru/foo/bar
, но оставит без изменений запрос http://google.ru/baz
. Обратите внимание, если необходимо сохранить путь внутри домена без изменений, то нужно указывать этот путь в обеих частях правила, т.к. google.ru/foo => yandex.ru
заменит http://google.ru/foo/bar
на http://yandex.ru/bar
.
Если в правой части правила указать протокол file://
, у нас получится маленький static-сервер.
# windows
host.com/some/path => file://c:/www/host.com
# linux
host.com/some/path => file:///home/www/host.com
index-файл для директорий -- index.html. Для приведённого примера по урлу http://host.com/some/path
прилетит файл /home/www/host.com/index.html
, по урлу http://host.com/some/path/empty.gif
прилетит файл /home/www/host.com/empty.gif
.
Если замена настолько простая, что даже файл создавать неохота, можно использовать data:uri.
host.com/some/path => data:text/html;<script type="text/javascript">alert('Привет!');</script>
В этом случае на все урлы, начинающиеся на host.com/some/path
будет ответ <script type="text/javascript">alert('Привет!');</script>
.
host.com/some/path/png => data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
На урлы, начинающиеся на host.com/some/path/png
отвечаем картинкой.
Если необходимо запустить консольную утилиту и вернуть в http-ответе её вывод, используем bin:
.
# Запускаем Jossy для сборки js-файла
site.my/js/my.js => bin: jossy /home/me/site/js/my.js
# Запускаем Jossy для сборки всех js-файлов в папке js
/http://site\.my/s/js/([^?]+)/ => bin: jossy /home/me/site/js/$1
# Можно и другие переменные передавать
site.my => bin: my-program --url ${url}
Помимо указания параметра --proxy
при запуске, Yaxy позволяет выполнять только нужные запросы через другой прокси-сервер.
www.yandex.ru => proxy:localhost:3000
Теперь запросы к Яндексу будут идти через прокси локальный сервер, слушающий на 3000-м порту. А если Yaxy запущен с аргументом --proxy localhost:3333
, то все запросы будут выполняться через прокси-сервер на 3333-м порту, а запросы к Яндексу через сервер на 3000-м порту.
Если с урлом ничего делать не надо, то в правой части правила пишем $
.
host.com/some/path => $
Это бывает необходимо, если какой-нибудь запрос изменять не надо, но нужно применить к нему модификаторы, о которых ниже.
Если правую часть правила оставить пустой, то запрос просто оборвётся, не вернув даже http-заголовков.
При большом количестве правил или при наличии большого количества разных проектов можно разделить конфиг на несколько файлов. Внешние файлы в текущий конфиг подключаются командой $Include
. Директива принимает абсолютный путь до подключаемого файла, но, как и везде, можно использовать ~
для указания текущей директории.
$Include ~/some-project/.yaxy
Подключаемый файл будет парситься независимо от подключающего. Правила в одном файле никак не влияют на правила в другом. DocumentRoot
в подключаемом файле изначально равен директории, в которой лежит этот файл.
Строки, начинающиеся на $
(не считая пробелов в начале строки) являются модификаторами. До первого пробела идёт название модификатора, после -- аргументы. Модификатор относится к тому правилу, после которого он записан. Если модификатор записан в начале файла, до всех правил, то он применяется ко всем правилам. Если модификатор записан в начале секции, то он применяется ко всем правилам в этой секции.
Обратите внимание, модификаторы в начале файла влияют именно на все правила, т.е. на запросы, попадающие под эти правила, а не на абсолютно все запросы, проходящие через прокси-сервер.
# Добавляем или изменяем параметр
$SetQueryParam from=yaxy
# Удаляем параметр
$RemoveQueryParam from
Cookie меняются для сервера, т.е. браузер посылает одни куки, а сервер получает другие.
# Добавляем или изменяем куку
$SetCookie user=YaxyUser
# Удаляем куку
$RemoveCookie ssid
# Устанавливаем заголовок запроса
$SetRequestHeader X-Requested-With: Yaxy
# Устанавливаем заголовок ответа
$SetResponseHeader X-Proxy: Yaxy
# Удаляем заголовок запроса
$RemoveRequestHeader Referer
# Удаляем заголовок ответа
$RemoveResponseHeader Content-Type
# Всегда отвечаем статусом 200, даже если что-то сломалось
$StatusCode 200
#Отвечаем не раньше, чем через 5 секунд
$Delay 5