简体   繁体   English

如何解码 nock 记录的响应

[英]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?如何对 nock 记录器产生的输出进行临时解码/解压缩,以便我们可以将响应视为文本? 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.当我们将它加载到 nock 中时,该对象会正常工作,并且我们的测试表现与我们预期的一样。 To see what the API produced, we are having to put logging statements in the implementation file.要查看 API 生成了什么,我们必须将日志记录语句放入实现文件中。

We are recording and saving the JSON the responses:我们正在记录并保存 JSON 响应:

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": "user@api.com",
      "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"
    }
  }
]

The response from the http request is coming back as gzipped data, indicated by the content-encoding header. http 请求的响应以压缩数据的形式返回,由content-encoding标头指示。 Nock is saving this data a hex encoded buffer string. Nock 将此数据保存为十六进制编码的缓冲区字符串。

You can convert these cassettes into json with the following utility:您可以使用以下实用程序将这些磁带转换为 json:

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.请注意,这将使用已将所有 gzip 请求转换为 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.另请注意,我没有检查内容类型,因此如果您的响应不是 json,则需要对其进行调整。

Nock serialize compressed (gzipped) response as "hex buffer"; Nock 将压缩(gzipped)响应序列化为“十六进制缓冲区”; luckily xxd can revert the hex-buffer to binary data that can be gunzipped to get the plain json text.幸运的是, xxd可以将十六进制缓冲区恢复为二进制数据,可以将其压缩以获得纯 json 文本。

in summary: echo <YOUR-HEX-BUFFER-HERE> | xxd -r -p | gunzip总之: echo <YOUR-HEX-BUFFER-HERE> | xxd -r -p | gunzip 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;此外,目前我正在回答关于 nock 项目的积极讨论和建议,这可能会在未来的版本中发生变化; with reference to:参考:

使用jqxxd来提取和解码响应字段:

jq -r .response file.json | xxd -r -p | gunzip

A little late to the party, but using Franco Rondini's and ChiperSoft's answer I came up with this:派对有点晚了,但使用 Franco Rondini 和 ChiperSoft 的回答我想出了这个:

const zlib = require('zlib');

// Goes from a hex representation of gzipped binary data to an object
module.exports.decode = input => {
  if (typeof input.join === 'function') {
    input = input.join('');
  }

  const tempBuffer = Buffer.from(input, 'hex');
  const unzippedBuffer = zlib.gunzipSync(tempBuffer);
  const contents = unzippedBuffer.toString('utf8');

  return JSON.parse(contents);
};

// Goes from an object to a zipped buffer encoded in hex
module.exports.encode = input => {
  const inputAsString = JSON.stringify(input);
  const tempBuffer = Buffer.from(inputAsString);
  const zippedBuffer = zlib.gzipSync(tempBuffer);

  return zippedBuffer.toString('hex');
};

This is probably not perfect but it was helpful to be able to replace replies on the fly with objects.这可能并不完美,但能够用对象动态替换回复很有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM