1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.eclipse.jetty.http.gzip;
16
17 import java.io.IOException;
18 import java.io.OutputStream;
19 import java.io.OutputStreamWriter;
20 import java.io.PrintWriter;
21 import java.io.UnsupportedEncodingException;
22 import java.util.Set;
23
24 import javax.servlet.ServletOutputStream;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27 import javax.servlet.http.HttpServletResponseWrapper;
28
29 import org.eclipse.jetty.util.StringUtil;
30
31
32
33
34
35 public class GzipResponseWrapper extends HttpServletResponseWrapper
36 {
37 public static final int DEFAULT_BUFFER_SIZE = 8192;
38 public static final int DEFAULT_MIN_GZIP_SIZE = 256;
39
40 private HttpServletRequest _request;
41 private Set<String> _mimeTypes;
42 private int _bufferSize=DEFAULT_BUFFER_SIZE;
43 private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE;
44
45 private PrintWriter _writer;
46 private GzipStream _gzStream;
47 private long _contentLength=-1;
48 private boolean _noGzip;
49
50
51
52
53
54
55
56 public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
57 {
58 super(response);
59 _request=request;
60 }
61
62
63
64
65
66
67
68 public void setMimeTypes(Set<String> mimeTypes)
69 {
70 _mimeTypes = mimeTypes;
71 }
72
73
74
75
76
77 public void setBufferSize(int bufferSize)
78 {
79 _bufferSize = bufferSize;
80 }
81
82
83
84
85
86
87
88 public void setMinGzipSize(int minGzipSize)
89 {
90 _minGzipSize = minGzipSize;
91 }
92
93
94
95
96
97 public void setContentType(String ct)
98 {
99 super.setContentType(ct);
100
101 if (ct!=null)
102 {
103 int colon=ct.indexOf(";");
104 if (colon>0)
105 ct=ct.substring(0,colon);
106 }
107
108 if ((_gzStream==null || _gzStream._out==null) &&
109 (_mimeTypes==null && "application/gzip".equalsIgnoreCase(ct) ||
110 _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
111 {
112 noGzip();
113 }
114 }
115
116
117
118
119
120 public void setStatus(int sc, String sm)
121 {
122 super.setStatus(sc,sm);
123 if (sc<200 || sc==204 || sc==205 || sc>=300)
124 noGzip();
125 }
126
127
128
129
130
131 public void setStatus(int sc)
132 {
133 super.setStatus(sc);
134 if (sc<200 || sc==204 || sc==205 ||sc>=300)
135 noGzip();
136 }
137
138
139
140
141
142 public void setContentLength(int length)
143 {
144 setContentLength((long)length);
145 }
146
147
148 protected void setContentLength(long length)
149 {
150 _contentLength=length;
151 if (_gzStream!=null)
152 _gzStream.setContentLength(length);
153 else if (_noGzip && _contentLength>=0)
154 {
155 HttpServletResponse response = (HttpServletResponse)getResponse();
156 if(_contentLength<Integer.MAX_VALUE)
157 {
158 response.setContentLength((int)_contentLength);
159 }
160 else
161 {
162 response.setHeader("Content-Length", Long.toString(_contentLength));
163 }
164 }
165 }
166
167
168
169
170
171 public void addHeader(String name, String value)
172 {
173 if ("content-length".equalsIgnoreCase(name))
174 {
175 _contentLength=Long.parseLong(value);
176 if (_gzStream!=null)
177 _gzStream.setContentLength(_contentLength);
178 }
179 else if ("content-type".equalsIgnoreCase(name))
180 {
181 setContentType(value);
182 }
183 else if ("content-encoding".equalsIgnoreCase(name))
184 {
185 super.addHeader(name,value);
186 if (!isCommitted())
187 {
188 noGzip();
189 }
190 }
191 else
192 super.addHeader(name,value);
193 }
194
195
196
197
198
199 public void setHeader(String name, String value)
200 {
201 if ("content-length".equalsIgnoreCase(name))
202 {
203 setContentLength(Long.parseLong(value));
204 }
205 else if ("content-type".equalsIgnoreCase(name))
206 {
207 setContentType(value);
208 }
209 else if ("content-encoding".equalsIgnoreCase(name))
210 {
211 super.setHeader(name,value);
212 if (!isCommitted())
213 {
214 noGzip();
215 }
216 }
217 else
218 super.setHeader(name,value);
219 }
220
221
222
223
224
225 public void setIntHeader(String name, int value)
226 {
227 if ("content-length".equalsIgnoreCase(name))
228 {
229 _contentLength=value;
230 if (_gzStream!=null)
231 _gzStream.setContentLength(_contentLength);
232 }
233 else
234 super.setIntHeader(name,value);
235 }
236
237
238
239
240
241 public void flushBuffer() throws IOException
242 {
243 if (_writer!=null)
244 _writer.flush();
245 if (_gzStream!=null)
246 _gzStream.finish();
247 else
248 getResponse().flushBuffer();
249 }
250
251
252
253
254
255 public void reset()
256 {
257 super.reset();
258 if (_gzStream!=null)
259 _gzStream.resetBuffer();
260 _writer=null;
261 _gzStream=null;
262 _noGzip=false;
263 _contentLength=-1;
264 }
265
266
267
268
269
270 public void resetBuffer()
271 {
272 super.resetBuffer();
273 if (_gzStream!=null)
274 _gzStream.resetBuffer();
275 _writer=null;
276 _gzStream=null;
277 }
278
279
280
281
282
283 public void sendError(int sc, String msg) throws IOException
284 {
285 resetBuffer();
286 super.sendError(sc,msg);
287 }
288
289
290
291
292
293 public void sendError(int sc) throws IOException
294 {
295 resetBuffer();
296 super.sendError(sc);
297 }
298
299
300
301
302
303 public void sendRedirect(String location) throws IOException
304 {
305 resetBuffer();
306 super.sendRedirect(location);
307 }
308
309
310
311
312
313 public ServletOutputStream getOutputStream() throws IOException
314 {
315 if (_gzStream==null)
316 {
317 if (getResponse().isCommitted() || _noGzip)
318 {
319 setContentLength(_contentLength);
320 return getResponse().getOutputStream();
321 }
322
323 _gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
324 }
325 else if (_writer!=null)
326 throw new IllegalStateException("getWriter() called");
327
328 return _gzStream;
329 }
330
331
332
333
334
335 public PrintWriter getWriter() throws IOException
336 {
337 if (_writer==null)
338 {
339 if (_gzStream!=null)
340 throw new IllegalStateException("getOutputStream() called");
341
342 if (getResponse().isCommitted() || _noGzip)
343 {
344 setContentLength(_contentLength);
345 return getResponse().getWriter();
346 }
347
348 _gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
349 _writer=newWriter(_gzStream,getCharacterEncoding());
350 }
351 return _writer;
352 }
353
354
355
356
357
358 public void noGzip()
359 {
360 _noGzip=true;
361 if (_gzStream!=null)
362 {
363 try
364 {
365 _gzStream.doNotGzip();
366 }
367 catch (IOException e)
368 {
369 throw new IllegalStateException(e);
370 }
371 }
372 }
373
374
375
376
377
378
379
380 public void finish() throws IOException
381 {
382 if (_writer!=null && !_gzStream._closed)
383 _writer.flush();
384 if (_gzStream!=null)
385 _gzStream.finish();
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400 protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
401 {
402 return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
403 }
404
405
406
407
408
409
410
411
412
413
414 protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
415 {
416 return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
417 }
418 }
419