Listen on HTTP and HTTPS for a single express app

2019-01-10 18:28发布

问题:

Can I create an Express server listening on both HTTP and HTTPS, with the same routes and the same middlewares?

Currently I do this with Express on HTTP, with stunnel tunneling HTTPS to Express, but I prefer a pure Node solution.

I can do it with this code, but using the handle method that is marked as private:

var express = require( 'express' )
    , https = require("https")
    , fs = require( 'fs' );

var app = express.createServer();
// init routes and middlewares
app.listen( 80 );

var privateKey = fs.readFileSync( 'privatekey.pem' ).toString();
var certificate = fs.readFileSync( 'certificate.pem' ).toString();
var options = {key: privateKey, cert: certificate};
https.createServer( options, function(req,res)
{
    app.handle( req, res );
} ).listen( 443 );

回答1:

You can share the implementation via something like:

var register = function (app) {
    // config middleware
    app.configure({

    });

    // config routes
    app.get(...);
};

var http = express.createServer();
register(http);
http.listen(80);

var https = express.createServer({ key: /* https properties */ });
register(https);
https.listen(443);


回答2:

As a possible update to this question, you might want to check out the changes here for express 3. The change document says:

The return value of express() is a JavaScript Function, encapsulating everything that makes an Express app tick. This means you can easily setup HTTP and HTTPS versions of your application by passing it to node's http.createServer() and https.createServer():

In Express 3, express.createServer() is now express()

Here is a complete example for express 3:

var fs = require('fs')
    , https = require('https')
    , http = require('http')
    , express = require('express')
    , keys_dir = 'keys/'
    , server_options = {
        key  : fs.readFileSync(keys_dir + 'privatekey.pem'),
        ca   : fs.readFileSync(keys_dir + 'certauthority.pem'),
        cert : fs.readFileSync(keys_dir + 'certificate.pem')
      }
    , app = express();
app.configure(function(){
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.session( { secret: '' } ));
  app.use(app.router);
});
app.configure('development',function(){
  app.use(express.static(__dirname + '/public'));
  app.use(express.errorHandler({dumpExceptions: true, showStack:true}));
  app.set('view options', { pretty: true });
});
app.get('/', function(req, res){
  res.send('Hello World!');
});
https.createServer(server_options,app).listen(7000);
http.createServer(app).listen(8000);


回答3:

To enable your app to listen for both http and https on ports 80 and 443 respectively, do the following

Create an express app:

var express = require('express');
var app = express();

The app returned by express() is a JavaScript function. It can be be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app using the same code base.

You can do so as follows:

var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();

var options = {
  key: fs.readFileSync('/path/to/key.pem'),
  cert: fs.readFileSync('/path/to/cert.pem')
};

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

For complete detail see the doc



回答4:

Similar post

Can I configure expressjs to serve some pages over http and others over https?

Be aware that express now support creating Https servers with:

 var app = require('express').createServer({ key: ... });