简体   繁体   English

如何发送 gzip 压缩的正文

[英]How to send gzip compressed body

We want to send compressed body by gzip HTTP request in chai-http in mocha.我们想在 mocha 的chai-http中通过 gzip HTTP 请求发送压缩的主体。

let chai = require('chai');
let chaiHttp = require('chai-http');
const zlib = require('zlib');

chai.use(chaiHttp);


object = {
    "content": {
        "data": {
            "key": "testval"
        }
    }
};

const objStr = JSON.stringify(object);
const objBuf = Buffer.from(objStr, "utf-8");
const bodyContent = zlib.gzipSync(objBuf);
const bodyLen = Buffer.byteLength(bodyContent, 'utf-8');

chai.request("http://serverurl")
    .post('/path')
    .set('Content-Type', 'application/json')
    .set('Content-Encoding', 'gzip')
    .set('Content-Length', bodyLen) 
    .set('Accept-Encoding', 'gzip')
    .send(bodyContent)
    .end((err, res) => {
        expect(err).to.be.null;
        expect(res).to.have.status(200);

        done();
    });

However, we met the error Error: incorrect header check at Zlib.zlibOnError on the server-side.但是,我们在服务器端遇到错误Error: incorrect header check at Zlib.zlibOnError Is there anything am I missing?我有什么想念的吗?

Looks like it's superagent, it's breaking the encoding, because it stringifies everything that is not a string and has application/json , so instead of a Buffer:看起来它是超级代理,它破坏了编码,因为它对所有不是字符串且具有application/json的东西进行了字符串化,因此不是缓冲区:

<Buffer 1f 8b 08 00 00 00 

it's sending a JSON:它正在发送 JSON:

{"type":"Buffer","data":[31,139,8,0,...

breaking the encoding, causing the error.破坏编码,导致错误。

It happens here:它发生在这里:

https://github.com/visionmedia/superagent/blob/2f4af99bdee91b9fc63c6563abae367a4b3f1a8e/src/node/index.js#L988-L996 https://github.com/visionmedia/superagent/blob/2f4af99bdee91b9fc63c6563abae367a4b3f1a8e/src/node/index.js#L988-L996

Adding .Buffer.isBuffer(data) or something there might work.添加.Buffer.isBuffer(data)或可能会起作用的东西。

Until then, try a workaround, for example with http :在此之前,请尝试解决方法,例如使用http

const http = require('http')


const options = {
  hostname: 'serverurl',
  port: 443,
  path: '/path',
  method: 'POST',
  headers: {
    'Content-Encoding': 'gzip',
    'Content-Type': 'application/json',
    'Accept-Encoding': 'gzip',
    'Content-Length': bodyLen
  }
};

const req = http.request(options, (res) => {

  //res.setEncoding('utf8');
  //res.on('data', function(chunk) {
  //  console.log('data', chunk);
  //});

  expect(res).to.have.status(200);
  done();

});
req.on('error', function(e) {
  console.log('err: ' + e.message);
  //expect(err).to.be.null;
  process.exit();
});

req.write(bodyContent);
req.end();

I was able to make this function for superagent by overriding the serialize function when application/json is in play.当 application/json 正在运行时,我可以通过覆盖序列化 function 来为超级代理制作这个 function。 If the buffer is identified as a gzip buffer, then let it pass through the serialization unmodified.如果缓冲区被识别为 gzip 缓冲区,则让它不加修改地通过序列化。

var isgzipBuffer = require('@stdlib/assert-is-gzip-buffer')

superagent.serialize['application/json'] = function(...args) {
    if (isgzipBuffer(args[0]) === false) {
        return JSON.stringify(...args)
    }
    return args[0]
}

I also added this to update the Content-Encoding:我还添加了这个来更新内容编码:

       if (isgzipBuffer(bodyParam) === true) {
            headerParams['Content-Encoding'] = 'gzip'
        }

This was done within the context of a codegen javascript client so exact syntax for setting headers may vary.这是在 codegen javascript 客户端的上下文中完成的,因此设置标头的确切语法可能会有所不同。

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

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