NodeJS Proxy Router Table - node.js

I'm trying to make a NodeJS http-proxy with a Router Table.
I saw some examples using http-proxy and try like this :
var httpProxy = require('http-proxy');
var proxyTable = {};
proxyTable['testproxy.com/toto'] = 'google.com:80';
proxyTable['testproxy.com/tata'] = 'gmail.com:80';
var httpOptions = {
router: proxyTable
};
console.log('Proxy Server Listening on port 80');
console.log('Requests to textproxy.com/toto (on port 80) are redirected to google.com:80');
console.log('Requests to textproxy.com/tata (on port 80) are redirected to gmail.com:80');
httpProxy.createServer(httpOptions).listen(80);
FYI : testproxy.com refer to 127.0.0.1.
It seems to work (it only intercepts request to testproxy.com/toto and tata) but when I try :
curl http://testproxy.com/toto
I have a NodeJS error :
var proxyReq = (options.target.protocol === 'https:' ? https : http).reque
^
TypeError: Cannot read property 'protocol' of undefined
at Array.stream [as 3] (D:\workspace\Proxy W_S\node_modules\http-proxy\l
ib\http-proxy\passes\web-incoming.js:103:35)
at ProxyServer.<anonymous> (D:\workspace\Proxy W_S\node_modules\http-pro
xy\lib\http-proxy\index.js:83:21)
at Server.closure (D:\workspace\Proxy W_S\node_modules\http-proxy\lib\ht
tp-proxy\index.js:125:43)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2108:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23
)
at Socket.socket.ondata (http.js:1966:22)
at TCP.onread (net.js:525:27)
Is router table already supported by http-proxy module ?
I have to do a dynamic proxy, any idea ?
I'm new at NodeJS, and I'm stuck.
Thanks a lot for your answers.
Pierre-Luc

It seems that proxy table routing was removed from node-http-proxy when they released version 1.0.0.
However, they provided a new way of doing it using the new API:
https://blog.nodejitsu.com/node-http-proxy-1dot0/

Related

Error while testing NodeJS and MongoDB stack using Mocha and Chai

Right now, I'm running Mocha tests and am getting the following error:
Error: connect ECONNREFUSED 127.0.0.1:27017
at Object.exports._errnoException (util.js:873:11)
at exports._exceptionWithHostPort (util.js:896:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1077:14)
I assume it's because I am unable to connect to port 27017 because I did not include:
var express = require('express')
var app = express()
However, what is particularly confusing to me is how I connect by test to MongoDB so I can create fake records for testing and then destroy them. If anyone can show me (with an example please) how to do it, that would be awesome!
Thanks again.
The error is coming may be the mongo server is not running or from more than one server trying to listen on same port. Also for test environment only can create different folder or use different port. So that can delete the folder once test case is over
In server.js
if(process.env === 'test')
{
mongoport = 57017;
}
else
{
mongoport = 27017;
}
mongoUrl = "mongodb://localhost:"+mongoport+"/student"
// use the mongodb url
In test.js
//on start of test case
var fs = require('fs-extra');
fs.removeSync("test/db/");
fs.ensureDirSync("test/db/");
//ur test case definition

Node: Can't bind to IPv6 localAddress while using https.request()

I can bind to localAddress just fine when using HTTP, but as soon as I switch to HTTPS I get an error: bind EINVAL. Please consider this code:
var http = require('http');
var https = require('https');
var options = { host:'icanhazip.com',path:'/',localAddress:'2604:a880:1:20::27:a00f',family:6 };
callback = function(response) {
var data = '';
response.on('data',function(chunk) { data+= chunk; });
response.on('error',function(error) { console.log("error: "+error.message); });
response.on('end',function() {
console.log(data);
});
}
http.request(options,callback).end(); // Works. IP:2604:a880:1:20::27:a00f
https.request(options,callback).end(); // Fails. IP:2604:a880:1:20::27:a00f
https.request({host:'icanhazip.com',path:'/',family:6},callback).end(); // Works. IP:2604:a880:1:20::27:a00f
Here's the error while running node v5.0.0:
Error: bind EINVAL 2604:a880:1:20::27:a00f
at Object.exports._errnoException (util.js:860:11)
at exports._exceptionWithHostPort (util.js:883:20)
at connect (net.js:809:16)
at net.js:984:7
at GetAddrInfoReqWrap.asyncCallback [as callback] (dns.js:63:16)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:82:10)
The only difference between the working and the failing code is setting localAddress and ironically, the last example binds to the correct IP address, but won't let you do it using localAddress.
The problem here is I have to make a request from a completely separate IPv6 address under my use case, and it works fine with HTTP but I need this to work for HTTPS requests. Currently I can only make this work while using cURL. Could you please provide some insight as to why this is happening or how I could make this work without additional libraries?
I had same issue as you. Figured it out. Update your node to the latest stable. They fixed it. Check it with node --version I'm on 6.6.0 and it works great.
The version I got from doing an apt-get was way too old.

