Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/AsyncHttpConnection.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children | 8e9db0bbf4f9 |
comparison
equal
deleted
inserted
replaced
801:6a21393191c1 | 802:3428c60d7cfc |
---|---|
1 // | |
2 // ======================================================================== | |
3 // Copyright (c) 1995-2014 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.HttpException; | |
24 import org.eclipse.jetty.http.HttpStatus; | |
25 import org.eclipse.jetty.io.AsyncEndPoint; | |
26 import org.eclipse.jetty.io.Connection; | |
27 import org.eclipse.jetty.io.EndPoint; | |
28 import org.eclipse.jetty.io.nio.AsyncConnection; | |
29 import org.eclipse.jetty.io.nio.SelectChannelEndPoint; | |
30 import org.eclipse.jetty.util.log.Log; | |
31 import org.eclipse.jetty.util.log.Logger; | |
32 | |
33 | |
34 /* ------------------------------------------------------------ */ | |
35 /** Asychronous Server HTTP connection | |
36 * | |
37 */ | |
38 public class AsyncHttpConnection extends AbstractHttpConnection implements AsyncConnection | |
39 { | |
40 private final static int NO_PROGRESS_INFO = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_INFO",100); | |
41 private final static int NO_PROGRESS_CLOSE = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_CLOSE",200); | |
42 | |
43 private static final Logger LOG = Log.getLogger(AsyncHttpConnection.class); | |
44 private int _total_no_progress; | |
45 private final AsyncEndPoint _asyncEndp; | |
46 private boolean _readInterested = true; | |
47 | |
48 public AsyncHttpConnection(Connector connector, EndPoint endpoint, Server server) | |
49 { | |
50 super(connector,endpoint,server); | |
51 _asyncEndp=(AsyncEndPoint)endpoint; | |
52 } | |
53 | |
54 @Override | |
55 public Connection handle() throws IOException | |
56 { | |
57 Connection connection = this; | |
58 boolean some_progress=false; | |
59 boolean progress=true; | |
60 | |
61 try | |
62 { | |
63 setCurrentConnection(this); | |
64 | |
65 // don't check for idle while dispatched (unless blocking IO is done). | |
66 _asyncEndp.setCheckForIdle(false); | |
67 | |
68 | |
69 // While progress and the connection has not changed | |
70 while (progress && connection==this) | |
71 { | |
72 progress=false; | |
73 try | |
74 { | |
75 // Handle resumed request | |
76 if (_request._async.isAsync()) | |
77 { | |
78 if (_request._async.isDispatchable()) | |
79 handleRequest(); | |
80 } | |
81 // else Parse more input | |
82 else if (!_parser.isComplete() && _parser.parseAvailable()) | |
83 progress=true; | |
84 | |
85 // Generate more output | |
86 if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown() && !_request.getAsyncContinuation().isAsyncStarted()) | |
87 if (_generator.flushBuffer()>0) | |
88 progress=true; | |
89 | |
90 // Flush output | |
91 _endp.flush(); | |
92 | |
93 // Has any IO been done by the endpoint itself since last loop | |
94 if (_asyncEndp.hasProgressed()) | |
95 progress=true; | |
96 } | |
97 catch (HttpException e) | |
98 { | |
99 if (LOG.isDebugEnabled()) | |
100 { | |
101 LOG.debug("uri="+_uri); | |
102 LOG.debug("fields="+_requestFields); | |
103 LOG.debug(e); | |
104 } | |
105 progress=true; | |
106 _generator.sendError(e.getStatus(), e.getReason(), null, true); | |
107 } | |
108 finally | |
109 { | |
110 some_progress|=progress; | |
111 // Is this request/response round complete and are fully flushed? | |
112 boolean parserComplete = _parser.isComplete(); | |
113 boolean generatorComplete = _generator.isComplete(); | |
114 boolean complete = parserComplete && generatorComplete; | |
115 if (parserComplete) | |
116 { | |
117 if (generatorComplete) | |
118 { | |
119 // Reset the parser/generator | |
120 progress=true; | |
121 | |
122 // look for a switched connection instance? | |
123 if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101) | |
124 { | |
125 Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection"); | |
126 if (switched!=null) | |
127 connection=switched; | |
128 } | |
129 | |
130 reset(); | |
131 | |
132 // TODO Is this still required? | |
133 if (!_generator.isPersistent() && !_endp.isOutputShutdown()) | |
134 { | |
135 LOG.warn("Safety net oshut!!! IF YOU SEE THIS, PLEASE RAISE BUGZILLA"); | |
136 _endp.shutdownOutput(); | |
137 } | |
138 } | |
139 else | |
140 { | |
141 // We have finished parsing, but not generating so | |
142 // we must not be interested in reading until we | |
143 // have finished generating and we reset the generator | |
144 _readInterested = false; | |
145 LOG.debug("Disabled read interest while writing response {}", _endp); | |
146 } | |
147 } | |
148 | |
149 if (!complete && _request.getAsyncContinuation().isAsyncStarted()) | |
150 { | |
151 // The request is suspended, so even though progress has been made, | |
152 // exit the while loop by setting progress to false | |
153 LOG.debug("suspended {}",this); | |
154 progress=false; | |
155 } | |
156 } | |
157 } | |
158 } | |
159 finally | |
160 { | |
161 setCurrentConnection(null); | |
162 | |
163 // If we are not suspended | |
164 if (!_request.getAsyncContinuation().isAsyncStarted()) | |
165 { | |
166 // return buffers | |
167 _parser.returnBuffers(); | |
168 _generator.returnBuffers(); | |
169 | |
170 // reenable idle checking unless request is suspended | |
171 _asyncEndp.setCheckForIdle(true); | |
172 } | |
173 | |
174 // Safety net to catch spinning | |
175 if (some_progress) | |
176 _total_no_progress=0; | |
177 else | |
178 { | |
179 _total_no_progress++; | |
180 if (NO_PROGRESS_INFO>0 && _total_no_progress%NO_PROGRESS_INFO==0 && (NO_PROGRESS_CLOSE<=0 || _total_no_progress< NO_PROGRESS_CLOSE)) | |
181 LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this); | |
182 if (NO_PROGRESS_CLOSE>0 && _total_no_progress==NO_PROGRESS_CLOSE) | |
183 { | |
184 LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this); | |
185 if (_endp instanceof SelectChannelEndPoint) | |
186 ((SelectChannelEndPoint)_endp).getChannel().close(); | |
187 } | |
188 } | |
189 } | |
190 return connection; | |
191 } | |
192 | |
193 public void onInputShutdown() throws IOException | |
194 { | |
195 // If we don't have a committed response and we are not suspended | |
196 if (_generator.isIdle() && !_request.getAsyncContinuation().isSuspended()) | |
197 { | |
198 // then no more can happen, so close. | |
199 _endp.close(); | |
200 } | |
201 | |
202 // Make idle parser seek EOF | |
203 if (_parser.isIdle()) | |
204 _parser.setPersistent(false); | |
205 } | |
206 | |
207 @Override | |
208 public void reset() | |
209 { | |
210 _readInterested = true; | |
211 LOG.debug("Enabled read interest {}", _endp); | |
212 super.reset(); | |
213 } | |
214 | |
215 @Override | |
216 public boolean isSuspended() | |
217 { | |
218 return !_readInterested || super.isSuspended(); | |
219 } | |
220 } |