From 48feb0c15c634abe6ce58861f099b9b7ba92ede3 Mon Sep 17 00:00:00 2001 From: Adam Kliment Date: Tue, 30 Jul 2013 13:47:03 +0200 Subject: [PATCH 1/2] API Blueprint output format --- README.md | 86 +++++++++++++++++++-------- bin/curl-trace-parser | 30 ++++++++-- package.json | 11 +++- test/fixtures/get/expected-output.md | 28 +++++++++ test/fixtures/post/expected-output.md | 28 +++++++++ test/integration/cli-test.coffee | 34 ++++++++++- 6 files changed, 184 insertions(+), 33 deletions(-) create mode 100644 test/fixtures/get/expected-output.md create mode 100644 test/fixtures/post/expected-output.md diff --git a/README.md b/README.md index bf8fddf..74614a7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The only glitch is that cURL `--trace` saves data in [its custom format][gist], $ curl --trace - http://httpbin.org/ip | curl-trace-parser ``` -## Example +## Sample API We will be using this [sample API][apiarydoc] created with the [Apiary.io mock server](http://apiary.io) to demonstrate tracing an HTTP communication and the use of the cURL trace parser. @@ -45,51 +45,89 @@ Note this cURL example is copied and pasted from [Apiary interactive API documen [example]: http://docs.curltraceparser.apiary.io/#get-%2Fshopping-cart -## Parse the trace file from command line +## Exapmles + +### `--raw` output foramt + +The output is ASCII representation of a raw [HTTP message][message] with few modifications: + +- Request line begins with `> ` +- Response line begins with `< ` +- Request and response is delimited by CR+LF +- Both Request and Response are terminated by an extra trailing LF + +Note: This is little bit tricky because HTTP RFC does not have declared delimiter for Request and Response, for obvious reasons. ```bash -$ cat tracefile | curl-trace-parser -> GET /shopping-cart HTTP/1.1 +$ cat tracefile | curl-trace-parser --raw +> POST /shopping-cart HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5 > Host: curltraceparser.apiary.io > Accept: */* -> +> Content-Type: application/json +> Content-Length: 39 > +> { "product":"1AB23ORM", "quantity": 2 } -< HTTP/1.1 200 OK +< HTTP/1.1 201 Created < Content-Type: application/json -< Date: Sun, 21 Jul 2013 13:23:55 GMT +< Date: Tue, 30 Jul 2013 11:32:30 GMT < X-Apiary-Ratelimit-Limit: 120 < X-Apiary-Ratelimit-Remaining: 119 -< Content-Length: 119 +< Content-Length: 50 < Connection: keep-alive < -< { "items": [ -< { "url": "/shopping-cart/1", "product":"2ZY48XPZ", "quantity": 1, "name": "New socks", "price": 1.25 } -< ] } +< { "status": "created", "url": "/shopping-cart/2" } +``` + +### `--blueprint` output format + +The output is HTTP Request and Response in the [API blueprint format](http://apiblueprint.org) + +```bash +$ cat tracefile | ./bin/curl-trace-parser --blueprint +# POST /shopping-cart ++ Request + + Headers + + User-Agent:curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5 + Host:curltraceparser.apiary.io + Accept:*/* + Content-Type:application/json + Content-Length:39 + + + Body + + { "product":"1AB23ORM", "quantity": 2 } + ++ Response 201 + + Headers + + Content-Type:application/json + Date:Tue, 30 Jul 2013 11:32:30 GMT + X-Apiary-Ratelimit-Limit:120 + X-Apiary-Ratelimit-Remaining:119 + Content-Length:50 + Connection:keep-alive + + + Body + + { "status": "created", "url": "/shopping-cart/2" } + ``` -## Parse the trace file using Node.JS +Note: This format does not expect any CR+LF in body + +### Parse the trace to raw HTTP file using Node.JS ```javascript var fs = require('fs'); var parser = require('curl-trace-parser'); fs.readFile('./tracefile', 'utf8', function (err,trace) { - console.log(parser.parseToString(trace)); + console.log(parser.parse(trace)); }) ``` -## Output format - -The output is ASCII representation of a raw [HTTP message][message] with few modifications: - -- Request line begins with `> ` -- Response line begins with `< ` -- Request and response is delimited by CR+LF -- Both Request and Response are terminated by an extra trailing LF - -Note: This is little bit tricky because HTTP RFC does not have declared delimiter for Request and Response, for obvious reasons. - ## Output format reverse parser ```javascript diff --git a/bin/curl-trace-parser b/bin/curl-trace-parser index 1cf46a0..d18e1a3 100755 --- a/bin/curl-trace-parser +++ b/bin/curl-trace-parser @@ -1,21 +1,43 @@ #!/usr/bin/env node var cmd = require('commander'); -var parser = require('../lib/parser'); -cmd.version('0.0.1'); +var curl = require('../lib/parser'); +var http = require('http-string-parser'); +var bf = require('api-blueprint-http-formatter') var stdin = ""; process.stdin.resume(); process.stdin.setEncoding('utf8'); +cmd.command('curl-trace-parser') + .description('Parse output form curl --trace option') + .version('0.0.8') + .option('-r, --raw', 'Output raw data (Default)') + .option('-b, --blueprint', 'Output in API blueprint format') + .parse(process.argv); + process.stdin.on('data', function(data) { stdin += data; }); process.stdin.on('end', function() { - parserOutput = parser.parseToString(stdin) - process.stdout.write(parserOutput); + //TODO commander options does not work here :( + var option = process.argv[2]; + + if(option == '-r' || option == '--raw' || option == undefined){ + var parserOutput = curl.parseToString(stdin); + process.stdout.write(parserOutput); + } + if(option == 'b' || option == '--blueprint'){ + var rawPair = curl.parse(stdin); + parsedPair = { + 'request': http.parseRequest(rawPair['request']), + 'response': http.parseResponse(rawPair['response']) + } + var blueprint = bf.format(parsedPair); + process.stdout.write(blueprint); + } process.exit(0) }); diff --git a/package.json b/package.json index 646a68d..13b6464 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "curl-trace-parser", - "version": "0.0.7", + "version": "0.0.8", "description": "Parse curl --trace option output to raw HTTP message", "main": "lib/parser.js", "scripts": { @@ -11,7 +11,9 @@ "curl-trace-parser": "bin/curl-trace-parser" }, "dependencies": { - "commander": "1.2.0" + "commander": "1.2.0", + "api-blueprint-http-formatter": "0.0.1", + "http-string-parser": "0.0.4" }, "devDependencies": { "coffee-script": "1.6.3", @@ -26,7 +28,10 @@ "http", "message", "request", - "repsponse" + "repsponse", + "api", + "blueprint", + "apiary" ], "author": "Adam Kliment ", "license": "MIT", diff --git a/test/fixtures/get/expected-output.md b/test/fixtures/get/expected-output.md new file mode 100644 index 0000000..b07e362 --- /dev/null +++ b/test/fixtures/get/expected-output.md @@ -0,0 +1,28 @@ +# GET /shopping-cart ++ Request + + Headers + + User-Agent:curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5 + Host:curltraceparser.apiary.io + Accept:*/* + + + Body + + + ++ Response 200 + + Headers + + Content-Type:application/json + Date:Sun, 21 Jul 2013 13:23:55 GMT + X-Apiary-Ratelimit-Limit:120 + X-Apiary-Ratelimit-Remaining:119 + Content-Length:119 + Connection:keep-alive + + + Body + + { "items": [ + { "url": "/shopping-cart/1", "product":"2ZY48XPZ", "quantity": 1, "name": "New socks", "price": 1.25 } + ] } + diff --git a/test/fixtures/post/expected-output.md b/test/fixtures/post/expected-output.md new file mode 100644 index 0000000..424b2a5 --- /dev/null +++ b/test/fixtures/post/expected-output.md @@ -0,0 +1,28 @@ +# POST /shopping-cart ++ Request + + Headers + + User-Agent:curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5 + Host:curltraceparser.apiary.io + Accept:*/* + Content-Type:application/json + Content-Length:39 + + + Body + + { "product":"1AB23ORM", "quantity": 2 } + ++ Response 201 + + Headers + + Content-Type:application/json + Date:Sun, 21 Jul 2013 14:51:09 GMT + X-Apiary-Ratelimit-Limit:120 + X-Apiary-Ratelimit-Remaining:119 + Content-Length:50 + Connection:keep-alive + + + Body + + { "status": "created", "url": "/shopping-cart/2" } + diff --git a/test/integration/cli-test.coffee b/test/integration/cli-test.coffee index 9e4df76..f2f4397 100644 --- a/test/integration/cli-test.coffee +++ b/test/integration/cli-test.coffee @@ -13,14 +13,14 @@ describe "Command line", () -> done error done() - describe "parsing from standard input", () -> + describe "parsing from standard input with --raw", () -> stdout = "" stderr = "" exitStatus = "" before (done) -> cmd = 'cat ./test/fixtures/get/tracefile | ' + - './bin/curl-trace-parser' + './bin/curl-trace-parser --raw' cli = exec cmdPrefix + cmd, (error, out, err) -> stdout = out @@ -43,6 +43,36 @@ describe "Command line", () -> assert.equal stdout, expected done() + describe "parsing from standard input with --blueprint option", () -> + stdout = "" + stderr = "" + exitStatus = "" + + before (done) -> + cmd = 'cat ./test/fixtures/post/tracefile | ' + + './bin/curl-trace-parser --blueprint' + + cli = exec cmdPrefix + cmd, (error, out, err) -> + stdout = out + stderr = err + if error + exitStatus = error.status + done() + + cli.on 'exit', (code) -> + exitStatus = code + + it "should not return nothing to stderr", () -> + assert.equal stderr, "" + + it "should return with exit code 0", () -> + + it "should return parsed body in API Blueprint format to standard output", (done) -> + expectedOutputPath = "./test/fixtures/post/expected-output.md" + fs.readFile expectedOutputPath, 'utf8', (err, expected) -> + assert.equal stdout, expected + done() + describe "no input on stdin and no options", ()-> stdout = "" From adadd66ff7e1ea2cf6b9721d5ae69e44d05f342a Mon Sep 17 00:00:00 2001 From: Adam Kliment Date: Tue, 30 Jul 2013 13:53:25 +0200 Subject: [PATCH 2/2] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 74614a7..17bddae 100644 --- a/README.md +++ b/README.md @@ -45,15 +45,15 @@ Note this cURL example is copied and pasted from [Apiary interactive API documen [example]: http://docs.curltraceparser.apiary.io/#get-%2Fshopping-cart -## Exapmles +## Examples -### `--raw` output foramt +### `--raw` format The output is ASCII representation of a raw [HTTP message][message] with few modifications: - Request line begins with `> ` - Response line begins with `< ` -- Request and response is delimited by CR+LF +- Request and Response is delimited by CR+LF - Both Request and Response are terminated by an extra trailing LF Note: This is little bit tricky because HTTP RFC does not have declared delimiter for Request and Response, for obvious reasons. @@ -80,11 +80,11 @@ $ cat tracefile | curl-trace-parser --raw < { "status": "created", "url": "/shopping-cart/2" } ``` -### `--blueprint` output format +### `--blueprint` format -The output is HTTP Request and Response in the [API blueprint format](http://apiblueprint.org) +The output is HTTP Request and Response in the [API blueprint format](http://apiblueprint.org) which is the superset of markdown. -```bash +``` $ cat tracefile | ./bin/curl-trace-parser --blueprint # POST /shopping-cart + Request