NodeJS: write http response with JavaScript content - node.js

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);

Related

Nodejs SSL using CloudFlare not working over https

So the problem I'm having is that the client won't connect with the server.js when the server.js is using https.
if I go to "https://mydomainame.com" I get this error in the console of every other browser than brave browser
index.js:83 GET https://serverip:8081/socket.io/?EIO=3&transport=polling&t=NK0oCD6 net::ERR_CERT_AUTHORITY_INVALID
(The blacked out is the IP address of the server)
the weird thing is that in the brave browser the domain changes to "http://mydomainame.com" and the client then is connected to server.js
I'm using free Cloudflare with Full end to end encryption
server.js code:
var express = require('express'),
https = require('https');
var app = express();
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('/var/www/ssl/sitename.com.key'),
cert: fs.readFileSync('/var/www/ssl/sitename.com.pem')};
var server = https.createServer(httpsOptions,app);
var io = require('socket.io').listen(server);
const port = 8081;
server.listen(port);
And client.js connection code:
socket = io.connect('https://serverip:8081', {secure: true});
I am using the same Origin Certificates for the server and for the nodejs code.
The server is using Apache2 with PHPMyAdmin and is configured to make the domain only work using https.
I read somewhere something Cloudflare not being able to use other ports than 443 and some other but I did not really understand it, And I can't get the server.js to work over port 443.
I'm thankful for any information or help I can get! :)
So I figured it out, big thanks to Eric Wong for pointing out the biggest problem that I was trying to connect to the server using its IP there for not going thru Cloudflare.
Then in this article Identifying network ports compatible with Cloudflare's proxy
you can see what ports Cloudflare allows connections on then, I changed my code to used the https port 8443.
socket = io.connect('https://domainname.com:8443',{secure: true});
then the only thing I had to do was to port forward the new port and everything worked fine!

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.)

Node.js server for Socket.IO explanation?

I have the following code:
express = require('express');
app = express();
http = require('http').createServer(app);
io = require('socket.io')(http);
app.use(express.static(__dirname + '/'));
http.listen(80);
I know it creates a server that clients can connect to and it works. But I don't know what exactly happens. Can you explain in detail?
Also, why things don't work when I forget about Express.js and just use this line:
io = require('socket.io').listen(80);
It appears to listen for connections. However, inside the browser when I go to http://localhost/, nothing happens. My guess is that I don't specify the directory for my app like that:
app.use(express.static(__dirname + '/'));
Is that why I need Express? To specify the directory?
At the client, I use:
socket = io('http://localhost/'); // this
socket = io(); // or this
None of them work with the single line code at the server-side.
Also, why do I need an HTTP server when Socket.IO uses the WebSocket protocol?
When your browser goes to http://localhost/, you need a web server that's going to respond back to the browser with a web page. That's what Express and the express.static() lines were doing. When you remove those, you do indeed have a server listening for webSocket connections on a specific path, but you don't have anything serving web pages. So, when the browser goes to http://localhost/, there's nothing responding back with a plain web page.
Also, why do I need an HTTP server when Socket.IO uses the WebSocket
protocol?
All socket.io connections start with an HTTP request. socket.io is based on the webSocket protocol and all webSocket connections are initiated with an HTTP request. So, to accept a socket.io connection, you need a web server that responds to an HTTP request and you then need a web server that is smart enough to recognize a request for a webSocket connection so it can "upgrade" the protocol from HTTP to webSocket.
For a well written overview of how a webSocket connection is established, see this overview on MDN.
The socket.io infrastructure then runs on top of that webSocket once it is connected.
I know it creates a server that clients can connect to and it works.
But I don't know what exactly happens. Can you explain in detail?
Here's a line-by-line explanation of your code:
express = require('express');
This loads the Express library.
app = express();
This creates an Express app object which can be used as a webServer request handler.
http = require('http').createServer(app);
This creates a web server and passes it the Express app object as the webServer request handler.
io = require('socket.io')(http);
This hooks socket.io into your web server as another request handler so it can see any incoming http requests that are actually the first stage of starting a webSocket/socket.io connection.
app.use(express.static(__dirname + '/'));
This tells Express that if any request is made for a web page that it should look in the __dirname for a file that matches the requested path. If found, it should return that path.
http.listen(80);
This starts the web server listening on port 80.
None of them work with the single line code at the server-side.
Both of those lines of code to create a socket.io connection will work when used properly. You don't say how this code is being run. If you're trying to run this code from a web page that the browser loads from http://localhost/, then I've already explained why that web page won't load if you don't start Express. If you're trying to run those lines of code from a web page loaded some other way, then you're probably having a same-origin security issue were the browser by default won't let you access a domain that is different than the one the web page came from.
You need the express http server to deliver the socket client to the browser.
Express server starts on port 80
Browser connects to express on port 80, the socket.io server component delivers socket client javascript to the browser (http://localhost:80/socket.io/socket.io.js)
Socket client (running in browser) can then connect to socket.io server

How can I bind http and https in one node server

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?

Resources