简体   繁体   中英

Variable HTTP/HTTPS Express Server

I'm sure this is just a simple Javascript scoping issue (go figure), but I've tried several different ways and can't seem to get this to work.

The idea is that the Express.js server defaults to HTTP with the call to express.createServer(), but optionally switches to HTTPS upon detection of ./conf/cert.pem and ./conf/key.pem . I'm using asynchronous calls to Node's path.exists() , whereby the second callback argument contains the boolean result.

I have them nested currently so that a HTTPS server isn't created until it's "safe" (we know the outcome of whether the two files exist or not) since no ordering is guaranteed otherwise. However, as I mentioned, I've tried several different ways, but I can't seem to modify the outer app variable.

I'm sure there's a simple fix that I'm not seeing right now, but any help would be appreciated!

app = module.exports = express.createServer();

path.exists('./conf/key.pem', function(exists){
    var keyExists = exists;
    path.exists('./conf/cert.pem', function(exists) {
        var certExists = exists;
        if (keyExists && certExists) {
             app = express.createServer({
                key: fs.readFileSync('./conf/key.pem'),
                cert: fs.readFileSync('./conf/cert.pem')
              });
         }
    });
});

This is not ideal. You shouldn't create a regular http server only to have it overwritten by an https server. I think the problem you're referring to comes from the fact that you're setting the app variable below, but not module.exports . So module.exports still refers to the original server created. This is what you should do:

var app = express.createServer({
  key: fs.readFileSync('./conf/key.pem'),
  cert: fs.readFileSync('./conf/cert.pem')
});
module.exports = app;

There's no reason to check whether the files exist first. If the files don't exist, readFileSync will just throw an ENOENT. There is also no reason to do anything asynchronously before you have even entered the event loop.

I don't know why you would want your server to conditionally be https, but to do something similiar to what you were trying to do there:

var app;
try {
  app = express.createServer({
    key: fs.readFileSync('./conf/key.pem'),
    cert: fs.readFileSync('./conf/cert.pem')
  });
} catch(e) {
  if (e.code !== 'ENOENT') throw e;
  app = express.createServer();
}
module.exports = app;

Or, this might look nicer:

var app;
if (path.existsSync('./conf/key.pem')) {
  app = express.createServer({
    key: fs.readFileSync('./conf/key.pem'),
    cert: fs.readFileSync('./conf/cert.pem')
  });
} else {
  app = express.createServer();
}
module.exports = app;

Remember, doing things synchronously is fine as long as you don't have to serve a million requests at the same time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM