Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode nock recorded response

How to ad-hoc decode/uncompress the output produced by the nock recorder so we can see the response as text? I guess we do not understand if the response is gzipped and/or encoded

The object works find when we load it into nock, and our tests are behaving as we expect. To see what the API produced, we are having to put logging statements in the implementation file.

We are recording and saving the JSON the responses:

nock.recorder.rec({output_objects: true, dont_print: true});
JSON.stringify(nock.recorder.play())

And our file looks like:

[
  {
    "scope": "https://some.api.com:443",
    "method": "POST",
    "path": "/auth?key=some_key",
    "body": {
      "logonId": "[email protected]",
      "logonPassword": "secret"
    },
    "status": 400,
    "response": [
      "1f8b0800000000000000458cbd6ac34010067b3fc5c735691263bb741344ec42f827420a492916692d1d9cb461f71c218cdf3d97266e6786b92d00c7aaa205290d1c59cd6d71bb3fff8b376939a1cd6abd7ac003cf89b97a5f96757efecc8ef9aede9fb2fc586455f5f55eeedca33db119757f0f5704266334a2ca4d44ec19170941263f76f06657b62dd6cb2af919ec9357cc7255f0cb403e4014df643689b6687d3b3e450c149b1e534f1113a3a71f868cb8f8c04b7ca48b8fa08efcf8ea16f75fa1776d91ee000000"
    ],
    "headers": {
      "cache-control": "no-store, no-cache, must-revalidate",
      "content-encoding": "gzip",
      "content-type": "application/json",
      "transfer-encoding": "chunked",
      "connection": "Close"
    }
  }
]
like image 218
donnie_armstrong Avatar asked Jan 26 '15 15:01

donnie_armstrong


3 Answers

The response from the http request is coming back as gzipped data, indicated by the content-encoding header. Nock is saving this data a hex encoded buffer string.

You can convert these cassettes into json with the following utility:

var zlib = require('zlib');
var fs = require('fs');
var argv = process.argv.slice(2);
var path = require('path');

var filename = path.resolve(argv[0]);
var file = fs.readFileSync(filename, { encoding: 'utf8' });
var cassettes = JSON.parse(file);

cassettes.forEach(function (cassette) {
  if (cassette.headers['content-encoding'] !== 'gzip') {
    return;
  }

  var response = new Buffer(cassette.response[0], 'hex');

  var contents = zlib.gunzipSync(response).toString('utf8');

  cassette.response = JSON.parse(contents);
  delete cassette.headers['content-encoding'];
});

fs.writeFileSync(filename, JSON.stringify(cassettes, null, 2), { encoding: 'utf8' });

Note, this will overwrite the original cassette with one that has converted all gzip requests into json. Also note that I'm not checking content type, so you'll need to adapt this if you have responses that aren't json.

like image 119
ChiperSoft Avatar answered Nov 09 '22 05:11

ChiperSoft


Nock serialize compressed (gzipped) response as "hex buffer"; luckily xxd can revert the hex-buffer to binary data that can be gunzipped to get the plain json text.

in summary: echo <YOUR-HEX-BUFFER-HERE> | xxd -r -p | gunzip

with reference to the example in question:

$ echo 1f8b0800000000000000458cbd6ac34010067b3fc5c735691263bb741344ec42f827420a492916692d1d9cb461f71c218cdf3d97266e6786b92d00c7aaa205290d1c59cd6d71bb3fff8b376939a1cd6abd7ac003cf89b97a5f96757efecc8ef9aede9fb2fc586455f5f55eeedca33db119757f0f5704266334a2ca4d44ec19170941263f76f06657b62dd6cb2af919ec9357cc7255f0cb403e4014df643689b6687d3b3e450c149b1e534f1113a3a71f868cb8f8c04b7ca48b8fa08efcf8ea16f75fa1776d91ee000000 \
> | xxd -r -p \
> | gunzip
{
  "errorParameters": {},
  "errorCode": 2010,
  "errorKey": "_ERR_INVALID_EMAILPASSWORD",
  "errorMessage": "Please correct the following issues: 1.Sorry either your e-mail or password didn't match what we have on file. Try it again?"
}

Also at the moment I'm answering there are active discussions and proposals on the nock project and may be this could change in future releases; with reference to:

  • https://github.com/nock/nock/issues/1212
  • https://github.com/nock/nock/pull/1372
  • https://github.com/nock/nock/issues/1212
like image 4
Franco Rondini Avatar answered Nov 09 '22 06:11

Franco Rondini


Use jq with xxd to extract and decode the response field:

jq -r .response file.json | xxd -r -p | gunzip
like image 1
Patrick Fisher Avatar answered Nov 09 '22 05:11

Patrick Fisher