从Docker容器到LAN IP的HTTPS请求失败,但curl有效

时间:2017-02-08 03:02:49

标签: node.js docker https

我正在开发一种可在我的LAN上访问的嵌入式设备。我想从包含我的开发环境的Docker容器中向其API发出请求。

设备在https://172.16.1.92公开(当然,它没有正确的HTTPS证书)。我可以在浏览器中成功访问此URL,一切正常。

如果我这样做:

docker run -it --rm node:5 curl --insecure https://172.16.1.92/api

我看到了预期的结果(一个JSON对象)。

然而,在编写快速JS测试脚本之后:

var https = require('https');

https.request({
  host: '172.16.1.92',
  method: 'GET',
  path: '/api',
  timeout: 5 * 1000,
  rejectUnauthorized: false, // for the lack of certificate
}, function(res) {
  console.log(res.statusCode);
});

运行它:

docker run -it --rm -v `pwd`:/code -w /code node:5 node test.js

几秒钟后我收到此错误:

events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: socket hang up
    at createHangUpError (_http_client.js:206:15)
    at TLSSocket.socketOnEnd (_http_client.js:298:23)
    at emitNone (events.js:72:20)
    at TLSSocket.emit (events.js:166:7)
    at endReadableNT (_stream_readable.js:905:12)
    at nextTickCallbackWith2Args (node.js:474:9)
    at process._tickCallback (node.js:388:17)

我很困惑 - 为什么我可以使用curl访问URL,但不使用节点的https库?

如果我在我的主机上运行nmap -sP 172.16.1.*,我会看到这一行:

Nmap scan report for WRN_002258.lan (172.16.1.92)
Host is up (0.0011s latency).
MAC Address: xx:xx:xx:xx:xx:xx (vendor)

但是如果我在Docker容器中安装nmap并运行相同的命令,我会看到:

Nmap scan report for 172.16.1.92
Host is up (0.0032s latency).

那有意义吗?

1 个答案:

答案 0 :(得分:1)

您的代码与HTTP服务器执行TCP握手,但不会通过它发送数据。

将Node.js代码修改为:

var https = require('https');

var req = https.request({
    host: '172.16.1.92',
    method: 'GET',
    path: '/api',
    timeout: 5 * 1000,
    rejectUnauthorized: false, // for the lack of certificate
}, function(res) {
    console.log(res.statusCode);
});

req.end()

您应该阅读https.request()的文档和http.request()的文档。完成后,您最终还会阅读request.end()

的文档

对于TL; DR时刻:request.end()完成发送请求。