尝试使用node.js 0.12进行代理HTTPS请求时出现EPROTO错误

时间:2015-05-20 21:53:04

标签: node.js heroku https proxy openssl

在较高级别,我正在尝试使用Quota Guard Static与来自node.js应用程序的Heroku应用程序中的IP限制API进行通信。 API有自己的node.js客户端实现,但在底层它只是一个HTTP [S] api。该库使用封底下的superagentsuperagent-proxy来执行实际的HTTP [S]请求。

在节点0.10中,一切正常。在节点0.12中,我看到如下错误:

Error: write EPROTO 140735203734288:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:../deps/openssl/openssl/ssl/s23_clnt.c:782:
    at exports._errnoException (util.js:746:11)
    at WriteWrap.afterWrite (net.js:775:14)

在io.js 2.02中,我看到:

Error: write EPROTO    at Object.exports._errnoException (util.js:844:11)

我尝试全局使用SSLv3,如answer所示,但似乎没有效果。

代理网址指定为带有端口9293的http网址。此answer建议使用端口443,但由于代理提供程序在我外部,我无法更改。

如何让代理请求在节点0.12中工作?

1 个答案:

答案 0 :(得分:2)

Tim来自QuotaGuard。这似乎是superagent-proxy用于HTTPS请求的https-proxy-agent中出现的一个问题,导致请求在错误的端口上发送到安全端点。

这是一个应该通过端口443连接到Google的简单示例。

var url = require('url');
var https = require('https');
var HttpsProxyAgent = require('https-proxy-agent');

// HTTP/HTTPS proxy to connect to
var proxy = process.env.QUOTAGUARDSTATIC_URL;
console.log('using proxy server %j', proxy);

// HTTPS endpoint for the proxy to connect to
var endpoint = process.argv[2] || 'https://www.google.com/';
console.log('attempting to GET %j', endpoint);
var opts = url.parse(endpoint);

// create an instance of the `HttpsProxyAgent` class with the proxy server information
var agent = new HttpsProxyAgent(proxy);
opts.agent = agent;
https.get(opts, function (res) {
  console.log('"response" event!', res.headers);
  res.pipe(process.stdout);
});

实际请求是在端口80上进行的,因此Google拒绝了它。以下是HTTP标头:

["Proxy-Authorization: Basic Xgat28sa78saBZZ \r\n", "Host: www.google.com:80\r\n", "Connection: close\r\n"]

修补版本上的相同示例正确连接到端口443并且可以正常工作:

https://github.com/TooTallNate/node-https-proxy-agent/compare/master...timrwilliams:master

我怀疑上游发生了一些变化,导致错误的端口被传递给https-proxy-agent,但Github issues更恰当地讨论了这类问题。

快速修复将转而使用请求库:

var request = require('request');

var options = {
    proxy: process.env.QUOTAGUARDSTATIC_URL,
    url: 'https://www.google.com/',
    headers: {
        'User-Agent': 'node.js'
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);