Termin4t0r
Termin4t0r

Reputation: 319

GZip encoding in Jersey

I'm writing a RESTful web service in Jersey 2. I want to support the Gzip encoding for the responses. Following this answer, I enabled the org.glassfish.jersey.server.filter.EncodingFilter in my ResourceConfig class.

public class MyWebService extends ResourceConfig {
    public MyWebService() {
        register(EncodingFilter.class);
        register(GZipEncoder.class);
        register(DeflateEncoder.class);
    }
}

On my resource class, I'm returning a javax.ws.rs.core.Response object.

@GET
@Path("api/configs") 
public Response listConfigs() throws Exception {
    List<UserConfig> configs = configService.getAll();
    return Response.ok().entity(configs).build();
}

Now when I hit this api, I get a response but the response headers do not contain a Content-Encoding header, rather it contains Transfer-Encoding: chunked.

Request:

> GET /api/configs HTTP/1.1
> Accept-Encoding: gzip

Response:

> HTTP/1.1 200 
> Transfer-Encoding: chunked
* Received 14.8 KB chunk
* Received 504 B chunk
* Received 15.2 KB chunk
* Received 506 B chunk
* Received 15.1 KB chunk
* Received 514 B chunk

There is no Content-Encoding: gzip header in the response, nor there is any Content-Length header.

I'm using Jersey 2.27 on Tomcat 9.

Is there any other configuration I'm missing? How do I get these two headers and get the response as gzip compressed rather than receiving chunked response?

Edit: I have noticed that when I send large files ( > 1000 KB) I get both the Content-Encoding: gzip and Transfer-Encoding: chunked headers.

Upvotes: 4

Views: 4090

Answers (1)

bytesandcaffeine
bytesandcaffeine

Reputation: 195

Whether to use Transfer-Encoding or Content-Length is entirely the container's discretion. It depends on the allowed buffer size.

If the container has to set the Content-Length header, it has to know the length of the compressed response beforehand, therefore, the container has to buffer the entire response in the memory.

In case of Jersey, the content length buffer size is defined by ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER. By default, this is 8192 bytes.

You can easily increase this from your MyWebService class:

public class MyWebService extends ResourceConfig {
    public MyWebService() {
        register(EncodingFilter.class);
        register(GZipEncoder.class);
        register(DeflateEncoder.class);

        ...

        property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 32768);

    }
}

Hope this helps.

Upvotes: 2

Related Questions