繁体   English   中英

如何解码 nock 记录的响应

[英]How to decode nock recorded response

如何对 nock 记录器产生的输出进行临时解码/解压缩,以便我们可以将响应视为文本? 我想我们不明白响应是否被压缩和/或编码

当我们将它加载到 nock 中时,该对象会正常工作,并且我们的测试表现与我们预期的一样。 要查看 API 生成了什么,我们必须将日志记录语句放入实现文件中。

我们正在记录并保存 JSON 响应:

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

我们的文件看起来像:

[
  {
    "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"
    }
  }
]

http 请求的响应以压缩数据的形式返回,由content-encoding标头指示。 Nock 将此数据保存为十六进制编码的缓冲区字符串。

您可以使用以下实用程序将这些磁带转换为 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' });

请注意,这将使用已将所有 gzip 请求转换为 json 的磁带覆盖原始磁带。 另请注意,我没有检查内容类型,因此如果您的响应不是 json,则需要对其进行调整。

Nock 将压缩(gzipped)响应序列化为“十六进制缓冲区”; 幸运的是, xxd可以将十六进制缓冲区恢复为二进制数据,可以将其压缩以获得纯 json 文本。

总之: echo <YOUR-HEX-BUFFER-HERE> | xxd -r -p | gunzip echo <YOUR-HEX-BUFFER-HERE> | xxd -r -p | gunzip

参考有问题的示例:

$ 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?"
}

此外,目前我正在回答关于 nock 项目的积极讨论和建议,这可能会在未来的版本中发生变化; 参考:

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

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

派对有点晚了,但使用 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');
};

这可能并不完美,但能够用对象动态替换回复很有帮助。

暂无
暂无

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

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