View Javadoc

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