【问题标题】:Why does https.Agent throw a parse error when proxying via node-http-proxy?为什么 https.Agent 通过 node-http-proxy 代理时会抛出解析错误?
【发布时间】:2017-09-14 16:39:10
【问题描述】:

我想在我的node-http-proxy 应用程序中通过http.Agenthttps.Agent 启用连接池。为此,我建立了一个安全代理,如下所示:

const secureAgent = new https.secureAgent({ keepAlive: true });

(为简洁起见,我省略了互补的 http 代理。)

我创建了一个代理服务器,如下所示:

const proxy = httpProxy.createProxyServer({});

最后我在 Connect 中间件中代理一个请求,如下所示:

proxy.web(req, res {
  agent: isSecure ? secureAgent : agent,
  target: ...,
  secure: false,
});

这似乎适用于大多数请求,但每隔几分钟我就会看到如下所示的错误:

{
    "message": "Parse Error",
    "stack": "Error: Parse Error\n    at TLSSocket.socketOnData (_http_client.js:411:20)\n    at emitOne (events.js:96:13)\n    at TLSSocket.emit (events.js:191:7)\n    at readableAddChunk (_stream_readable.js:178:18)\n    at TLSSocket.Readable.push (_stream_readable.js:136:10)\n    at TLSWrap.onread (net.js:560:20)",
    "bytesParsed": 215,
    "code": "HPE_INVALID_CONSTANT",
    "__error_callsites": [
        {},
        {},
        {},
        {},
        {},
        {}
    ],
    "level": "error",
    "timestamp": "2017-04-18T17:34:09.735Z"
}

从粗略的阅读中可以看出,HPE_INVALID_CONSTANT 似乎在响应格式错误时出现。但是,在引入安全代理之前,这些响应都很好。

有没有人知道这里发生了什么或者我该如何解决?

注意:此错误发生在 Docker 容器中的 Node v7.9.0 上,通过 FROM node:7.9。到目前为止,我只在HEAD 请求中观察到这一点——这一定是有原因的。

【问题讨论】:

  • 您的请求参数中是否有空格,例如 ?a="ab"
  • 我没有详尽的请求参数列表,尽管我想说在这种特殊情况下这似乎不太可能 - 请注意这些是对客户站点的代理请求,因此它们可以是任何东西。跨度>
  • 我遇到了类似的问题。 (正在使用节点请求库),在我的情况下,请求参数中的值之一是空间。另外,我正在向localhost(nginx)发出请求,然后被python重定向到localhost。这两者的结合导致了我的问题。在我的案例中,我注意到一件事,我有可用的请求正文,但 Parse 错误曾经来过。我做了一个小技巧来忽略错误,并发送响应。如果你愿意,我可以分享代码。 PS - 使用手机打字,请原谅任何错别字或错误
  • 当然我很想知道你是如何解决这个问题的。
  • 你发现问题了吗?

标签: javascript node.js ssl proxy node-http-proxy


【解决方案1】:

只需在此处添加评论。 我面临着类似的问题。 (正在使用节点请求库),在我的情况下,请求参数中的值之一是空间。另外,我向http://localhost(http)(nginx)发出请求,然后被python重定向到https://localhost(https)。这两者的结合导致了我的问题。在我的案例中,我注意到一件事,我有可用的请求正文,但 Parse 错误曾经来过。我做了一个小技巧来忽略错误并发送响应。

    let formData = "some data";
    let headers = // some headers;
    headers["content-length"] = formData.length;
    headers["Accept-Encoding"] = "gzip, deflate";
    let gunzip;
    return new Promise(function (resolve, reject) {
        let buffer = [];
        let req = http.request({
            port: 80,
            method: "POST",
            path: url,
            headers: headers
        }, function (res) {
            let resHeaders = res.headers["content-encoding"];
            switch (resHeaders){
                case "gzip":
                    gunzip = zlib.createGunzip();
                    res.pipe(gunzip);
                    gunzip.on("data", function (data) {
                        buffer.push(data.toString());
                    }).on("end", function () {
                        resolve(buffer[0])
                    });
                    break;
                case "deflate":
                    gunzip = zlib.createDeflate();
                    res.pipe(gunzip);
                    gunzip.on("data", function (data) {
                        buffer.push(data.toString());
                    }).on("end", function () {
                        resolve(buffer[0])
                    });
                    break;
                default:
                    res.on("data", function (data) {
                        buffer.push(data.toString())
                    }).on("end", function () {
                        resolve(buffer[0])
                    })
            }
        });
        req.on('error', (e) => {
            // This is the Hack. If there is an error just ignore it.
            logger.debug("Error in getting requests, ", e)
        });
        req.write(formData);
        req.end();
    })
}

希望对您有所帮助。如果您找出原因,请分享。我试图找出原因一天,但不能。由于我们在生产中遇到了这个问题,所以不得不做这个快速补丁。

据我所知,这很可能是因为流程中的 HTTPS 重定向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2018-08-10
    • 2013-09-14
    • 2021-11-14
    相关资源
    最近更新 更多