How can I bind http and https in one node server - node.js

I have a chatting application using node.js server, Few days back we moved from http to https server, Where https server is working fine on web but not on native app, so for this we have created new http server with different port number.
Now I have two node socket.io server, one is http who is working on port 3000(for mobile client) and another one is https who is working on 3001 port(for web client), both the server has a same code, but now I am not able to make communication between native and web user.
So is it possible for node server to listen HTTP and HTTPS request simultaneously on a same port.
or
Is there any way through which I can send HTTp server request to HTTPS server ?
Below is the code for HTTP server
var app = require('http').createServer(handler),
io =require('socket.io').listen(app);
var querystring = require('querystring');
var http=require('http');
var fs = require('fs');
var webservice_host="xxxxxxxxxxxx.com";
var port = process.argv[2] || 3000;
var authKey="";

I'm not sure if you can get the http and https servers to listen simultaneously on the same port and accept only its protocol.
Is there any way through which I can send HTTp server request to HTTPS server ?
Yes, check out this question that explains how to create an HTTP -> HTTPS proxy. How to use node-http-proxy for HTTP to HTTPS routing?

Related

Creating A HTTP proxy server with https support and use another proxy server to serve the response using nodejs

I need help creating a proxy server using node js to use with firefox.
the end goal is to create a proxy server that will tunnel the traffic through another proxy server (HTTP/SOCKS) and return the response back to firefox. like this
I wanna keep the original response received from the proxy server and also wanna support https websites as well.
Here is the code I came up with.
var http = require('http');
var request = require("request");
http.createServer(function(req, res){
const resu = request(req.url, {
// I wanna Fetch the proxy From database and use it here
proxy: "<Proxy URL>"
})
req.pipe(resu);
resu.pipe(res);
}).listen(8080);
But it has 2 problems.
It does not support https requests.
It also does not supports SOCKS 4/5 proxies.
EDIT: I tried to create a proxy server using this module. https://github.com/http-party/node-http-proxy
but the problem is we cannot specify any external proxy server to send connections through.
I have found a really super simple solution to the problem. We can just forward all packets as it is to the proxy server. and still can handle the server logic with ease.
var net = require('net');
const server = net.createServer()
server.on('connection', function(socket){
var laddr = socket.remoteAddress;
console.log(laddr)
var to = net.createConnection({
host: "<Proxy IP>",
port: <Proxy Port>
});
socket.pipe(to);
to.pipe(socket);
});
server.listen(3000, "0.0.0.0");
You have to use some middleware like http-proxy module.
Documentation here: https://www.npmjs.com/package/http-proxy
Install it using npm install node-http-proxy
This might help too: How to create a simple http proxy in node.js?

What is best practice node.js recommended port in production environment?

I have created a chat app in node.js using port 4000. Everything works just fine, but when I rolled it out in production, I found that many corporate networks block outgoing port 4000. I considered using other ports that would be more likely to be open on a corporate network, but then found this list of ports blocked by chrome browser:
https://superuser.com/questions/188058/which-ports-are-considered-unsafe-by-chrome
Using ports such as 995 would result in a chrome error of "ERR_UNSAFE_PORT"
So it appears that the only ports allowed are 80 and 443 for a node.js server? What is the recommended best practice for choosing a port for your node.js application in a production environment?
My webserver is already using ports 80 and 443 for typical apache web serving. Do I need to create a dedicated server just for node.js?
I am using the following code to initiate the connection from the browser to the node.js server:
var socket = io.connect('https://duplex.example.com:4000');
and here is the code on the server side:
const https = require('https');
const fs = require('fs');
var express = require('express')
, bodyParser = require('body-parser');
var socket = require('socket.io');
var adminid = '';
var clientlist = new Array();
var port = 4000;
const options = {
cert: fs.readFileSync('./fullchain.pem'),
key: fs.readFileSync('./privkey.pem')
};
var app = express();
var server = https.createServer(options, app).listen(port, function(){
console.log("Express server listening on port " + port);
});
443 and 80 are the main ports for https and HTTP traffic respectively.
other ports can be used for WebSockets, but that doesn't sound like your use case.
What I have done in the past is use a reverse proxy, to discriminate on the incoming URL, and map the ports internally on my machine without the client needing to know.
NGINX is usually the easiest bet for this if you are on any sort of linux distro.
here is a blog about how to setup reverse proxy for a node app using nginx.
http://thejonarnold.com/configure-sails-js-with-subdomains-on-ubuntu/
the article references sailsjs, but there is nothing framework specific about the techique.
Most people don't expose their Node.js server directly to the internet but use Apache or Nginx as a frontend proxy.
Have your server bind to localhost only (or use firewall rules to only allow incoming 80 and 443.
server.listen('localhost', 4000)
Configure your reverse proxy. I'm using Caddy:
example.com {
root /var/www/example.com
# et cetera
}
duplex.example.com {
proxy / localhost:4000 {
websocket
}
}
When proxying websocket, you need to ensure the Connection and Upgrade headers aren't lost, which I've done with Caddy's shortcut here.
You could also use the same domain as the main site and only proxy a certain path.
Have the client socket.io connect to wss://duplex.example.com (on port 443). (I'm not familiar with socket.io to say why it uses an HTTPS URL instead of WSS, but I'll assume you have that working.)

NodeJS: write http response with JavaScript content

I have a server running on port 5000 and users don’t have access to this port.
I started another node server on 4000 and want to read the http content (localhost:5000/test) (content has javascripts) and users should see it on the browser by accessing port localhost:4000/test
Something like http content forward not the URL forward.
Any examples? Thanks in advance
For this problem, I would recommend using a proxy such as https://github.com/nodejitsu/node-http-proxyThe code that you would need to implement on your server on port 4000 should look something like this:
const http = require('http'),
httpProxy = require('http-proxy');
//
// Create your proxy server and set the target in the options.
//
httpProxy.createProxyServer({target:'http://localhost:5000'}).listen(4000);

http server and web sockets from separate servers

It's pretty easy to configure a http server (using express) and a socket server (socket.io) assigned to it:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
How can I run http server and socket server in two different node.js instances?
My idea is to leverage the performance this way, releasing the http node instance from the responsibility of also sending notifications back to the clients.
In a regular Socket.IO + Express app, Socket.IO intercepts requests starting with /socket.io/.
You may set Nginx (or any other webserver that supports proxying) listening 80 port, and make it proxy to Socket.IO process if request starts with /socket.io/, and to Express process otherwise.
Edit: To set up Socket.IO in separate process you may use the following code:
var io = require('socket.io')();
io.on('connection', function(socket){
//here you can emit and listen messages
});
io.listen(3000);

Serving socket.io through SSL

I'd like to implement ssl in all of my projects. One of them is using socket.io.
My code to create the socket:
var server = require('http');
var app = server.createServer(function(request, response) {
response.end();
});
var io = require('socket.io').listen(app);
app.listen(8000);
I can't bind node.js / socket.io to ssl port cause it's already in use by my webserver (cherokee). Therefore i can't serve the client using https.
Any ideas how to solve this problem?
You can only bind one application to a port. Since your web server is already bound to port 443, you have two choices:
Run the web server like you are now and proxy the node.js stuff running on port 8000:
http://www.cherokee-project.com/doc/modules_handlers_proxy.html
Run node.js on that port, change the port of the web server and proxy the web server using node.js: https://github.com/nodejitsu/node-http-proxy

Resources