Thursday, April 05, 2007

GZIPFilter

A while back in 2003, I spent some time and wrote a GZIPFilter which worked with WebLogic Server. It was a simple, efficient implementation which I then published on dev2dev.bea.com which can be found here
After getting a lot of feedback from customers, I made a few changes which were incorporated into the source back then. Many customers have asked me for the latest version but I haven't had time to enhance it further. So finally i've decided to post the sources here on my site so users can download and use it anyway they wish. I'd be interested to know your experiences with it though.

Update: I've just uploaded the sources and the binary version of the GzipFilter.

gzip-filter-src-v1.zip
gzip-filter-v1.jar

Update 2: Peter Laird informed me that it would serve others better if I included the license and complying with that request, here is the latest source. No major changes, just some cleanup and the Apache 2.0 License addition. Peter, do keep me informed how it goes and thanks for letting me know about the license.

gzip-filter-src-v2.zip

Labels:

6 Comments:

Blogger Vinny Carpetner said...

Hi Nagesh and thank you very much for making the source-code publicly available. This is a great filter and a must for every WebLogic instance. Thanks again.

--Vinny

12:11 PM  
Blogger Nagesh said...

Thanks, Vinny. Appreciate your feedback.

2:04 PM  
Blogger the love dada said...

Nagesh, I use your gzip compression filter in weblogic 8.1sp4 and it is great. Why doesn't WLS do this out of the box ?

One thing I have noticed is that if an exception propagates to the container, WLS discards any response data that's been written and constructs its own error page (which doesn't get processed by the filter) but does not reset the Content-Encoding header (why not ?). This results in my browser reporting a message about the web site using an invalid encoding instead of the normal error 500 page. I've overcome this locally by catching IOException, ServletException, RuntimeException and explicitly executing "reponse.reset()" before re-throwing the original exception.

String requestURI = req.getRequestURI();

GZIPResponseWrapper wrapper = new GZIPResponseWrapper(res);
try {
chain.doFilter(request, wrapper);
}
catch(IOException e) {
res.reset();
throw e;
}
catch(ServletException e) {
res.reset();
throw e;
}
catch(RuntimeException e) {
res.reset();
throw e;
}

finally {
wrapper.finish();
}

Duncan Loveday
duncan.loveday@bt.com

11:12 AM  
Blogger 英幸 said...

Hello, MR Nagesh I intend to use your GZIPFilter.
Please teach whether the Public method that is two nonimplement does not have any problem in movement of GZIPFilter which there was when I watch a source code.

1.GZIPResponseWrapper#setContentLength()
2.GzipServletOutputStream#close()

11:33 PM  
Blogger Nagesh said...

1.GZIPResponseWrapper#setContentLength()
2.GzipServletOutputStream#close()

Are you asking why these methods are left as no-ops?
The reason is that the actual content-length is determined by the compressed stream so the one that is set by calling setContentLength is inaccurate. Also not setting content-length allows the WebLogic container to use http chunked transfer encoding. (if allowed)

The close is left as a no-op again to allow the actual stream to be finished after the service() method of a servlet has completed. This allows any other filters to successfully decorate the response if necessary

example:
GZIPFilter -> DecoratingFilter -ActualServlet

Hope that helps
Nagesh

11:01 AM  
Blogger Nagesh said...

Duncan,

Thanks for your interest in GZIPFilter. Although I agree that your fix would help the user see the error message (and I will incorporate your fix) its still possible that the headers have been sent to the client in which case you'd still see the same exception.

-- Nagesh

11:04 AM  

Post a Comment

<< Home