View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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.continuation;
20  
21  import java.io.IOException;
22  
23  import javax.servlet.Filter;
24  import javax.servlet.FilterChain;
25  import javax.servlet.FilterConfig;
26  import javax.servlet.ServletContext;
27  import javax.servlet.ServletException;
28  import javax.servlet.ServletRequest;
29  import javax.servlet.ServletResponse;
30  
31  
32  
33  /* ------------------------------------------------------------ */
34  /**
35   * <p>ContinuationFilter must be applied to servlet paths that make use of
36   * the asynchronous features provided by {@link Continuation} APIs, but that
37   * are deployed in servlet containers that are a
38   * compliant Servlet 3.0 container.</p>
39   * <p>The following init parameters may be used to configure the filter (these are mostly for testing):</p>
40   * <dl>
41   * <dt>debug</dt><dd>Boolean controlling debug output</dd>
42   * <dt>faux</dt><dd>Boolean to force use of faux continuations</dd>
43   * </dl>
44   * <p>If the servlet container is not Jetty 7+ nor a Servlet 3
45   * container, then "faux" continuations will be used.</p>
46   * <p>Faux continuations will just put the thread that called {@link Continuation#suspend()}
47   * in wait, and will notify that thread when {@link Continuation#resume()} or
48   * {@link Continuation#complete()} is called.</p>
49   * <p>Faux continuations are not threadless continuations (they are "faux" - fake - for this reason)
50   * and as such they will scale less than proper continuations.</p>
51   */
52  public class ContinuationFilter implements Filter
53  {
54      static boolean _initialized;
55      static boolean __debug; // shared debug status
56      private boolean _faux;
57      private boolean _filtered;
58      ServletContext _context;
59      private boolean _debug;
60  
61      public void init(FilterConfig filterConfig) throws ServletException
62      {
63          boolean jetty_7_or_greater="org.eclipse.jetty.servlet".equals(filterConfig.getClass().getPackage().getName());
64          _context = filterConfig.getServletContext();
65  
66          String param=filterConfig.getInitParameter("debug");
67          _debug=param!=null&&Boolean.parseBoolean(param);
68          if (_debug)
69              __debug=true;
70  
71          param=filterConfig.getInitParameter("partial");
72          param=filterConfig.getInitParameter("faux");
73          if (param!=null)
74              _faux=Boolean.parseBoolean(param);
75          else
76              _faux=!(jetty_7_or_greater || _context.getMajorVersion()>=3);
77  
78          _filtered=_faux;
79          if (_debug)
80              _context.log("ContinuationFilter "+
81                      " jetty="+jetty_7_or_greater+
82                      " faux="+_faux+
83                      " filtered="+_filtered+
84                      " servlet3="+ContinuationSupport.__servlet3);
85          _initialized=true;
86      }
87  
88      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
89      {
90          if (_filtered)
91          {
92              Continuation c = (Continuation) request.getAttribute(Continuation.ATTRIBUTE);
93              FilteredContinuation fc;
94              if (_faux && (c==null || !(c instanceof FauxContinuation)))
95              {
96                  fc = new FauxContinuation(request);
97                  request.setAttribute(Continuation.ATTRIBUTE,fc);
98              }
99              else
100                 fc=(FilteredContinuation)c;
101 
102             boolean complete=false;
103             while (!complete)
104             {
105                 try
106                 {
107                     if (fc==null || (fc).enter(response))
108                         chain.doFilter(request,response);
109                 }
110                 catch (ContinuationThrowable e)
111                 {
112                     debug("faux",e);
113                 }
114                 finally
115                 {
116                     if (fc==null)
117                         fc = (FilteredContinuation) request.getAttribute(Continuation.ATTRIBUTE);
118 
119                     complete=fc==null || (fc).exit();
120                 }
121             }
122         }
123         else
124         {
125             try
126             {
127                 chain.doFilter(request,response);
128             }
129             catch (ContinuationThrowable e)
130             {
131                 debug("caught",e);
132             }
133         }
134     }
135 
136     private void debug(String string)
137     {
138         if (_debug)
139         {
140             _context.log(string);
141         }
142     }
143 
144     private void debug(String string, Throwable th)
145     {
146         if (_debug)
147         {
148             if (th instanceof ContinuationThrowable)
149                 _context.log(string+":"+th);
150             else
151                 _context.log(string,th);
152         }
153     }
154 
155     public void destroy()
156     {
157     }
158 
159     public interface FilteredContinuation extends Continuation
160     {
161         boolean enter(ServletResponse response);
162         boolean exit();
163     }
164 }