Setting up ssl in heroku using node.js express and socket.io

I attempting to create a ssl handled websocket in heroku using express socket.io and node.
I know that heroku handles ssl funky and that in order to not get a H12 request timeout error I need to handle http as well. I have tried a few different methods at approaching the situation and all leave me at a loss. This is my final product, but I get a EADDRINUSE error. I was wondering if anyone has tried this, and if I could see their approach at it, or if anyone could see where I am going wrong in my code.
Please let me know if this is too vague and hopefully I can narrow it down.
class ServerInitializer
constructor: (port, sslport) ->
#port = port
#express = require 'express'
#http = require 'http'
#https = require 'https'
#fs = require 'fs'
#options = {
key: #fs.readFileSync(__dirname+'/../../../private/key.pem'),
cert: #fs.readFileSync(__dirname+'/../../../private/cacert.pem')
}
console.log "STARTING SERVER"
#startExpress()
#startSocketIO()
#startStaticService()
startExpress: ->
console.log " ...preparing express server."
global.app = #express()
app.set 'port', 4001
startSocketIO: ->
console.log " ...preparing http for socket.io"
if process.env.NODE_ENV == 'production'
app.listen app.get 'port'
global.server = #https.createServer(#options, app)
server.listen port
#httpserver = #http.createServer(app)
global.io = require('socket.io').listen(server)
console.log " ...socket.io listening on port #{port}"
startStaticService: ->
console.log " ...preparing to serve static assets"
app.use #express.bodyParser()
app.use #express.static(__dirname + '/static')
console.log "..done."
exports.ServerInitializer = ServerInitializer

how to resolve following easyrtc issue?

