2016-04-06 86 views
1

我在Cody-CMS中使用Express +虛擬主機,現在有一段時間在多個主機上使用了nodejs。現在我想包含虛擬https服務器。Express與多個證書/虛擬主機

SNICallback被調用,但它在那裏結束......我的Express應用程序「exp」永遠不會被調用(即使我用一個簡單的函數在註釋中將其替換爲createServer)。我收到「site1.com」(或site2.com)的請求,但沒有任何內容返回給瀏覽器。

對於http服務器來說它是完美的。

任何幫助,歡迎。

"use strict"; 

var express = require("express"); 
var vhost = require("vhost"); 
var fs = require("fs"); 


var app1 = express(); 
app1.all("/", function(req, res) { 
    res.send('Hello World, site #1'); 
}); 

var app2 = express(); 
app2.all("/", function(req, res) { 
    res.send('Hello World, site #2'); 
}); 


////////////////// 
// certificates // 
////////////////// 
var crypto = require('crypto'); 

const site1 = { 
    app: app1, 
    context: crypto.createCredentials({ 
    key: fs.readFileSync('ws.key').toString(), 
    cert: fs.readFileSync('ws.crt').toString() 
    }).context 

}; 
const site2 = { 
    app: app2, 
    context: crypto.createCredentials({ 
    key: fs.readFileSync('ws2.key').toString(), 
    cert: fs.readFileSync('ws2.crt').toString() 
    }).context 
}; 

var sites = { 
    "www.site1.com": site1, 
    "site1.com": site1, 

    "www.site2.com": site2, 
    "site2.com": site2 
}; 

// put (www.)site1/2.com in /etc/hosts to 127.0.0.1 



////////// 
// http // 
////////// 

var exp = express(); 
for (let s in sites) { 
    console.log("http -> " + s); 
    exp.use(vhost(s, sites[s].app)); 
} 

exp.listen(80, function() { 
    console.log("Listening https on port: 80") 
}); 


/////////// 
// https // 
/////////// 

var secureOpts = { 
    SNICallback: function (domain) { 
    console.log('request for: ', domain); 
    return sites[domain].context; 
    }, 
    key: fs.readFileSync('ws.key').toString(), 
    cert: fs.readFileSync('ws.crt').toString() 
}; 


var https = require('https'); 
var httpsServer = https.createServer(secureOpts, exp); 
// var httpsServer = https.createServer(secureOpts, function(req, resp) { resp.send("hello"); }); 

httpsServer.listen(443, function() { 
    console.log("Listening https on port: 443") 
}); 

回答

1

SNICallback有第二個參數:cbcb的簽名爲(error, context)。所以你的secureOpts應該看起來像:

var secureOpts = { 
    SNICallback: function(domain, cb) { 
    console.log('request for: ', domain); 
    cb(null, sites[domain].context); 
    }, 
    key: fs.readFileSync('ws.key').toString(), 
    cert: fs.readFileSync('ws.crt').toString() 
}; 
+0

謝謝!作品完美。 – Johan

+0

當我收到一個我沒有證書的域名時,我應該怎麼做? – Johan

+0

您可以像第一個例子那樣,將錯誤對象傳遞給'cb'作爲第一個參數,而不是'null'。 – mscdex