I have a web app built with PHP on IIS as backend and Node.JS socket.io for realtime communication, however I need to run both app (IIS and Node.JS) on a same port (443) to secure both connection, so im creating reverse proxy like this :
var httpProxy = require('http-proxy');
proxy = httpProxy.createProxyServer({}),
url = require('url');
http = require('http');
http.createServer(function(req, res) {
var hostname = req.headers.host.split(":")[0];
var pathname = url.parse(req.url).pathname;
if(pathname == '/realtime_script')
proxy.web(req, res, { target: 'http://localhost:8000/socket.io/socket.io.js' });
else if(pathname.indexOf("/socket.io") > -1)
proxy.web(req, res, { target: 'http://localhost:8000'+req.url });
else
proxy.web(req, res, { target: 'http://localhost:8080' });
}).listen(80, function() {
console.log('proxy listening on port 9000');
});
I set socket.io to listen to port 8000 and IIS bind to port 8080, I managed to access home page using http://localhost, everything loads and connected perfectly (including socket.io), however every time a redirect happened (e.g submitting form or clicking a link), the node js crashed with this message :
C:\inetpub\wwwroot\node\node_modules\http-proxy\lib\http-proxy\index.js:119
throw err;
^Error: socket hang up
at createHangUpError (http.js:1472:15)
at Socket.socketCloseListener (http.js:1522:23)
at Socket.emit (events.js:95:17)
at TCP.close (net.js:465:12)
anybody can tell me what's wrong here?
Thank you
Related
I have a cpanel where Apache is activated and displaying my website on port 80,443 https://mydomain.io
The below setup works on port 80 but not on other ports like if I want to run this at Port 8070
I want to run nodejs on port 8070 i.e http://IP:8070
SERVER SIDE
server.js
var compression = require('compression');
var _ = require('lodash');
var express = require('express');
var server = express();
var app = require('http').createServer(server);
var io = module.exports.io = require('socket.io')(app);
server.use(compression());
app.get('/', (req, res) => {
res.sendFile(__dirname + '/tester.html');
});
app.listen(8070, function(){
console.log('listening on *:' + 8070);
});
Now when I open this IP:8070 this renders the HTML and it connects to sockets
WORKING
console.log(io.connect());
But I want to access it via mydomain.io
so If I try to go to mydomain.io/tester.html or a file locally on my pc
It doesn't connect to sockets
//NONE OF THESE WORKING!
WITH HTTP GETTING ERR:
console.log(io.connect('http://mydomain.io:8070/', { transports: ["websocket"]}));
console.log(io.connect('http://localhost:8070/', { transports: ["websocket"]}));
console.log(io.connect('http://localhost/', { transports: ["websocket"]}));
console.log(io.connect('http://mydomain.io/', { transports: ["websocket"]}));
console.log(io.connect());
GETTIG ERR: Mixed Content: The page at '<URL>' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws:<URL>/socket.io/?EIO=3&transport=websocket'. This request has been blocked; this endpoint must be available over WSS.
WITH HTTPS NOT WORKING
console.log(io.connect('https://mydomain.io:8070/', { transports: ["websocket"]}));
console.log(io.connect('https://localhost:8070/', { transports: ["websocket"]}));
console.log(io.connect('https://localhost/', { transports: ["websocket"]}));
console.log(io.connect('https://mydomain.io/', { transports: ["websocket"]}));
WITH PORT 80 ITS WORKING BUT NOT ON ELSE
BUT if I run my server.js at port 80 and stopping apache using service httpd stop
then it works with mydomain.io/tester.html or a file locally on my pc
var socket = io.connect('wss://mydomain.io'); //Socket Address WOKRING
Yes, Thank you #v1shva, trying https.createserver instead of http createserver with my cpanel keys and cert file I am able to connect with this from anywhere.
Thank You
I wrote a simple node express server for webRTC using peerjs-server and simple client using peerjs. Everything works fine on localhost, but when I try it on vps, I get error:
Firefox can't connect with server ws://my.vps/peerjs/peerjs?key=peerjs&id=hj3hpekwaa38fr00&token=ymtfvhagiw
PeerJS: Socket closed.
PeerJS: ERROR Error: Lost connection to server.
Error: "Lost connection to server."
emitError https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:16426
_initializeServerConnection https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:12260
emit https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:25516
onclose https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:19350
Server:
const express = require('express');
enter code here`const app = express();
const ExpressPeerServer = require('peer').ExpressPeerServer;
app.use(express.static('./public'));
const server = app.listen(80, () => { // 3000 on localhost
console.log('Express server listen on port ' + 80);
});
const options = { debug: true };
const peerserver = ExpressPeerServer(server, options);
app.use('/peerjs', peerserver);
app.use('/*', express.static('./public/index.html'));
Client:
var peer = new Peer('', {
host: location.hostname,
port: location.port || (location.protocol === 'https:' ? 443 : 80),
path: '/peerjs',
debug: 3
});
peer.on('open', function (id) {
console.log(id);
});
Any help appreciate.
It looks like you are connecting with server ws://my.vps/, which is a web socket to a server at http://my.vps/ which doesn't seem to exist.
It should probably also be using https (or wss)
I'm trying to run a basic node.js file on an aws server running ubuntu 14.04 and apache 2.4.7
var http = require('http');
var hostname = '33.33.33.33';
var port = 3000;
var server = http.createServer(function(req, res) {
console.log(req.headers);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Hello World</h1>');
});
server.listen(port, hostname, function() {
console.log('Server running at http://${hostname}:${port}/');
});
The hostname is just the IP to the server. Should it be something else? Should the hostname be the IP or should it be something else?
The above code gives the following error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EADDRNOTAVAIL
at errnoException (net.js:901:11)
at Server._listen2 (net.js:1020:19)
at listen (net.js:1061:10)
at net.js:1135:9
at dns.js:72:18
at process._tickCallback (node.js:415:13)
at Function.Module.runMain (module.js:499:11)
at startup (node.js:119:16)
at node.js:901:3
********Update*********
I have updated my code with localhost. That got rid of the error and allowed me to run the .js file. However I can't access the file from the server. I type in the IP like so
**.**.**.**:3000
This returns the message:
This site can’t be reached
**.**.**.** refused to connect.
ERR_CONNECTION_REFUSED
I also try accessing the location the file is located on the server but I get the same result.
**.**.**.**:3000/nodelearning/c1_node_week1/node-express
After I run:
node myNodeApp.js
In the terminal, I just need to access the IP of the server from a web browser right? Do I need to access only the root **.**.**.**:3000 or do I need to access the specific location of the node file **.**.**.**:3000/learningNode/myNodeApp.js
I only need to access the root right?
So **.**.**.**:3000 should work?
Below is the .js file that I'm able to run. But I can't access.
var express = require('express'),
http = require('http');
var hostname = 'localhost';
var port = 3000;
var app = express();
app.use(function (req,res, next) {
console.log(req.headers);
res.writeHead(200, {'Content-Type': 'text/html' });
res.end('<html><body><h1>Hello World</h1></body></html>');
});
var server = http.createServer(app);
server.listen(port, hostname, function(){
console.log('Server running at http:// NVM');
});
Cheers
the issue is with
var hostname = '33.33.33.33';
because when routes are recycled new ip address are assigned to the machine. so this will fail. As a recomendation skip host parameter in listen() or if you still want to use hostname use
var hostname = '127.0.0.1';
or
var hostname = 'localhost';
hope it helps :)
I need to make tcp socket connection to smtp server. Is it possible to connect through proxy server on nodejs? Is there any npm modules available to use? I couldn't find any at all.
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('I am here!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('DATA: ' + data);
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
net.socket, tls.connect and dgram have no proxy support.
The simplest way to use it with proxy is to replace some libc functions with proxychains or something similar.
var client = require('tls')
.connect(443, 'www.facebook.com', function() {
console.log('connected');
client.write('hello');
})
.on('data', function(data) {
console.log('received', data.toString());
})
.on('close', function() {
console.log('closed');
});
proxychains node fit.js
connected
received HTTP/1.1 400 Bad Request
...
closed
Other than 'net' you don't need another module to make a socket connect to a host through a proxy server as long at the proxy server supports HTTPS traffic.
Create a socket connection to the proxy server
Send an HTTP CONNECT message to inform the proxy server of the host and port you want to connect to
If the proxy server responds with an HTTP 200 response then the proxy server established a socket connection to your desired target and is now relaying the traffic between the sockets
If the proxy server responded with any HTTP response other than 200 then the connection was not established.
Even though this process starts with HTTP it doesn't mean it wouldn't work for SMTP traffic. The initial HTTP message is just used to negotiate the connection, after that its just raw traffic. A proxy server might look at the port or host you want to connect to and disallow it. For example, block connections to ports below 80 or below 443 such as port 25 so it really depends on the proxy server if the connection will be allowed.
Yes, it is possible with one of these NPM modules:
http-proxy-agent: An HTTP(s) proxy http.Agent implementation for HTTP endpoints
https-proxy-agent: An HTTP(s) proxy http.Agent implementation for HTTPS endpoints
pac-proxy-agent: A PAC file proxy http.Agent implementation for HTTP and HTTPS
socks-proxy-agent: A SOCKS (v4a) proxy http.Agent implementation for HTTP and HTTPS
HTTPS Proxy Example:
var url = require('url');
var WebSocket = require('ws');
var HttpsProxyAgent = require('https-proxy-agent');
// HTTP/HTTPS proxy to connect to
var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
console.log('using proxy server %j', proxy);
// WebSocket endpoint for the proxy to connect to
var endpoint = process.argv[2] || 'ws://echo.websocket.org';
var parsed = url.parse(endpoint);
console.log('attempting to connect to WebSocket %j', endpoint);
// create an instance of the `HttpsProxyAgent` class with the proxy server information
var opts = url.parse(proxy);
var agent = new HttpsProxyAgent(opts);
// finally, initiate the WebSocket connection
var socket = new WebSocket(endpoint, { agent: agent });
socket.on('open', function () {
console.log('"open" event!');
socket.send('hello world');
});
socket.on('message', function (data, flags) {
console.log('"message" event! %j %j', data, flags);
socket.close();
});
I hope this helps.
These are the versions of node and required modules I am using:
Node.js: 0.10.16
Websocket Library: einaros/ws ws#0.4.28
Proxy server: nodejitsu/node-http-proxy http-proxy#0.10.3
When I run the following program my console output looks like this, and doesn't move beyond this point:
$ node app.js
proxy: got upgrade, proxying web request
wss: got connection
Here's the code:
// app.js
// A simple proxying example
//
// Setup websocket server on port 19000
// Setup proxy on port 9000 to proxy to 19000
// Make a websocket request to 9000
//
var WebSocket = require('ws'),
WebSocketServer = WebSocket.Server,
proxy = require('http-proxy');
// goes in a loop sending messages to the server as soon as
// the servers are setup
var triggerClient = function() {
var ws = new WebSocket('ws://localhost:9090/');
ws.on('open', function() {
console.log('ws: connection open');
setInterval(function() {
ws.send("Hello");
}, 1000);
});
ws.on('message', function(data) {
console.log('ws: got ' + data);
});
}
// setup websocket server and a proxy
//
var go = function() {
// setup a websocket server on port 19000
//
var wss = new WebSocketServer({ port: 19000 });
wss.on('connection', function(ws) {
console.log('wss: got connection');
ws.on('message', function(data) {
console.log('wss: got ' + data);
ws.send('wss response: ' + data);
});
});
// setup a proxy server
var server = proxy.createServer(function (req, res, proxy) {
proxy.proxyRequest(req, res, {
host: 'localhost',
port: 19000
});
});
server.on('upgrade', function (req, socket, head) {
console.log('proxy: got upgrade, proxying web request');
server.proxy.proxyWebSocketRequest(req, socket, head, {
host: 'localhost',
port: 19000
});
});
server.listen(9090, triggerClient);
};
process.nextTick(go);
My problem eventually started when I was trying to use hipache, I then simplified things to node-http-proxy and then finally to this piece of code.
If you change the port the WebSocket client is connecting to from 9090 to 19000 (thereby bypassing the proxy), things seem to work fine.
Any suggestions, pointers, feedback would be greatly appreciated.
Thanks!
The core problem is that the master branch of node-http-proxy is only compatible with node <= 0.8.x (see https://github.com/nodejitsu/node-http-proxy#when-to-use-node-http-proxy): there's a tree that implements support for 0.10.x (see https://github.com/nodejitsu/node-http-proxy/tree/caronte) but it isn't the mainline branch and I haven't found any indication of when it will be merged in and available.