HTTPS 请求,指定主机名和特定 IP 地址

Bra*_*rad 5 https node.js

我的应用程序服务器有一个基于 Node.js 的部署脚本。部署过程中的一个步骤是在向 DNS 注册之前验证这些应用程序服务器是否正确侦听 HTTPS。为此,我只需要向该服务器的 IP 地址发出 HTTPS 请求。

如果这是 HTTP,这不是问题。我可以为 发出 HTTPGET请求http://[2001:0db8::0370:7334]/,这将起作用。但是,如果我对 发出 HTTPS GET 请求https://[2001:0db8::0370:7334]/,这将失败,因为证书是针对特定主机名的,例如api.example.com.

如果我手动测试,我会暂时将 IP 地址放在hosts文件和 cURL 中https://api.example.com。但是,在此自动化过程中,我可能会同时部署多个主机,因此这不是我的部署脚本的解决方案。

如何在指定主机名和 IP 地址的情况下发出 HTTPS 请求?

也许有某种方法可以使用自定义代理来做到这一点?

我目前正在使用node-fetch,但我很高兴使用任何需要的 API 来完成这项工作。

rob*_*lep 10

设置host请求的标头:

const https = require('https');

https.get('https://AA.BB.CC.DD', {
  headers : { host : 'api.example.com' }
}, res => {
  console.log('okay');
}).on('error', e => {
  console.log('E', e.message);
});
Run Code Online (Sandbox Code Playgroud)

编辑:我仔细研究了一下,看看它是如何工作的。为了允许基于 HTTPS 的虚拟主机,有一个名为SNI(服务器名称指示)的 TLS 扩展。客户端使用此扩展来指示它尝试连接的主机名,因此服务器可以选择属于该主机名的适当证书。

tls由 使用的节点模块https具有servername设置此主机名的选项:

https.get('https://AA.BB.CC.DD', {
  servername : api.example.com'
}, ...)
Run Code Online (Sandbox Code Playgroud)

但是,您仍然需要传递Host标头(这是常规 HTTP 协议的一部分):

https.get('https://AA.BB.CC.DD', {
  headers : { host : 'api.example.com' },
  servername : 'api.example.com'
}, ...)
Run Code Online (Sandbox Code Playgroud)

为了保持 DRY,Node.js 将设置servernameHost标头,除非它已经设置为其他内容(此处)。