diff src/org/eclipse/jetty/server/AbstractHttpConnection.java @ 826:6ebf86e4d2ca

remove HttpContent
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 14 Sep 2016 18:51:34 -0600
parents 292f2e31ab41
children 86338c0029a9
line wrap: on
line diff
--- a/src/org/eclipse/jetty/server/AbstractHttpConnection.java	Wed Sep 14 16:38:33 2016 -0600
+++ b/src/org/eclipse/jetty/server/AbstractHttpConnection.java	Wed Sep 14 18:51:34 2016 -0600
@@ -33,7 +33,6 @@
 import org.eclipse.jetty.http.EncodedHttpURI;
 import org.eclipse.jetty.http.Generator;
 import org.eclipse.jetty.http.HttpBuffers;
-import org.eclipse.jetty.http.HttpContent;
 import org.eclipse.jetty.http.HttpException;
 import org.eclipse.jetty.http.HttpFields;
 import org.eclipse.jetty.http.HttpGenerator;
@@ -99,1164 +98,1110 @@
  */
 public abstract class AbstractHttpConnection  extends AbstractConnection
 {
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpConnection.class);
+	private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpConnection.class);
 
-    private static final int UNKNOWN = -2;
-    private static final ThreadLocal<AbstractHttpConnection> __currentConnection = new ThreadLocal<AbstractHttpConnection>();
+	private static final int UNKNOWN = -2;
+	private static final ThreadLocal<AbstractHttpConnection> __currentConnection = new ThreadLocal<AbstractHttpConnection>();
 
-    private int _requests;
+	private int _requests;
 
-    protected final Connector _connector;
-    protected final Server _server;
-    protected final HttpURI _uri;
+	protected final Connector _connector;
+	protected final Server _server;
+	protected final HttpURI _uri;
 
-    protected final Parser _parser;
-    protected final HttpFields _requestFields;
-    protected final Request _request;
-    protected volatile ServletInputStream _in;
+	protected final Parser _parser;
+	protected final HttpFields _requestFields;
+	protected final Request _request;
+	protected volatile ServletInputStream _in;
 
-    protected final Generator _generator;
-    protected final HttpFields _responseFields;
-    protected final Response _response;
-    protected volatile Output _out;
-    protected volatile OutputWriter _writer;
-    protected volatile PrintWriter _printWriter;
+	protected final Generator _generator;
+	protected final HttpFields _responseFields;
+	protected final Response _response;
+	protected volatile Output _out;
+	protected volatile OutputWriter _writer;
+	protected volatile PrintWriter _printWriter;
 
-    int _include;
+	int _include;
 
-    private Object _associatedObject; // associated object
+	private Object _associatedObject; // associated object
 
-    private int _version = UNKNOWN;
+	private int _version = UNKNOWN;
 
-    private String _charset;
-    private boolean _expect = false;
-    private boolean _expect100Continue = false;
-    private boolean _expect102Processing = false;
-    private boolean _head = false;
-    private boolean _host = false;
-    private boolean _delayedHandling=false;
-    private boolean _earlyEOF = false;
+	private String _charset;
+	private boolean _expect = false;
+	private boolean _expect100Continue = false;
+	private boolean _expect102Processing = false;
+	private boolean _head = false;
+	private boolean _host = false;
+	private boolean _delayedHandling=false;
+	private boolean _earlyEOF = false;
 
-    /* ------------------------------------------------------------ */
-    public static AbstractHttpConnection getCurrentConnection()
-    {
-        return __currentConnection.get();
-    }
+	/* ------------------------------------------------------------ */
+	public static AbstractHttpConnection getCurrentConnection()
+	{
+		return __currentConnection.get();
+	}
 
-    /* ------------------------------------------------------------ */
-    protected static void setCurrentConnection(AbstractHttpConnection connection)
-    {
-        __currentConnection.set(connection);
-    }
+	/* ------------------------------------------------------------ */
+	protected static void setCurrentConnection(AbstractHttpConnection connection)
+	{
+		__currentConnection.set(connection);
+	}
 
-    /* ------------------------------------------------------------ */
-    public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server)
-    {
-        super(endpoint);
-        _uri = StringUtil.__UTF8.equals(URIUtil.__CHARSET)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
-        _connector = connector;
-        HttpBuffers ab = (HttpBuffers)_connector;
-        _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
-        _requestFields = new HttpFields();
-        _responseFields = new HttpFields();
-        _request = new Request(this);
-        _response = new Response(this);
-        _generator = newHttpGenerator(ab.getResponseBuffers(), endpoint);
-        _generator.setSendServerVersion(server.getSendServerVersion());
-        _server = server;
-    }
+	/* ------------------------------------------------------------ */
+	public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server)
+	{
+		super(endpoint);
+		_uri = StringUtil.__UTF8.equals(URIUtil.__CHARSET)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
+		_connector = connector;
+		HttpBuffers ab = (HttpBuffers)_connector;
+		_parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
+		_requestFields = new HttpFields();
+		_responseFields = new HttpFields();
+		_request = new Request(this);
+		_response = new Response(this);
+		_generator = newHttpGenerator(ab.getResponseBuffers(), endpoint);
+		_generator.setSendServerVersion(server.getSendServerVersion());
+		_server = server;
+	}
 
-    /* ------------------------------------------------------------ */
-    protected AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server,
-            Parser parser, Generator generator, Request request)
-    {
-        super(endpoint);
+	/* ------------------------------------------------------------ */
+	protected AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server,
+			Parser parser, Generator generator, Request request)
+	{
+		super(endpoint);
 
-        _uri = URIUtil.__CHARSET.equals(StringUtil.__UTF8)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
-        _connector = connector;
-        _parser = parser;
-        _requestFields = new HttpFields();
-        _responseFields = new HttpFields();
-        _request = request;
-        _response = new Response(this);
-        _generator = generator;
-        _generator.setSendServerVersion(server.getSendServerVersion());
-        _server = server;
-    }
+		_uri = URIUtil.__CHARSET.equals(StringUtil.__UTF8)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
+		_connector = connector;
+		_parser = parser;
+		_requestFields = new HttpFields();
+		_responseFields = new HttpFields();
+		_request = request;
+		_response = new Response(this);
+		_generator = generator;
+		_generator.setSendServerVersion(server.getSendServerVersion());
+		_server = server;
+	}
 
-    protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endpoint, HttpParser.EventHandler requestHandler)
-    {
-        return new HttpParser(requestBuffers, endpoint, requestHandler);
-    }
+	protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endpoint, HttpParser.EventHandler requestHandler)
+	{
+		return new HttpParser(requestBuffers, endpoint, requestHandler);
+	}
 
