Bug report 1. Client send request to Zuul, without Accept-Encoding header. We use PHP GuzzleHttp/6.3.3 lib; 2. Zuul will add Accept-Encoding: gzip header, and forward to the remote service; 3. remote service return compression response and Content-Encoding: gzip header. 4. Zuul will decompress response, then return to the client; but the response header also has the Content-Encoding header。 5. GuzzleHttp Client receive the response has Content-Encoding: gzip header. so it will decompress response body but the body is not compressed. then throw exception.
Detail info:
$: curl -v -I http://127.0.0.1:7777/provider/env
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 7777 (#0)
> GET /provider/env HTTP/1.1
> Host: 127.0.0.1:7777
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200
HTTP/1.1 200
... some other headers ....
< Content-Encoding: gzip
Content-Encoding: gzip
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
request not accept gzip and response body not compressed,
but return the Content-Encoding: gzip header.
GuzzleHttp Exception: cURL error 23: Error while processing content unencoding: invalid distance too far back (see http:\/\/curl.haxx.se\/libcurl\/c\/libcurl-errors.html)
Solution: https://github.com/spring-cloud/spring-cloud-netflix/blob/c24e7e05bfbacbfe26e1189fb326e5e3103f9cc9/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java#L232 add which case need add Content-Encoding header maybe can solve this problem.
// if request client not support gzip, don't add content-encoding header
if (name.equalsIgnoreCase(HttpHeaders.CONTENT_ENCODING) && !isGzipRequested(context))) {
return false;
}
Comment From: ryanjbaxter
Can you tell us what version of Spring Cloud you are using? What does the request look like that you are sending?
Comment From: billnote
Spring Cloud Version: Finchley.SR2
Request:
$: curl -v -I http://127.0.0.1:7777/provider/env
It's sample request, does not contain any parameters and headers.
Comment From: amanzag
I believe this was introduced by #3062
Comment From: amanzag
I think I got to the bottom of it. With the fix introduced in #3062, the Content-Encoding header is always copied from the downstream response, and because of that, the SendResponseFilter can't decide if it should be included or not. It should probably be fixed by having 2 lists of ignored headers, one for requests and one for responses. Content-Encoding, for instance, should be ignored for responses but not for requests. Until this is fixed, here's a workaround that I found:
@Component
// This is a workaround for bug https://github.com/spring-cloud/spring-cloud-netflix/pull/3062
public class ContentTypeFixFilter extends ZuulFilter {
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext.getCurrentContext().getZuulResponseHeaders().removeIf(h -> h.first().equals(HttpHeaders.CONTENT_ENCODING));
return null;
}
@Override
public String filterType() {
return FilterConstants.ROUTE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.RIBBON_ROUTING_FILTER_ORDER + 1;
}
}
Comment From: Fantaztig
Was this issue ever resolved? I think we are experiencing it still in Hoxton.RELEASE.