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 22e8b073c5e..f79af2ae6d6 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 @@ -204,6 +204,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection @Override public void recycle() { + getStream().removeAttribute(IStream.CHANNEL_ATTRIBUTE); super.recycle(); channels.offer(this); } @@ -212,18 +213,20 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection public void onCompleted() { super.onCompleted(); - recycle(); + if (!getStream().isReset()) + recycle(); } @Override public void reject() { IStream stream = getStream(); + if (LOG.isDebugEnabled()) + LOG.debug("HTTP2 Request #{}/{} rejected", stream.getId(), Integer.toHexString(stream.getSession().hashCode())); stream.reset(new ResetFrame(stream.getId(), ErrorCode.ENHANCE_YOUR_CALM_ERROR.code), Callback.NOOP); // Consume the existing queued data frames to // avoid stalling the session flow control. - getHttpTransport().consumeInput(); - recycle(); + consumeInput(); } } } 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 ec3e49c2493..8c71562437e 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 @@ -191,6 +191,17 @@ public class HttpChannelOverHTTP2 extends HttpChannel public Runnable requestContent(DataFrame frame, final Callback callback) { + Stream stream = getStream(); + if (stream.isReset()) + { + // Consume previously queued content to + // enlarge the session flow control window. + consumeInput(); + // Consume immediately this content. + callback.succeeded(); + return null; + } + // We must copy the data since we do not know when the // application will consume the bytes (we queue them by // calling onContent()), and the parsing will continue @@ -233,7 +244,6 @@ public class HttpChannelOverHTTP2 extends HttpChannel if (LOG.isDebugEnabled()) { - Stream stream = getStream(); LOG.debug("HTTP2 Request #{}/{}: {} bytes of {} content, handle: {}", stream.getId(), Integer.toHexString(stream.getSession().hashCode()), @@ -248,6 +258,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel return handle || delayed ? this : null; } + protected void consumeInput() + { + getRequest().getHttpInput().consumeAll(); + } + /** * If the associated response has the Expect header set to 100 Continue, * then accessing the input stream indicates that the handler/servlet diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index 21d03ff0a67..1541688589a 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -31,7 +31,6 @@ import org.eclipse.jetty.http2.frames.HeadersFrame; import org.eclipse.jetty.http2.frames.PushPromiseFrame; import org.eclipse.jetty.http2.frames.ResetFrame; import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; @@ -193,17 +192,16 @@ public class HttpTransportOverHTTP2 implements HttpTransport // If the stream is not closed, it is still reading the request content. // Send a reset to the other end so that it stops sending data. if (!stream.isClosed()) + { + if (LOG.isDebugEnabled()) + LOG.debug("HTTP2 Response #{}: unconsumed request content, resetting stream", stream.getId()); stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP); + } // Consume the existing queued data frames to // avoid stalling the session flow control. - consumeInput(); - } - - protected void consumeInput() - { - HttpChannel channel = (HttpChannel)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); - channel.getRequest().getHttpInput().consumeAll(); + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + channel.consumeInput(); } @Override