Node.js https.get通过代理生成SSL3_GET_RECORD错误的版本号错误

foi*_*rth 9 ssl https proxy openssl node.js

TLDR

尝试通过我的公司代理使用https.request从github下载zip文件时出现以下错误:

尝试下载Casper.JS时发生错误140735122252160:错误:1408F10B:SSL例程:SSL3_GET_RECORD:错误的版本号:../ deps/openssl/openssl/ssl/s3_pkt.c:337:

更多信息

我正在尝试编辑grunt-casperjs安装脚本,以允许我和我的同事安装在我们的代理后面.该脚本从Github获取Casper并下载它.最初脚本不支持代理,所以我复制了grunt-phantomjs代理支持.Phantomjs通过http连接下载,这可以通过我们的代理工作正常(如果我将其更改为https URL,它会失败并出现相同的错误).

我尝试过以下方法:

  • 我添加了https.globalAgent.options.secureProtocol ='SSLv3_method'; 如前所述,显示未知的协议错误.
  • 使用curl,请求完成正常
  • 更新了OpenSSL和Node
  • 我添加了https.globalAgent.options.secureOptions ='SSL_OP_NO_TLSv1'; 但这会导致节点在请求发出后返回而没有消息

减少测试用例

var https = require('https');
https.globalAgent.options.secureProtocol = 'SSLv3_method'

var url = require('url');
var downloadUrl = 'https://codeload.github.com/n1k0/casperjs/zip/1.0.3'
var proxy = 'https://username:password@IP:port';

var options = url.parse(proxy);
options.path = downloadUrl;
options.headers = { Host: url.parse(downloadUrl).host }
// If going through proxy, spoof the User-Agent, since may commercial proxies block blank or unknown agents in headers
options.headers['User-Agent'] = 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5'
// Turn basic authorization into proxy-authorization.
options.headers['Proxy-Authorization'] = 'Basic ' + new Buffer(options.auth).toString('base64');
delete options.auth;

var request = https.get(options, function(response) {
    console.log('response received');
}).on('error', function(e) {
    console.log('An error occurred whilst trying to download Casper.JS ' + e.message);
});
Run Code Online (Sandbox Code Playgroud)

原始代码

function downloadZipFromGithub() {
    var file = fs.createWriteStream(path.join(tmpPath, "archive.zip"));
    var lengthSoFar = 0;
    var npmconfDeferred = kew.defer();
    npmconf.load(npmconfDeferred.makeNodeResolver());

    npmconfDeferred.then(function(conf){
        var requestOptions = getRequestOptions(conf.get('https-proxy'));

        https.globalAgent.options.secureProtocol = 'SSLv3_method';

        var request = https.get(requestOptions, function(response) {
            if (response.statusCode === 301 || response.statusCode === 302) {
                downloadUrl = response.headers.location;
                downloadZipFromGithub();
            } else {
                response.pipe(file);
                response.on('data', function(chunk) {
                    console.log('Receiving ' + Math.floor((lengthSoFar += chunk.length) / 1024) + 'K...' );
                }).
                    on('end', unzipTheZippedFile).
                    on('error', function(e) {
                        console.log('An error occured whilst trying to download Casper.JS ' + e.message);
                        tidyUp();
                    });
            }
         }).on('error', function(e) {
            console.log('An error occured whilst trying to download Casper.JS ' + e.message);
            tidyUp();
        });
     });
 }

function getRequestOptions(proxyUrl) {
    if (proxyUrl) {
        var options = url.parse(proxyUrl);
        options.path = downloadUrl;
        options.headers = { Host: url.parse(downloadUrl).host }
        // If going through proxy, spoof the User-Agent, since may commerical proxies block blank or unknown agents in headers
       options.headers['User-Agent'] = 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5'
        // Turn basic authorization into proxy-authorization.
        if (options.auth) {
            options.headers['Proxy-Authorization'] = 'Basic ' + new Buffer(options.auth).toString('base64');
            delete options.auth;
        }

        return options;
    } else {
        return url.parse(downloadUrl);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 9

上面的解决方案都不适合我,但是我能够通过将https-proxy URL从httpS URL更新为http URL来解决我的问题


foi*_*rth 7

当squid(代理)未启用https或您连接到错误的端口时,可能导致此错误。

来源:https : //github.com/joyent/node/issues/6779