1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.servlets;
14
15 import java.io.IOException;
16 import java.io.OutputStream;
17 import java.io.OutputStreamWriter;
18 import java.io.PrintWriter;
19 import java.io.UnsupportedEncodingException;
20 import java.util.HashSet;
21 import java.util.Set;
22 import java.util.StringTokenizer;
23
24 import javax.servlet.FilterChain;
25 import javax.servlet.FilterConfig;
26 import javax.servlet.ServletException;
27 import javax.servlet.ServletRequest;
28 import javax.servlet.ServletResponse;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import org.eclipse.jetty.continuation.Continuation;
33 import org.eclipse.jetty.continuation.ContinuationListener;
34 import org.eclipse.jetty.continuation.ContinuationSupport;
35 import org.eclipse.jetty.http.HttpMethods;
36 import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
37 import org.eclipse.jetty.util.log.Log;
38 import org.eclipse.jetty.util.log.Logger;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class GzipFilter extends UserAgentFilter
64 {
65 private static final Logger LOG = Log.getLogger(GzipFilter.class);
66
67 protected Set<String> _mimeTypes;
68 protected int _bufferSize=8192;
69 protected int _minGzipSize=256;
70 protected Set<String> _excluded;
71
72
73
74
75
76 public void init(FilterConfig filterConfig) throws ServletException
77 {
78 super.init(filterConfig);
79
80 String tmp=filterConfig.getInitParameter("bufferSize");
81 if (tmp!=null)
82 _bufferSize=Integer.parseInt(tmp);
83
84 tmp=filterConfig.getInitParameter("minGzipSize");
85 if (tmp!=null)
86 _minGzipSize=Integer.parseInt(tmp);
87
88 tmp=filterConfig.getInitParameter("mimeTypes");
89 if (tmp!=null)
90 {
91 _mimeTypes=new HashSet<String>();
92 StringTokenizer tok = new StringTokenizer(tmp,",",false);
93 while (tok.hasMoreTokens())
94 _mimeTypes.add(tok.nextToken());
95 }
96
97 tmp=filterConfig.getInitParameter("excludedAgents");
98 if (tmp!=null)
99 {
100 _excluded=new HashSet<String>();
101 StringTokenizer tok = new StringTokenizer(tmp,",",false);
102 while (tok.hasMoreTokens())
103 _excluded.add(tok.nextToken());
104 }
105 }
106
107
108
109
110
111 public void destroy()
112 {
113 }
114
115
116
117
118
119 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
120 throws IOException, ServletException
121 {
122 HttpServletRequest request=(HttpServletRequest)req;
123 HttpServletResponse response=(HttpServletResponse)res;
124
125 String ae = request.getHeader("accept-encoding");
126 if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
127 && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
128 {
129 if (_excluded!=null)
130 {
131 String ua=getUserAgent(request);
132 if (_excluded.contains(ua))
133 {
134 super.doFilter(request,response,chain);
135 return;
136 }
137 }
138
139 final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response);
140
141 boolean exceptional=true;
142 try
143 {
144 super.doFilter(request,wrappedResponse,chain);
145 exceptional=false;
146 }
147 finally
148 {
149 Continuation continuation = ContinuationSupport.getContinuation(request);
150 if (continuation.isSuspended() && continuation.isResponseWrapped())
151 {
152 continuation.addContinuationListener(new ContinuationListener()
153 {
154 public void onComplete(Continuation continuation)
155 {
156 try
157 {
158 wrappedResponse.finish();
159 }
160 catch(IOException e)
161 {
162 LOG.warn(e);
163 }
164 }
165
166 public void onTimeout(Continuation continuation)
167 {}
168 });
169 }
170 else if (exceptional && !response.isCommitted())
171 {
172 wrappedResponse.resetBuffer();
173 wrappedResponse.noGzip();
174 }
175 else
176 wrappedResponse.finish();
177 }
178 }
179 else
180 {
181 super.doFilter(request,response,chain);
182 }
183 }
184
185
186
187
188
189
190
191
192 protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
193 {
194 return new GzipResponseWrapper(request, response)
195 {
196 {
197 setMimeTypes(GzipFilter.this._mimeTypes);
198 setBufferSize(GzipFilter.this._bufferSize);
199 setMinGzipSize(GzipFilter.this._minGzipSize);
200 }
201
202 @Override
203 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
204 {
205 return GzipFilter.this.newWriter(out,encoding);
206 }
207 };
208 }
209
210
211
212
213
214
215
216
217
218 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
219 {
220 return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
221 }
222 }