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