Написал тут HTTP-проксю на Erlang’е. Зачем? Ну, например, мне захотелось попробовать Cowboy и написать на Erlang относительно серьезное приложение. Кода получилось довольно много, целых 300 строк! Разбирать его здесь я смысла не вижу, желающие сами ознакомятся и разберутся. Лучше я расскажу, что прокся умеет и как ею пользоваться.

Итак, что прокся умеет:

  • Скрывать ваш IP, при этом вы сможете нормально загружать странички, отправлять формочки и даже закачивать небольшие файлики;
  • Скачивать большие объемы данных;
  • Сжимать данные gzip’ом, если они не были сжаты;
  • Работать в режиме reverse proxy с буфферизацией данных и рерайтами;
  • Игнорировать рекурсивные запросы;
  • Читать конфигурационный файл;

Что прокся не умеет:

  • Ограничивать доступ к самой себе по логину-паролю;
  • Кэшировать страницы;
  • Самостоятельно раздавать статику;
  • Понимать запросы, отличные от GET, POST и HEAD;
  • Хорошо обрабатывать большие POST-запросы;
  • Работать с SSL;
  • И многое другое;

Собираем:

sudo apt-get install erlang
git clone git: // github.com / afiskon / erlang-http-proxy.git
cd erlang-http-proxy
make build

Прогоняем простенький тест:

make test

В этом тесте прокся поднимается на 8080-м порту и через нее загружается ya.ru. Если приходит код 200, тест пройден. Если вы располагаете большим количеством времени, то можете прогнать все-все-все тесты:

make test_full

Настраивается прокси через app.config. Основные параметры следующие:

{ http_proxy , [
{ port , 8080 } ,

Номер порта, на котором поднимается прокси.

{ workers , 256 } ,

Количество воркеров.

{ time out , 10000 } ,

Сколько миллисекунд дается клиенту на отправку запроса.

{ sync_stream , true } ,

Если false, данные буферизируются, если true — не буферизируются.

{ stream_chunk_size , 4096 } ,

Какими кусками отдавать данные клиенту. Имеет смысл только при sync_stream = false. Например, если вы решили использовать сервер в качестве reverse proxy для того, чтобы Apache не занимался передачей данных по медленным соединениям, нужно присвоить sync_stream значение false, а stream_chunk_size — максимальный размер веб-страницы.

{ enable_gzip , true } ,

Если данные никак не закодированы, сжимать их gzip’ом .

{ rewrite_rules , [
{ «^http://[^/]+/mail/(.*)$» , «http://mail.ru/ \ 1″ }
] }
] }

Если запрашиваемый URL соответствует регулярному выражению (первый элемент пары), заменить его в соответствии с правилом (второй элемент пары). Если не соответствует, идем дальше по списку пар. Если в списке больше не осталось элементов, оставляем URL без изменений.

Запускаем:

. / start.sh

Проверяем:

http_proxy =localhost: 8080 wget http: // google.com -S -O

Сказав браузеру работать через прокси, я:

  • Скачал ISO образ размером 4 Гб на скорости около 200 Кб/сек при включенном сжатии gzip’ом, проверил значение MD5;
  • Почитал бложики, послушал музыку во Вконтакте, посмотрел видео на YouTube;
  • Открыл десяток вкладок с «тяжелыми» сайтами типа lenta.ru, заставил их обновляться каждую минуту с помощью специального плагина, после чего отправился спать;
  • На утро написал этот пост;

Прокся работает шустренько и стабильненько. В худшем случае на моем слабеньком домашнем компьютере она кушала 5-7% CPU и около 18 Мб памяти. Притом с ростом количества соединений это число как-то не особо думает увеличиваться. Не падает, ошибками не сыпет.

Весь код лежит на GitHub’е . Надеюсь, кому-нибудь он пригодится. Буду рад вашим багрепортам и пуллреквестам.

Дополнение: См также заметку про получение load average в Erlang .

EnglishRussianUkrainian