/** Destroy the connection. called by handle when handleNext returns false. */
  protected void destroy() {
    try {
      close();
    } catch (IOException e) {
      LogSupport.ignore(log, e);
    } catch (Exception e) {
      log.warn(LogSupport.EXCEPTION, e);
    }

    // Destroy request and response
    if (_request != null) _request.destroy();
    if (_response != null) _response.destroy();
    if (_inputStream != null) _inputStream.destroy();
    if (_outputStream != null) _outputStream.destroy();
    _inputStream = null;
    _outputStream = null;
    _request = null;
    _response = null;
    _handlingThread = null;

    if (_statsOn) {
      _tmpTime = System.currentTimeMillis();
      if (_reqTime > 0) _httpServer.statsEndRequest(_tmpTime - _reqTime, false);
      _httpServer.statsCloseConnection(_tmpTime - _openTime, _requests);
    }
  }
  /**
   * Constructor.
   *
   * @param listener The listener that created this connection.
   * @param remoteAddr The address of the remote end or null.
   * @param in InputStream to read request(s) from.
   * @param out OutputputStream to write response(s) to.
   * @param connection The underlying connection object, most likely a socket. This is not used by
   *     HttpConnection other than to make it available via getConnection().
   */
  public HttpConnection(
      HttpListener listener,
      InetAddress remoteAddr,
      InputStream in,
      OutputStream out,
      Object connection) {
    if (log.isDebugEnabled()) log.debug("new HttpConnection: " + connection);
    _listener = listener;
    _remoteInetAddress = remoteAddr;
    int bufferSize = listener == null ? 4096 : listener.getBufferSize();
    int reserveSize = listener == null ? 512 : listener.getBufferReserve();
    _inputStream = new HttpInputStream(in, bufferSize);
    _outputStream = new HttpOutputStream(out, bufferSize, reserveSize);
    _outputStream.addObserver(this);
    _firstWrite = false;
    if (_listener != null) _httpServer = _listener.getHttpServer();
    _connection = connection;

    _statsOn = _httpServer != null && _httpServer.getStatsOn();
    if (_statsOn) {
      _openTime = System.currentTimeMillis();
      _httpServer.statsOpenConnection();
    }
    _reqTime = 0;
    _requests = 0;

    _request = new HttpRequest(this);
    _response = new HttpResponse(this);

    _resolveRemoteHost =
        _listener != null
            && _listener.getHttpServer() != null
            && _listener.getHttpServer().getResolveRemoteHost();
  }
 /* ------------------------------------------------------------ */
 protected void statsRequestEnd() {
   if (_statsOn && _reqTime > 0) {
     _httpServer.statsEndRequest(System.currentTimeMillis() - _reqTime, (_response != null));
     _reqTime = 0;
   }
 }