Forum Discussion
Yes, this is possible!
The solution that you are referencing (Production Web Traffic Replication), will not handle sessions properly. However, the power of the LineRate scripting engine and Node.js allow us to accomplish this with some slight modifications to the script.
The idea is that you need to add some extra code to handle your session information and translate it if necessary. The logic depends on whether you are using a shared authentication system between the Production and Staging environments or if users are authenticated independently in these environments.
If you are using a shared authentication system, you can check for a login request and prevent that request from being replicated so that the auth system only sees a single request. Any subsequent requests should contain the proper session variables/cookies and be validated by either Production or Staging environments.
If you are using local authentication, you'll let the login request pass to both environments. But in this scenario, you'll need to maintain a mapping between the Production system session information and the Staging system session information and replace this info in requests to the Staging environment.
Here's some example code for the local authentication scenario to get you started. There are plenty of inline comments, but let me know if you have any questions!
ReplicateTraffic.prototype.parseSessionCreds = function(res) {
// Custom code to parse the session credentials, such as
// a session ID, out of the response if they are there.
return credentials; // or null
}
ReplicateTraffic.prototype.replaceCreds = function(req) {
// Custom code to replace the service A credentials
// (if present in this request) with the service B
// credentials.
// No return value.
}
ReplicateTraffic.prototype.copyHeaders = function(from, to) {
for(var header in from.headers) {
to.setHeader(header, from.headers[header]);
}
}
ReplicateTraffic.prototype.replicate = function(req, res, cliReq) {
if(req.method == 'GET' || req.method == 'HEAD' || req.method == 'POST') {
// Only do GET and HEAD and POST
var newReq = this.cloneReq(req);
// Register for and handle responses on the original req
req.on('response', function(cliRes) {
// manually forward the response on
cliRes.bindHeaders(res);
cliRes.pipe(res);
// also parse the session credentials out of the response if present.
// this happens simultaneously with sending data on, so
// the user experience is not impacted.
var creds = this.parseSessionCreds(cliRes);
if (creds) {
this.sessionCredsA = creds;
}
});
// Register for and handle responses on the clone
newReq.on('response', function(cliResB) {
console.log('saw B resp');
// parse the session credentials out of the B response if present
var creds = this.parseSessionCreds(cliResB);
if (creds) {
this.sessionCredsB = creds;
}
});
// Send the original request on
this.copyHeaders(req, cliReq);
req.pipe(cliReq);
// Send the original request data on to the second server
req.pipe(newReq);
} else {
// for other requests, forward it and its response on
this.copyHeaders(req, cliReq);
req.fastPipe(cliReq, {response: res});
}
}
Brian