View Javadoc

1   package org.eclipse.jetty.server;
2   
3   import java.io.IOException;
4   
5   import org.eclipse.jetty.http.Generator;
6   import org.eclipse.jetty.http.HttpException;
7   import org.eclipse.jetty.http.HttpStatus;
8   import org.eclipse.jetty.http.Parser;
9   import org.eclipse.jetty.io.AsyncEndPoint;
10  import org.eclipse.jetty.io.Connection;
11  import org.eclipse.jetty.io.EndPoint;
12  import org.eclipse.jetty.util.log.Log;
13  import org.eclipse.jetty.util.log.Logger;
14  
15  public class BlockingHttpConnection extends HttpConnection
16  {
17      private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
18  
19      private volatile boolean _handling;
20      
21      public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server)
22      {
23          super(connector,endpoint,server);
24      }
25  
26      
27      public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request)
28      {
29          super(connector,endpoint,server,parser,generator,request);
30      }
31  
32  
33      public Connection handle() throws IOException
34      {
35          Connection connection = this;
36  
37          // Loop while more in buffer
38          boolean more_in_buffer =true; // assume true until proven otherwise
39  
40          try
41          {
42              setCurrentConnection(this);
43  
44              while (more_in_buffer && _endp.isOpen())
45              {
46                  try
47                  {
48                      // If we are not ended then parse available
49                      if (!_parser.isComplete())
50                          _parser.parseAvailable();
51  
52                      // Do we have more generating to do?
53                      // Loop here because some writes may take multiple steps and
54                      // we need to flush them all before potentially blocking in the
55                      // next loop.
56                      while (_generator.isCommitted() && !_generator.isComplete())
57                      {
58                          long written=_generator.flushBuffer();
59                          if (written<=0)
60                              break;
61                          if (_endp.isBufferingOutput())
62                              _endp.flush();
63                      }
64  
65                      // Flush buffers
66                      if (_endp.isBufferingOutput())
67                          _endp.flush();
68        
69                  }
70                  catch (HttpException e)
71                  {
72                      if (LOG.isDebugEnabled())
73                      {
74                          LOG.debug("uri="+_uri);
75                          LOG.debug("fields="+_requestFields);
76                          LOG.debug(e);
77                      }
78                      _generator.sendError(e.getStatus(), e.getReason(), null, true);
79                      _parser.reset();
80                      _endp.shutdownOutput();
81                  }
82                  finally
83                  {
84                      more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
85                      
86                      // Is this request/response round complete?
87                      if (_parser.isComplete() && _generator.isComplete() && !_endp.isBufferingOutput())
88                      {
89                          // look for a switched connection instance?
90                          Connection switched=(_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
91                          ?(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection"):null;
92  
93                          // have we switched?
94                          if (switched!=null)
95                          {
96                              _parser.reset();
97                              _generator.reset(true);
98                              connection=switched;
99                          }
100                         else
101                         {
102                             // No switch, so cleanup and reset
103                             if (!_generator.isPersistent() || _endp.isInputShutdown())
104                             {
105                                 _parser.reset();
106                                 more_in_buffer=false;
107                                 _endp.close();
108                             }
109 
110                             if (more_in_buffer)
111                             {
112                                 reset(false);
113                                 more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
114                             }
115                             else
116                                 reset(true);
117                         }
118                     }
119                     else if (_parser.isIdle() && _endp.isInputShutdown())
120                     {
121                         more_in_buffer=false;
122                         _endp.close();
123                     }
124 
125                     if (_request.isAsyncStarted())
126                         throw new IllegalStateException();
127                 }
128             }
129         }
130         finally
131         {
132             _parser.returnBuffers();
133             setCurrentConnection(null);
134             _handling=false;
135         }
136         return connection;
137     }
138 
139 }