web-dev-qa-db-ja.com

プロキシ経由のNode.jshttps.getは、SSL3_GET_RECORDの間違ったバージョン番号エラーを生成します

TLDR

会社のプロキシ経由でhttps.requestを使用してgithubからZipファイルをダウンロードしようとすると、次のエラーが発生します。

Casper.JS 140735122252160:error: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とノードを更新しました
  • 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);
});

元のコード

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);
    }
}
13
foiseworth

このエラーは、squid(プロキシ)でhttpsが有効になっていないか、間違ったポートに接続している場合に発生するようです。

ソース: https://github.com/joyent/node/issues/6779

8
foiseworth

上記の解決策はどれも私にはうまくいきませんでしたが、https-proxyURLをhttpSURLからhttpURLに更新することで問題を解決することができました

12
Ampp3

これは、Requestモジュール(npm install request)を使用して可能になるはずです。以下は、HTTPプロキシを介した標準のHTTPSリクエストで機能します。 HTTPSリクエストをエンドサーバー(この例ではGithub)にトンネリングしているため、プロキシもHTTPSである必要があるかどうかはわかりません。

var request = require('request');

var proxy = 'http://username:password@IP:port';
var downloadUrl = 'https://codeload.github.com/n1k0/casperjs/Zip/1.0.3'
var options = {
    proxy: proxy,
    url: downloadUrl
};

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

}

request(options, callback);
0
Tim Williams