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