Nginx и конечная косая черта с прокси-проходом

Я использую следующую конфигурацию для nginx 1.4.1:

server {
    listen       8000;
    server_name  correct.name.gr;

    location /test/register {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1;
    }
}

То, что я хочу сделать, - это когда пользователь vist http://correct.name.gr:8000/test/register/ должен быть проксирован на apache, который выполняется на порту 80.

Когда я навещаю http://correct.name.gr:8000/test/register/, я получаю правильные результаты (index.php). Когда я навещаю http://correct.name.gr:8000/test/register/asd, я получаю правильные результаты (404 из apache). Когда я посещаю http://correct.name.gr:8000/test/asd, я получаю правильные результаты (404 из nginx). Когда я навещаю http://correct.name.gr:8000/test/register123, я получаю правильные результаты (404 из apache).

Проблема заключается в том, что я посещаю http://correct.name.gr:8000/test/register. Я получаю 301 ответ, и я перенаправлен на http://localhost/test/register/ (обратите внимание на конечную косую черту и, конечно, на "localhost" )!!!

Я не делал никаких других конфигураций для nginx, чтобы положить трейлинг-косые черты или что-то подобное. Вы знаете, в чем проблема? Я хочу, чтобы http://correct.name.gr:8000/test/register работал корректно, проксируя на apache (или, если возможно, по крайней мере, чтобы выпустить ошибку 404, а не перенаправление на локальный хост пользователя).

Обновление 1: я пробовал http://correct.name.gr:8000/test/register с другого компьютера, чем вчера, когда у меня было плохое поведение. Ну, это сработало: я получил ответ 301, который указал мне на правильный http://correct.name.gr:8000/test/register/! Как можно работать с одного компьютера, но не с другого (я использую тот же браузер Chrome на обоих компьютерах)? Я попробую еще раз завтра, чтобы проверить с третьего, чтобы увидеть поведение.

Спасибо!

Ответ 1

Я предполагаю, что ваш восходящий сервер (либо apache, либо ваш script) вызвал перенаправление на абсолютный url http://localhost/test/register/. Поскольку вы используете http://127.0.0.1 в своей директиве proxy_pass, nginx не находит совпадения имени домена и возвращает заголовок Location как есть.

Я думаю, что правильным решением является НЕ использовать абсолютное перенаправление, если перенаправление относится к внутреннему URL-адресу. Это всегда хорошая практика.

Однако, не меняя сервер восходящего потока, есть два быстрых решения.

вы можете использовать

proxy_pass http://localhost;

Это сообщит nginx, что доменное имя upstream localhost. Тогда nginx будет знать, чтобы заменить http://localhost на http://correct.name.gr:8000, когда он найдет эту часть в заголовке Location вверх по течению.

Другим является добавление строки proxy_redirect, чтобы заставить nginx переписать любой заголовок местоположения с http://localhost/ в нем.

 proxy_pass http://127.0.0.1;
 proxy_redirect http://localhost/ /;

Я предпочитаю первое решение, потому что оно проще. Накладные расходы на поиск DNS не используются с помощью proxy_pass http://localhost;, потому что nginx выполняет поиск заранее, когда он запускает веб-сервер.

ссылка: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Ответ 2

Вы уже пытались играть с server_name_in_redirect?

Однако, я нашел вас вопросом через google, потому что я запускаю ту же проблему с завершающим косой чертой. Nginx заставляет 301 на тот же URL с завершающей косой чертой.