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 } |
