Рейтинг:1

Как проксировать полный URL-адрес в конфигурации nginx?

флаг ve

Мне нужно прокси-места /v1/апи/ на другой URL как:

местоположение /api/v1/ {
        proxy_pass http://frontend-api.preprod.my-app.com/api/v1/;
    }

однако в мейнстриме принимается только слаг:

"GET /api/v1/ HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, например Gecko) Chrome/96.0.4664.110 Safari/537.36"

потому что апстрим настроен на конкретный домен интерфейс-api.preprod.my-app.com:

сервер {
    слушать 80;
    server_name интерфейс-api.preprod.my-app.com;

   место расположения / {
      корень /var/www/frontend_api/current/public;

      # Включить пассажира
      пассажир_включен;
      пассажир_ruby /home/deploy/.rvm/gems/ruby-2.7.2/wrappers/ruby;
    }

}

окончательный результат 404. Как настроить proxy_pass на прокси-сервере для отправки хоста, чтобы принимающий сервер получал полный URL-адрес, а не только /апи/v1/ ?

Рейтинг:2
флаг us

документация по nginx объясняет поведение:

Если директива proxy_pass указана с URI, то при передаче запроса на сервер часть нормализованного URI запроса, соответствующая местоположению, заменяется URI, указанным в директиве:

В вашем случае это означает, что URI запроса заменен на /апи/v1/ URI, указанный в вашем proxy_pass директива.

Если вы хотите, чтобы URI передавался как есть, вам нужно сделать:

местоположение /api/v1/ {
    proxy_pass http://frontend-api.preprod.example.com;
}

В этом случае nginx использует URI из исходного запроса с proxy_pass пункт назначения, как описано:

Если proxy_pass указан без URI, то URI запроса передается на сервер в том же виде, в каком он был отправлен клиентом при обработке исходного запроса, или полный нормализованный URI запроса передается при обработке измененного URI:

Если вы хотите заменить часть URI запроса другой частью, вам нужно использовать захват регулярного выражения:

расположение ~ ^/источник/путь/(.*) {
    proxy_pass http://example.com/destination/path/$1;
}

Редактировать:

Чтобы получить доменное имя исходного запроса, переданного восходящему потоку, необходимо установить Хозяин Заголовок HTTP для восходящего запроса:

proxy_set_header Хост $host;

Часто бывает полезно также передать IP-адрес посетителя через заголовок:

proxy_set_header X-Forwarded-For $remote_addr;
simo avatar
флаг ve
Я попробовал `proxy_pass http://frontend-api.preprod.example.com;`, но с другой стороны я все еще получаю тот же результат. У меня нет проблем с передачей слага, проблема в том, что базовый URL-адрес не передается, на принимающем сервере виден только `/api/v1/`, а не `http://frontend-api.preprod. пример.com/api/v1/`
флаг us
Вы не можете передать полный URL-адрес в качестве URI для запроса к серверной части. Чтобы получить имя хоста, вам нужно использовать заголовки HTTP. Я добавил пример к ответу.
simo avatar
флаг ve
Спасибо, я попытался установить заголовок Host на $host, однако после этого я не вижу журналы, поступающие в access.log получателя nginx!
флаг us
Тогда ваша настройка имени виртуального хоста в получателе nginx неверна.
simo avatar
флаг ve
Спасибо, была проблема..

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.