diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java index 4a9ebb32bc6..fbf1b9954ed 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java @@ -156,7 +156,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection public boolean onStreamTimeout(IStream stream, Throwable failure) { HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); - boolean result = channel != null && channel.onStreamTimeout(failure); + boolean result = channel != null && channel.onStreamTimeout(failure, task -> offerTask(task, true)); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", stream, failure); return result; @@ -168,7 +168,11 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection LOG.debug("Processing failure on {}: {}", stream, failure); HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); if (channel != null) - channel.onFailure(failure); + { + Runnable task = channel.onFailure(failure); + if (task != null) + offerTask(task, true); + } } public boolean onSessionTimeout(Throwable failure) @@ -179,7 +183,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); if (channel != null) - result &= !channel.isRequestExecuting(); + result &= channel.isRequestIdle(); } if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", session, failure); diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index e55dc27e593..144a8cc8d36 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.http2.server; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.function.Consumer; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpField; @@ -40,6 +41,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpInput; +import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; @@ -277,32 +279,39 @@ public class HttpChannelOverHTTP2 extends HttpChannel return handle || wasDelayed ? this : null; } - public boolean isRequestExecuting() + public boolean isRequestIdle() { - return !getState().isIdle(); + return getState().isIdle(); } - public boolean onStreamTimeout(Throwable failure) + public boolean onStreamTimeout(Throwable failure, Consumer consumer) { + boolean result = false; + if (isRequestIdle()) + { + consumeInput(); + result = true; + } + getHttpTransport().onStreamTimeout(failure); if (getRequest().getHttpInput().onIdleTimeout(failure)) - handle(); + consumer.accept(this::handleWithContext); - if (isRequestExecuting()) - return false; - - consumeInput(); - return true; + return result; } - public void onFailure(Throwable failure) + public Runnable onFailure(Throwable failure) { getHttpTransport().onStreamFailure(failure); - if (getRequest().getHttpInput().failed(failure)) - handle(); - else - getState().asyncError(failure); + boolean handle = getRequest().getHttpInput().failed(failure); consumeInput(); + return () -> + { + if (handle) + handleWithContext(); + else + getState().asyncError(failure); + }; } protected void consumeInput() @@ -310,6 +319,15 @@ public class HttpChannelOverHTTP2 extends HttpChannel getRequest().getHttpInput().consumeAll(); } + private void handleWithContext() + { + ContextHandler context = getState().getContextHandler(); + if (context != null) + context.handle(getRequest(), this); + else + handle(); + } + /** * If the associated response has the Expect header set to 100 Continue, * then accessing the input stream indicates that the handler/servlet