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