Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for http and https in the same app? #17

Open
amitkumar opened this issue Mar 29, 2013 · 7 comments
Open

Support for http and https in the same app? #17

amitkumar opened this issue Mar 29, 2013 · 7 comments

Comments

@amitkumar
Copy link

I have an Express app that handles both http and https requests. The Express 3.0 examples suggest using explicit http and https server objects to accomplish this, rather than using app.listen(). Express.io doesn't seem to support that, so when I attempted to integrate express.io, I tried out the following code:

var app =  require('express.io')(),
      fs = require('fs')
      httpsOptions = {
        key: fs.readFileSync('server.key'),
        cert: fs.readFileSync('server.crt')
      }; 

app.http().io();
app.https(httpsOptions).io(); 

app.listen(process.env.PORT || 80, function(){});
app.listen(443, function(){});

My app now responds to http requests, but with https it returns Error 102 (net::ERR_CONNECTION_REFUSED): The server refused the connection. Thanks for any help!

@techpines
Copy link
Owner

@amitkumar I'm working on a better syntax for this. And i'm open to any suggestions. But here is how you can get your code to work:

var express =  require('express.io'),
fs = require('fs');
var app = express();
httpsOptions = {
   key: fs.readFileSync('./server.key'),
   cert: fs.readFileSync('./server.crt')
};

app.http().io();
httpsServer = require('https').createServer(httpsOptions, app);

app.listen(process.env.PORT || 80, function(){});
express.io.listen(httpsServer);
httpsServer.listen(443, function(){});

I always thought it was kind of strange to run http and https for the same app, what is your use case? I usually just setup a redirect from http to https.

Cheers!

@amitkumar
Copy link
Author

@techpines 2 reasons: One, I'm developing a Heroku app. When it's on Heroku, the app only listens on http since Heroku's proxy hides the https handling. My redirection handler has a special case when deployed to Heroku to check x-forwarded-proto rather than req.secure. When I'm developing locally however, my app uses https.

The other reason is I have Arduino-based devices that need to talk to my API, and Arduinos aren't really able to handle the load of https encryption. So I have them using HMAC-based auth over regular http instead.

Thanks for the help! I actually went ahead and implemented regular socket.io in my app, but I'll try this out soon.

@techpines
Copy link
Owner

@amitkumar Cool, thanks for the update.

If you think about your code that you posted earlier, it is somewhat ambigiuous as to which port a particular server would bind to on listen.

I was thinking that maybe a better solution would be something like this:

app.http({
    io: true, // enable websockets, probably defaults true
    port: 80 // specify the port here instead
});

app.https({
    io: true,
    port: [443, 449] // support for multiple ports.
    key: 'some-key',
    cert: 'some-cert'
});

app.listen(function(error, port) {
    // This would get called multiple times for each port.
});

I think a clean syntax is possible. But this would be breaking with my current implentation, so I would probably need to do a major version bump.

If anyone else has an opinion on this, please drop a note on this thread.

@bpytlik
Copy link

bpytlik commented May 13, 2013

@techpines I like the proposed new syntax. I think it makes things much clearer as to what's going on. You might also consider a very minor variation like:

app.setup({
    http: {
        io: true,
        port: 80
    },
    https: {
        ...
    }
)

app.listen(...)

which would provide a single interface for setting up both http and https.

@maxkueng
Copy link

Another interesting way would be to pass an object to the listen function, since this is where the port is currently specified anyway. You could get rid of app.http() or app.https().

var express = require('express.io'),
    app = express().io(); // no http() or https()

app.get('/', ... );
app.io.route( ... );

app.listen({
    http: {
        io : true,
        por t: 80
    },
    https: {
        ...
    }
})

I'd also love to see an easy way enable both HTTP and HTTPS. This is a really cool project, btw. Thanks!

@KevinRausch
Copy link

I'm in favor of @maxkueng's method. This separates the application from the connection protocol. Additionally, I think it would be helpful to use the app.listen(options) to specify a socket.io port if desired, as well as any other options that could be passed to http[s].server.listen().

var express = require('express.io'),
    app = express().io();

app.get( ... );
app.io.route( ... );

app.listen({
  http: {
    port: 80,
    io: 8080,
    hostname: [hostname],
    callback: function(){}
  },
  https: {
    key: fs.readFileSync('./key'),
    cert: fs.readFileSync('./cert'),
    ...
  }
})

@benkaiser
Copy link

Any progress with this issue?

Are any of the suggested better ways of handling http and https going to be implemented?

Also I found that if I setup the server with express on http and created the https server later I ran into issues with the client-side of socket.io not properly emitting messages to the server even after connection (it dropped to XHR polling and things like that, but messages weren't getting through). To fix this I made it so that the server is created as https and then later creates a mirroring http server. The equivalent of the first suggested code being like this:

var express =  require('express.io'),
fs = require('fs');
var app = express();
httpsOptions = {
   key: fs.readFileSync('./server.key'),
   cert: fs.readFileSync('./server.crt')
};

app.https(httpsOptions).io();
httpServer = require('http').createServer(app);

app.listen(443);
express.io.listen(httpServer);
httpServer.listen(process.env.PORT || 80, function(){}, function(){});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants