Author Archives: elwood

Редиректы из-под nginx

Written by elwood

Предположим у нас есть nginx и проксируемая приложунька.

Nginx отвечает на запросы http://frontend.ru:8080/foo и проксирует их локально на http://localhost:8090/foo

Если приложение хочет ответить редиректом на /somewhere, то пользователь должен увидеть Location: http://frontend.ru:8080/somewhere

Тут есть нюанс. Поведение зависит от того, как мы передаём заголовок Host в бекенд. Можно написать так:

location / {
    proxy_pass http://localhost:8080;

    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-NginX-Proxy true;

    proxy_redirect off;
}

И тогда бекенду будет приходить заголовок Host: frontend.ru. Если приложение не экзотическое, оно на такой заголовок сформирует редирект без указания порта (т.к. про порт ему и узнать неоткуда). В результате ответ будет такой: Location: http://frontend.ru/, что совсем не круто. Нам-то нужен нормальный Location ! С портом !

В общем, есть два пути решения этой проблемы.

Первый способ: настроить rewrite для заголовков ответа

proxy_redirect http://$host/ http://$host:$server_port/;

Эта штука будет перехватывать ответ приложения и заменять в заголовках Location, дописывая порт.

И второй: использовать в директиве proxy_set_header HOST $host; переменную $http_host вместо переменной $host:

proxy_set_header HOST $http_host;

$http_host выгодно отличается от просто $host тем, что содержит порт (хехе), и всё сразу начинает работать. Приложение формирует правильные редиректы, их даже и не приходится перезаписывать, пользователи довольны, донатят тысячи и тысячи в валюте.

strace и setuid

Written by elwood

Игрался сегодня с strace. Запускал в нём ping. Но пинг, запущенный таким образом, почему-то отказывался работать, возвращая ошибку:

elwood@elwood:~$ strace -o out ping ya.ru
ping: icmp open socket: Operation not permitted

При этом просто пинг (без strace) вполне себе работал.

Почему так ?..

Выяснилось, что дело в особых правах на ping. Прикол в том, что для пинга установлен бит setuid:

elwood@elwood:~$ ls -l `which ping`
-rwsr-xr-x 1 root root 44168 May  7  2014 /bin/ping

И при запуске он по сути работает от рута. А strace такими правами не обладает, и запуская ping через него, я получал ошибку. Если убрать setuid бит с /bin/ping, то при запуске ping я тоже буду получать ошибку:

elwood@elwood:~$ sudo chmod u-s `which ping`
elwood@elwood:~$ ls -l `which ping`
-rwxr-xr-x 1 root root 44168 May  7  2014 /bin/ping
elwood@elwood:~$ ping ya.ru
ping: icmp open socket: Operation not permitted

Решить проблему можно либо добавив setuid бит для strace (chmod u+s `which strace`), либо запуская strace через sudo.

Баг с Type Annotations исправят, но только в Java 9

Written by elwood

bugslife_7

Когда я писал JCoro, наткнулся на неприятный баг, который не позволял полноценно поддерживать работу с лямбдами: часть type-аннотаций при компиляции просто не записывалась в class-файл. Возмущённый этим беспределом, пошёл тогда на оракловый багтрекер и выяснил, что иначе как через написание письма баг не засабмитить. Ушёл писать письмо. Написал письмо, отправил и стал ждать. Как оказалось, отлупы при рассмотрении таких писем не приходят, и ждал я тщетно. И вот сегодня вспомнил про эту шляпу и решил поискать ручками – а что, а вдруг ? И слава богам – бажулька действительно была принята и даже пофикшена ! Да вот только фикс приедет лишь в Java 9. Это.. это печально. К тому времени Kotlin может опередить jcoro 🙂 (хотя они ещё не взялись за свой async-await, а лишь зарезервировали ключевые слова).