View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.server;
20  
21  import java.io.IOException;
22  
23  import org.eclipse.jetty.http.Generator;
24  import org.eclipse.jetty.http.HttpException;
25  import org.eclipse.jetty.http.HttpStatus;
26  import org.eclipse.jetty.http.Parser;
27  import org.eclipse.jetty.io.Connection;
28  import org.eclipse.jetty.io.EndPoint;
29  import org.eclipse.jetty.util.log.Log;
30  import org.eclipse.jetty.util.log.Logger;
31  
32  
33  /* ------------------------------------------------------------ */
34  /** Blocking Server HTTP Connection
35   */
36  public class BlockingHttpConnection extends AbstractHttpConnection
37  {
38      private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
39  
40      public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server)
41      {
42          super(connector,endpoint,server);
43      }
44  
45      public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request)
46      {
47          super(connector,endpoint,server,parser,generator,request);
48      }
49  
50      @Override
51      protected void handleRequest() throws IOException
52      {
53          super.handleRequest();
54      }
55  
56      public Connection handle() throws IOException
57      {
58          Connection connection = this;
59  
60          try
61          {
62              setCurrentConnection(this);
63  
64              // do while the endpoint is open
65              // AND the connection has not changed
66              while (_endp.isOpen() && connection==this)
67              {
68                  try
69                  {
70                      // If we are not ended then parse available
71                      if (!_parser.isComplete() && !_endp.isInputShutdown())
72                          _parser.parseAvailable();
73  
74                      // Do we have more generating to do?
75                      // Loop here because some writes may take multiple steps and
76                      // we need to flush them all before potentially blocking in the
77                      // next loop.
78                      if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown())
79                          _generator.flushBuffer();
80  
81                      // Flush buffers
82                      _endp.flush();
83                  }
84                  catch (HttpException e)
85                  {
86                      if (LOG.isDebugEnabled())
87                      {
88                          LOG.debug("uri="+_uri);
89                          LOG.debug("fields="+_requestFields);
90                          LOG.debug(e);
91                      }
92                      _generator.sendError(e.getStatus(), e.getReason(), null, true);
93                      _parser.reset();
94                      _endp.shutdownOutput();
95                  }
96                  finally
97                  {
98                      //  Is this request/response round complete and are fully flushed?
99                      if (_parser.isComplete() && _generator.isComplete())
100                     {
101                         // Reset the parser/generator
102                         reset();
103 
104                         // look for a switched connection instance?
105                         if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
106                         {
107                             Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
108                             if (switched!=null)
109                                 connection=switched;
110                         }
111 
112                         // TODO Is this required?
113                         if (!_generator.isPersistent() && !_endp.isOutputShutdown())
114                         {
115                             LOG.warn("Safety net oshut!!! Please open a bugzilla");
116                             _endp.shutdownOutput();
117                         }
118                     }
119                     
120                     // If we don't have a committed response and we are not suspended
121                     if (_endp.isInputShutdown() && _generator.isIdle() && !_request.getAsyncContinuation().isSuspended())
122                     {
123                         // then no more can happen, so close.
124                         _endp.close();
125                     }
126                 }
127             }
128 
129             return connection;
130         }
131         finally
132         {
133             setCurrentConnection(null);
134             _parser.returnBuffers();
135             _generator.returnBuffers();
136         }
137     }
138 }