From d4550af148b86f18148c003cab1b1907b60964d8 Mon Sep 17 00:00:00 2001 From: An Tran Date: Thu, 27 Jun 2024 11:08:40 +1000 Subject: [PATCH] Prevent APIcast fallback to global proxy settings for direct connection With the newer version of lua-resty-http (0.7.1), if a proxy options is not provided when calling the connect() method, it will fall back to using the global proxy settings set by the "set_proxy_option" function (has no effect in previous versions of the library). This then causes unexpected behavior where the direct connection will now go through the proxy server. This PR explicitly sets the proxy options to an empty table to bypass global proxy settings when connecting directly. --- CHANGELOG.md | 2 ++ gateway/src/resty/http/proxy.lua | 5 +++- t/http-proxy.t | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a866c58b9..31def373e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed 3scale Batcher policy unable to handle `app_id`/`access_token` contains special characters [PR #1457](https://github.com/3scale/APIcast/pull/1457) [THREESCALE-10934](https://issues.redhat.com/browse/THREESCALE-10934) +- Fixed APIcast send request through proxy server even when `NO_PROXY` is used [PR #1478](https://github.com/3scale/APIcast/pull/1478) [THREESCALE-11128](https://issues.redhat.com/browse/THREESCALE-11128) + ### Added - Bump openresty to 1.21.4.3 [PR #1461](https://github.com/3scale/APIcast/pull/1461) [THREESCALE-10601](https://issues.redhat.com/browse/THREESCALE-10601) diff --git a/gateway/src/resty/http/proxy.lua b/gateway/src/resty/http/proxy.lua index 40ea28c88..637ed0e3e 100644 --- a/gateway/src/resty/http/proxy.lua +++ b/gateway/src/resty/http/proxy.lua @@ -57,10 +57,13 @@ local function connect(request) -- openresty treat nil as false, so we need to explicitly set ssl_verify to false if nil local ssl_verify = request.options and request.options.ssl and request.options.ssl.verify or false + -- We need to set proxy_opts to an empty table here otherwise, lua-resty-http will fallback + -- to the global proxy options local options = { scheme = scheme, host = host, - port = port + port = port, + proxy_opts = {} } if scheme == 'https' then options.ssl_server_name = host diff --git a/t/http-proxy.t b/t/http-proxy.t index de623f152..0e57c1010 100644 --- a/t/http-proxy.t +++ b/t/http-proxy.t @@ -2083,3 +2083,46 @@ qr/a client request body is buffered to a temporary file/ --- grep_error_log_out a client request body is buffered to a temporary file --- user_files fixture=tls.pl eval + + + +=== TEST 36: APIcast should not ingore NO_PROXY, when HTTP_PROXY and HTTPS_PROXY are also set +It connects directly to backened and forwards request to the upstream via proxy. +--- env random_port eval +( + 'http_proxy' => $ENV{TEST_NGINX_HTTP_PROXY}, + 'no_proxy' => '127.0.0.1,localhost,test_backend', +) +--- configuration +{ + "services": [ + { + "id": 42, + "backend_version": 1, + "proxy": { + "api_backend": "http://test-upstream.lvh.me:$TEST_NGINX_SERVER_PORT/", + "proxy_rules": [ + { "pattern": "/", "http_method": "GET", "metric_system_name": "hits", "delta": 2 } + ] + } + } + ] +} +--- backend + server_name test_backend.lvh.me; + location /transactions/authrep.xml { + content_by_lua_block { + ngx.exit(ngx.OK) + } + } +--- upstream + server_name test-upstream.lvh.me; + location / { + echo 'yay, api backend: $http_host'; + } +--- request +GET /?user_key=value +--- response_body env +yay, api backend: test-upstream.lvh.me:$TEST_NGINX_SERVER_PORT +--- error_code: 200 +--- no_error_log