I have set compression="on" and compressableMimeType="text/html" in server.xml. It appears that the value of compressableMimeType is being ignored. My XML responses are all coming back gzipped. If I switch to compression="off" the responses are not gzipped, but as soon as I turn it on, regardless of the value of compressableMimeType, the XML responses are coming back gzipped. A full Connector tag follows. Note that this is just an example -- I have tried many values for compressableMimeType (that do NOT include text/xml) and the responses are still compressed. <Connector port="7630" address="${jboss.bind.address}" maxThreads="20" minSpareThreads="4" maxSpareThreads="10" strategy="ms" maxHttpHeaderSize="8192" emptySessionPath="true" enableLookups="false" redirectPort="7643" acceptCount="16" connectionTimeout="20000" disableUploadTimeout="true" compression="off" compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript" />
The compressableMimeType isn't exactly ignored. It lets you add new MIME types for compression, but there doesn't seem to be any way to remove the default set of types. That is, if you specify compressableMimeType="text/html" you effectively end up with compressableMimeType="text/html,text/xml,text/plain,text/html". I have verified the problem in 5.5.23 and 6.0.trunk. It looks easy to fix, I'll give it a try.
Created attachment 20702 [details] patch vs. tc6.0.x/trunk Patch for 6.0.trunk. Connector attribute compressableMimeType is the complete list of compressable MIME types, instead of being added to the default list.
Created attachment 20713 [details] patch for 5.5 Here's the same patch for 5.5, since that's what the bug was reported against.
If seems that this is a good idea, but can be a regression with older tomcat versions :-( Peter
*** Bug 37834 has been marked as a duplicate of this bug. ***
(In reply to comment #4) As it is, there is no way to turn off gzip compression for one file type while keeping it for others. That seems more serious than the possible regression, which is easy to fix by setting compressableMimeType correctly. (And are there really a lot of users that are using it incorrectly? The documentation is quite clear.) Alternatively, I guess you could add a new attribute that does what compressableMimeType was supposed to do...
I have applied your patch to trunk (expanded to include the other connectors) and proposed it for 6.0.x and 5.5.x
This has been applied to 6.0.x and will be included in 6.0.17 onwards.
Opps - this is still open for 5.5.x
I would like to share an alternative approach for this problem I just implemented which avoids having to update Tomcat (or patch it). Grab CompressionFilter.java, CompressionResponseStream.java and CompressionServletResponseWrapper.java from the Tomcat source code distribution (I did this with the 5.5.25 source). Open up CompressionServletResponseWrapper.java and modify the writetoGZip() method. On line 305, replace... response.addHeader("Content-Encoding", "gzip"); gzipstream = new GZIPOutputStream(output); ...with... if ((response.getContentType()!=null) && (response.getContentType().equals("application/pdf")) { // I want to compress this content type response.addHeader("Content-Encoding", "gzip"); gzipstream = new GZIPOutputStream(output); } else { // Don't want to compress this content type gzipstream = output; } Compile all three Java classes, then add the filter into your web.xml file: <filter> <filter-name>Compressing Filter</filter-name> <filter-class>compressionFilters.CompressionFilter</filter-class> <init-param> <param-name>compressionThreshold</param-name> <param-value>1</param-value> </init-param> </filter> <filter-mapping> <filter-name>Compressing Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> This is very handy if you don't want to upgrade Tomcat, or for Tomcat 5.5.x users for who there isn't an upgrade with the patch available yet. Also useful if you don't want to compress server-wide for all of your web applications. Enjoy!
For such a simple concept, every compression filter I have ever seen has serious problems. Mostly the problems are not addressed, and instead all kinds of finely grained mechanisms are created to more selectively apply compression. For example, if a response sets the content-length header, I have seen compression filters break. The browser either hangs waiting for the rest of the response, or the response is truncated to the length set. I don't remember if Tomcat's compression filter is guilty of this behavior or not, but I suspect the latter due to the existence of the compressionThreshold setting. I have created my own GZIPFilter which addresses all the problems I have seen in various other compression filter implementations. I am posting it as an attachment to this bug, feel free to use it, or not. Its advantages are captured in the comments, in summary, it streams rather than makes a copy, it handles content-length correctly, it detects client support of gzip compression, and it doesn't double compress. It is not problem-free, the known problems and limitations are also captured in the comments. My theory on filter mapping is to keep it simple. So my filter doesn't care about mime-types, or any other qualification other compression filters use to decide whether to compress or not. As I stated before, it is my experience that these features exist to "fix" other problems in the filters. The original poster can use my GZIPFilter in one of a few ways: 1) Use filter-mapping to selectively compress content. 2) Extend GZIPFilter, look at the mime-type header, and compress or not by calling super.doFilter(). 3) Modify my GZIPFilter to look at mime-types.
Created attachment 22203 [details] GZIP compression filter
This is fixed for 5.5.x and will be included in 5.5.27 onwards.