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