I've written following code:
var http = require("http"); // http server core module
var express = require("express"); // web framework external module
var io = require("socket.io"); // web socket external module
var easyrtc = require("easyrtc"); // EasyRTC external module
var app = express();
var server = http.createServer(app).listen(app.get('port'));
io= io.listen(server,{"log level":1});
var rtc = easyrtc.listen(server, io);
this is giving following error:
$node server info - EasyRTC: Starting EasyRTC Server (v1.0.10) on
Node (v0.10.26) [TypeError: Object # has no method 'get']
TypeError: Object # has no method 'get'
at async.waterfall.pub.socketServer.sockets.on.easyrtcid (/home/ritzy1/Downloads/downloaded
codes/VEDIO/change2/testexpandwb/node_modules/easyrtc/lib/easyrtc_default_event_listeners.js:1472:29)
at fn (/home/ritzy1/Downloads/downloaded codes/VEDIO/change2/testexpandwb/node_modules/easyrtc/node_modules/async/lib/async.js:582:34)
at Object._onImmediate (/home/ritzy1/Downloads/downloaded codes/VEDIO/change2/testexpandwb/node_modules/easyrtc/node_modules/async/lib/async.js:498:34)
at processImmediate [as _immediateCallback] (timers.js:330:15)
Ηow can i fix it?
You have to give a specific port number in the listen() function.
Change the following line var server = http.createServer(app).listen(app.get('port')); with var server = http.createServer(app).listen(8080); Note : 8080 is a port number you can specify any other port number which are not currently using.
Happy coding

node.js and Redis on Heroku for IODocs

I'm trying to get IODocs running on Heroku. It requires node.js and Redis. Admittedly, I'm new to all of these technologies. Nonetheless, I've managed to get it running locally. However, I receive the following error when deploying to Heroku.
2011-12-01T11:55:18+00:00 app[web.1]: Redis To Go - port: 9030 hostname: dogfish.redistogo.com
2011-12-01T11:55:18+00:00 app[web.1]: Express server listening on port 9694
2011-12-01T11:55:19+00:00 heroku[web.1]: State changed from starting to up
2011-12-01T11:55:21+00:00 app[web.1]: ^
2011-12-01T11:55:21+00:00 app[web.1]: Error: Redis connection to localhost:6379 failed - ECONNREFUSED, Connection refused
2011-12-01T11:55:21+00:00 app[web.1]: at Socket.<anonymous> (/app/node_modules/redis/index.js:123:28)
2011-12-01T11:55:21+00:00 app[web.1]: at Socket.emit (events.js:64:17)
2011-12-01T11:55:21+00:00 app[web.1]: at Array.<anonymous> (net.js:828:27)
2011-12-01T11:55:21+00:00 app[web.1]: at EventEmitter._tickCallback (node.js:126:26)
2011-12-01T11:55:23+00:00 heroku[web.1]: State changed from up to crashed
The only time I received a similar warning on my local mating was when Redis was not running. From what I can tell the Redis add-on is enabled for my app and running:
$ heroku config --long
NODE_ENV => production
PATH => bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin
REDISTOGO_URL => redis://redistogo:52847221366cb677460c306e4f482c5b#dogfish.redistogo.com:9030/
I've also tried some configuration suggestions. Neither seem to work.
// redis connection in app.js
var db;
if (process.env.REDISTOGO_URL) {
var rtg = require("url").parse(process.env.REDISTOGO_URL);
// tried this line as well... gave a different error on .connect();
// db = require('redis-url').connect(process.env.REDISTOGO_URL);
db = redis.createClient(rtg.port, rtg.hostname);
db.auth(rtg.auth.split(":")[1]);
// debug
sys.puts('Redis To Go - port: ' + rtg.port + ' hostname: ' + rtg.hostname);
} else {
db = redis.createClient(config.redis.port, config.redis.host);
db.auth(config.redis.password);
}
From the difference in my Redis To Go debug line and Error, I'm sure this is a configuration issue. But don't know how to fix it. Any help is greatly appreciated.
According to this line:
2011-12-01T11:55:21+00:00 app[web.1]: Error: Redis connection to localhost:6379 failed - ECONNREFUSED, Connection refused
You are trying to connect to localhost:6379, but the redis server is running at redis://redistogo:52847221366cb677460c306e4f482c5b#dogfish.redistogo.com:9030/. Can you try connecting to that URL manually and see if that works?
This indeed had to do with the configuration for Redis on Heroku. There were additional lines that required updates in I/O Docs app.js.
In the end, I piggy-backed the global config object at the top (~ line 60) after sniffing out the production (Heroku) environment.
if (process.env.REDISTOGOURL) {
// use production (Heroku) redis configuration
// overwrite config to keep it simple
var rtg = require(‘url’).parse(process.env.REDISTOGOURL);
config.redis.port = rtg.port;
config.redis.host = rtg.hostname;
config.redis.password = rtg.auth.split(“:”)[1];
}
I created a blog post for installing, configuring, and deploying I/O Docs that includes this as well as other changes that were required to run I/O Docs. I recommend you review it if you're interested in this project.
Thanks to Jan Jongboom and Kirsten Jones for helping me get started. In addition, I believe the project has been updated on GitHub to include Heroku configuration out of the box. However, I've yet to test it.
I actually have a blog post about how to get IODocs working on Heroku. It's got the config changes needed to get the REDIS working on Heroku with IODocs.
http://www.princesspolymath.com/princess_polymath/?p=489
Here's the code changes needed:
Add the following block under “var db;” to app.'s:
if (process.env.REDISTOGO_URL) {
var rtg = require("url").parse(process.env.REDISTOGO_URL);
db = require("redis").createClient(rtg.port, rtg.hostname);
db.auth(rtg.auth.split(":")[1]);
} else {
db = redis.createClient(config.redis.port, config.redis.host);
db.auth(config.redis.password);
}
And then this in the Load API Configs section, after reading the config file:
var app = module.exports = express.createServer();
var hostname, port, password
if (process.env.REDISTOGO_URL) {
var rtg = require("url").parse(process.env.REDISTOGO_URL);
hostname = rtg.hostname;
port = rtg.port;
password = rtg.auth.split(":")[1];
} else {
hostname = config.redis.host;
port = config.redis.port;
password = config.redis.password;
}
Recently, a cleaner way would be to use the redis-url module which handles the configuration.
I'm personnaly using Express with Redis (via the Redis To Go addon) as a sessionStore, and it works well on Heroku.
Exemple :
const express = require('express')
, redis = process.env.REDISTOGO_URL
? require('redis-url').connect(process.env.REDISTOGO_URL)
: require('redis').createClient()
, RedisStore = require('connect-redis')(express)
, sessionStore = new RedisStore({ client: redis })
, app = express.createServer();
[...]
app.configure(function() {
this
.use(express.session({
secret: 'mySecretHash',
store: sessionStore // Set redis as the sessionStore for Express
}));
});

Resources