View Javadoc

1   /*
2   * Copyright 2004 The Apache Software Foundation
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *     http://www.apache.org/licenses/LICENSE-2.0
9   *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16  
17  package compressionFilters;
18  
19  import java.io.IOException;
20  import java.util.Enumeration;
21  import javax.servlet.Filter;
22  import javax.servlet.FilterChain;
23  import javax.servlet.FilterConfig;
24  import javax.servlet.ServletException;
25  import javax.servlet.ServletRequest;
26  import javax.servlet.ServletResponse;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  
31  /**
32   * Implementation of <code>javax.servlet.Filter</code> used to compress
33   * the ServletResponse if it is bigger than a threshold.
34   *
35   * @author Amy Roh
36   * @author Dmitri Valdin
37   * @version $Revision: 267129 $, $Date: 2004-03-18 08:40:35 -0800 (Thu, 18 Mar 2004) $
38   */
39  
40  public class CompressionFilter implements Filter{
41  
42      /**
43       * The filter configuration object we are associated with.  If this value
44       * is null, this filter instance is not currently configured.
45       */
46      private FilterConfig config = null;
47  
48      /**
49       * Minimal reasonable threshold
50       */
51      private int minThreshold = 128;
52  
53  
54      /**
55       * The threshold number to compress
56       */
57      protected int compressionThreshold;
58  
59      /**
60       * Debug level for this filter
61       */
62      private int debug = 0;
63  
64      /**
65       * Place this filter into service.
66       *
67       * @param filterConfig The filter configuration object
68       */
69  
70      public void init(FilterConfig filterConfig) {
71  
72          config = filterConfig;
73          if (filterConfig != null) {
74              String value = filterConfig.getInitParameter("debug");
75              if (value!=null) {
76                  debug = Integer.parseInt(value);
77              } else {
78                  debug = 0;
79              }
80              String str = filterConfig.getInitParameter("compressionThreshold");
81              if (str!=null) {
82                  compressionThreshold = Integer.parseInt(str);
83                  if (compressionThreshold != 0 && compressionThreshold < minThreshold) {
84                      if (debug > 0) {
85                          System.out.println("compressionThreshold should be either 0 - no compression or >= " + minThreshold);
86                          System.out.println("compressionThreshold set to " + minThreshold);
87                      }
88                      compressionThreshold = minThreshold;
89                  }
90              } else {
91                  compressionThreshold = 0;
92              }
93  
94          } else {
95              compressionThreshold = 0;
96          }
97  
98      }
99  
100     /**
101     * Take this filter out of service.
102     */
103     public void destroy() {
104 
105         this.config = null;
106 
107     }
108 
109     /**
110      * The <code>doFilter</code> method of the Filter is called by the container
111      * each time a request/response pair is passed through the chain due
112      * to a client request for a resource at the end of the chain.
113      * The FilterChain passed into this method allows the Filter to pass on the
114      * request and response to the next entity in the chain.<p>
115      * This method first examines the request to check whether the client support
116      * compression. <br>
117      * It simply just pass the request and response if there is no support for
118      * compression.<br>
119      * If the compression support is available, it creates a
120      * CompressionServletResponseWrapper object which compresses the content and
121      * modifies the header if the content length is big enough.
122      * It then invokes the next entity in the chain using the FilterChain object
123      * (<code>chain.doFilter()</code>), <br>
124      **/
125 
126     public void doFilter ( ServletRequest request, ServletResponse response,
127                         FilterChain chain ) throws IOException, ServletException {
128 
129         if (debug > 0) {
130             System.out.println("@doFilter");
131         }
132 
133         if (compressionThreshold == 0) {
134             if (debug > 0) {
135                 System.out.println("doFilter gets called, but compressionTreshold is set to 0 - no compression");
136             }
137             chain.doFilter(request, response);
138             return;
139         }
140 
141         boolean supportCompression = false;
142         if (request instanceof HttpServletRequest) {
143             if (debug > 1) {
144                 System.out.println("requestURI = " + ((HttpServletRequest)request).getRequestURI());
145             }
146 
147             // Are we allowed to compress ?
148             String s = (String) ((HttpServletRequest)request).getParameter("gzip");
149             if ("false".equals(s)) {
150                 if (debug > 0) {
151                     System.out.println("got parameter gzip=false --> don't compress, just chain filter");
152                 }
153                 chain.doFilter(request, response);
154                 return;
155             }
156 
157             Enumeration e =
158                 ((HttpServletRequest)request).getHeaders("Accept-Encoding");
159             while (e.hasMoreElements()) {
160                 String name = (String)e.nextElement();
161                 if (name.indexOf("gzip") != -1) {
162                     if (debug > 0) {
163                         System.out.println("supports compression");
164                     }
165                     supportCompression = true;
166                 } else {
167                     if (debug > 0) {
168                         System.out.println("no support for compresion");
169                     }
170                 }
171             }
172         }
173 
174         if (!supportCompression) {
175             if (debug > 0) {
176                 System.out.println("doFilter gets called wo compression");
177             }
178             chain.doFilter(request, response);
179             return;
180         } else {
181             if (response instanceof HttpServletResponse) {
182                 CompressionServletResponseWrapper wrappedResponse =
183                     new CompressionServletResponseWrapper((HttpServletResponse)response);
184                 wrappedResponse.setDebugLevel(debug);
185                 wrappedResponse.setCompressionThreshold(compressionThreshold);
186                 if (debug > 0) {
187                     System.out.println("doFilter gets called with compression");
188                 }
189                 try {
190                     chain.doFilter(request, wrappedResponse);
191                 } finally {
192                     wrappedResponse.finishResponse();
193                 }
194                 return;
195             }
196         }
197     }
198 
199     /**
200      * Set filter config
201      * This function is equivalent to init. Required by Weblogic 6.1
202      *
203      * @param filterConfig The filter configuration object
204      */
205     public void setFilterConfig(FilterConfig filterConfig) {
206         init(filterConfig);
207     }
208 
209     /**
210      * Return filter config
211      * Required by Weblogic 6.1
212      */
213     public FilterConfig getFilterConfig() {
214         return config;
215     }
216 
217 }
218