Избегайте nginx декодирования параметров запроса на прокси-пропуске (эквивалентно AllowEncodedSlashes NoDecode)
Я использую nginx в качестве balencer нагрузки в передней части несколько котищ. В моих входящих запросах я закодировал параметры запроса. Но когда запрос поступает в Tomcat, параметры декодирования :
входящий запрос на nginx:
curl -i "http://server/1.1/json/T;cID=1234;pID=1200;rF=http%3A%2F%2Fwww.google.com%2F"
входящий запрос к tomcat:
curl -i "http://server/1.1/json/T;cID=1234;pID=1200;rF=http:/www.google.com/"
Я не хочу, чтобы мои параметры запроса были преобразованы, потому что в этом случае мой tomcat выдает ошибку 405.
моя конфигурация nginx следующая :
upstream tracking {
server front-01.server.com:8080;
server front-02.server.com:8080;
server front-03.server.com:8080;
server front-04.server.com:8080;
}
server {
listen 80;
server_name tracking.server.com;
access_log /var/log/nginx/tracking-access.log;
error_log /var/log/nginx/tracking-error.log;
location / {
proxy_pass http://tracking/webapp;
}
}
в моей текущей конфигурации балансировщика нагрузки apache у меня есть AllowEncodedSlashes директива, которая сохраняет мои закодированные параметры:
AllowEncodedSlashes NoDecode
мне нужно перейти от apache к nginx.
мой вопрос совершенно противоположен этому вопросу:избегайте nginx экранирования параметров запроса на proxy_pass
5 ответов
Я, наконец, нашел решение: мне нужно передать $request_uri
параметр :
location / {
proxy_pass http://tracking/webapp$request_uri;
}
таким образом, символы, которые были закодированы в исходном запросе будет не будет декодирован, т. е. будет передан как есть проксированному серверу.
Жан это хорошо, но это не работает с подстановками. В этом случае более общий ответ:
location /path/ {
if ($request_uri ~* "/path/(.*)") {
proxy_pass http://tracking/webapp/;
}
}
существует один документированный вариант для директива proxy_pass nginx в директива
Если необходимо передать URI в необработанной форме, то следует использовать директиву proxy_pass без URI:
location /some/path/ {
proxy_pass http://127.0.0.1;
}
Так что в вашем случае это может быть такой. Не беспокойтесь о запросе URI, он будет передан вышестоящим серверам
location / {
proxy_pass http://tracking;
}
надеюсь, что это помогает.
обратите внимание, что декодирование URL, широко известный как $uri
"нормализации" в документации nginx, происходит до бэкэнда IFF:
либо любой URI указан в
proxy_pass
сам, даже если только косая черта сама по себе,или URI изменяется во время обработки, например, через
rewrite
.
оба условия явно документировано вhttp://nginx.org/r/proxy_pass (Курсив мой):
если это без URI, URI запроса передается на сервер в та же форма, что и отправлена клиентом при обработке исходного запроса или полное нормированный запрос URI передается , когда обработка изменен URI
решение зависит от того, нужно ли изменять URL-адрес между интерфейсом и бэкэндом.
-
если изменение URI не требуется:
# map `/foo` to `/foo`: location /foo { proxy_pass http://localhost:8080; # no URI -- not even just a slash }
-
в противном случае, если вам нужно поменять местами или map
/api
передней части с/app
на бэкэнде, то вы можете получить оригинальный URI из$request_uri
переменная и использованиеrewrite
директивы по$uri
переменная, похожая на DFA (кстати, если вы хотите большеrewrite
Действие DFA, взгляните наmdoc.su). Обратите внимание, чтоreturn 400
часть необходима в случае, если кто-то пытается обойти ваше второе правило перезаписи, так как он не соответствует что-то вроде//api/
.# map `/api` to `/app`: location /foo { rewrite ^ $request_uri; # get original URI rewrite ^/api(/.*) /app break; # drop /api, put /app return 400; # if the second rewrite won't match proxy_pass http://localhost:8080$uri; }
-
если вы просто хотите добавить префикс для серверной, то вы можете просто использовать
$request_uri
переменной сразу:# add `/webapp` to the backend: location / { proxy_pass http://localhost:8080/webapp$request_uri; }
вы также можете взглянуть на связанный ответ, который показывает некоторые тестовые прогоны кода аналогичны приведенным выше.
в некоторых случаях проблема не на стороне nginx - вы должны установить кодировку uri на Tomcat connector в UTF-8.