comparison src/org/eclipse/jetty/server/handler/GzipHandler.java @ 916:4de7f6e9c453

remove ContinuationSupport
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 09 Oct 2016 02:08:40 -0600
parents 8e9db0bbf4f9
children aa7dc1802d29
comparison
equal deleted inserted replaced
915:65e0fba5861a 916:4de7f6e9c453
33 import javax.servlet.http.HttpServletRequest; 33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse; 34 import javax.servlet.http.HttpServletResponse;
35 35
36 import org.eclipse.jetty.continuation.Continuation; 36 import org.eclipse.jetty.continuation.Continuation;
37 import org.eclipse.jetty.continuation.ContinuationListener; 37 import org.eclipse.jetty.continuation.ContinuationListener;
38 import org.eclipse.jetty.continuation.ContinuationSupport;
39 import org.eclipse.jetty.http.HttpMethods; 38 import org.eclipse.jetty.http.HttpMethods;
40 import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; 39 import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
41 import org.eclipse.jetty.http.gzip.AbstractCompressedStream; 40 import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
42 import org.eclipse.jetty.server.Request; 41 import org.eclipse.jetty.server.Request;
43 import org.slf4j.Logger; 42 import org.slf4j.Logger;
60 * then use of efficient direct NIO may be prevented, thus use of the gzip mechanism of the <code>org.eclipse.jetty.servlet.DefaultServlet</code> is advised instead. 59 * then use of efficient direct NIO may be prevented, thus use of the gzip mechanism of the <code>org.eclipse.jetty.servlet.DefaultServlet</code> is advised instead.
61 * </p> 60 * </p>
62 */ 61 */
63 public class GzipHandler extends HandlerWrapper 62 public class GzipHandler extends HandlerWrapper
64 { 63 {
65 private static final Logger LOG = LoggerFactory.getLogger(GzipHandler.class); 64 private static final Logger LOG = LoggerFactory.getLogger(GzipHandler.class);
66 65
67 protected Set<String> _mimeTypes; 66 protected Set<String> _mimeTypes;
68 protected Set<String> _excluded; 67 protected Set<String> _excluded;
69 protected int _bufferSize = 8192; 68 protected int _bufferSize = 8192;
70 protected int _minGzipSize = 256; 69 protected int _minGzipSize = 256;
71 protected String _vary = "Accept-Encoding, User-Agent"; 70 protected String _vary = "Accept-Encoding, User-Agent";
72 71
73 /* ------------------------------------------------------------ */ 72 /* ------------------------------------------------------------ */
74 /** 73 /**
75 * Instantiates a new gzip handler. 74 * Instantiates a new gzip handler.
76 */ 75 */
77 public GzipHandler() 76 public GzipHandler()
78 { 77 {
79 } 78 }
80 79
81 /* ------------------------------------------------------------ */ 80 /* ------------------------------------------------------------ */
82 /** 81 /**
83 * Get the mime types. 82 * Get the mime types.
84 * 83 *
85 * @return mime types to set 84 * @return mime types to set
86 */ 85 */
87 public Set<String> getMimeTypes() 86 public Set<String> getMimeTypes()
88 { 87 {
89 return _mimeTypes; 88 return _mimeTypes;
90 } 89 }
91 90
92 /* ------------------------------------------------------------ */ 91 /* ------------------------------------------------------------ */
93 /** 92 /**
94 * Set the mime types. 93 * Set the mime types.
95 * 94 *
96 * @param mimeTypes 95 * @param mimeTypes
97 * the mime types to set 96 * the mime types to set
98 */ 97 */
99 public void setMimeTypes(Set<String> mimeTypes) 98 public void setMimeTypes(Set<String> mimeTypes)
100 { 99 {
101 _mimeTypes = mimeTypes; 100 _mimeTypes = mimeTypes;
102 } 101 }
103 102
104 /* ------------------------------------------------------------ */ 103 /* ------------------------------------------------------------ */
105 /** 104 /**
106 * Set the mime types. 105 * Set the mime types.
107 * 106 *
108 * @param mimeTypes 107 * @param mimeTypes
109 * the mime types to set 108 * the mime types to set
110 */ 109 */
111 public void setMimeTypes(String mimeTypes) 110 public void setMimeTypes(String mimeTypes)
112 { 111 {
113 if (mimeTypes != null) 112 if (mimeTypes != null)
114 { 113 {
115 _mimeTypes = new HashSet<String>(); 114 _mimeTypes = new HashSet<String>();
116 StringTokenizer tok = new StringTokenizer(mimeTypes,",",false); 115 StringTokenizer tok = new StringTokenizer(mimeTypes,",",false);
117 while (tok.hasMoreTokens()) 116 while (tok.hasMoreTokens())
118 { 117 {
119 _mimeTypes.add(tok.nextToken()); 118 _mimeTypes.add(tok.nextToken());
120 } 119 }
121 } 120 }
122 } 121 }
123 122
124 /* ------------------------------------------------------------ */ 123 /* ------------------------------------------------------------ */
125 /** 124 /**
126 * Get the excluded user agents. 125 * Get the excluded user agents.
127 * 126 *
128 * @return excluded user agents 127 * @return excluded user agents
129 */ 128 */
130 public Set<String> getExcluded() 129 public Set<String> getExcluded()
131 { 130 {
132 return _excluded; 131 return _excluded;
133 } 132 }
134 133
135 /* ------------------------------------------------------------ */ 134 /* ------------------------------------------------------------ */
136 /** 135 /**
137 * Set the excluded user agents. 136 * Set the excluded user agents.
138 * 137 *
139 * @param excluded 138 * @param excluded
140 * excluded user agents to set 139 * excluded user agents to set
141 */ 140 */
142 public void setExcluded(Set<String> excluded) 141 public void setExcluded(Set<String> excluded)
143 { 142 {
144 _excluded = excluded; 143 _excluded = excluded;
145 } 144 }
146 145
147 /* ------------------------------------------------------------ */ 146 /* ------------------------------------------------------------ */
148 /** 147 /**
149 * Set the excluded user agents. 148 * Set the excluded user agents.
150 * 149 *
151 * @param excluded 150 * @param excluded
152 * excluded user agents to set 151 * excluded user agents to set
153 */ 152 */
154 public void setExcluded(String excluded) 153 public void setExcluded(String excluded)
155 { 154 {
156 if (excluded != null) 155 if (excluded != null)
157 { 156 {
158 _excluded = new HashSet<String>(); 157 _excluded = new HashSet<String>();
159 StringTokenizer tok = new StringTokenizer(excluded,",",false); 158 StringTokenizer tok = new StringTokenizer(excluded,",",false);
160 while (tok.hasMoreTokens()) 159 while (tok.hasMoreTokens())
161 _excluded.add(tok.nextToken()); 160 _excluded.add(tok.nextToken());
162 } 161 }
163 } 162 }
164 163
165 /* ------------------------------------------------------------ */ 164 /* ------------------------------------------------------------ */
166 /** 165 /**
167 * @return The value of the Vary header set if a response can be compressed. 166 * @return The value of the Vary header set if a response can be compressed.
168 */ 167 */
169 public String getVary() 168 public String getVary()
170 { 169 {
171 return _vary; 170 return _vary;
172 } 171 }
173 172
174 /* ------------------------------------------------------------ */ 173 /* ------------------------------------------------------------ */
175 /** 174 /**
176 * Set the value of the Vary header sent with responses that could be compressed. 175 * Set the value of the Vary header sent with responses that could be compressed.
177 * <p> 176 * <p>
178 * By default it is set to 'Accept-Encoding, User-Agent' since IE6 is excluded by 177 * By default it is set to 'Accept-Encoding, User-Agent' since IE6 is excluded by
179 * default from the excludedAgents. If user-agents are not to be excluded, then 178 * default from the excludedAgents. If user-agents are not to be excluded, then
180 * this can be set to 'Accept-Encoding'. Note also that shared caches may cache 179 * this can be set to 'Accept-Encoding'. Note also that shared caches may cache
181 * many copies of a resource that is varied by User-Agent - one per variation of the 180 * many copies of a resource that is varied by User-Agent - one per variation of the
182 * User-Agent, unless the cache does some normalization of the UA string. 181 * User-Agent, unless the cache does some normalization of the UA string.
183 * @param vary The value of the Vary header set if a response can be compressed. 182 * @param vary The value of the Vary header set if a response can be compressed.
184 */ 183 */
185 public void setVary(String vary) 184 public void setVary(String vary)
186 { 185 {
187 _vary = vary; 186 _vary = vary;
188 } 187 }
189 188
190 /* ------------------------------------------------------------ */ 189 /* ------------------------------------------------------------ */
191 /** 190 /**
192 * Get the buffer size. 191 * Get the buffer size.
193 * 192 *
194 * @return the buffer size 193 * @return the buffer size
195 */ 194 */
196 public int getBufferSize() 195 public int getBufferSize()
197 { 196 {
198 return _bufferSize; 197 return _bufferSize;
199 } 198 }
200 199
201 /* ------------------------------------------------------------ */ 200 /* ------------------------------------------------------------ */
202 /** 201 /**
203 * Set the buffer size. 202 * Set the buffer size.
204 * 203 *
205 * @param bufferSize 204 * @param bufferSize
206 * buffer size to set 205 * buffer size to set
207 */ 206 */
208 public void setBufferSize(int bufferSize) 207 public void setBufferSize(int bufferSize)
209 { 208 {
210 _bufferSize = bufferSize; 209 _bufferSize = bufferSize;
211 } 210 }
212 211
213 /* ------------------------------------------------------------ */ 212 /* ------------------------------------------------------------ */
214 /** 213 /**
215 * Get the minimum reponse size. 214 * Get the minimum reponse size.
216 * 215 *
217 * @return minimum reponse size 216 * @return minimum reponse size
218 */ 217 */
219 public int getMinGzipSize() 218 public int getMinGzipSize()
220 { 219 {
221 return _minGzipSize; 220 return _minGzipSize;
222 } 221 }
223 222
224 /* ------------------------------------------------------------ */ 223 /* ------------------------------------------------------------ */
225 /** 224 /**
226 * Set the minimum reponse size. 225 * Set the minimum reponse size.
227 * 226 *
228 * @param minGzipSize 227 * @param minGzipSize
229 * minimum reponse size 228 * minimum reponse size
230 */ 229 */
231 public void setMinGzipSize(int minGzipSize) 230 public void setMinGzipSize(int minGzipSize)
232 { 231 {
233 _minGzipSize = minGzipSize; 232 _minGzipSize = minGzipSize;
234 } 233 }
235 234
236 /* ------------------------------------------------------------ */ 235 /* ------------------------------------------------------------ */
237 /** 236 /**
238 * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 237 * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
239 */ 238 */
240 @Override 239 @Override
241 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 240 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
242 { 241 {
243 if (_handler!=null && isStarted()) 242 if (_handler!=null && isStarted())
244 { 243 {
245 String ae = request.getHeader("accept-encoding"); 244 String ae = request.getHeader("accept-encoding");
246 if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding") 245 if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
247 && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) 246 && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
248 { 247 {
249 if (_excluded!=null) 248 if (_excluded!=null)
250 { 249 {
251 String ua = request.getHeader("User-Agent"); 250 String ua = request.getHeader("User-Agent");
252 if (_excluded.contains(ua)) 251 if (_excluded.contains(ua))
253 { 252 {
254 _handler.handle(target,baseRequest, request, response); 253 _handler.handle(target,baseRequest, request, response);
255 return; 254 return;
256 } 255 }
257 } 256 }
258 257
259 final CompressedResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response); 258 final CompressedResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
260 259
261 boolean exceptional=true; 260 boolean exceptional=true;
262 try 261 try
263 { 262 {
264 _handler.handle(target, baseRequest, request, wrappedResponse); 263 _handler.handle(target, baseRequest, request, wrappedResponse);
265 exceptional=false; 264 exceptional=false;
266 } 265 }
267 finally 266 finally
268 { 267 {
269 Continuation continuation = ContinuationSupport.getContinuation(request); 268 if (exceptional && !response.isCommitted())
270 if (continuation.isSuspended() && continuation.isResponseWrapped()) 269 {
271 { 270 wrappedResponse.resetBuffer();
272 continuation.addContinuationListener(new ContinuationListener() 271 wrappedResponse.noCompression();
273 { 272 }
274 public void onComplete(Continuation continuation) 273 else
275 { 274 wrappedResponse.finish();
276 try 275 }
277 { 276 }
278 wrappedResponse.finish(); 277 else
279 } 278 {
280 catch(IOException e) 279 _handler.handle(target,baseRequest, request, response);
281 { 280 }
282 LOG.warn("",e); 281 }
283 } 282 }
284 } 283
285 284 /**
286 public void onTimeout(Continuation continuation) 285 * Allows derived implementations to replace ResponseWrapper implementation.
287 {} 286 *
288 }); 287 * @param request the request
289 } 288 * @param response the response
290 else if (exceptional && !response.isCommitted()) 289 * @return the gzip response wrapper
291 { 290 */
292 wrappedResponse.resetBuffer(); 291 protected CompressedResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
293 wrappedResponse.noCompression(); 292 {
294 } 293 return new CompressedResponseWrapper(request,response)
295 else 294 {
296 wrappedResponse.finish(); 295 {
297 } 296 super.setMimeTypes(GzipHandler.this._mimeTypes);
298 } 297 super.setBufferSize(GzipHandler.this._bufferSize);
299 else 298 super.setMinCompressSize(GzipHandler.this._minGzipSize);
300 { 299 }
301 _handler.handle(target,baseRequest, request, response); 300
302 } 301 @Override
303 } 302 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
304 } 303 {
305 304 return new AbstractCompressedStream("gzip",request,this,_vary)
306 /** 305 {
307 * Allows derived implementations to replace ResponseWrapper implementation. 306 @Override
308 * 307 protected DeflaterOutputStream createStream() throws IOException
309 * @param request the request 308 {
310 * @param response the response 309 return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
311 * @return the gzip response wrapper 310 }
312 */ 311 };
313 protected CompressedResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) 312 }
314 { 313
315 return new CompressedResponseWrapper(request,response) 314 @Override
316 { 315 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
317 { 316 {
318 super.setMimeTypes(GzipHandler.this._mimeTypes); 317 return GzipHandler.this.newWriter(out,encoding);
319 super.setBufferSize(GzipHandler.this._bufferSize); 318 }
320 super.setMinCompressSize(GzipHandler.this._minGzipSize); 319 };
321 } 320 }
322 321
323 @Override 322 /**
324 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException 323 * Allows derived implementations to replace PrintWriter implementation.
325 { 324 *
326 return new AbstractCompressedStream("gzip",request,this,_vary) 325 * @param out the out
327 { 326 * @param encoding the encoding
328 @Override 327 * @return the prints the writer
329 protected DeflaterOutputStream createStream() throws IOException 328 * @throws UnsupportedEncodingException
330 { 329 */
331 return new GZIPOutputStream(_response.getOutputStream(),_bufferSize); 330 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
332 } 331 {
333 }; 332 return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
334 } 333 }
335
336 @Override
337 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
338 {
339 return GzipHandler.this.newWriter(out,encoding);
340 }
341 };
342 }
343
344 /**
345 * Allows derived implementations to replace PrintWriter implementation.
346 *
347 * @param out the out
348 * @param encoding the encoding
349 * @return the prints the writer
350 * @throws UnsupportedEncodingException
351 */
352 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
353 {
354 return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
355 }
356 } 334 }