jetty-9 HttpChannel cleanup

This commit is contained in:
Greg Wilkins 2012-05-17 15:56:02 +02:00
parent b9a2661a4e
commit 60b38b7775
2 changed files with 53 additions and 64 deletions

View File

@ -21,6 +21,7 @@ import java.nio.ByteBuffer;
import java.util.Timer; import java.util.Timer;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream; import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -77,14 +78,14 @@ public abstract class HttpChannel
private final HttpFields _requestFields; private final HttpFields _requestFields;
private final Request _request; private final Request _request;
private final AsyncContinuation _async; private final AsyncContinuation _state;
private final HttpFields _responseFields; private final HttpFields _responseFields;
private final Response _response; private final Response _response;
private final HttpInput _in; private final HttpInput _in;
private volatile Output _out; private final Output _out;
private volatile HttpWriter _writer; private volatile HttpWriter _writer;
private volatile PrintWriter _printWriter; private volatile PrintWriter _printWriter;
@ -114,8 +115,9 @@ public abstract class HttpChannel
_responseFields = new HttpFields(server.getMaxCookieVersion()); _responseFields = new HttpFields(server.getMaxCookieVersion());
_request = new Request(this); _request = new Request(this);
_response = new Response(this); _response = new Response(this);
_async = _request.getAsyncContinuation(); _state = _request.getAsyncContinuation();
_in=input; _in=input;
_out=new Output();
} }
public interface EventHandler extends HttpParser.RequestHandler public interface EventHandler extends HttpParser.RequestHandler
@ -132,7 +134,7 @@ public abstract class HttpChannel
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean isIdle() public boolean isIdle()
{ {
return _async.isIdle(); return _state.isIdle();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -154,7 +156,7 @@ public abstract class HttpChannel
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public AsyncContinuation getAsyncContinuation() public AsyncContinuation getAsyncContinuation()
{ {
return _async; return _state;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -247,8 +249,6 @@ public abstract class HttpChannel
*/ */
public HttpOutput getOutputStream() public HttpOutput getOutputStream()
{ {
if (_out == null)
_out = new Output();
return _out; return _out;
} }
@ -297,103 +297,92 @@ public abstract class HttpChannel
_responseFields.clear(); _responseFields.clear();
_response.recycle(); _response.recycle();
_uri.clear(); _uri.clear();
if (_out!=null) _out.reset();
_out.reset();
_in.recycle(); // TODO done here or in connection? _in.recycle(); // TODO done here or in connection?
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected void handleRequest() throws IOException protected void handleRequest() throws IOException
{ {
System.err.println("handleRequest"); LOG.debug("{} handleRequest",this);
boolean error = false;
String threadName=null; String threadName=null;
if (LOG.isDebugEnabled())
{
threadName=Thread.currentThread().getName();
Thread.currentThread().setName(threadName+" - "+_uri);
}
Throwable async_exception=null; Throwable async_exception=null;
__currentChannel.set(this);
try try
{ {
if (LOG.isDebugEnabled())
{
threadName=Thread.currentThread().getName();
Thread.currentThread().setName(threadName+" - "+_uri);
}
// Loop here to handle async request redispatches. // Loop here to handle async request redispatches.
// The loop is controlled by the call to async.unhandle in the // The loop is controlled by the call to async.unhandle in the
// finally block below. If call is from a non-blocking connector, // finally block below. Unhandle will return false only if an async dispatch has
// then the unhandle will return false only if an async dispatch has // already happened when unhandle is called.
// already happened when unhandle is called. For a blocking connector, boolean handling=_state.handling();
// the wait for the asynchronous dispatch or timeout actually happens
// within the call to unhandle().
final Server server=_server; while(handling && getServer().isRunning())
boolean handling=_async.handling() && server!=null && server.isRunning();
while (handling)
{ {
_request.setHandled(false);
String info=null;
try try
{ {
_uri.getPort(); _request.setHandled(false);
info=URIUtil.canonicalPath(_uri.getDecodedPath()); _out.reopen();
if (info==null && !_request.getMethod().equals(HttpMethod.CONNECT))
{
sendError(400,null,null,true);
return;
}
if (_out!=null) if (_state.isInitial())
_out.reopen();
if (_async.isInitial())
{ {
_request.setDispatcherType(DispatcherType.REQUEST); _request.setDispatcherType(DispatcherType.REQUEST);
getHttpConnector().customize(_request); getHttpConnector().customize(_request);
server.handle(this); getServer().handle(this);
} }
else else
{ {
_request.setDispatcherType(DispatcherType.ASYNC); _request.setDispatcherType(DispatcherType.ASYNC);
server.handleAsync(this); getServer().handleAsync(this);
} }
} }
catch (ContinuationThrowable e) catch (ContinuationThrowable e)
{ {
LOG.ignore(e); LOG.ignore(e);
} }
catch (EofException | RuntimeIOException e) catch (ServletException e)
{
// TODO
}
catch (EofException e)
{ {
async_exception=e;
LOG.debug(e); LOG.debug(e);
error=true; async_exception=e;
_request.setHandled(true); _request.setHandled(true);
} }
catch (Throwable e) catch (Throwable e)
{ {
async_exception=e;
LOG.warn(String.valueOf(_uri),e); LOG.warn(String.valueOf(_uri),e);
error=true; async_exception=e;
_request.setHandled(true); _request.setHandled(true);
if (!_response.isCommitted()) sendError(500, null, e.toString(), true);
sendError(info==null?400:500, null, null, true);
} }
finally finally
{ {
handling = !_async.unhandle() && server.isRunning() && _server!=null; handling = !_state.unhandle();
} }
} }
} }
finally finally
{ {
__currentChannel.set(null);
if (threadName!=null) if (threadName!=null)
Thread.currentThread().setName(threadName); Thread.currentThread().setName(threadName);
if (_async.isUncompleted()) if (_state.isUncompleted())
{ {
_async.doComplete(async_exception); _state.doComplete(async_exception);
if (_expect100Continue) if (_expect100Continue)
{ {
@ -407,17 +396,18 @@ public abstract class HttpChannel
_response.addHeader(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE.toString()); _response.addHeader(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE.toString());
} }
if (!error && !_response.isCommitted() && !_request.isHandled()) if (!_response.isCommitted() && !_request.isHandled())
_response.sendError(HttpServletResponse.SC_NOT_FOUND); _response.sendError(HttpServletResponse.SC_NOT_FOUND);
// TODO - this is not correct. complete can get called too often.
_response.complete(); _response.complete();
_request.setHandled(true); _request.setHandled(true);
completed(); completed();
} }
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected boolean sendError(final int status, final String reason, String content, boolean close) protected boolean sendError(final int status, final String reason, String content, boolean close)
{ {
@ -465,8 +455,7 @@ public abstract class HttpChannel
public void included() public void included()
{ {
_include--; _include--;
if (_out!=null) _out.reopen();
_out.reopen();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -503,7 +492,7 @@ public abstract class HttpChannel
return String.format("%s{r=%d,a=%s}", return String.format("%s{r=%d,a=%s}",
super.toString(), super.toString(),
_requests, _requests,
_async.getState()); _state.getState());
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -68,6 +68,12 @@ public class HttpOutput extends ServletOutputStream
_closed=false; _closed=false;
} }
/* ------------------------------------------------------------ */
public void reopen()
{
_closed=false;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see java.io.OutputStream#close() * @see java.io.OutputStream#close()
@ -86,12 +92,6 @@ public class HttpOutput extends ServletOutputStream
return _closed; return _closed;
} }
/* ------------------------------------------------------------ */
public void reopen()
{
_closed=false;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void flush() throws IOException public void flush() throws IOException