Nodejs v0.10.x(freebsd)“X509_STORE_add_cert:cert已经在哈希表中”

我正在使用asynchronousWeb API,并且在nodejs版本比v0.8.9高

$ uname -a FreeBSD home 9.1-STABLE FreeBSD 9.1-STABLE#0:Fri Feb 1 10:38:27 EET 2013 root @ home:/ usr / obj / usr / src / sys / HOME amd64

$ node -v v0.10.0

$ node ./client.js

events.js:72 throw er; // Unhandled 'error' event ^ Error: 34401711104:error:0B07C065:x509 certificate routines:X509_STORE_add_cert:cert already in hash table:../deps/openssl/openssl/crypto/x509/x509_lu.c:357: 34401711104:error:0B07C065:x509 certificate routines:X509_STORE_add_cert:cert already in hash table:../deps/openssl/openssl/crypto/x509/x509_lu.c:357: at SlabBuffer.use (tls.js:221:18) at CleartextStream.read [as _read] (tls.js:408:29) at CleartextStream.Readable.read (_stream_readable.js:293:10) at tls.js:465:12 at process._tickCallback (node.js:415:13) 

代码(client.js):

 var fs = require('fs'); var https = require('https'); var agent = require('agent').agent; var config={ host: 'sample.host.com', port: 443, path: '/worker.do', pfx: fs.readFileSync('./client.pfx'), passphrase: "passwordHere" }; config.agent = new https.Agent({ pfx: config.pfx, passphrase: config.passphrase }); agent.config=config; agent.makeRequest([{request:"search",query:"*"}],function(data){ if(!data.success){ console.log(data.error); return; } var items=[]; for(var item in data.data){ items.push(data.data[item][0]); } agent.makeRequest([{"request":"update","group":true,"arr":JSON.stringify(items)}],function(data){ if(!data.success){ console.log(data.error); return; } console.log('Done: '+data.result); }); }); 

代码(agent.js):

 var https = require('https'); var agent={ config: {}, getId: function() { return this.id || (this.id = new Date().getTime()); }, makeRequest: function(params,callback){ var options = { host: this.config.host, port: this.config.port, path: '/worker.do', method: 'POST', agent: this.config.agent }; var that=this; var req = https.request(options, function(res) { if(res.statusCode!='200'){ callback({ success: false, error: res.statusCode }); return; } var body=''; res.on('data', function(data) { body+=data.toString(); }); res.on('end', function(){ try { body=JSON.parse(body); } catch(e) { callback({ success: false, error: '[makeRequest] Cant parse body: '+body }); } var reqId=body[0]; that.getContent(reqId,callback); }); }); req.on('error', function(e) { callback({ success: false, error: e }); }); req.end(JSON.stringify(params)+'\n\n'); }, getContent: function(reqId,callback){ var options = { path: '/worker.do?_dc='+this.getId(), method: 'GET', host: this.config.host, port: this.config.port, agent: this.config.agent }; var req = https.request(options, function(res) { if(res.statusCode!='200'){ callback({ success: false, error: res.statusCode }); return; } var body=''; res.on('data', function(data) { body+=data.toString(); }); res.on('end', function(){ try { body=JSON.parse(body); } catch(e) { callback({ success: false, error: '[getContent] Cant parse body: '+body }); } callback(body[reqId]); }); }); req.on('error', function(e) { callback({ success: false, error: e }); }); req.end(); } } exports.agent=agent; 

在nodejs v0.6.x和v0.8.x上它是完美的。 在v0.10.x上 – 失败。 请帮忙find问题。

解决scheme是隔离您的PEM并逐一添加,而不是捆绑。 在最低的叶子,然后是父母,然后是父母等,每次testing。

请参阅https://github.com/iojs/io.js/issues/712

我认为这一定是node.js / io.js内部的一个bug,在第一次使用的时候,重复的cert不会被检查。

奇怪的是,为特定的https服务器实例添加一个证书链可能会导致一个不相关的https请求(应该使用默认链,而不是与https服务器有关)。