This is the code I used to connect http server.
var app = require('http').createServer(require('express')),
io = require('socket.io').listen(app),
util = require('util'),
connectionsArray = [], // maintain active connected client details
connectionStatistics = {'summary': {'instance_count': 0, 'user_count': 0, 'customer_count': 0}, 'customers': {}}, // for debugging purpose
server_port = 3000, // port on which nodejs engine to run
POLLING_INTERVAL = 10 * 1000, // 10 sec
pollingTimer = [], // timeouts for connected sockets
fs = require('fs'), // lib for file related operations
log_file = {
'error': fs.createWriteStream(__dirname + '/debug.log', {flags: 'a'}), // file to log error messages
'info': fs.createWriteStream(__dirname + '/info.log', {flags: 'a'}) // file to log info messages
};
var server = app.listen(server_port, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Please use your browser to navigate to http://%s:%s', host, port);
});
I want to include https connection in the above code.
I tried to connect https using SSLCertificateFile and SSLCertificateKeyFile.
But it didn't work for me.
install https module ( yarn add https / npm i https )
change options (ssl file path) as below :
const options = {
key: fs.readFileSync('./ssl/private.key'),
cert: fs.readFileSync('./ssl/certificate.crt'),
ca:fs.readFileSync('./ssl/ca_bundle.crt')
}
https.createServer(options, app).listen(port);
Try this snippet using express and https module instead of http
let fs = require('fs');
let https = require('https');
let express = require('express');
let app = express();
let options = {
key: fs.readFileSync('./file.pem'),
cert: fs.readFileSync('./file.crt')
};
let serverPort = 3000;
let server = https.createServer(options, app);
let io = require('socket.io')(server);
io.on('connection', function(socket) {
console.log('new connection');
});
server.listen(serverPort, function() {
console.log('server up and running at %s port', serverPort);
});
Related
i have a self signed grpc service on server, and got it working for dart server with dart client.
But i could not figure how to bypass or allow self signed certificate for node client..
I've tried this:
const sslCreds = await grpc.credentials.createSsl(
fs.readFileSync('./ssl/client.crt'),
null, // privatekey
null, // certChain
{
checkServerIdentity: function(host, info) {
console.log('verify?', host, info);
if (
host.startsWith('127.0.0.1') ||
host.startsWith('logs.example.com')
) {
return true;
}
console.log('verify other?', host);
return true;
},
},
);
// sslCreds.options.checkServerIdentity = checkCert;
const gLogClient = new synagieLogGrpc.LoggerClient(
'host:port',
sslCreds,
);
but when i call, my validation checkServerIdentity did not call.
anyone have any clue?
after checking out multiple github issues, and testing for 2 days,
this code below works.
critical point is, actual host:port is the destination, which could be localhost. but we will need to override the ssl target name with the actual generated ssl domain.
for sample of tls generation:
https://github.com/grpc/grpc-node/issues/1451
const host = 'localhost';
const port = 8088;;
const hostPort = `${host}:${port}`;
const gLogClient = new synagieLogGrpc.LoggerClient(hostPort, sslCreds, {
'grpc.ssl_target_name_override': 'actual_tlsdomain.example.com',
});
The Problem
I have a simple Nodejs Express Hello_World application up and running both locally and on a live server using Plesk-Onyx17.8.11. The app runs correctly on localhost:3000 in my browser:
But after I push the files to the server (using a Filezilla ftp client), my browser can't load the files in the public folder, so it won't load the CSS file:
As you can see the file http://shamimkeshani.ir/stylesheets/style.css cannot be downloaded. This is the correct URL, because we use app.use(express.static(path.join(__dirname, '/public'))); in the Express app. But hypothetically if we insert a wrong URL file of http://shamimkeshani.ir/public/stylesheets/style.css it would find the file and download it correctly from shamimkeshani.ir, which is not the correct behavior! Also, this will not work locally which is the right behavior!!
The codes
I used express-generator to create the default Hello_World Express application. The app.js file:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
console.log(__dirname);
app.use(express.static(path.join(__dirname, '/public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
I use a server.js file to run the Nodejs application. This file is actually a copy of ./bin/www file that Express uses. I use npm start which runs this file locally. Also, the server.js file is set in the Plesk for starting the application on the server:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('./app');
var debug = require('debug')('app:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
package.json file:
{
"name": "app",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./server.js"
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"morgan": "~1.9.0",
"pug": "2.0.0-beta11"
}
}
I also checked the Nodejs versions running locally and at the server and they both match (10.1.0).
I searched a lot and couldn't figure out how to solve this problem. I want for my Nodejs application to work the same locally and on the server. Any additional thoughts on the future problems that I may encounter and any further suggestions are appreciated. Thanks.
I am trying to make a call within a firebase function to a locally managed server. I am not super familiar with node as a development environment so I am not sure what is the issue.
const functions = require('firebase-functions');
const https = require('http');
exports.testPost = functions.https.onRequest((req, res) => {
var options = {
host: 'localdevserver.edu',
port: 80,
path: '/my/endpoint'
};
let data = '';
http.get(options, function(resp){
resp.on('data', function(chunk){
//do something with chunk
data += chunk;
resp.on('end', console.log("dones"));
});
}).on("error", function(e){
console.log("Got error: " + e.message);
});
});
When I look in the Firebase Functions Log, it says either timeout or no reject defined.
With HTTP type functions, you need to send a response to the client in order to terminate the function. Otherwise it will time out.
res.send("OK");
Please read the documentation for more details.
You can use SYNC-REQUEST
npm install sync-request
var request = require('sync-request');
var res = request('GET', 'http://google.com');
console.log(res.body.toString('utf-8'));
the function would be something like this:
exports.testPost = functions.https.onRequest((req, res) => {
var request = require('sync-request');
var res = request('GET', 'http://google.com');
var res = res.body.toString('utf-8');
resp.on(res, console.log("dones"));
});
Currently building an application in node.js. I am trying to make a server-side HTTP request to an ASP script and return the results.
If I navigate to the url in my browser, everything is fine. Data is returned. However, when I do this in node.js using restler, or any other module for that matter. I get nothing back......UNTIL I add the ASP.NET_SessionId cookie to the header of the request. I copied this cookie from the successul GET from my browser.
How do I get/set this session cookie server-side in node.js?
Using express framework. Code below.
app.js
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('cat'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
route index.js
/*
* GET home page.
*/
exports.index = function(req, res){
var http = require("http"),
sys = require('util'),
rest = require('restler');
rest.get('http://192.168.154.134/dca/stream/StreamDown.asp?' +
'Action=GetRepositoryConnections' , {headers:{
'Cookie':'ASP.NET_SessionId=jj1jx255wlkwib45gq0d3555;' +
' ASPSESSIONIDASDDSBQR=ACABCJNDIIONGGMPGAOMMJJD;' +
' ASPSESSIONIDCQQRQDQR=BAIBCEODMMKAPJAOLLMMDNEJ;' +
' ASPSESSIONIDAQSTRAQR=KMLDIOODECFNBKPGINLLNBKC;' +
' ASPSESSIONIDASQQQDQR=OKGBKCPDHDIKAJNOGFKACCCG'}
}).on('complete', function(result) {
if (result instanceof Error) {
sys.puts('Error: ' + result.message);
this.retry(5000); // try again after 5 sec
} else {
sys.puts(result);
}
});
res.render('index', { title: 'Express' });
};
Try request. It has a "cookie jar" so it will remember cookies for you.
I am developing a node.js proxy server application and I want it to support HTTP and HTTPS(SSL) protocols (as server).
I'm currently using node-http-proxy like this:
const httpProxy = require('http-proxy'),
http = require('http');
var server = httpProxy.createServer(9000, 'localhost', function(req, res, proxy) {
console.log(req.url);
proxy.proxyRequest(req, res);
});
http.createServer(function(req, res) {
res.end('hello!');
}).listen(9000);
server.listen(8000);
I setup my browser to use HTTP proxy on localhost:8000 and it works. I also want to catch HTTPS requests (ie. setup my browser to use localhost:8000 as HTTPS proxy as well and catch the requests in my application). Could you please help me how can I do that?
PS:
If I subscribe to upgrade event of httpProxy server object I can get the requests but I don't know how to forward the request and send response to client:
server.on('upgrade', function(req, socket, head) {
console.log(req.url);
// I don't know how to forward the request and send the response to client
});
Any helps would be appreciated.
Solutions barely exist for this, and the documentation is poor at best for supporting both on one server. The trick here is to understand that client proxy configurations may send https requests to an http proxy server. This is true for Firefox if you specify an HTTP proxy and then check "same for all protocols".
You can handle https connections sent to an HTTP server by listening for the "connect" event. Note that you won't have access to the response object on the connect event, only the socket and bodyhead. Data sent over this socket will remain encrypted to you as the proxy server.
In this solution, you don't have to make your own certificates, and you won't have certificate conflicts as a result. The traffic is simply proxied, not intercepted and rewritten with different certificates.
// Install npm dependencies first
// npm init
// npm install --save url#0.10.3
// npm install --save http-proxy#1.11.1
var httpProxy = require("http-proxy");
var http = require("http");
var url = require("url");
var net = require('net');
var server = http.createServer(function (req, res) {
var urlObj = url.parse(req.url);
var target = urlObj.protocol + "//" + urlObj.host;
console.log("Proxy HTTP request for:", target);
var proxy = httpProxy.createProxyServer({});
proxy.on("error", function (err, req, res) {
console.log("proxy error", err);
res.end();
});
proxy.web(req, res, {target: target});
}).listen(8080); //this is the port your clients will connect to
var regex_hostport = /^([^:]+)(:([0-9]+))?$/;
var getHostPortFromString = function (hostString, defaultPort) {
var host = hostString;
var port = defaultPort;
var result = regex_hostport.exec(hostString);
if (result != null) {
host = result[1];
if (result[2] != null) {
port = result[3];
}
}
return ( [host, port] );
};
server.addListener('connect', function (req, socket, bodyhead) {
var hostPort = getHostPortFromString(req.url, 443);
var hostDomain = hostPort[0];
var port = parseInt(hostPort[1]);
console.log("Proxying HTTPS request for:", hostDomain, port);
var proxySocket = new net.Socket();
proxySocket.connect(port, hostDomain, function () {
proxySocket.write(bodyhead);
socket.write("HTTP/" + req.httpVersion + " 200 Connection established\r\n\r\n");
}
);
proxySocket.on('data', function (chunk) {
socket.write(chunk);
});
proxySocket.on('end', function () {
socket.end();
});
proxySocket.on('error', function () {
socket.write("HTTP/" + req.httpVersion + " 500 Connection error\r\n\r\n");
socket.end();
});
socket.on('data', function (chunk) {
proxySocket.write(chunk);
});
socket.on('end', function () {
proxySocket.end();
});
socket.on('error', function () {
proxySocket.end();
});
});
Here is my NO-dependencies solution (pure NodeJS system libraries):
const http = require('http')
const port = process.env.PORT || 9191
const net = require('net')
const url = require('url')
const requestHandler = (req, res) => { // discard all request to proxy server except HTTP/1.1 CONNECT method
res.writeHead(405, {'Content-Type': 'text/plain'})
res.end('Method not allowed')
}
const server = http.createServer(requestHandler)
const listener = server.listen(port, (err) => {
if (err) {
return console.error(err)
}
const info = listener.address()
console.log(`Server is listening on address ${info.address} port ${info.port}`)
})
server.on('connect', (req, clientSocket, head) => { // listen only for HTTP/1.1 CONNECT method
console.log(clientSocket.remoteAddress, clientSocket.remotePort, req.method, req.url)
if (!req.headers['proxy-authorization']) { // here you can add check for any username/password, I just check that this header must exist!
clientSocket.write([
'HTTP/1.1 407 Proxy Authentication Required',
'Proxy-Authenticate: Basic realm="proxy"',
'Proxy-Connection: close',
].join('\r\n'))
clientSocket.end('\r\n\r\n') // empty body
return
}
const {port, hostname} = url.parse(`//${req.url}`, false, true) // extract destination host and port from CONNECT request
if (hostname && port) {
const serverErrorHandler = (err) => {
console.error(err.message)
if (clientSocket) {
clientSocket.end(`HTTP/1.1 500 ${err.message}\r\n`)
}
}
const serverEndHandler = () => {
if (clientSocket) {
clientSocket.end(`HTTP/1.1 500 External Server End\r\n`)
}
}
const serverSocket = net.connect(port, hostname) // connect to destination host and port
const clientErrorHandler = (err) => {
console.error(err.message)
if (serverSocket) {
serverSocket.end()
}
}
const clientEndHandler = () => {
if (serverSocket) {
serverSocket.end()
}
}
clientSocket.on('error', clientErrorHandler)
clientSocket.on('end', clientEndHandler)
serverSocket.on('error', serverErrorHandler)
serverSocket.on('end', serverEndHandler)
serverSocket.on('connect', () => {
clientSocket.write([
'HTTP/1.1 200 Connection Established',
'Proxy-agent: Node-VPN',
].join('\r\n'))
clientSocket.write('\r\n\r\n') // empty body
// "blindly" (for performance) pipe client socket and destination socket between each other
serverSocket.pipe(clientSocket, {end: false})
clientSocket.pipe(serverSocket, {end: false})
})
} else {
clientSocket.end('HTTP/1.1 400 Bad Request\r\n')
clientSocket.destroy()
}
})
I tested this code with Firefox Proxy Settings (it even asks for username and password!). I entered IP address of machine where this code is runned and 9191 port as you can see in the code. I also set "Use this proxy server for all protocols". I run this code locally and on VPS - in both cases works!
You can test your NodeJS proxy with curl:
curl -x http://username:password#127.0.0.1:9191 https://www.google.com/
I have created a http/https proxy with the aid of the http-proxy module: https://gist.github.com/ncthis/6863947
Code as of now:
var fs = require('fs'),
http = require('http'),
https = require('https'),
httpProxy = require('http-proxy');
var isHttps = true; // do you want a https proxy?
var options = {
https: {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('key-cert.pem')
}
};
// this is the target server
var proxy = new httpProxy.HttpProxy({
target: {
host: '127.0.0.1',
port: 8080
}
});
if (isHttps)
https.createServer(options.https, function(req, res) {
console.log('Proxying https request at %s', new Date());
proxy.proxyRequest(req, res);
}).listen(443, function(err) {
if (err)
console.log('Error serving https proxy request: %s', req);
console.log('Created https proxy. Forwarding requests from %s to %s:%s', '443', proxy.target.host, proxy.target.port);
});
else
http.createServer(options.https, function(req, res) {
console.log('Proxying http request at %s', new Date());
console.log(req);
proxy.proxyRequest(req, res);
}).listen(80, function(err) {
if (err)
console.log('Error serving http proxy request: %s', req);
console.log('Created http proxy. Forwarding requests from %s to %s:%s', '80', proxy.target.host, proxy.target.port);
});
The node-http-proxy docs contain examples of this. Look for "Proxying to HTTPS from HTTPS" at https://github.com/nodejitsu/node-http-proxy The configuration process is slightly different in every browser. Some have the option to use your proxy settings for all protocols; some you need to configure the SSL proxy separately.