反向代理时,如何让Nginx传递外部DNS名称?

时间:2019-07-12 14:57:36

标签: nginx dns

我正在尝试使用Nginx封装由我们的一位客户托管的,记录不佳且气质性很差的API。尽管我尽了最大的努力,但我还是无法让Nginx将我们要发出的请求(带有两个参数作为URL参数的GET请求)的入站格式转换成我们需要提交给此API的内容(带有POST请求的一个将参数编码为JSON Blob的请求正文。

我可以用Python代码对该API进行有效调用,但是我无法弄清楚在Nginx设置中我无法做的事情来复制行为。这里的想法是将请求从慢速Python代码包装到Nginx。

Python代码如下所示:

REMOTE_URI = 'https://api.mycompany.com/services/some/api/endpoint/here/'

async def get_promotion_data(customer_id, product_id):
    params = {'AccountNumber': customer_id,
              'ProductIdentifier': product_id}

    async with aiohttp.ClientSession() as session:
        async with session.post(REMOTE_URI,
                                headers={'Content-Type': 'application/json'},
                                data=json.dumps(params)) as response:

            data = await response.json()

            if not data:
                return {}

            return data

要使它在Nginx中正常运行,我的最佳尝试是:

location /internal/wrapper {
    proxy_set_header   Host      api.mycompany.com;
    proxy_set_header Connection "";
    proxy_connect_timeout 100ms;
    proxy_read_timeout 5s;
    proxy_method POST;
    proxy_set_body '{"AccountNumber":"${arg_customer_id}","ProductIdentifier":"${arg_product_id}"}';
    proxy_set_header X-Content-Type application/json;
    proxy_pass https://api.mycompany.com/services/some/api/endpoint/here/;
}

但是,当我调用Nginx包装版本时,它总是返回504,即与上游的连接超时。 (我已经尝试增加Nginx中的代理超时;我们连接到的API速度很快,所以几乎绝对不是问题。)

通过使用我们直接使用curl之类的工具来调用API的最大猜测是,客户端的某些内容是根据URL中的主机名进行路由的。当我尝试执行curl "https://api.mycompany.com/services/some/api/endpoint/here/"时,它会返回一条响应,表明我在选择正确的服务器。当我做curl "https://123.123.123.123/services/some/api/endpoint/here/"时,会得到一堆重定向。

似乎Nginx正在解析域并直接调用IP,而不是显式传递主机名。在error.log文件中,它记录了它尝试(并对其超时)的上游是123.123.123.123而不是api.mycompany.com。这也是为什么我尝试添加Host标头作为代理通过的一部分。

也许我还想念其他东西吗?代理时还有其他方法告诉Nginx如何处理主机名吗?

1 个答案:

答案 0 :(得分:0)

事实证明这里有两个错误。首先,JSON内容类型的标头是Content-Type而不是X-Content-Type。更重要的是,我需要向配置中添加proxy_ssl_server_name on。原来我对主机名是一个问题是正确的,真正的问题是由于Nginx在发出HTTP请求时未发送服务器名。