Zuul is not sending a GZIP response when requested by the client. When I make a request to my API through Zuul and set Accept-Encoding: gzip, I do not get back a Gzipped response as expected. Is this not the expected behavior? I have tried with larger response sizes over 50KB and still get the same result.

I don't see any documentation stating that I have to configure Zuul to enable compression.

The API is a Spring Boot 2.0.5 REST API that returns JSON. The API does not gzip the response sent to Zuul.

Zuul is on Spring Cloud Finchley.SR1, Spring Boot 2.0.5 and is using service discovery with Consul.

Spring Cloud version: Finchley.SR1 Spring Boot version: 2.0.5

Comment From: ryanjbaxter

Can you try with Finchley.SR3?

Comment From: shan916

I see the same behavior with Finchley.SR3. No gzip even though it's requested by the client.

http://localhost:8080/test-app/blob?kSize=20

GET /test-app/blob
cache-control: no-cache
Postman-Token: 64241d8c-5db4-44db-ade6-f4d4182f08ac
User-Agent: PostmanRuntime/7.6.0
Accept: */*
Host: localhost:8080
accept-encoding: gzip, deflate

HTTP/1.1 200
status: 200
Date: Tue, 05 Mar 2019 21:25:48 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

One experiment I tried was to set server.compression.enabled: true in the Zuul proxy. I was able to get back a gzip when requested, and no gzip when not requested. Is turning on server level compression (Tomcat) the correct way to do it? If I set compression enabled on the REST API instead, then Zuul always returns gzip unless the client sends Accept-Encoding: identity.

Also, I've attached a sample Zuul proxy and sample API. You need to run both with spring.profiles.active: local and Consul v0.9.3. test-app.zip zuul-proxy.zip

Comment From: ryanjbaxter

@shan916 can you please provide a sample that does not require Consul?

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: shan916

Please see the attached example which doesn't require Consul.

The app will run on port 8000. Zuul will run on port 8080. URL to make request to API through Zuul: http://localhost:8080/test-app/blob?kSize=1 where kSize is number of kilobytes to return in the response.

test-app.zip zuul-proxy.zip

Comment From: shan916

Any updates on this?

Comment From: jebeaudet

Enabling server.compression.enabled on Zuul is IMO the right way to do it, it lets the servlet container handling the compression if required.

Check the logic in SendResponseFilter, if zuul received a gzipped stream from the backend and client also request gzip via the Accept-Encoding header, Zuul binds directly the backend InputStream with the client OutputStream. If the client doesn't accept gzip, it will inflate the stream before returning it to the client.

If the stream coming from the backend is not gzipped, this is where the logic from server.compression.enabled kicks in. The logic in Jetty is that it will deflate the stream if the Content-Encoding has not been already set on the HttpServletResponse and the client Accept-Encoding contains gzip. The same logic makes sure the stream is not deflated twice because when the backend returns a gzipped stream, Content-Encodingwill be set on the response so Jetty won't act on the OutputStream.

Comment From: spencergibb

This module has entered maintenance mode. This means that the Spring Cloud team will no longer be adding new features to the module. We will fix blocker bugs and security issues, and we will also consider and review small pull requests from the community.