diff --git a/.gitignore b/.gitignore index 69a671c..3c3629e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ node_modules -/lib \ No newline at end of file diff --git a/.npmignore b/.npmignore index b7ccf7b..c1c9f4d 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1 @@ -src/ .git* - diff --git a/.travis.yml b/.travis.yml index 05d5124..a170b52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - 4 - 6 - 8 - 'stable' diff --git a/lib/parser.js b/lib/parser.js new file mode 100644 index 0000000..aaa8559 --- /dev/null +++ b/lib/parser.js @@ -0,0 +1,123 @@ +function dir(ident) { + if (ident === '=>') { + return 'request'; + } + if (ident === '<=') { + return 'response'; + } +} + +function parse(trace) { + // better regex, please, start here: + // http://scriptular.com/#%5E(%3F%3A%5Ba-z0-9%5D%7B4%7D%3A)%20((%3F%3A%5Ba-z0-9%5D%7B2%7D%20)%7B1%2C16%7D)%7C%7C%7C%7C%7C%7C%7C%7C%5B%2200a0%3A%2011%2022%2033%2044%2055%2066%2077%2088%2099%2010%2011%2012%2013%2014%2015%2016%2017%20%20%7B.%20%20%5C%22headers%5C%22%3A%20%7B%22%5D + const traceLines = trace.split('\n'); + const dataPattern = /^(?:[a-z0-9]{4}:) ((?:[a-z0-9]{2} ){1,16})/; + const dirPattern = /^(=>|<=)/; + + // find ASCI bytes in raw lines + + // will contain array of arrays with direction and data + // e.g [['<=', "47 45 54 20 2f 73 68 6f 70 70 69 6e 67 2d 63 61"]] + const asciiHexSets = []; + let lastDir = ''; + + for (const line of traceLines) { + const dirMatch = dirPattern.exec(line); + if (dirMatch !== null) { + lastDir = dirMatch[0].trim(); + } + + const dataMatch = dataPattern.exec(line); + if (dataMatch !== null) { + const data = dataMatch[1].trim(); + asciiHexSets.push([lastDir, data]); + } + } + + // split lines by spaces and make array of ASCII hex bytes + const asciiHexBuffer = { request: [], response: [] }; + for (const [direction, data] of asciiHexSets) { + for (const byte of data.split(' ')) { + asciiHexBuffer[dir(direction)].push(byte); + } + } + + // convert ASCII hex to ASCII integers codes + const asciiIntBuffer = { request: [], response: [] }; + for (const key of Object.keys(asciiHexBuffer)) { + const hexs = asciiHexBuffer[key]; + for (const hex of hexs) { + asciiIntBuffer[key].push(parseInt(hex, 16)); + } + } + + // convert ACII codes to charactes + const stringBuffer = { request: [], response: [] }; + for (const key of Object.keys(asciiIntBuffer)) { + const codes = asciiIntBuffer[key]; + for (const code of codes) { + stringBuffer[key].push(String.fromCharCode(code)); + } + } + + return { + request: stringBuffer.request.join(''), + response: stringBuffer.response.join('') + }; +} + +function parseToString(trace) { + const message = parse(trace); + let output = ''; + + const request = []; + const requestLines = message.request.split('\r\n'); + for (const line of requestLines) { + request.push(`> ${line}`); + } + output += request.join('\r\n'); + output += '\n'; + output += '\r\n'; + const response = []; + const responseLines = message.response.split('\r\n'); + for (const line of responseLines) { + response.push(`< ${line}`); + } + output += response.join('\r\n'); + output += '\n'; + return output; +} + +function parseBackRequestAndResponseFromString(string) { + const output = {request: '', response: ''}; + + const request = []; + const stringLines = string.split('\r\n'); + for (const line of stringLines) { + if (line.startsWith('> ')) { + request.push(line.replace(/^> /, '')); + } + } + + // removing trailing LF + output.request = request.join('\r\n').replace(/\n$/, ''); + + const response = []; + for (const line of stringLines) { + if (line.startsWith('< ')) { + response.push(line.replace(/^< /, '')); + } + } + + // removing trailing LF + output.response = response.join('\r\n').replace(/\n$/, ''); + + return output; +} + +module.exports = { + parseBackRequestAndResponseFromString, + parseBack: parseBackRequestAndResponseFromString, + parseToString, + parse +}; diff --git a/package.json b/package.json index b155b1d..4492a12 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Parse curl --trace option output to raw HTTP message", "main": "lib/parser.js", "engines": { - "node": ">= 4" + "node": ">= 6" }, "scripts": { "test": "scripts/test", diff --git a/scripts/build b/scripts/build deleted file mode 100755 index 8bcd475..0000000 --- a/scripts/build +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -if [ -d "src/" ]; then - rm -fr lib/ - node_modules/.bin/coffee -b -c -o lib/ src/ - #mkdir lib - #cp -a -R src/* lib/ -fi - - diff --git a/scripts/prepublish b/scripts/prepublish index 2fcc6bf..a5344cf 100755 --- a/scripts/prepublish +++ b/scripts/prepublish @@ -1,3 +1,2 @@ #!/bin/sh -./scripts/test && -./scripts/build \ No newline at end of file +./scripts/test diff --git a/scripts/test b/scripts/test index abfee6d..72ca538 100755 --- a/scripts/test +++ b/scripts/test @@ -1,3 +1,2 @@ #!/bin/sh -./scripts/build ./node_modules/mocha/bin/mocha --reporter spec --compilers=coffee:coffeescript/register ./test/**/*-test.coffee diff --git a/src/parser.coffee b/src/parser.coffee deleted file mode 100644 index c2ba2d0..0000000 --- a/src/parser.coffee +++ /dev/null @@ -1,106 +0,0 @@ -parse = (trace) -> - - dir = (ident) -> - - if ident == "=>" - return "request" - if ident == "<=" - return "response" - - # better regex, please, start here: - # http://scriptular.com/#%5E(%3F%3A%5Ba-z0-9%5D%7B4%7D%3A)%20((%3F%3A%5Ba-z0-9%5D%7B2%7D%20)%7B1%2C16%7D)%7C%7C%7C%7C%7C%7C%7C%7C%5B%2200a0%3A%2011%2022%2033%2044%2055%2066%2077%2088%2099%2010%2011%2012%2013%2014%2015%2016%2017%20%20%7B.%20%20%5C%22headers%5C%22%3A%20%7B%22%5D - - traceLines = trace.split("\n") - dataPattern = /^(?:[a-z0-9]{4}:) ((?:[a-z0-9]{2} ){1,16})/ - dirPattern = /^(=>|<=)/ - - # find ASCI bytes in raw lines - - # will contain array of arrays with direction and data - # e.g [['<=', "47 45 54 20 2f 73 68 6f 70 70 69 6e 67 2d 63 61"]] - asciiHexSets = [] - lastDir = "" - - for line in traceLines - dirMatch = dirPattern.exec line - unless dirMatch == null - lastDir = dirMatch[0].trim() - - dataMatch = dataPattern.exec line - unless dataMatch == null - data = dataMatch[1].trim() - asciiHexSets.push [lastDir, data] - - - # split lines by spaces and make array of ASCII hex bytes - asciiHexBuffer = {request: [], response: []} - for set in asciiHexSets - data = set[1] - for byte in data.split " " - asciiHexBuffer[dir(set[0])].push byte - - #convert ASCII hex to ASCII integers codes - asciiIntBuffer = {request: [], response: []} - for dir, hexs of asciiHexBuffer - for hex in hexs - asciiIntBuffer[dir].push(parseInt('0x' + hex)) - - #convert ACII codes to charactes - stringBuffer = {request: [], response: []} - for dir, codes of asciiIntBuffer - for code in codes - stringBuffer[dir].push String.fromCharCode code - - output = {} - output['request'] = stringBuffer['request'].join "" - output['response'] = stringBuffer['response'].join "" - output - - -parseToString = (trace) -> - message = parse(trace) - output = "" - - request = [] - requestLines = message['request'].split "\r\n" - for line in requestLines - request.push "> " + line - output += request.join "\r\n" - output += "\n" - output += "\r\n" - response = [] - responseLines = message['response'].split "\r\n" - for line in responseLines - response.push "< " + line - output += response.join "\r\n" - output += "\n" - output - - - -parseBackRequestAndResponseFromString = (string) -> - output = {} - - request = [] - stringLines = string.split('\r\n') - for line in stringLines - request.push line.replace /^> /, '' if /^> /.test line - - #removing trailing LF - output['request'] = request.join('\r\n').replace /\n$/, '' - - response = [] - for line in stringLines - response.push line.replace /^< /, '' if /^< /.test line - - #removing trailing LF - output['response'] = response.join('\r\n').replace /\n$/, '' - - output - - -module.exports.parseBackRequestAndResponseFromString = parseBackRequestAndResponseFromString -module.exports.parseBack = parseBackRequestAndResponseFromString -module.exports.parseToString = parseToString -module.exports.parse = parse - diff --git a/test/integration/cli-test.coffee b/test/integration/cli-test.coffee index f2f4397..0d954d7 100644 --- a/test/integration/cli-test.coffee +++ b/test/integration/cli-test.coffee @@ -5,14 +5,6 @@ fs = require('fs') cmdPrefix = '' describe "Command line", () -> - before (done) -> - #CLI is linked with native JS in /lib so re-compile Coffee /src to /lib - cmd = './scripts/build' - cli = exec cmdPrefix + cmd, (error, out, err) -> - if error - done error - done() - describe "parsing from standard input with --raw", () -> stdout = "" stderr = "" diff --git a/test/integration/js-api-test.coffee b/test/integration/js-api-test.coffee index dc2ed2a..013890e 100644 --- a/test/integration/js-api-test.coffee +++ b/test/integration/js-api-test.coffee @@ -2,7 +2,7 @@ fs = require 'fs' {assert} = require('chai') {exec} = require('child_process') -parser = require('../../src/parser') +parser = require('../../lib/parser') describe "Javascript API", () -> describe "parsing from file", () -> diff --git a/test/unit/parser-test.coffee b/test/unit/parser-test.coffee index ee0119c..c06fab8 100644 --- a/test/unit/parser-test.coffee +++ b/test/unit/parser-test.coffee @@ -1,6 +1,6 @@ fs = require 'fs' assert = require('chai').assert -parser = require '../../src/parser' +parser = require '../../lib/parser' describe 'parser module', () -> output = ""