Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http-proxy with gzip chunked server responses #1007

Open
wtritch opened this issue May 16, 2016 · 2 comments
Open

http-proxy with gzip chunked server responses #1007

wtritch opened this issue May 16, 2016 · 2 comments

Comments

@wtritch
Copy link

wtritch commented May 16, 2016

Node Version: 4.4.4
http-proxy version: 1.13.2

When proxying a browser request to a JSON RESTful endpoint that returns gzip content-encoding and chunked transfer-encoding the browser is receiving invalid bytes back from the proxy. This causes a browser error: ERR_CONTENT_DECODING_FAILED

It looks like the server is returning valid bytes to the proxy, but when http-proxy pipes the data from the proxy response to the browser response, the bytes are being UTF-8 encoded. To work around this I added an onProxyRes handler that hijacks the browser response "write" and "end" methods to force "binary" encoding when receiving a "content-encoding" header that contains gzip.

This feels like a really ugly solution:

function handleGzip(proxyRes, req, res) {
    var gzipped = /gzip/.test(proxyRes.headers["content-encoding"]);
    if (gzipped) {
        res.write = (function(override) {
            return function(chunk, encoding, callback) {
                override.call(res, chunk, "binary", callback);
            };
        })(res.write);
        res.end = (function(override) {
            return function(chunk, encoding, callback) {
                override.call(res, chunk, "binary", callback);
            };
        })(res.end);
    }
}

Oddly enough, this is only an issue when the Accept request header contains "text/html" or "application/xhtml+xml" When no Accept request header is specified, the response is properly proxied.

I was hoping to use ServerResponse#setDefaultEncoding("binary") but it appears ServerResponse doesn't implement that Writable method.

I'm not sure if this is an issue with http-proxy or the underlying node http implementation, but please help.

@marmelo
Copy link

marmelo commented Aug 6, 2018

Hi all,

The workaround I am using is disabling compression in the DevServer:

module.exports = {
  ...
  devServer: {
    ...
    compress: false
  }
};

This results in all responses to the browser not being compressed (usually gzip) which is not efficient.
Do you know a more efficient workaround?

What about a real fix for this?
@johnyb did you sent a pull request with your fix?

Thanks.

@vansen
Copy link

vansen commented Feb 6, 2019

I just encountered this issue as well. Since that post is already a bit older - are there any recent suggestions on how to handle this properly? In my case it only happens when Transfer-Encoding is chunked. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants