WebProxy : Web proxy server
WebProxy
is an HTTP programmable proxying middleware that supports websocket and socket.io. It is suitable for implementing components such as reverse proxies and load balancers.
User can use the following code to import the WebProxy
module.
var WebProxy = require('middleware').WebProxy;
Support
The following shows WebProxy
module APIs available for each permissions.
User Mode | Privilege Mode | |
---|---|---|
WebProxy.create | ● | |
proxy.web | ● | |
proxy.ws | ● |
WebProxy Class
WebProxy.create(server)
server
{WebApp} WebApp object.
Create a proxy middleware.
Example
var socket = require('socket');
var WebApp = require('webapp');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy middlewrae.
var proxy = WebProxy.create(app);
WebProxy Object
proxy.web([path, ]target[, opts])
path
{String | RegExp} Route the request's path to target. See: app.METHOD path userage.target
{String | Function} Http target URL for HTTP[S] proxy. When target` is used as a function, the proxy address can be set dynamically. The function target Description:req
{WebRequest} WebRequest object.opts
{Object} Proxy options.- Returns: {String} Http target URL for HTTP[S] proxy.
opts
{Object} The following are the options:tlsOpt
{Object} TLS securely connections options.default: undefined, means use TCP connection.xfwd
{Boolean} If adds'X-Forward'
headers. default: false.headers
{Object} Object with extra headers to be added to target requests.prependPath
{Boolean} Specify whether you want to prepend the target's path to the proxy path.default: true.ignorePath
{Boolean} Specify whether you want to ignore the proxy path of the incoming request (You will have to append/
manually if required). default: false.changeOrigin
{Boolean} Changes the origin of the host header to the target URL. default: false.reqCallback
{Function} This function is called before the data is sent. It gives you a chance to alter the proxyReq request object. It's argument:proxyReq
{HttpClient} Proxy request object. Reference to httpclient for more informance.req
{WebRequest} The origin request object. Reference to webrequest for more informance.res
{WebResponse} The origin response object. Reference to webresponse for more informance.
resCallback
{Function} This function is called if the request to the target got a response. It's argument:proxyRes
{HttpClientResponse} Proxy response object. Reference to httpclient for more informance.req
{WebRequest} The origin request object. Reference to webrequest for more informance.res
{WebResponse} The origin response object. Reference to webresponse for more informance.
Used for proxying regular HTTP(S) requests.
Example
- Base example.
var socket = require('socket');
var WebApp = require('webapp');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy.
var proxy = WebProxy.create(app);
// Use proxy middleware.
app.use('/', proxy.web('http://192.168.7.32:3010'));
- Dynamic target.
var socket = require('socket');
var WebApp = require('webapp');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy.
var proxy = WebProxy.create(app);
// Use proxy middleware.
app.use('/', proxy.web(function(req, opts) {
return 'http://192.168.7.32:3010';
}));
- Proxy callback.
var socket = require('socket');
var WebApp = require('webapp');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy.
var proxy = WebProxy.create(app);
// Use proxy middleware.
app.use('/', proxy.web('http://192.168.7.32:3010', {
reqCallback: function(proxyReq, req, res) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foo');
},
resCallback: function(proxyRes, req, res) {
res.setHeader('X-Special-Proxy-Header', 'bar');
}
}));
proxy.ws([path, ]target[, opts])
path
{String | RegExp} Route the request's path to target. See: app.METHOD path userage.target
{String | Function} Http target URL for HTTP[S] proxy. When target` is used as a function, the proxy address can be set dynamically. The function target Description:req
{WebRequest} WebRequest object.opts
{Object} Proxy options.- Returns: {String} Http target URL for HTTP[S] proxy.
opts
{Object} The following are the options:tlsOpt
{Object} TLS securely connections options.default: undefined, means use TCP connection.xfwd
{Boolean} If adds'X-Forward'
headers. default: false.headers
{Object} Object with extra headers to be added to target requests.prependPath
{Boolean} Specify whether you want to prepend the target's path to the proxy path.default: true.ignorePath
{Boolean} Specify whether you want to ignore the proxy path of the incoming request (You will have to append/
manually if required). default: false.changeOrigin
{Boolean} Changes the origin of the host header to the target URL. default: false.
Used for proxying WS(S) requests.
Example
- Base example.
var socket = require('socket');
var WebApp = require('webapp');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy.
var proxy = WebProxy.create(app);
// Use websocket proxy.
proxy.ws('/', 'ws://192.168.7.32:3010');
- Dynamic target.
var socket = require('socket');
var WebApp = require('webapp');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy.
var proxy = WebProxy.create(app);
// Use websocket proxy.
proxy.ws('/', function(req, opts) {
return 'ws://192.168.7.32:3010';
});
WebProxy Events
request
This event is emitted before the data is sent. It gives you a chance to alter the proxyReq request object. It's argument:
proxyReq
{HttpClient} Proxy request object. Reference to httpclient for more informance.req
{WebRequest} The origin request object. Reference to webrequest for more informance.res
{WebResponse} The origin response object. Reference to webresponse for more informance.
The request
event works the same as the reqCallback
of proxy.web([path,] target [, opts])
, except that the request
event is valid for all proxy requests. The request
event is emited before reqCallback
.
Example
var proxy = WebProxy.create(app);
proxy.on('request', function(proxyReq, req, res) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foo');
});
response
This event is emitted if the request to the target got a response. It's argument:
proxyRes
{HttpClientResponse} Proxy response object. Reference to httpclient for more informance.req
{WebRequest} The origin request object. Reference to webrequest for more informance.res
{WebResponse} The origin response object. Reference to webresponse for more informance.
The response
event works the same as the resCallback
of proxy.web([path,] target [, opts])
, except that the response
event is valid for all proxy response. The response
event is emited before resCallback
.
Example
var proxy = WebProxy.create(app);
proxy.on('response', function (proxyRes, req, res) {
res.setHeader('X-Special-Proxy-Header', 'bar');
});
Proxy Path Rule
When using proxy.web
or proxy.ws
middleware, you can configure multiple proxy path rules.
The default value of the prependPath
option is true
, and the target
path will be retained. The default value of the ignorePath
option is false
. In this case, the original path will be retained, and the target
path will precede the original path.
If the target
path ends with an absolute path, only the current path of the original path in the route matching process will be retained. If the target
path ends with a relative path, all the original paths are retained. The following examples show these situations:
Example
app.use('/root/', proxy.web('http://10.4.100.31:8000'));
// request url: http://10.4.100.31/root/sub
// proxy url: http://10.4.100.31:8000/root/sub
app.use('/root/', proxy.web('http://10.4.100.31:8000/'));
// request url: http://10.4.100.31/root/sub
// proxy url: http://10.4.100.31:8000/sub
app.use('/root/', proxy.web('http://10.4.100.31:8000/class'));
// request url: http://10.4.100.31/root/sub
// proxy url: http://10.4.100.31:8000/class/root/sub
app.use('/root/', proxy.web('http://10.4.100.31:8000/class/'));
// request url: http://10.4.100.31/root/sub
// proxy url: http://10.4.100.31:8000/class/sub
Example
The following is a comprehensive example of a dynamic proxy server.
var socket = require('socket');
var WebApp = require('webapp');
var iosched = require('iosched');
var WebProxy = require('middleware').WebProxy;
// Create app.
var app = WebApp.create('proxy', 0, socket.sockaddr(socket.INADDR_ANY, 80));
// Create proxy.
var proxy = WebProxy.create(app);
// Set ws proxy.
proxy.ws('/:id/?', function(req, opts) {
var target = undefined;
switch(req.params.id) {
case 'app1':
target = 'ws://10.4.100.81:8000/';
break;
case 'app2':
target = 'ws://10.4.100.81:8001/';
break;
default:
throw new Error('url error, id=', id);
}
return target;
});
// Set http proxy middleware.
app.use('/:id/?', proxy.web(function(req, opts) {
var target = undefined;
switch(req.params.id) {
case 'app1':
target = 'http://10.4.100.81:8000/';
break;
case 'app2':
target = 'http://10.4.100.81:8001/';
break;
default:
throw new Error('url error, id=', id);
}
return target;
}));
// Catch 404 and forward to error handler.
app.use(function(req, res, next) {
res.status(404);
next(new Error('Not Found'));
});
// Error handler.
app.use(function(err, req, res, next) {
if (res.headersSent) {
return next(err);
}
var status = err.status ? err.status : res.status();
status = status < 400 ? 500 : status;
res.status(status).json({status: status, msg: err.message});
});
// Start app.
app.start();
// Event loop.
while (true) {
iosched.poll();
}