Streaming GZip

28 views
Skip to first unread message

Albert Latacz

unread,
Sep 11, 2017, 4:31:42 AM9/11/17
to utterlyidle
Hi Folks,

We are in a need of streaming GZip handler as current GZipHandler does not seem to support it.

Here's what we have so far: 

@Override
public Response handle(Request request) throws Exception {
Response response = httpHandler.handle(request);
if (clientAcceptsGZip(request)) {
Response gzippedResponse = response
.headers(add(VARY, ACCEPT_ENCODING))
.header(CONTENT_ENCODING, GZIP);

if (response.entity().value() instanceof StreamingOutput) {
StreamingOutput decoratedStreamingOutput = (StreamingOutput) gzippedResponse.entity().value();
return gzippedResponse.entity((StreamingOutput) streamingOutput -> {
try(GZIPOutputStream outputStream = new GZIPOutputStream(streamingOutput)) {
decoratedStreamingOutput.write(outputStream);
}
});
} else {
return gzippedResponse.entity(gzip(response.entity().toBytes()));

}
}
return response;
}


Few questions around that:

1. As we tried add support for all entity types we have noticed StreamingWriter, which uses java Writer, meant to be used with character stream. I understand convenience but given that response can be a stream of bytes, I don't think that Writer is appropriate here. Can we refactor out StreamingWriter? Is there another way to wrap GZip Stream in there.

2. Happy to keep this project-local but is this change useful enough to be a pull request or commit maybe?

3. Not that I can see but are there any other places that should be taken care of apart from handler to add GZip streaming support.

Cheers,
Al


Daniel Worthington-Bodart

unread,
Sep 11, 2017, 5:32:35 AM9/11/17
to utterlyidle
For 1. Just Convert the StreamingWriter into a StreamingOutput:

output -> streamingWriter.write(new OutputStreamWriter(new GZIPOutputStream(output), Entity.DEFAULT_CHARACTER_SET));

2. Happy to take an additional class, the reason I didn't support this is by default is I feel that if you are streaming you basically want me to get out of your way. I.e the developer knows best and will decorate as needed.

3. You need to move the Vary header out side of the if statement (super important), and also note that you won't be able to use a lot of existing handlers (like ETag, Cache), plus you need to add this as late as possible in the chain of handlers) Generally be careful with this stuff and make sure you test it with all your clients especially if you cache or use Etags as you can end up serving GZipped content to non-supporting clients.

--
You received this message because you are subscribed to the Google Groups "utterlyidle" group.
To unsubscribe from this group and stop receiving emails from it, send an email to utterlyidle...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Albert Latacz

unread,
Sep 11, 2017, 8:13:19 AM9/11/17
to utter...@googlegroups.com
Great, Thanks Dan, will give it a try with wrapping in StreamingOutput. Good point on caches, better check how we're wired in. 

Still curious though if StreamingWriter is needed at all. Comes down to the second point as well, with a StreamingOutput only will still have a flexibility and also be 'out of the way', but happy to convert it this way if backward compatibility is at play.

Albert Latacz

unread,
Sep 12, 2017, 4:32:10 AM9/12/17
to utterlyidle
Thanks, that worked quite well. I have also added InputStream handling. Now, as I hear there is a problem to contribute sources/tests back from the client site - financial institution, ehhhh :( May need to rewrite at home
To unsubscribe from this group and stop receiving emails from it, send an email to utterlyidle+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "utterlyidle" group.
To unsubscribe from this group and stop receiving emails from it, send an email to utterlyidle+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages