View Javadoc

1   package org.eclipse.jetty.server;
2   
3   import java.io.IOException;
4   
5   import org.eclipse.jetty.http.HttpException;
6   import org.eclipse.jetty.http.HttpStatus;
7   import org.eclipse.jetty.io.AsyncEndPoint;
8   import org.eclipse.jetty.io.Connection;
9   import org.eclipse.jetty.io.EndPoint;
10  import org.eclipse.jetty.util.log.Log;
11  import org.eclipse.jetty.util.log.Logger;
12  
13  public class AsyncHttpConnection extends HttpConnection
14  {
15      private static final Logger LOG = Log.getLogger(AsyncHttpConnection.class);
16  
17      public AsyncHttpConnection(Connector connector, EndPoint endpoint, Server server)
18      {
19          super(connector,endpoint,server);
20      }
21  
22      public Connection handle() throws IOException
23      {
24          Connection connection = this;
25          
26          // Loop while more in buffer
27          try
28          {
29              setCurrentConnection(this);
30  
31              boolean progress=true; 
32              boolean more_in_buffer =false;
33              
34              while (_endp.isOpen() && (more_in_buffer || progress))
35              {
36                  progress=false;
37                  try
38                  {
39                      LOG.debug("async request",_request);
40                      
41                      // Handle resumed request
42                      if (_request._async.isAsync() && !_request._async.isComplete())
43                          handleRequest();
44                      
45                      // else Parse more input
46                      else if (!_parser.isComplete() && _parser.parseAvailable()>0)
47                          progress=true;
48  
49                      // Generate more output
50                      if (_generator.isCommitted() && !_generator.isComplete() && _generator.flushBuffer()>0)
51                          progress=true;
52                      
53                      // Flush output from buffering endpoint
54                      if (_endp.isBufferingOutput())
55                          _endp.flush();
56                  }
57                  catch (HttpException e)
58                  {
59                      if (LOG.isDebugEnabled())
60                      {
61                          LOG.debug("uri="+_uri);
62                          LOG.debug("fields="+_requestFields);
63                          LOG.debug(e);
64                      }
65                      _generator.sendError(e.getStatus(), e.getReason(), null, true);
66                      _parser.reset();
67                      _endp.close();
68                  }
69                  finally
70                  {
71                      // Do we need to complete a half close?
72                      if (_endp.isInputShutdown() && (_parser.isIdle() || _parser.isComplete()))
73                      {
74                          LOG.debug("complete half close {}",this);
75                          more_in_buffer=false;
76                          _endp.close();
77                          reset(true);
78                      }
79                      
80                      // else Is this request/response round complete?
81                      else if (_parser.isComplete() && _generator.isComplete() && !_endp.isBufferingOutput())
82                      {
83                          // look for a switched connection instance?
84                          if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
85                          {
86                              Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
87                              if (switched!=null)
88                              {
89                                  _parser.reset();
90                                  _generator.reset(true);
91                                  return switched;
92                              }
93                          }
94                          
95                          // Reset the parser/generator
96                          // keep the buffers as we will cycle 
97                          progress=true;
98                          reset(false);
99                          more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
100                     }
101 
102                     // else Are we suspended?
103                     else if (_request.isAsyncStarted())
104                     {
105                         LOG.debug("suspended {}",this);
106                         more_in_buffer=false;
107                         progress=false;
108                     }
109                     else
110                         more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
111                 }
112             }
113         }
114         finally
115         {
116             setCurrentConnection(null);
117             _parser.returnBuffers();
118 
119             // Are we write blocked
120             if (_generator.isCommitted() && !_generator.isComplete())
121                 ((AsyncEndPoint)_endp).scheduleWrite();
122             else
123                 _generator.returnBuffers();
124         }
125         return connection;
126     }
127 
128 }