Forum Discussion

Jack__Sun_16213's avatar
Jack__Sun_16213
Icon for Nimbostratus rankNimbostratus
Jun 26, 2014

can Production Web Traffic Replication handle dynamic content and POST such as login session?

can Production Web Traffic Replication handle dynamic content and POST such as login session? i am dealing with an application requires login and all content/functions tied up with login session tokens

 

4 Replies

  • Not much more to go on, but based on what I know of this product (very little) and the assumption that you're talking about HTTP communications, I'd say yes. More detail would be required if you need to know how that may work.

     

  • Brian_Talley_15's avatar
    Brian_Talley_15
    Historic F5 Account

    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