blob: 04aebdc6557685e1a3f027084263c4620099a201 [file] [log] [blame]
Jake Slack03928ae2014-05-13 18:41:56 -07001//
2// ========================================================================
3// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4// ------------------------------------------------------------------------
5// All rights reserved. This program and the accompanying materials
6// are made available under the terms of the Eclipse Public License v1.0
7// and Apache License v2.0 which accompanies this distribution.
8//
9// The Eclipse Public License is available at
10// http://www.eclipse.org/legal/epl-v10.html
11//
12// The Apache License v2.0 is available at
13// http://www.opensource.org/licenses/apache2.0.php
14//
15// You may elect to redistribute this code under either of these licenses.
16// ========================================================================
17//
18
19package org.eclipse.jetty.servlets;
20
21import java.io.IOException;
22import java.io.OutputStream;
23import java.io.OutputStreamWriter;
24import java.io.PrintWriter;
25import java.io.UnsupportedEncodingException;
26import java.util.zip.Deflater;
27import java.util.zip.DeflaterOutputStream;
28import java.util.zip.GZIPOutputStream;
29
30import javax.servlet.FilterConfig;
31import javax.servlet.ServletException;
32import javax.servlet.http.HttpServletRequest;
33import javax.servlet.http.HttpServletResponse;
34
35import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
36import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
37import org.eclipse.jetty.io.UncheckedPrintWriter;
38
39/* ------------------------------------------------------------ */
40/** Includable GZip Filter.
41 * This extension to the {@link GzipFilter} that uses Jetty features to allow
42 * headers to be set during calls to
43 * {@link javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}.
44 * This allows the gzip filter to function correct during includes and to make a decision to gzip or not
45 * at the time the buffer fills and on the basis of all response headers.
46 *
47 * If the init parameter "uncheckedPrintWriter" is set to "true", then the PrintWriter used by
48 * the wrapped getWriter will be {@link UncheckedPrintWriter}.
49 *
50 */
51public class IncludableGzipFilter extends GzipFilter
52{
53 boolean _uncheckedPrintWriter=false;
54
55 @Override
56 public void init(FilterConfig filterConfig) throws ServletException
57 {
58 super.init(filterConfig);
59
60 String tmp=filterConfig.getInitParameter("uncheckedPrintWriter");
61 if (tmp!=null)
62 _uncheckedPrintWriter=Boolean.valueOf(tmp).booleanValue();
63 }
64
65 /* ------------------------------------------------------------ */
66 /**
67 * @see org.eclipse.jetty.servlets.GzipFilter#createWrappedResponse(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
68 */
69 @Override
70 protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
71 {
72 CompressedResponseWrapper wrappedResponse = null;
73 if (compressionType==null)
74 {
75 wrappedResponse = new IncludableResponseWrapper(request,response)
76 {
77 @Override
78 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
79 {
80 return new AbstractCompressedStream(null,request,this,_vary)
81 {
82 @Override
83 protected DeflaterOutputStream createStream() throws IOException
84 {
85 return null;
86 }
87 };
88 }
89 };
90 }
91 else if (compressionType.equals(GZIP))
92 {
93 wrappedResponse = new IncludableResponseWrapper(request,response)
94 {
95 @Override
96 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
97 {
98 return new AbstractCompressedStream(compressionType,request,this,_vary)
99 {
100 @Override
101 protected DeflaterOutputStream createStream() throws IOException
102 {
103 return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
104 }
105 };
106 }
107 };
108 }
109 else if (compressionType.equals(DEFLATE))
110 {
111 wrappedResponse = new IncludableResponseWrapper(request,response)
112 {
113 @Override
114 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
115 {
116 return new AbstractCompressedStream(compressionType,request,this,_vary)
117 {
118 @Override
119 protected DeflaterOutputStream createStream() throws IOException
120 {
121 return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap));
122 }
123 };
124 }
125 };
126 }
127 else
128 {
129 throw new IllegalStateException(compressionType + " not supported");
130 }
131 configureWrappedResponse(wrappedResponse);
132 return wrappedResponse;
133 }
134
135
136 // Extend CompressedResponseWrapper to be able to set headers during include and to create unchecked printwriters
137 private abstract class IncludableResponseWrapper extends CompressedResponseWrapper
138 {
139 public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
140 {
141 super(request,response);
142 }
143
144 @Override
145 public void setHeader(String name,String value)
146 {
147 super.setHeader(name,value);
148 HttpServletResponse response = (HttpServletResponse)getResponse();
149 if (!response.containsHeader(name))
150 response.setHeader("org.eclipse.jetty.server.include."+name,value);
151 }
152
153 @Override
154 public void addHeader(String name, String value)
155 {
156 super.addHeader(name, value);
157 HttpServletResponse response = (HttpServletResponse)getResponse();
158 if (!response.containsHeader(name))
159 setHeader(name,value);
160 }
161
162 @Override
163 protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
164 {
165 if (_uncheckedPrintWriter)
166 return encoding == null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding));
167 return super.newWriter(out,encoding);
168 }
169 }
170
171}