-    protected HttpGenerator newHttpGenerator(Buffers responseBuffers, EndPoint endPoint)
-    {
-        return new HttpGenerator(responseBuffers, endPoint);
-    }
+	protected HttpGenerator newHttpGenerator(Buffers responseBuffers, EndPoint endPoint)
+	{
+		return new HttpGenerator(responseBuffers, endPoint);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the parser used by this connection
-     */
-    public Parser getParser()
-    {
-        return _parser;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return the parser used by this connection
+	 */
+	public Parser getParser()
+	{
+		return _parser;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the number of requests handled by this connection
-     */
-    public int getRequests()
-    {
-        return _requests;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return the number of requests handled by this connection
+	 */
+	public int getRequests()
+	{
+		return _requests;
+	}
 
-    /* ------------------------------------------------------------ */
-    public Server getServer()
-    {
-        return _server;
-    }
+	/* ------------------------------------------------------------ */
+	public Server getServer()
+	{
+		return _server;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the associatedObject.
-     */
-    public Object getAssociatedObject()
-    {
-        return _associatedObject;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the associatedObject.
+	 */
+	public Object getAssociatedObject()
+	{
+		return _associatedObject;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param associatedObject The associatedObject to set.
-     */
-    public void setAssociatedObject(Object associatedObject)
-    {
-        _associatedObject = associatedObject;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param associatedObject The associatedObject to set.
+	 */
+	public void setAssociatedObject(Object associatedObject)
+	{
+		_associatedObject = associatedObject;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the connector.
-     */
-    public Connector getConnector()
-    {
-        return _connector;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the connector.
+	 */
+	public Connector getConnector()
+	{
+		return _connector;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the requestFields.
-     */
-    public HttpFields getRequestFields()
-    {
-        return _requestFields;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the requestFields.
+	 */
+	public HttpFields getRequestFields()
+	{
+		return _requestFields;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the responseFields.
-     */
-    public HttpFields getResponseFields()
-    {
-        return _responseFields;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the responseFields.
+	 */
+	public HttpFields getResponseFields()
+	{
+		return _responseFields;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Find out if the request supports CONFIDENTIAL security.
-     * @param request the incoming HTTP request
-     * @return the result of calling {@link Connector#isConfidential(Request)}, or false
-     * if there is no connector
-     */
-    public boolean isConfidential(Request request)
-    {
-        return _connector != null && _connector.isConfidential(request);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Find out if the request supports CONFIDENTIAL security.
+	 * @param request the incoming HTTP request
+	 * @return the result of calling {@link Connector#isConfidential(Request)}, or false
+	 * if there is no connector
+	 */
+	public boolean isConfidential(Request request)
+	{
+		return _connector != null && _connector.isConfidential(request);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Find out if the request supports INTEGRAL security.
-     * @param request the incoming HTTP request
-     * @return the result of calling {@link Connector#isIntegral(Request)}, or false
-     * if there is no connector
-     */
-    public boolean isIntegral(Request request)
-    {
-        return _connector != null && _connector.isIntegral(request);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Find out if the request supports INTEGRAL security.
+	 * @param request the incoming HTTP request
+	 * @return the result of calling {@link Connector#isIntegral(Request)}, or false
+	 * if there is no connector
+	 */
+	public boolean isIntegral(Request request)
+	{
+		return _connector != null && _connector.isIntegral(request);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return <code>false</code> (this method is not yet implemented)
-     */
-    public boolean getResolveNames()
-    {
-        return _connector.getResolveNames();
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return <code>false</code> (this method is not yet implemented)
+	 */
+	public boolean getResolveNames()
+	{
+		return _connector.getResolveNames();
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the request.
-     */
-    public Request getRequest()
-    {
-        return _request;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the request.
+	 */
+	public Request getRequest()
+	{
+		return _request;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the response.
-     */
-    public Response getResponse()
-    {
-        return _response;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the response.
+	 */
+	public Response getResponse()
+	{
+		return _response;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Get the inputStream from the connection.
-     * <p>
-     * If the associated response has the Expect header set to 100 Continue,
-     * then accessing the input stream indicates that the handler/servlet
-     * is ready for the request body and thus a 100 Continue response is sent.
-     *
-     * @return The input stream for this connection.
-     * The stream will be created if it does not already exist.
-     * @throws IOException if the input stream cannot be retrieved
-     */
-    public ServletInputStream getInputStream() throws IOException
-    {
-        // If the client is expecting 100 CONTINUE, then send it now.
-        if (_expect100Continue)
-        {
-            // is content missing?
-            if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
-            {
-                if (_generator.isCommitted())
-                    throw new IllegalStateException("Committed before 100 Continues");
+	/* ------------------------------------------------------------ */
+	/**
+	 * Get the inputStream from the connection.
+	 * <p>
+	 * If the associated response has the Expect header set to 100 Continue,
+	 * then accessing the input stream indicates that the handler/servlet
+	 * is ready for the request body and thus a 100 Continue response is sent.
+	 *
+	 * @return The input stream for this connection.
+	 * The stream will be created if it does not already exist.
+	 * @throws IOException if the input stream cannot be retrieved
+	 */
+	public ServletInputStream getInputStream() throws IOException
+	{
+		// If the client is expecting 100 CONTINUE, then send it now.
+		if (_expect100Continue)
+		{
+			// is content missing?
+			if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
+			{
+				if (_generator.isCommitted())
+					throw new IllegalStateException("Committed before 100 Continues");
 
-                ((HttpGenerator)_generator).send1xx(HttpStatus.CONTINUE_100);
-            }
-            _expect100Continue=false;
-        }
+				((HttpGenerator)_generator).send1xx(HttpStatus.CONTINUE_100);
+			}
+			_expect100Continue=false;
+		}
 
-        if (_in == null)
-            _in = new HttpInput(AbstractHttpConnection.this);
-        return _in;
-    }
+		if (_in == null)
+			_in = new HttpInput(AbstractHttpConnection.this);
+		return _in;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return The output stream for this connection. The stream will be created if it does not already exist.
-     */
-    public ServletOutputStream getOutputStream()
-    {
-        if (_out == null)
-            _out = new Output();
-        return _out;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return The output stream for this connection. The stream will be created if it does not already exist.
+	 */
+	public ServletOutputStream getOutputStream()
+	{
+		if (_out == null)
+			_out = new Output();
+		return _out;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param encoding the PrintWriter encoding
-     * @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it
-     *    does not already exist.
-     */
-    public PrintWriter getPrintWriter(String encoding)
-    {
-        getOutputStream();
-        if (_writer==null)
-        {
-            _writer=new OutputWriter();
-            if (_server.isUncheckedPrintWriter())
-                _printWriter=new UncheckedPrintWriter(_writer);
-            else
-                _printWriter = new PrintWriter(_writer)
-                {
-                    public void close()
-                    {
-                        synchronized (lock)
-                        {
-                            try
-                            {
-                                out.close();
-                            }
-                            catch (IOException e)
-                            {
-                                setError();
-                            }
-                        }
-                    }
-                };
-        }
-        _writer.setCharacterEncoding(encoding);
-        return _printWriter;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param encoding the PrintWriter encoding
+	 * @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it
+	 *    does not already exist.
+	 */
+	public PrintWriter getPrintWriter(String encoding)
+	{
+		getOutputStream();
+		if (_writer==null)
+		{
+			_writer=new OutputWriter();
+			if (_server.isUncheckedPrintWriter())
+				_printWriter=new UncheckedPrintWriter(_writer);
+			else
+				_printWriter = new PrintWriter(_writer)
+				{
+					public void close()
+					{
+						synchronized (lock)
+						{
+							try
+							{
+								out.close();
+							}
+							catch (IOException e)
+							{
+								setError();
+							}
+						}
+					}
+				};
+		}
+		_writer.setCharacterEncoding(encoding);
+		return _printWriter;
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isResponseCommitted()
-    {
-        return _generator.isCommitted();
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isResponseCommitted()
+	{
+		return _generator.isCommitted();
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isEarlyEOF()
-    {
-        return _earlyEOF;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isEarlyEOF()
+	{
+		return _earlyEOF;
+	}
 
-    /* ------------------------------------------------------------ */
-    public void reset()
-    {
-        _parser.reset();
-        _parser.returnBuffers(); // TODO maybe only on unhandle
-        _requestFields.clear();
-        _request.recycle();
-        _generator.reset();
-        _generator.returnBuffers();// TODO maybe only on unhandle
-        _responseFields.clear();
-        _response.recycle();
-        _uri.clear();
-        _writer=null;
-        _earlyEOF = false;
-    }
+	/* ------------------------------------------------------------ */
+	public void reset()
+	{
+		_parser.reset();
+		_parser.returnBuffers(); // TODO maybe only on unhandle
+		_requestFields.clear();
+		_request.recycle();
+		_generator.reset();
+		_generator.returnBuffers();// TODO maybe only on unhandle
+		_responseFields.clear();
+		_response.recycle();
+		_uri.clear();
+		_writer=null;
+		_earlyEOF = false;
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void handleRequest() throws IOException
-    {
-        boolean error = false;
+	/* ------------------------------------------------------------ */
+	protected void handleRequest() throws IOException
+	{
+		boolean error = false;
 
-        String threadName=null;
-        Throwable async_exception=null;
-        try
-        {
-            if (LOG.isDebugEnabled())
-            {
-                threadName=Thread.currentThread().getName();
-                Thread.currentThread().setName(threadName+" - "+_uri);
-            }
+		String threadName=null;
+		Throwable async_exception=null;
+		try
+		{
+			if (LOG.isDebugEnabled())
+			{
+				threadName=Thread.currentThread().getName();
+				Thread.currentThread().setName(threadName+" - "+_uri);
+			}
 
 
-            // Loop here to handle async request redispatches.
-            // The loop is controlled by the call to async.unhandle in the
-            // finally block below.  If call is from a non-blocking connector,
-            // then the unhandle will return false only if an async dispatch has
-            // already happened when unhandle is called.   For a blocking connector,
-            // the wait for the asynchronous dispatch or timeout actually happens
-            // within the call to unhandle().
+			// Loop here to handle async request redispatches.
+			// The loop is controlled by the call to async.unhandle in the
+			// finally block below.  If call is from a non-blocking connector,
+			// then the unhandle will return false only if an async dispatch has
+			// already happened when unhandle is called.   For a blocking connector,
+			// the wait for the asynchronous dispatch or timeout actually happens
+			// within the call to unhandle().
 
-            final Server server=_server;
-            boolean was_continuation=_request._async.isContinuation();
-            boolean handling=_request._async.handling() && server!=null && server.isRunning();
-            while (handling)
-            {
-                _request.setHandled(false);
+			final Server server=_server;
+			boolean was_continuation=_request._async.isContinuation();
+			boolean handling=_request._async.handling() && server!=null && server.isRunning();
+			while (handling)
+			{
+				_request.setHandled(false);
 
-                String info=null;
-                try
-                {
-                    _uri.getPort();
-                    String path = null;
+				String info=null;
+				try
+				{
+					_uri.getPort();
+					String path = null;
 
-                    try
-                    {
-                        path = _uri.getDecodedPath();
-                    }
-                    catch (Exception e)
-                    {
-                        LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1");
-                        LOG.trace("",e);
-                        path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
-                    }
+					try
+					{
+						path = _uri.getDecodedPath();
+					}
+					catch (Exception e)
+					{
+						LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1");
+						LOG.trace("",e);
+						path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
+					}
 
-                    info=URIUtil.canonicalPath(path);
-                    if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT))
-                    {
-                        if (path==null && _uri.getScheme()!=null && _uri.getHost()!=null)
-                        {
-                            info="/";
-                            _request.setRequestURI("");
-                        }
-                        else
-                            throw new HttpException(400);
-                    }
-                    _request.setPathInfo(info);
+					info=URIUtil.canonicalPath(path);
+					if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT))
+					{
+						if (path==null && _uri.getScheme()!=null && _uri.getHost()!=null)
+						{
+							info="/";
+							_request.setRequestURI("");
+						}
+						else
+							throw new HttpException(400);
+					}
+					_request.setPathInfo(info);
 
-                    if (_out!=null)
-                        _out.reopen();
+					if (_out!=null)
+						_out.reopen();
 
-                    if (_request._async.isInitial())
-                    {
-                        _request.setDispatcherType(DispatcherType.REQUEST);
-                        _connector.customize(_endp, _request);
-                        server.handle(this);
-                    }
-                    else
-                    {
-                        if (_request._async.isExpired()&&!was_continuation)
-                        {
-                            async_exception = (Throwable)_request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
-                            _response.setStatus(500,async_exception==null?"Async Timeout":"Async Exception");
-                            _request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500));
-                            _request.setAttribute(RequestDispatcher.ERROR_MESSAGE, _response.getReason());
-                            _request.setDispatcherType(DispatcherType.ERROR);
-                        }
-                        else
-                            _request.setDispatcherType(DispatcherType.ASYNC);
-                        server.handleAsync(this);
-                    }
-                }
-                catch (ContinuationThrowable e)
-                {
-                    LOG.trace("",e);
-                }
-                catch (EofException e)
-                {
-                    async_exception=e;
-                    LOG.debug("",e);
-                    error=true;
-                    _request.setHandled(true);
-                    if (!_response.isCommitted())
-                        _generator.sendError(500, null, null, true);
-                }
-                catch (RuntimeIOException e)
-                {
-                    async_exception=e;
-                    LOG.debug("",e);
-                    error=true;
-                    _request.setHandled(true);
-                }
-                catch (HttpException e)
-                {
-                    LOG.debug("",e);
-                    error=true;
-                    _request.setHandled(true);
-                    _response.sendError(e.getStatus(), e.getReason());
-                }
-                catch (Throwable e)
-                {
-                    async_exception=e;
-                    LOG.warn(String.valueOf(_uri),e);
-                    error=true;
-                    _request.setHandled(true);
-                    _generator.sendError(info==null?400:500, null, null, true);
-                    
-                }
-                finally
-                {
-                    // Complete async requests 
-                    if (error && _request.isAsyncStarted())
-                        _request.getAsyncContinuation().errorComplete();
-                        
-                    was_continuation=_request._async.isContinuation();
-                    handling = !_request._async.unhandle() && server.isRunning() && _server!=null;
-                }
-            }
-        }
-        finally
-        {
-            if (threadName!=null)
-                Thread.currentThread().setName(threadName);
+					if (_request._async.isInitial())
+					{
+						_request.setDispatcherType(DispatcherType.REQUEST);
+						_connector.customize(_endp, _request);
+						server.handle(this);
+					}
+					else
+					{
+						if (_request._async.isExpired()&&!was_continuation)
+						{
+							async_exception = (Throwable)_request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+							_response.setStatus(500,async_exception==null?"Async Timeout":"Async Exception");
+							_request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500));
+							_request.setAttribute(RequestDispatcher.ERROR_MESSAGE, _response.getReason());
+							_request.setDispatcherType(DispatcherType.ERROR);
+						}
+						else
+							_request.setDispatcherType(DispatcherType.ASYNC);
+						server.handleAsync(this);
+					}
+				}
+				catch (ContinuationThrowable e)
+				{
+					LOG.trace("",e);
+				}
+				catch (EofException e)
+				{
+					async_exception=e;
+					LOG.debug("",e);
+					error=true;
+					_request.setHandled(true);
+					if (!_response.isCommitted())
+						_generator.sendError(500, null, null, true);
+				}
+				catch (RuntimeIOException e)
+				{
+					async_exception=e;
+					LOG.debug("",e);
+					error=true;
+					_request.setHandled(true);
+				}
+				catch (HttpException e)
+				{
+					LOG.debug("",e);
+					error=true;
+					_request.setHandled(true);
+					_response.sendError(e.getStatus(), e.getReason());
+				}
+				catch (Throwable e)
+				{
+					async_exception=e;
+					LOG.warn(String.valueOf(_uri),e);
+					error=true;
+					_request.setHandled(true);
+					_generator.sendError(info==null?400:500, null, null, true);
+					
+				}
+				finally
+				{
+					// Complete async requests 
+					if (error && _request.isAsyncStarted())
+						_request.getAsyncContinuation().errorComplete();
+						
+					was_continuation=_request._async.isContinuation();
+					handling = !_request._async.unhandle() && server.isRunning() && _server!=null;
+				}
+			}
+		}
+		finally
+		{
+			if (threadName!=null)
+				Thread.currentThread().setName(threadName);
 
-            if (_request._async.isUncompleted())
-            {
-                
-                _request._async.doComplete(async_exception);
+			if (_request._async.isUncompleted())
+			{
+				
+				_request._async.doComplete(async_exception);
 
-                if (_expect100Continue)
-                {
-                    LOG.debug("100 continues not sent");
-                    // We didn't send 100 continues, but the latest interpretation
-                    // of the spec (see httpbis) is that the client will either
-                    // send the body anyway, or close.  So we no longer need to
-                    // do anything special here other than make the connection not persistent
-                    _expect100Continue = false;
-                    if (!_response.isCommitted())
-                        _generator.setPersistent(false);
-                }
+				if (_expect100Continue)
+				{
+					LOG.debug("100 continues not sent");
+					// We didn't send 100 continues, but the latest interpretation
+					// of the spec (see httpbis) is that the client will either
+					// send the body anyway, or close.  So we no longer need to
+					// do anything special here other than make the connection not persistent
+					_expect100Continue = false;
+					if (!_response.isCommitted())
+						_generator.setPersistent(false);
+				}
 
-                if(_endp.isOpen())
-                {
-                    if (error)
-                    {
-                        _endp.shutdownOutput();
-                        _generator.setPersistent(false);
-                        if (!_generator.isComplete())
-                            _response.complete();
-                    }
-                    else
-                    {
-                        if (!_response.isCommitted() && !_request.isHandled())
-                            _response.sendError(HttpServletResponse.SC_NOT_FOUND);
-                        _response.complete();
-                        if (_generator.isPersistent())
-                            _connector.persist(_endp);
-                    }
-                }
-                else
-                {
-                    _response.complete();
-                }
+				if(_endp.isOpen())
+				{
+					if (error)
+					{
+						_endp.shutdownOutput();
+						_generator.setPersistent(false);
+						if (!_generator.isComplete())
+							_response.complete();
+					}
+					else
+					{
+						if (!_response.isCommitted() && !_request.isHandled())
+							_response.sendError(HttpServletResponse.SC_NOT_FOUND);
+						_response.complete();
+						if (_generator.isPersistent())
+							_connector.persist(_endp);
+					}
+				}
+				else
+				{
+					_response.complete();
+				}
 
-                _request.setHandled(true);
-            }
-        }
-    }
+				_request.setHandled(true);
+			}
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public abstract Connection handle() throws IOException;
+	/* ------------------------------------------------------------ */
+	public abstract Connection handle() throws IOException;
 
-    /* ------------------------------------------------------------ */
-    public void commitResponse(boolean last) throws IOException
-    {
-        if (!_generator.isCommitted())
-        {
-            _generator.setResponse(_response.getStatus(), _response.getReason());
-            try
-            {
-                // If the client was expecting 100 continues, but we sent something
-                // else, then we need to close the connection
-                if (_expect100Continue && _response.getStatus()!=100)
-                    _generator.setPersistent(false);
-                _generator.completeHeader(_responseFields, last);
-            }
-            catch(RuntimeException e)
-            {
-                LOG.warn("header full: " + e);
+	/* ------------------------------------------------------------ */
+	public void commitResponse(boolean last) throws IOException
+	{
+		if (!_generator.isCommitted())
+		{
+			_generator.setResponse(_response.getStatus(), _response.getReason());
+			try
+			{
+				// If the client was expecting 100 continues, but we sent something
+				// else, then we need to close the connection
+				if (_expect100Continue && _response.getStatus()!=100)
+					_generator.setPersistent(false);
+				_generator.completeHeader(_responseFields, last);
+			}
+			catch(RuntimeException e)
+			{
+				LOG.warn("header full: " + e);
 
-                _response.reset();
-                _generator.reset();
-                _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
-                _generator.completeHeader(_responseFields,Generator.LAST);
-                _generator.complete();
-                throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
-            }
+				_response.reset();
+				_generator.reset();
+				_generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
+				_generator.completeHeader(_responseFields,Generator.LAST);
+				_generator.complete();
+				throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
+			}
 
-        }
-        if (last)
-            _generator.complete();
-    }
+		}
+		if (last)
+			_generator.complete();
+	}
 
-    /* ------------------------------------------------------------ */
-    public void completeResponse() throws IOException
-    {
-        if (!_generator.isCommitted())
-        {
-            _generator.setResponse(_response.getStatus(), _response.getReason());
-            try
-            {
-                _generator.completeHeader(_responseFields, Generator.LAST);
-            }
-            catch(RuntimeException e)
-            {
-                LOG.warn("header full: "+e);
-                LOG.debug("",e);
+	/* ------------------------------------------------------------ */
+	public void completeResponse() throws IOException
+	{
+		if (!_generator.isCommitted())
+		{
+			_generator.setResponse(_response.getStatus(), _response.getReason());
+			try
+			{
+				_generator.completeHeader(_responseFields, Generator.LAST);
+			}
+			catch(RuntimeException e)
+			{
+				LOG.warn("header full: "+e);
+				LOG.debug("",e);
 
-                _response.reset();
-                _generator.reset();
-                _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
-                _generator.completeHeader(_responseFields,Generator.LAST);
-                _generator.complete();
-                throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
-            }
-        }
+				_response.reset();
+				_generator.reset();
+				_generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
+				_generator.completeHeader(_responseFields,Generator.LAST);
+				_generator.complete();
+				throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
+			}
+		}
 
-        _generator.complete();
-    }
+		_generator.complete();
+	}
 
-    /* ------------------------------------------------------------ */
-    public void flushResponse() throws IOException
-    {
-        try
-        {
-            commitResponse(Generator.MORE);
-            _generator.flushBuffer();
-        }
-        catch(IOException e)
-        {
-            throw (e instanceof EofException) ? e:new EofException(e);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void flushResponse() throws IOException
+	{
+		try
+		{
+			commitResponse(Generator.MORE);
+			_generator.flushBuffer();
+		}
+		catch(IOException e)
+		{
+			throw (e instanceof EofException) ? e:new EofException(e);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public Generator getGenerator()
-    {
-        return _generator;
-    }
+	/* ------------------------------------------------------------ */
+	public Generator getGenerator()
+	{
+		return _generator;
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isIncluding()
-    {
-        return _include>0;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isIncluding()
+	{
+		return _include>0;
+	}
 
-    /* ------------------------------------------------------------ */
-    public void include()
-    {
-        _include++;
-    }
+	/* ------------------------------------------------------------ */
+	public void include()
+	{
+		_include++;
+	}
 
-    /* ------------------------------------------------------------ */
-    public void included()
-    {
-        _include--;
-        if (_out!=null)
-            _out.reopen();
-    }
+	/* ------------------------------------------------------------ */
+	public void included()
+	{
+		_include--;
+		if (_out!=null)
+			_out.reopen();
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isIdle()
-    {
-        return _generator.isIdle() && (_parser.isIdle() || _delayedHandling);
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isIdle()
+	{
+		return _generator.isIdle() && (_parser.isIdle() || _delayedHandling);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.io.Connection#isSuspended()
-     */
-    public boolean isSuspended()
-    {
-        return _request.getAsyncContinuation().isSuspended();
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @see org.eclipse.jetty.io.Connection#isSuspended()
+	 */
+	public boolean isSuspended()
+	{
+		return _request.getAsyncContinuation().isSuspended();
+	}
 
-    /* ------------------------------------------------------------ */
-    public void onClose()
-    {
-        LOG.debug("closed {}",this);
-    }
+	/* ------------------------------------------------------------ */
+	public void onClose()
+	{
+		LOG.debug("closed {}",this);
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isExpecting100Continues()
-    {
-        return _expect100Continue;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isExpecting100Continues()
+	{
+		return _expect100Continue;
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isExpecting102Processing()
-    {
-        return _expect102Processing;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isExpecting102Processing()
+	{
+		return _expect102Processing;
+	}
 
-    /* ------------------------------------------------------------ */
-    public int getMaxIdleTime()
-    {
-        if (_connector.isLowResources() && _endp.getMaxIdleTime()==_connector.getMaxIdleTime())
-            return _connector.getLowResourceMaxIdleTime();
-        if (_endp.getMaxIdleTime()>0)
-            return _endp.getMaxIdleTime();
-        return _connector.getMaxIdleTime();
-    }
+	/* ------------------------------------------------------------ */
+	public int getMaxIdleTime()
+	{
+		if (_connector.isLowResources() && _endp.getMaxIdleTime()==_connector.getMaxIdleTime())
+			return _connector.getLowResourceMaxIdleTime();
+		if (_endp.getMaxIdleTime()>0)
+			return _endp.getMaxIdleTime();
+		return _connector.getMaxIdleTime();
+	}
 
-    /* ------------------------------------------------------------ */
-    public String toString()
-    {
-        return String.format("%s,g=%s,p=%s,r=%d",
-                super.toString(),
-                _generator,
-                _parser,
-                _requests);
-    }
+	/* ------------------------------------------------------------ */
+	public String toString()
+	{
+		return String.format("%s,g=%s,p=%s,r=%d",
+				super.toString(),
+				_generator,
+				_parser,
+				_requests);
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
-    {
-        uri=uri.asImmutableBuffer();
+	/* ------------------------------------------------------------ */
+	protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
+	{
+		uri=uri.asImmutableBuffer();
 
-        _host = false;
-        _expect = false;
-        _expect100Continue=false;
-        _expect102Processing=false;
-        _delayedHandling=false;
-        _charset=null;
+		_host = false;
+		_expect = false;
+		_expect100Continue=false;
+		_expect102Processing=false;
+		_delayedHandling=false;
+		_charset=null;
 
-        if(_request.getTimeStamp()==0)
-            _request.setTimeStamp(System.currentTimeMillis());
-        _request.setMethod(method.toString());
+		if(_request.getTimeStamp()==0)
+			_request.setTimeStamp(System.currentTimeMillis());
+		_request.setMethod(method.toString());
 
-        try
-        {
-            _head=false;
-            switch (HttpMethods.CACHE.getOrdinal(method))
-            {
-              case HttpMethods.CONNECT_ORDINAL:
-                  _uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
-                  break;
+		try
+		{
+			_head=false;
+			switch (HttpMethods.CACHE.getOrdinal(method))
+			{
+			  case HttpMethods.CONNECT_ORDINAL:
+				  _uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
+				  break;
 
-              case HttpMethods.HEAD_ORDINAL:
-                  _head=true;
-                  _uri.parse(uri.array(), uri.getIndex(), uri.length());
-                  break;
+			  case HttpMethods.HEAD_ORDINAL:
+				  _head=true;
+				  _uri.parse(uri.array(), uri.getIndex(), uri.length());
+				  break;
 
-              default:
-                  _uri.parse(uri.array(), uri.getIndex(), uri.length());
-            }
+			  default:
+				  _uri.parse(uri.array(), uri.getIndex(), uri.length());
+			}
 
-            _request.setUri(_uri);
+			_request.setUri(_uri);
 
-            if (version==null)
-            {
-                _request.setProtocol(HttpVersions.HTTP_0_9);
-                _version=HttpVersions.HTTP_0_9_ORDINAL;
-            }
-            else
-            {
-                version= HttpVersions.CACHE.get(version);
-                if (version==null)
-                    throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
-                _version = HttpVersions.CACHE.getOrdinal(version);
-                if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
-                _request.setProtocol(version.toString());
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.debug("",e);
-            if (e instanceof HttpException)
-                throw (HttpException)e;
-            throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e);
-        }
-    }
+			if (version==null)
+			{
+				_request.setProtocol(HttpVersions.HTTP_0_9);
+				_version=HttpVersions.HTTP_0_9_ORDINAL;
+			}
+			else
+			{
+				version= HttpVersions.CACHE.get(version);
+				if (version==null)
+					throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
+				_version = HttpVersions.CACHE.getOrdinal(version);
+				if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
+				_request.setProtocol(version.toString());
+			}
+		}
+		catch (Exception e)
+		{
+			LOG.debug("",e);
+			if (e instanceof HttpException)
+				throw (HttpException)e;
+			throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void parsedHeader(Buffer name, Buffer value) throws IOException
-    {
-        int ho = HttpHeaders.CACHE.getOrdinal(name);
-        switch (ho)
-        {
-            case HttpHeaders.HOST_ORDINAL:
-                // TODO check if host matched a host in the URI.
-                _host = true;
-                break;
+	/* ------------------------------------------------------------ */
+	protected void parsedHeader(Buffer name, Buffer value) throws IOException
+	{
+		int ho = HttpHeaders.CACHE.getOrdinal(name);
+		switch (ho)
+		{
+			case HttpHeaders.HOST_ORDINAL:
+				// TODO check if host matched a host in the URI.
+				_host = true;
+				break;
 
-            case HttpHeaders.EXPECT_ORDINAL:
-                if (_version>=HttpVersions.HTTP_1_1_ORDINAL)
-                {
-                    value = HttpHeaderValues.CACHE.lookup(value);
-                    switch(HttpHeaderValues.CACHE.getOrdinal(value))
-                    {
-                        case HttpHeaderValues.CONTINUE_ORDINAL:
-                            _expect100Continue=_generator instanceof HttpGenerator;
-                            break;
+			case HttpHeaders.EXPECT_ORDINAL:
+				if (_version>=HttpVersions.HTTP_1_1_ORDINAL)
+				{
+					value = HttpHeaderValues.CACHE.lookup(value);
+					switch(HttpHeaderValues.CACHE.getOrdinal(value))
+					{
+						case HttpHeaderValues.CONTINUE_ORDINAL:
+							_expect100Continue=_generator instanceof HttpGenerator;
+							break;
 
-                        case HttpHeaderValues.PROCESSING_ORDINAL:
-                            _expect102Processing=_generator instanceof HttpGenerator;
-                            break;
+						case HttpHeaderValues.PROCESSING_ORDINAL:
+							_expect102Processing=_generator instanceof HttpGenerator;
+							break;
 
-                        default:
-                            String[] values = value.toString().split(",");
-                            for  (int i=0;values!=null && i<values.length;i++)
-                            {
-                                CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
-                                if (cb==null)
-                                    _expect=true;
-                                else
-                                {
-                                    switch(cb.getOrdinal())
-                                    {
-                                        case HttpHeaderValues.CONTINUE_ORDINAL:
-                                            _expect100Continue=_generator instanceof HttpGenerator;
-                                            break;
-                                        case HttpHeaderValues.PROCESSING_ORDINAL:
-                                            _expect102Processing=_generator instanceof HttpGenerator;
-                                            break;
-                                        default:
-                                            _expect=true;
-                                    }
-                                }
-                            }
-                    }
-                }
-                break;
+						default:
+							String[] values = value.toString().split(",");
+							for  (int i=0;values!=null && i<values.length;i++)
+							{
+								CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
+								if (cb==null)
+									_expect=true;
+								else
+								{
+									switch(cb.getOrdinal())
+									{
+										case HttpHeaderValues.CONTINUE_ORDINAL:
+											_expect100Continue=_generator instanceof HttpGenerator;
+											break;
+										case HttpHeaderValues.PROCESSING_ORDINAL:
+											_expect102Processing=_generator instanceof HttpGenerator;
+											break;
+										default:
+											_expect=true;
+									}
+								}
+							}
+					}
+				}
+				break;
 
-            case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
-            case HttpHeaders.USER_AGENT_ORDINAL:
-                value = HttpHeaderValues.CACHE.lookup(value);
-                break;
+			case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
+			case HttpHeaders.USER_AGENT_ORDINAL:
+				value = HttpHeaderValues.CACHE.lookup(value);
+				break;
 
-            case HttpHeaders.CONTENT_TYPE_ORDINAL:
-                value = MimeTypes.CACHE.lookup(value);
-                _charset=MimeTypes.getCharsetFromContentType(value);
-                break;
-        }
+			case HttpHeaders.CONTENT_TYPE_ORDINAL:
+				value = MimeTypes.CACHE.lookup(value);
+				_charset=MimeTypes.getCharsetFromContentType(value);
+				break;
+		}
 
-        _requestFields.add(name, value);
-    }
+		_requestFields.add(name, value);
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void headerComplete() throws IOException
-    {
-        // Handle idle race
-        if (_endp.isOutputShutdown())
-        {
-            _endp.close();
-            return;
-        }
-        
-        _requests++;
-        _generator.setVersion(_version);
-        switch (_version)
-        {
-            case HttpVersions.HTTP_0_9_ORDINAL:
-                break;
-            case HttpVersions.HTTP_1_0_ORDINAL:
-                _generator.setHead(_head);
-                if (_parser.isPersistent())
-                {
-                    _responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
-                    _generator.setPersistent(true);
-                }
-                else if (HttpMethods.CONNECT.equals(_request.getMethod()))
-                {
-                    _generator.setPersistent(true);
-                    _parser.setPersistent(true);
-                }
+	/* ------------------------------------------------------------ */
+	protected void headerComplete() throws IOException
+	{
+		// Handle idle race
+		if (_endp.isOutputShutdown())
+		{
+			_endp.close();
+			return;
+		}
+		
+		_requests++;
+		_generator.setVersion(_version);
+		switch (_version)
+		{
+			case HttpVersions.HTTP_0_9_ORDINAL:
+				break;
+			case HttpVersions.HTTP_1_0_ORDINAL:
+				_generator.setHead(_head);
+				if (_parser.isPersistent())
+				{
+					_responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
+					_generator.setPersistent(true);
+				}
+				else if (HttpMethods.CONNECT.equals(_request.getMethod()))
+				{
+					_generator.setPersistent(true);
+					_parser.setPersistent(true);
+				}
 
-                if (_server.getSendDateHeader())
-                    _generator.setDate(_request.getTimeStampBuffer());
-                break;
+				if (_server.getSendDateHeader())
+					_generator.setDate(_request.getTimeStampBuffer());
+				break;
 
-            case HttpVersions.HTTP_1_1_ORDINAL:
-                _generator.setHead(_head);
+			case HttpVersions.HTTP_1_1_ORDINAL:
+				_generator.setHead(_head);
 
-                if (!_parser.isPersistent())
-                {
-                    _responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
-                    _generator.setPersistent(false);
-                }
-                if (_server.getSendDateHeader())
-                    _generator.setDate(_request.getTimeStampBuffer());
+				if (!_parser.isPersistent())
+				{
+					_responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
+					_generator.setPersistent(false);
+				}
+				if (_server.getSendDateHeader())
+					_generator.setDate(_request.getTimeStampBuffer());
 
-                if (!_host)
-                {
-                    LOG.debug("!host {}",this);
-                    _generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
-                    _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
-                    _generator.completeHeader(_responseFields, true);
-                    _generator.complete();
-                    return;
-                }
+				if (!_host)
+				{
+					LOG.debug("!host {}",this);
+					_generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
+					_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+					_generator.completeHeader(_responseFields, true);
+					_generator.complete();
+					return;
+				}
 
-                if (_expect)
-                {
-                    LOG.debug("!expectation {}",this);
-                    _generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
-                    _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
-                    _generator.completeHeader(_responseFields, true);
-                    _generator.complete();
-                    return;
-                }
+				if (_expect)
+				{
+					LOG.debug("!expectation {}",this);
+					_generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
+					_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+					_generator.completeHeader(_responseFields, true);
+					_generator.complete();
+					return;
+				}
 
-                break;
-            default:
-        }
+				break;
+			default:
+		}
 
-        if(_charset!=null)
-            _request.setCharacterEncodingUnchecked(_charset);
+		if(_charset!=null)
+			_request.setCharacterEncodingUnchecked(_charset);
 
-        // Either handle now or wait for first content
-        if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
-            handleRequest();
-        else
-            _delayedHandling=true;
-    }
+		// Either handle now or wait for first content
+		if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
+			handleRequest();
+		else
+			_delayedHandling=true;
+	}
 
-    /* ------------------------------------------------------------ */
-    protected void content(Buffer buffer) throws IOException
-    {
-        if (_delayedHandling)
-        {
-            _delayedHandling=false;
-            handleRequest();
-        }
-    }
+	/* ------------------------------------------------------------ */
+	protected void content(Buffer buffer) throws IOException
+	{
+		if (_delayedHandling)
+		{
+			_delayedHandling=false;
+			handleRequest();
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void messageComplete(long contentLength) throws IOException
-    {
-        if (_delayedHandling)
-        {
-            _delayedHandling=false;
-            handleRequest();
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void messageComplete(long contentLength) throws IOException
+	{
+		if (_delayedHandling)
+		{
+			_delayedHandling=false;
+			handleRequest();
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void earlyEOF()
-    {
-        _earlyEOF = true;
-    }
+	/* ------------------------------------------------------------ */
+	public void earlyEOF()
+	{
+		_earlyEOF = true;
+	}
 
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    private class RequestHandler extends HttpParser.EventHandler
-    {
-        /*
-         *
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startRequest(org.eclipse.io.Buffer,
-         *      org.eclipse.io.Buffer, org.eclipse.io.Buffer)
-         */
-        @Override
-        public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
-        {
-            AbstractHttpConnection.this.startRequest(method, uri, version);
-        }
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	private class RequestHandler extends HttpParser.EventHandler
+	{
+		/*
+		 *
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startRequest(org.eclipse.io.Buffer,
+		 *      org.eclipse.io.Buffer, org.eclipse.io.Buffer)
+		 */
+		@Override
+		public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
+		{
+			AbstractHttpConnection.this.startRequest(method, uri, version);
+		}
 
-        /*
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer)
-         */
-        @Override
-        public void parsedHeader(Buffer name, Buffer value) throws IOException
-        {
-            AbstractHttpConnection.this.parsedHeader(name, value);
-        }
+		/*
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer)
+		 */
+		@Override
+		public void parsedHeader(Buffer name, Buffer value) throws IOException
+		{
+			AbstractHttpConnection.this.parsedHeader(name, value);
+		}
 
-        /*
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#headerComplete()
-         */
-        @Override
-        public void headerComplete() throws IOException
-        {
-            AbstractHttpConnection.this.headerComplete();
-        }
+		/*
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#headerComplete()
+		 */
+		@Override
+		public void headerComplete() throws IOException
+		{
+			AbstractHttpConnection.this.headerComplete();
+		}
 
-        /* ------------------------------------------------------------ */
-        /*
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#content(int, org.eclipse.io.Buffer)
-         */
-        @Override
-        public void content(Buffer ref) throws IOException
-        {
-            AbstractHttpConnection.this.content(ref);
-        }
+		/* ------------------------------------------------------------ */
+		/*
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#content(int, org.eclipse.io.Buffer)
+		 */
+		@Override
+		public void content(Buffer ref) throws IOException
+		{
+			AbstractHttpConnection.this.content(ref);
+		}
 
-        /* ------------------------------------------------------------ */
-        /*
-         * (non-Javadoc)
-         *
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#messageComplete(int)
-         */
-        @Override
-        public void messageComplete(long contentLength) throws IOException
-        {
-            AbstractHttpConnection.this.messageComplete(contentLength);
-        }
+		/* ------------------------------------------------------------ */
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#messageComplete(int)
+		 */
+		@Override
+		public void messageComplete(long contentLength) throws IOException
+		{
+			AbstractHttpConnection.this.messageComplete(contentLength);
+		}
 
-        /* ------------------------------------------------------------ */
-        /*
-         * (non-Javadoc)
-         *
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startResponse(org.eclipse.io.Buffer, int,
-         *      org.eclipse.io.Buffer)
-         */
-        @Override
-        public void startResponse(Buffer version, int status, Buffer reason)
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Bad request!: "+version+" "+status+" "+reason);
-        }
+		/* ------------------------------------------------------------ */
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startResponse(org.eclipse.io.Buffer, int,
+		 *      org.eclipse.io.Buffer)
+		 */
+		@Override
+		public void startResponse(Buffer version, int status, Buffer reason)
+		{
+			if (LOG.isDebugEnabled())
+				LOG.debug("Bad request!: "+version+" "+status+" "+reason);
+		}
 
-        /* ------------------------------------------------------------ */
-        /*
-         * (non-Javadoc)
-         *
-         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#earlyEOF()
-         */
-        @Override
-        public void earlyEOF()
-        {
-            AbstractHttpConnection.this.earlyEOF();
-        }
-    }
+		/* ------------------------------------------------------------ */
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#earlyEOF()
+		 */
+		@Override
+		public void earlyEOF()
+		{
+			AbstractHttpConnection.this.earlyEOF();
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    public class Output extends HttpOutput
-    {
-        Output()
-        {
-            super(AbstractHttpConnection.this);
-        }
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	public class Output extends HttpOutput
+	{
+		Output()
+		{
+			super(AbstractHttpConnection.this);
+		}
 
-        /* ------------------------------------------------------------ */
-        /*
-         * @see java.io.OutputStream#close()
-         */
-        @Override
-        public void close() throws IOException
-        {
-            if (isClosed())
-                return;
+		/* ------------------------------------------------------------ */
+		/*
+		 * @see java.io.OutputStream#close()
+		 */
+		@Override
+		public void close() throws IOException
+		{
+			if (isClosed())
+				return;
 
-            if (!isIncluding() && !super._generator.isCommitted())
-                commitResponse(Generator.LAST);
-            else
-                flushResponse();
+			if (!isIncluding() && !super._generator.isCommitted())
+				commitResponse(Generator.LAST);
+			else
+				flushResponse();
 
-            super.close();
-        }
+			super.close();
+		}
 
 
-        /* ------------------------------------------------------------ */
-        /*
-         * @see java.io.OutputStream#flush()
-         */
-        @Override
-        public void flush() throws IOException
-        {
-            if (!super._generator.isCommitted())
-                commitResponse(Generator.MORE);
-            super.flush();
-        }
+		/* ------------------------------------------------------------ */
+		/*
+		 * @see java.io.OutputStream#flush()
+		 */
+		@Override
+		public void flush() throws IOException
+		{
+			if (!super._generator.isCommitted())
+				commitResponse(Generator.MORE);
+			super.flush();
+		}
 
-        /* ------------------------------------------------------------ */
-        /*
-         * @see javax.servlet.ServletOutputStream#print(java.lang.String)
-         */
-        @Override
-        public void print(String s) throws IOException
-        {
-            if (isClosed())
-                throw new IOException("Closed");
-            PrintWriter writer=getPrintWriter(null);
-            writer.print(s);
-        }
+		/* ------------------------------------------------------------ */
+		/*
+		 * @see javax.servlet.ServletOutputStream#print(java.lang.String)
+		 */
+		@Override
+		public void print(String s) throws IOException
+		{
+			if (isClosed())
+				throw new IOException("Closed");
+			PrintWriter writer=getPrintWriter(null);
+			writer.print(s);
+		}
 
-        /* ------------------------------------------------------------ */
-        public void sendResponse(Buffer response) throws IOException
-        {
-            ((HttpGenerator)super._generator).sendResponse(response);
-        }
+		/* ------------------------------------------------------------ */
+		public void sendResponse(Buffer response) throws IOException
+		{
+			((HttpGenerator)super._generator).sendResponse(response);
+		}
 
-        /* ------------------------------------------------------------ */
-        public void sendContent(Object content) throws IOException
-        {
-            Resource resource=null;
+		/* ------------------------------------------------------------ */
+		public void sendContent(Object content) throws IOException
+		{
+			Resource resource=null;
 
-            if (isClosed())
-                throw new IOException("Closed");
+			if (isClosed())
+				throw new IOException("Closed");
 
-            if (super._generator.isWritten())
-                throw new IllegalStateException("!empty");
+			if (super._generator.isWritten())
+				throw new IllegalStateException("!empty");
 
-            // Convert HTTP content to content
-            if (content instanceof HttpContent)
-            {
-                HttpContent httpContent = (HttpContent) content;
-                Buffer contentType = httpContent.getContentType();
-                if (contentType != null && !_responseFields.containsKey(HttpHeaders.CONTENT_TYPE_BUFFER))
-                {
-                    String enc = _response.getSetCharacterEncoding();
-                    if(enc==null)
-                        _responseFields.add(HttpHeaders.CONTENT_TYPE_BUFFER, contentType);
-                    else
-                    {
-                        if(contentType instanceof CachedBuffer)
-                        {
-                            CachedBuffer content_type = ((CachedBuffer)contentType).getAssociate(enc);
-                            if(content_type!=null)
-                                _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, content_type);
-                            else
-                            {
-                                _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER,
-                                        contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= "));
-                            }
-                        }
-                        else
-                        {
-                            _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER,
-                                    contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= "));
-                        }
-                    }
-                }
-                if (httpContent.getContentLength() > 0)
-                    _responseFields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER, httpContent.getContentLength());
-                Buffer lm = httpContent.getLastModified();
-                long lml=httpContent.getResource().lastModified();
-                if (lm != null)
-                {
-                    _responseFields.put(HttpHeaders.LAST_MODIFIED_BUFFER, lm);
-                }
-                else if (httpContent.getResource()!=null)
-                {
-                    if (lml!=-1)
-                        _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, lml);
-                }
-                
-                Buffer etag=httpContent.getETag();
-                if (etag!=null)
-                    _responseFields.put(HttpHeaders.ETAG_BUFFER,etag);
+			if (content instanceof Resource)
+			{
+				resource=(Resource)content;
+				_responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified());
+				content=resource.getInputStream();
+			}
+
+			// Process content.
+			if (content instanceof Buffer)
+			{
+				super._generator.addContent((Buffer) content, Generator.LAST);
+				commitResponse(Generator.LAST);
+			}
+			else if (content instanceof InputStream)
+			{
+				InputStream in = (InputStream)content;
+
+				try
+				{
+					int max = super._generator.prepareUncheckedAddContent();
+					Buffer buffer = super._generator.getUncheckedBuffer();
 
-                
-                boolean direct=_connector instanceof NIOConnector && ((NIOConnector)_connector).getUseDirectBuffers() && !(_connector instanceof SslConnector);
-                content = direct?httpContent.getDirectBuffer():httpContent.getIndirectBuffer();
-                if (content==null)
-                    content=httpContent.getInputStream();
-            }
-            else if (content instanceof Resource)
-            {
-                resource=(Resource)content;
-                _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified());
-                content=resource.getInputStream();
-            }
+					int len=buffer.readFrom(in,max);
 
-            // Process content.
-            if (content instanceof Buffer)
-            {
-                super._generator.addContent((Buffer) content, Generator.LAST);
-                commitResponse(Generator.LAST);
-            }
-            else if (content instanceof InputStream)
-            {
-                InputStream in = (InputStream)content;
+					while (len>=0)
+					{
+						super._generator.completeUncheckedAddContent();
+						_out.flush();
 
-                try
-                {
-                    int max = super._generator.prepareUncheckedAddContent();
-                    Buffer buffer = super._generator.getUncheckedBuffer();
-
-                    int len=buffer.readFrom(in,max);
-
-                    while (len>=0)
-                    {
-                        super._generator.completeUncheckedAddContent();
-                        _out.flush();
-
-                        max = super._generator.prepareUncheckedAddContent();
-                        buffer = super._generator.getUncheckedBuffer();
-                        len=buffer.readFrom(in,max);
-                    }
-                    super._generator.completeUncheckedAddContent();
-                    _out.flush();
-                }
-                finally
-                {
-                    if (resource!=null)
-                        resource.release();
-                    else
-                        in.close();
-                }
-            }
-            else
-                throw new IllegalArgumentException("unknown content type?");
+						max = super._generator.prepareUncheckedAddContent();
+						buffer = super._generator.getUncheckedBuffer();
+						len=buffer.readFrom(in,max);
+					}
+					super._generator.completeUncheckedAddContent();
+					_out.flush();
+				}
+				finally
+				{
+					if (resource!=null)
+						resource.release();
+					else
+						in.close();
+				}
+			}
+			else
+				throw new IllegalArgumentException("unknown content type?");
 
 
-        }
-    }
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    public class OutputWriter extends HttpWriter
-    {
-        OutputWriter()
-        {
-            super(AbstractHttpConnection.this._out);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	/* ------------------------------------------------------------ */
+	public class OutputWriter extends HttpWriter
+	{
+		OutputWriter()
+		{
+			super(AbstractHttpConnection.this._out);
+		}
+	}
 
 
 }