http-proxy-middleware icon indicating copy to clipboard operation
http-proxy-middleware copied to clipboard

Http Header Content-Encoding is wrong when access k8s api watch interface

Open GrantDuan opened this issue 3 years ago • 0 comments
trafficstars

Describe the feature you'd love to see

I implemented an react app to access k8s api directly. Everything work well until I tried to access the an interface with query parameter watch=1, for example: api/v1/configmaps?watch=1. By default, I mean the config is:

'/apis/': {
      target: 'https://*.*.*.*:6443',
      changeOrigin: true,
      secure: false,
    },

header Content-Encoding return by proxy is 'gzip'. It's wrong, I think the response is not compressed. when watch=1, k8s api will return response chunked, uncompressed, and the response will not end. (it looks like that, the browser will not deal with compressed and chunked response until the reponse is end.) So I google and change the config to be:

selfHandleResponse: true,
onProxyRes: function onProxyRes(proxyRes, req, res) {
        proxyRes.on('data', function (data) {
          res.write(data);
        });
        proxyRes.on('end', function () {
          res.end();
        });
      },

Then, access of interface with parameter watch like api/v1/configmaps?watch=1 works. there is not header 'Content-Coding' in the response of proxy, and browser handle the chunked response correctly. But the issue is every response from proxy has no header 'Content-Coding', even for those compressed resposne from k8s api. Browser cannot handle the compressed response correctly without header 'Content-Coding'.

Then I try to set header according to the headers fo response from k8s api. the config is:

 selfHandleResponse: true,
      onProxyRes: function onProxyRes(proxyRes, req, res) {
        for (const prop in proxyRes.headers) {
          res.setHeader(prop, proxyRes.headers[prop]);
        }

        proxyRes.on('data', function (data) {
          res.write(data);
        });
        proxyRes.on('end', function () {
          res.end();
        });
      },

Now, the problem is same as the begining, the header ‘Content-Coding’ is always 'gzip', even when watch=1 and the header 'content-coding' is not in the proxyRes.headers. I lost many hairs but cannot figure out the reason.

the work around is only set header 'Content-Coding', do not touch other headers, the config looks like below:

selfHandleResponse: true,
onProxyRes: function onProxyRes(proxyRes, req, res) {
        if (proxyRes.headers['content-encoding']) {
          res.setHeader('content-encoding', proxyRes.headers['content-encoding']);
        }

        proxyRes.on('data', function (data) {
          res.write(data);
        });
        proxyRes.on('end', function () {
          res.end();
        });
      },

the con is that access of most api is not compressed, even for those api without parameter 'watch', like api/v1/configmaps. this affect the performance.

Thank you everyone in advance. If someone could help, it would be great. I have to left this issue for now, because I have spent too much time on this issue.

Additional context (optional)

No response

GrantDuan avatar Dec 30 '21 03:12 GrantDuan