1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server.handler;
15
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.io.OutputStreamWriter;
19 import java.io.PrintWriter;
20 import java.io.UnsupportedEncodingException;
21 import java.util.HashSet;
22 import java.util.Set;
23 import java.util.StringTokenizer;
24
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28
29 import org.eclipse.jetty.continuation.Continuation;
30 import org.eclipse.jetty.continuation.ContinuationListener;
31 import org.eclipse.jetty.continuation.ContinuationSupport;
32 import org.eclipse.jetty.http.HttpMethods;
33 import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
34 import org.eclipse.jetty.server.Request;
35 import org.eclipse.jetty.util.log.Log;
36 import org.eclipse.jetty.util.log.Logger;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class GzipHandler extends HandlerWrapper
56 {
57 private static final Logger LOG = Log.getLogger(GzipHandler.class);
58
59 protected Set<String> _mimeTypes;
60 protected Set<String> _excluded;
61 protected int _bufferSize = 8192;
62 protected int _minGzipSize = 256;
63
64
65
66
67
68 public GzipHandler()
69 {
70 }
71
72
73
74
75
76
77
78 public Set<String> getMimeTypes()
79 {
80 return _mimeTypes;
81 }
82
83
84
85
86
87
88
89
90 public void setMimeTypes(Set<String> mimeTypes)
91 {
92 _mimeTypes = mimeTypes;
93 }
94
95
96
97
98
99
100
101
102 public void setMimeTypes(String mimeTypes)
103 {
104 if (mimeTypes != null)
105 {
106 _mimeTypes = new HashSet<String>();
107 StringTokenizer tok = new StringTokenizer(mimeTypes,",",false);
108 while (tok.hasMoreTokens())
109 {
110 _mimeTypes.add(tok.nextToken());
111 }
112 }
113 }
114
115
116
117
118
119
120
121 public Set<String> getExcluded()
122 {
123 return _excluded;
124 }
125
126
127
128
129
130
131
132
133 public void setExcluded(Set<String> excluded)
134 {
135 _excluded = excluded;
136 }
137
138
139
140
141
142
143
144
145 public void setExcluded(String excluded)
146 {
147 if (excluded != null)
148 {
149 _excluded = new HashSet<String>();
150 StringTokenizer tok = new StringTokenizer(excluded,",",false);
151 while (tok.hasMoreTokens())
152 _excluded.add(tok.nextToken());
153 }
154 }
155
156
157
158
159
160
161
162 public int getBufferSize()
163 {
164 return _bufferSize;
165 }
166
167
168
169
170
171
172
173
174 public void setBufferSize(int bufferSize)
175 {
176 _bufferSize = bufferSize;
177 }
178
179
180
181
182
183
184
185 public int getMinGzipSize()
186 {
187 return _minGzipSize;
188 }
189
190
191
192
193
194
195
196
197 public void setMinGzipSize(int minGzipSize)
198 {
199 _minGzipSize = minGzipSize;
200 }
201
202
203
204
205
206 @Override
207 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
208 {
209 if (_handler!=null && isStarted())
210 {
211 String ae = request.getHeader("accept-encoding");
212 if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
213 && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
214 {
215 if (_excluded!=null)
216 {
217 String ua = request.getHeader("User-Agent");
218 if (_excluded.contains(ua))
219 {
220 _handler.handle(target,baseRequest, request, response);
221 return;
222 }
223 }
224
225 final GzipResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
226
227 boolean exceptional=true;
228 try
229 {
230 _handler.handle(target, baseRequest, request, wrappedResponse);
231 exceptional=false;
232 }
233 finally
234 {
235 Continuation continuation = ContinuationSupport.getContinuation(request);
236 if (continuation.isSuspended() && continuation.isResponseWrapped())
237 {
238 continuation.addContinuationListener(new ContinuationListener()
239 {
240 public void onComplete(Continuation continuation)
241 {
242 try
243 {
244 wrappedResponse.finish();
245 }
246 catch(IOException e)
247 {
248 LOG.warn(e);
249 }
250 }
251
252 public void onTimeout(Continuation continuation)
253 {}
254 });
255 }
256 else if (exceptional && !response.isCommitted())
257 {
258 wrappedResponse.resetBuffer();
259 wrappedResponse.noGzip();
260 }
261 else
262 wrappedResponse.finish();
263 }
264 }
265 else
266 {
267 _handler.handle(target,baseRequest, request, response);
268 }
269 }
270 }
271
272
273
274
275
276
277
278
279 protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
280 {
281 return new GzipResponseWrapper(request, response)
282 {
283 {
284 setMimeTypes(GzipHandler.this._mimeTypes);
285 setBufferSize(GzipHandler.this._bufferSize);
286 setMinGzipSize(GzipHandler.this._minGzipSize);
287 }
288
289 @Override
290 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
291 {
292 return GzipHandler.this.newWriter(out,encoding);
293 }
294 };
295 }
296
297
298
299
300
301
302
303
304
305 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
306 {
307 return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
308 }
309 }