View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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  
19  package org.eclipse.jetty.servlets;
20  
21  import java.io.IOException;
22  import java.io.OutputStream;
23  import java.io.OutputStreamWriter;
24  import java.io.PrintWriter;
25  import java.io.UnsupportedEncodingException;
26  import java.util.zip.Deflater;
27  import java.util.zip.DeflaterOutputStream;
28  import java.util.zip.GZIPOutputStream;
29  
30  import javax.servlet.FilterConfig;
31  import javax.servlet.ServletException;
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpServletResponse;
34  
35  import org.eclipse.jetty.io.UncheckedPrintWriter;
36  import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream;
37  import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper;
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   */
51  public 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                          @Override
89                          protected void setHeader(String name, String value)
90                          {
91                              super.setHeader(name, value);
92                              HttpServletResponse response = (HttpServletResponse)getResponse();
93                              if (!response.containsHeader(name))
94                                  response.setHeader("org.eclipse.jetty.server.include." + name, value);
95                          }
96                      };
97                  }
98              };
99          }
100         else if (compressionType.equals(GZIP))
101         {
102             wrappedResponse = new IncludableResponseWrapper(request,response)
103             {
104                 @Override
105                 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
106                 {
107                     return new AbstractCompressedStream(compressionType,request,this,_vary)
108                     {
109                         @Override
110                         protected DeflaterOutputStream createStream() throws IOException
111                         {
112                             return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
113                         }
114 
115                         @Override
116                         protected void setHeader(String name, String value)
117                         {
118                             super.setHeader(name, value);
119                             HttpServletResponse response = (HttpServletResponse)getResponse();
120                             if (!response.containsHeader(name))
121                                 response.setHeader("org.eclipse.jetty.server.include." + name, value);
122                         }
123                     };
124                 }
125             };
126         }
127         else if (compressionType.equals(DEFLATE))
128         {
129             wrappedResponse = new IncludableResponseWrapper(request,response)
130             {
131                 @Override
132                 protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
133                 {
134                     return new AbstractCompressedStream(compressionType,request,this,_vary)
135                     {
136                         @Override
137                         protected DeflaterOutputStream createStream() throws IOException
138                         {
139                             return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap));
140                         }
141 
142                         @Override
143                         protected void setHeader(String name, String value)
144                         {
145                             super.setHeader(name, value);
146                             HttpServletResponse response = (HttpServletResponse)getResponse();
147                             if (!response.containsHeader(name))
148                                 response.setHeader("org.eclipse.jetty.server.include." + name, value);
149                         }
150                     };
151                 }
152             };
153         }
154         else
155         {
156             throw new IllegalStateException(compressionType + " not supported");
157         }
158         configureWrappedResponse(wrappedResponse);
159         return wrappedResponse;
160     }
161 
162 
163     // Extend CompressedResponseWrapper to be able to set headers during include and to create unchecked printwriters
164     private abstract class IncludableResponseWrapper extends CompressedResponseWrapper
165     {
166         public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
167         {
168             super(request,response);
169         }
170 
171         @Override
172         public void setHeader(String name,String value)
173         {
174             super.setHeader(name,value);
175             HttpServletResponse response = (HttpServletResponse)getResponse();
176             if (!response.containsHeader(name))
177                 response.setHeader("org.eclipse.jetty.server.include."+name,value);
178         }
179         @Override
180         protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
181         {
182             if (_uncheckedPrintWriter)
183                 return encoding == null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding));
184             return super.newWriter(out,encoding);
185         }
186     }
187 
188 }