public void handleRequest(final HttpServerExchange exchange) throws Exception { final ProxyClient.ProxyTarget target = proxyClient.findTarget(exchange); if (target == null) { log.debugf("No proxy target for request to %s", exchange.getRequestURL()); next.handleRequest(exchange); return; } final long timeout = maxRequestTime > 0 ? System.currentTimeMillis() + maxRequestTime : 0; final ProxyClientHandler clientHandler = new ProxyClientHandler(exchange, target, timeout, maxConnectionRetries); if (timeout > 0) { final XnioExecutor.Key key = exchange .getIoThread() .executeAfter( new Runnable() { @Override public void run() { clientHandler.cancel(exchange); } }, maxRequestTime, TimeUnit.MILLISECONDS); exchange.putAttachment(TIMEOUT_KEY, key); exchange.addExchangeCompleteListener( new ExchangeCompletionListener() { @Override public void exchangeEvent(HttpServerExchange exchange, NextListener nextListener) { key.remove(); nextListener.proceed(); } }); } exchange.dispatch( exchange.isInIoThread() ? SameThreadExecutor.INSTANCE : exchange.getIoThread(), clientHandler); }