From d3e2a2be64294838212bbd7cebcf0a99356ff7fc Mon Sep 17 00:00:00 2001 From: James Stauffer Date: Mon, 25 Aug 2014 13:33:37 -0500 Subject: [PATCH 1/4] Grabs the username from the log and includes that in the request. --- replay.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/replay.js b/replay.js index d36e6c5..a7b00fd 100644 --- a/replay.js +++ b/replay.js @@ -24,6 +24,8 @@ try { process.exit(1); } +console.log('Playing ' + config.source + ' against ' + config.target.host + ':' + config.target.port); + // Require the necessary modules var http = config.target.port == '443' ? require('https') : require('http'); var Lazy = require('lazy'); @@ -31,7 +33,7 @@ var spawn = require('child_process').spawn; var logfile = spawn('cat', [config.source]); // Set up some variables -var regexLogLine = /^[0-9a-f.:]+ - - \[([0-9]{2}\/[a-z]{3}\/[0-9]{4}):([0-9]{2}:[0-9]{2}:[0-9]{2}[^\]]*)\] \"([^\"]+)\" [0-9]+ [0-9]+/i; +var regexLogLine = /^[0-9a-f.:]+ - ([^ ]+) \[([0-9]{2}\/[a-z]{3}\/[0-9]{4}):([0-9]{2}:[0-9]{2}:[0-9]{2}[^\]]*)\] \"([^\"]+)\" [0-9]+ [0-9]+/i; var regexHttpRequest = /^(GET|POST) (.+) HTTP\/(1.[0-1])$/i; var dtStart = Date.now(); var dtDuration = 0; @@ -44,9 +46,10 @@ Lazy(logfile.stdout) .map(String) .map(function (line) { // Chop the line + console.log('Parsing: ' + line); var parts = regexLogLine.exec(line); if ( parts != null ) { - var recDate = Date.parse(new Date(parts[1]+' '+parts[2])); + var recDate = Date.parse(new Date(parts[2]+' '+parts[3])); // Determine the earliest datetime covered by log if (recDate < dtStart ) { @@ -54,13 +57,14 @@ Lazy(logfile.stdout) } // Process the HTTP request portion - var httpRec = regexHttpRequest.exec(parts[3]); + var httpRec = regexHttpRequest.exec(parts[4]); if ( httpRec != null ) { return { datetime: recDate, method: httpRec[1], http: httpRec[3], - uri: httpRec[2] + uri: httpRec[2], + username: parts[1] }; } } @@ -109,13 +113,15 @@ Lazy(logfile.stdout) // FIRE ZE MISSILES!!...er, requests, I mean requestSet[runOffset].forEach(function(item){ var reqNum = reqSeq++; + console.log(item.username + ': ' + item.uri); var req = http.request({ host: config.target.host, port: config.target.port, path: item.uri, method: item.method, reqStart: new Date().getTime(), - agent: false + agent: false, + auth: item.username + ':' }, function(resp) {} ) From daf0a10fa9b48c5e517febb0b997973c52d8faf4 Mon Sep 17 00:00:00 2001 From: James Stauffer Date: Mon, 25 Aug 2014 14:55:21 -0500 Subject: [PATCH 2/4] Catch error when doing HTTP request. --- replay.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replay.js b/replay.js index a7b00fd..f641cda 100644 --- a/replay.js +++ b/replay.js @@ -46,7 +46,6 @@ Lazy(logfile.stdout) .map(String) .map(function (line) { // Chop the line - console.log('Parsing: ' + line); var parts = regexLogLine.exec(line); if ( parts != null ) { var recDate = Date.parse(new Date(parts[2]+' '+parts[3])); @@ -126,6 +125,7 @@ Lazy(logfile.stdout) function(resp) {} ) .on('socket', function() { timings[reqNum] = new Date().getTime(); }) + .on('error', function(e) { console.log('problem with request: ' + e.message); }) .on('response', function(resp) { var diff = (new Date().getTime()) - timings[reqNum]; console.log(' - #' + reqNum + ' [DT=' + diff + 'ms, R=' + resp.statusCode + ']'); } From 5845250f883440b52d201869d2779927221e147e Mon Sep 17 00:00:00 2001 From: James Stauffer Date: Tue, 26 Aug 2014 07:30:46 -0500 Subject: [PATCH 3/4] Supports an optional anonymous user that will be used for all requests that don't have a user specified. --- replay.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/replay.js b/replay.js index f641cda..46781a5 100644 --- a/replay.js +++ b/replay.js @@ -63,7 +63,7 @@ Lazy(logfile.stdout) method: httpRec[1], http: httpRec[3], uri: httpRec[2], - username: parts[1] + username: parts[1] != '-' ? parts[1] : (!config.anonymousUser ? null : config.anonymousUser) }; } } @@ -112,7 +112,8 @@ Lazy(logfile.stdout) // FIRE ZE MISSILES!!...er, requests, I mean requestSet[runOffset].forEach(function(item){ var reqNum = reqSeq++; - console.log(item.username + ': ' + item.uri); + var toString = reqNum + ': ' + (item.username == null ? '' : (item.username + '@')) + item.uri; + console.log(toString); var req = http.request({ host: config.target.host, port: config.target.port, @@ -120,15 +121,15 @@ Lazy(logfile.stdout) method: item.method, reqStart: new Date().getTime(), agent: false, - auth: item.username + ':' + auth: item.username == null ? null : (item.username + ':') }, function(resp) {} ) .on('socket', function() { timings[reqNum] = new Date().getTime(); }) - .on('error', function(e) { console.log('problem with request: ' + e.message); }) + .on('error', function(e) { console.log(toString + ': ' + e.message); }) .on('response', function(resp) { var diff = (new Date().getTime()) - timings[reqNum]; - console.log(' - #' + reqNum + ' [DT=' + diff + 'ms, R=' + resp.statusCode + ']'); } + console.log(toString + ' [DT=' + diff + 'ms, R=' + resp.statusCode + ']'); } ); req.end(); }); From 74fa32fb4ac658db4e5012d2adae1fa801854ca2 Mon Sep 17 00:00:00 2001 From: James Stauffer Date: Tue, 26 Aug 2014 08:09:04 -0500 Subject: [PATCH 4/4] Exit if there is an "getaddrinfo ENOTFOUND" or "connect EMFILE" error. --- replay.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/replay.js b/replay.js index 46781a5..6d80228 100644 --- a/replay.js +++ b/replay.js @@ -126,7 +126,13 @@ Lazy(logfile.stdout) function(resp) {} ) .on('socket', function() { timings[reqNum] = new Date().getTime(); }) - .on('error', function(e) { console.log(toString + ': ' + e.message); }) + .on('error', function(e) { + console.log(toString + ': ' + e.message); + if(e.message.indexOf('getaddrinfo ENOTFOUND') > -1 || e.message.indexOf('connect EMFILE') > -1) { + console.log('Exiting'); + process.exit(1); + } + }) .on('response', function(resp) { var diff = (new Date().getTime()) - timings[reqNum]; console.log(toString + ' [DT=' + diff + 'ms, R=' + resp.statusCode + ']'); }