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  
80                      _parser.reset();
81                      _endp.close();
82                  }
83                  finally
84                  {
85                      more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
86                      
87                      // Is this request/response round complete?
88                      if (_parser.isComplete() && _generator.isComplete() && !_endp.isBufferingOutput())
89                      {
90                          // look for a switched connection instance?
91                          Connection switched=(_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
92                          ?(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection"):null;
93  
94                          // have we switched?
95                          if (switched!=null)
96                          {
97                              _parser.reset();
98                              _generator.reset(true);
99                              connection=switched;
100                         }
101                         else
102                         {
103                             // No switch, so cleanup and reset
104                             if (!_generator.isPersistent() || _endp.isInputShutdown())
105                             {
106                                 _parser.reset();
107                                 more_in_buffer=false;
108                                 _endp.close();
109                             }
110 
111                             if (more_in_buffer)
112                             {
113                                 reset(false);
114                                 more_in_buffer = _parser.isMoreInBuffer() || _endp.isBufferingInput();
115                             }
116                             else
117                                 reset(true);
118                         }
119                     }
120                     else if (_parser.isIdle() && _endp.isInputShutdown())
121                     {
122                         more_in_buffer=false;
123                         _endp.close();
124                     }
125 
126                     if (_request.isAsyncStarted())
127                         throw new IllegalStateException();
128                 }
129             }
130         }
131         finally
132         {
133             _parser.returnBuffers();
134             setCurrentConnection(null);
135             _handling=false;
136         }
137         return connection;
138     }
139 
140 }