Nodejs: how to clone or duplicate an incoming soap http request? - node.js

My Node.js server receives http soap requests. I would like to clone/duplicate each requests in order to send one to server A and the other to server B. How can I do that? Thanks
var proxy = httpProxy.createProxyServer({changeOrigin: true});
app.all('/', (req, res) =>{
// Duplicate or clone request
// ..... and send it to server B
// Forward original request to Server A
proxy.web(req, res, { target: url_serverA }, function(e) {})
});

Related

Edit the response after a redirect (node.js & express)

I have a Nodejs express app which receives POST requests (XML) and simply redirects them to a different host replying to the original caller (also with an XML message).
var app = require('express')();
app.post('/', function(req, res) {
res.redirect(307, 'http://localhost:8888/');
});
app.listen(3000, function() {
console.log('Application listening on http://localhost:3000/');
});
What I am trying to achieve is to modify the response from the second host (localhost:8888). How do I intercept and edit the response from the second host before it reaches the original caller?
I cannot figure it out from the documentation so any help would be very appreciated, thank you.
You cannot do that as the response from server 2 is fetched by the client handling the redirect (e.g. your browser). You have to fetch the response yourself in the server side, modify it and send it back.
var app = require('express')();
var request = // your preferred http library
app.post('/', function(req, res) {
request.get('http://localhost:8888/', function (err, response) {
if (err) {
return res.error(err);
}
// Here you have the response, you can modify it.
res.send(response.body);
});
});
app.listen(3000, function() {
console.log('Application listening on http://localhost:3000/');
});

How to query a request at Nodejs Proxy Server?

I have a Nodejs Proxy server like this:
`var http = require('http'),
httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
proxy.on('proxyReq', function(proxyReq, req, res, options) {
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});
var server = http.createServer(function(req, res) {
console.log(req.body);
proxy.web(req, res, {
target: 'http://localhost:3000'
});
});
console.log("listening on port 9000")
server.listen(9000);`
What i want is get the req.body at the proxy server when i post a request to the Origin server, go through the proxy server.
I used "console.log(req.body);" at both proxy server and the origin server. I get the body object {"id": "user003"} at origin server, but undefined at the proxy server.
So how can i get the req.body at proxy server?
I suspect the problem here is that you don't have a body parser on your proxy server, but do have one on your origin.
req.body itself isn't set by node. Instead, you have to handle events emitted by the req stream:
let body = '';
req.on('data', (data) => {
// data is a buffer so need toString()
body += data.toString();
});
req.on('end', () => {
// at this point you'll have the full body
console.log(body);
});
You can make this easier with a body parser (e.g https://www.npmjs.com/package/body-parser) but since you're running a proxy server, you probably don't want to parse the entire req stream before forwarding onto your origin. So I'd maybe stick with handling the events.

Authenticate jwt token and proxy to another server using Node JS

Want to use NodeJS as reverse proxy to another server.
My Scenario is to authenticate all requests (each request will have jwt token), authentication using jwt in nodejs is fine.
Same request should be sent to another server after successful authentication and the response should be sent back to client.
Looked into redbird, node-http-proxy and other readily available nodejs proxy modules. Nothing have a concrete way of authenticating the jwt and redirecting to target.
Is there a module which can be used? If not any idea/what steps I can follow to achieve this? Also I will be adding tls termination.
I was able to get something to work this might not be an optimal solution. This is an http proxy server. Next quest is to modify this to use as https server with tls termination (which is not the scope for this question atleast)
let http = require('http')
let httpProxy = require('http-proxy')
let jwt = require('jsonwebtoken')
let token = require('./token.json')
let proxy = httpProxy.createProxyServer({})
let server = http.createServer(function(req, res) {
jwt.verify(req.headers["authorization"], token.secret, { issuer:'IssuerName' }, function(err, decoded) {
if(err){
console.log("Error: " + err)
res.setHeader('Content-Type','application/json')
res.write(JSON.stringify({"statusCode":401, "message":err}))
res.end()
return
}
proxy.web(req, res, {
changeOrigin: true,
target: 'https://some_url'
})
})
})
proxy.on('proxyReq', function(proxyReq, req, res, options) {
proxyReq.removeHeader('authorization')
})
proxy.on('error', function (err, req, res) {
res.setHeader('Content-Type','application/json')
res.write(JSON.stringify({"statusCode":500, "message":err}))
res.end()
})
let port = process.env.PORT || 9200
server.listen(port)
console.log('HTTP Proxy server is running on port: ' + port)

node.js node-http-proxy: How to avoid exceptions with WebSocket when target in proxy.web

Using http-proxy (aka node-http-proxy) in node.js, I am having trouble figuring out how to proxy web sockets when the target is determined dynamically (i.e. when processing the request).
Looking at the documentation:
https://github.com/nodejitsu/node-http-proxy
There is an example that shows being able to set the target when processing the request:
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});
//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
});
console.log("listening on port 5050")
server.listen(5050);
There is another example farther down showing support for websockets via proxy.ws(), but it shows the target being set statically rather than depending on the request:
//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9015
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head);
});
proxyServer.listen(8015);
I took the first example and added the proxyServer.on('upgrade'... proxy.ws() ... stuff from the second example in order to get an example that sets the target while processing the request and also supports websockets. HTTP web pages seem to work fine, but it throws an exception when handling a websocket request.
'use strict';
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});
//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
server.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head);
});
console.log("listening on port 5050")
server.listen(5050);
The exception happens in the proxy.ws(req, socket, head) call:
Error: Must provide a proper URL as target
at ProxyServer.<anonymous> (...../node_modules/http-proxy/lib/http-proxy/index.js:68:35)
at Server.<anonymous> (...../poc.js:26:9) // the location in my sample code of the proxy.ws(req, socket, head) above
at emitThree (events.js:116:13)
at Server.emit (events.js:194:7)
at onParserExecuteCommon (_http_server.js:409:14)
at HTTPParser.onParserExecute (_http_server.js:377:5)
The code in http-proxy/index.js:68:35 throws this exception if there is no .target or .forward member of the options.
How do I set the target on a per request basis and also get websockets to work?
I have an answer. After looking at this question by Conrad and the comments, and then experimenting:
single-proxyserver-to-multiple-targets
proxy.ws can take an additional argument of options, just like proxy.web.
Here is the working code.
'use strict';
var http = require('http'),
httpProxy = require('http-proxy');
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});
//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
server.on('upgrade', function (req, socket, head) {
proxy.ws(req, socket, head, { target: 'ws://127.0.0.1:5060' });
});
console.log("listening on port 5050")
server.listen(5050);

NodeJS HTTP proxy - Add a header and update the request URL

I am using this module to do the following:
Parse the req URL
Add a new header to the request using the token from the URL
Update the actual request URL (remove the token from the URL)
I am trying to do that with the following code:
function initializeServer(){
var server = app.listen(5050, function () {
var host = server.address().address
var port = server.address().port
logger.info('NodeJS Server listening at http://%s:%s', host, port)
});
}
proxy.on('proxyReq', function(proxyReq, req, res, options) {
console.log("intercepting ... ")
proxyReq.setHeader('x-replica', '123');
req.url = '/newurl';
});
function initializeController(){
app.get('/myapp*', function (req, res) {
proxy.web(req, res, { target: 'http://127.0.0.1:8081' });
});
}
where 8081 is my test server and proxy server runs at 5050.
Now, the header setting works but the setting the URL does not. How to achieve this with node HTTP proxy ?
In the proxy.on('proxyReq',...) handler req is the (original) incoming request, while proxyReq is the request that will be issued to the target server. You need to set the proxyReq.path field.

Resources