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 }