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