From 298ddfd722a1aff207afe42f127adfa82a6e5634 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Nov 2020 17:38:05 +0100 Subject: [PATCH] Issue 5310 - Review HTTP/2 GOAWAY handling. Fixed javadocs and TODOs. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/http2/HTTP2Session.java | 84 ++++--------------- 1 file changed, 16 insertions(+), 68 deletions(-) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java index 9ad5b36add5..e9c22320cf8 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java @@ -429,22 +429,12 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } /** - * This method is called when receiving a GO_AWAY from the other peer. - * We check the close state to act appropriately: - * + *

This method is called when receiving a GO_AWAY from the other peer.

* * @param frame the GO_AWAY frame that has been received. * @see #close(int, String, Callback) * @see #onShutdown() * @see #onIdleTimeout() - * TODO: Review javadocs */ @Override public void onGoAway(GoAwayFrame frame) @@ -636,20 +626,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } /** - * Invoked internally and by applications to send a GO_AWAY frame to the - * other peer. We check the close state to act appropriately: - * + *

Invoked internally and by applications to send a GO_AWAY frame to the other peer.

* * @param error the error code * @param reason the reason @@ -657,7 +634,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio * @see #onGoAway(GoAwayFrame) * @see #onShutdown() * @see #onIdleTimeout() - * // TODO: review javadocs */ @Override public boolean close(int error, String reason, Callback callback) @@ -919,26 +895,11 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } /** - * A typical close by a remote peer involves a GO_AWAY frame followed by TCP FIN. - * This method is invoked when the TCP FIN is received, or when an exception is - * thrown while reading, and we check the close state to act appropriately: - * + *

This method is called when the TCP FIN is received from the remote peer.

* * @see #onGoAway(GoAwayFrame) * @see #close(int, String, Callback) * @see #onIdleTimeout() - * TODO: review javadocs */ @Override public void onShutdown() @@ -947,25 +908,12 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } /** - * This method is invoked when the idle timeout triggers. We check the close state - * to act appropriately: - * + *

This method is invoked when the idle timeout expires.

* * @return true if the session should be closed, false otherwise * @see #onGoAway(GoAwayFrame) * @see #close(int, String, Callback) * @see #onShutdown() - * TODO: review javadocs */ @Override public boolean onIdleTimeout() @@ -1457,13 +1405,15 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } /** - * SPEC: It is required that stream ids are monotonically increasing. - * Here we use a queue to atomically create the stream id and - * claim the slot in the queue. Concurrent threads will only - * flush up to the slot with a non-null entry to make sure - * frames are sent strictly in their stream id order. - * See https://tools.ietf.org/html/rfc7540#section-5.1.1. - * TODO: javadocs + *

The HTTP/2 specification requires that stream ids are monotonically increasing, + * see https://tools.ietf.org/html/rfc7540#section-5.1.1.

+ *

This implementation uses a queue to atomically reserve a stream id and claim + * a slot in the queue; the slot is then assigned the entries to write.

+ *

Concurrent threads push slots in the queue but only one thread flushes + * the slots, up to the slot that has a non-null entries to write, therefore + * guaranteeing that frames are sent strictly in their stream id order.

+ *

This class also coordinates the creation of streams with the close of + * the session, see https://tools.ietf.org/html/rfc7540#section-6.8.

*/ private class StreamsState { @@ -1475,7 +1425,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio private Runnable closingAction; private GoAwayFrame goAwayRecv; private GoAwayFrame goAwaySent; - private Throwable failure; + private volatile Throwable failure; private Thread flushing; private CloseState getCloseState() @@ -1505,9 +1455,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio // when the last stream is destroyed. closingAction = action = () -> { - // TODO: verify this GoAwayFrame goAwayFrame = newGoAwayFrame(ErrorCode.NO_ERROR.code, "close"); - goAway(goAwayFrame, Callback.from(Callback.NOOP::succeeded, HTTP2Session.this::terminate)); + goAway(goAwayFrame, Callback.NOOP); }; } break; @@ -1549,9 +1498,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio // when the last stream is destroyed. closingAction = action = () -> { - // TODO: verify this GoAwayFrame goAwayFrame = newGoAwayFrame(ErrorCode.NO_ERROR.code, "close"); - goAway(goAwayFrame, Callback.from(Callback.NOOP::succeeded, HTTP2Session.this::terminate)); + goAway(goAwayFrame, Callback.NOOP); }; } else