001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 package org.apache.tapestry.util.io; 015 016 import org.apache.tapestry.web.WebRequest; 017 018 019 /** 020 * Encapsulates logic related to various gzip compression schemes and their rules 021 * as they apply to different browsers. 022 */ 023 public final class GzipUtil 024 { 025 private static final float MIN_IE_VERSION = 7.0f; 026 027 private static final String MSIE_6_COMPATIBLE_STRING = "SV1"; 028 029 /* defeat instantiation */ 030 private GzipUtil() { } 031 032 /** 033 * Determines if gzip compression is appropriate/possible based on the User Agent and 034 * other limiting factors. IE versions < 6.1 are known to not work with gzip compression reliably. 035 * 036 * @param request The current web request to check the headers of. 037 * 038 * @return True, if this request can be served in gzip format. False otherwise. 039 */ 040 public static boolean isGzipCapable(WebRequest request) 041 { 042 String encoding = request.getHeader("Accept-Encoding"); 043 044 if (encoding == null || encoding.indexOf("gzip") < 0) 045 return false; 046 047 // Handle IE specific hacks 048 049 String userAgent = request.getHeader("User-Agent"); 050 int ieIndex = (userAgent != null) ? userAgent.indexOf("MSIE") : -1; 051 if (ieIndex > -1) 052 { 053 float version = -1; 054 055 try 056 { 057 version = Float.parseFloat(userAgent.substring(ieIndex + 4, ieIndex + 8)); 058 } catch (NumberFormatException nf) {nf.printStackTrace();} 059 060 if (version >= MIN_IE_VERSION) 061 return true; 062 063 if (userAgent.indexOf(MSIE_6_COMPATIBLE_STRING) > -1) 064 return true; 065 066 // else false 067 068 return false; 069 } 070 071 return true; 072 } 073 074 /** 075 * Based on the given type of content, determines if compression is appropriate. The biggest 076 * thing it does is make sure that image content isn't compressed as that kind of content 077 * is already compressed fairly well. 078 * 079 * @param contentType 080 * The content type to check. (ie "text/javascript","text/html", etc..) 081 * 082 * @return True if compression is appropriate for the content specified, false otherwise. 083 */ 084 public static boolean shouldCompressContentType(String contentType) 085 { 086 if (contentType == null) 087 return false; 088 089 return contentType.indexOf("javascript") > -1 090 || contentType.indexOf("css") > -1 091 || contentType.indexOf("html") > -1 092 || contentType.indexOf("text") > -1; 093 } 094 }