/*
* Copyright 2014 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License, version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise;
import io.netty.util.internal.UnstableApi;
Manager for the state of an HTTP/2 connection with the remote end-point.
/**
* Manager for the state of an HTTP/2 connection with the remote end-point.
*/
@UnstableApi
public interface Http2Connection {
Listener for life-cycle events for streams in this connection.
/**
* Listener for life-cycle events for streams in this connection.
*/
interface Listener {
Notifies the listener that the given stream was added to the connection. This stream may not yet be active (i.e. OPEN
or HALF CLOSED
). If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
/**
* Notifies the listener that the given stream was added to the connection. This stream may
* not yet be active (i.e. {@code OPEN} or {@code HALF CLOSED}).
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
*/
void onStreamAdded(Http2Stream stream);
Notifies the listener that the given stream was made active (i.e. OPEN
or HALF CLOSED
). If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
/**
* Notifies the listener that the given stream was made active (i.e. {@code OPEN} or {@code HALF CLOSED}).
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
*/
void onStreamActive(Http2Stream stream);
Notifies the listener that the given stream has transitioned from OPEN
to HALF CLOSED
. This method will not be called until a state transition occurs from when onStreamActive(Http2Stream)
was called. The stream can be inspected to determine which side is HALF CLOSED
. If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
/**
* Notifies the listener that the given stream has transitioned from {@code OPEN} to {@code HALF CLOSED}.
* This method will <strong>not</strong> be called until a state transition occurs from when
* {@link #onStreamActive(Http2Stream)} was called.
* The stream can be inspected to determine which side is {@code HALF CLOSED}.
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
*/
void onStreamHalfClosed(Http2Stream stream);
Notifies the listener that the given stream is now CLOSED
in both directions and will no longer be accessible via Http2Connection.forEachActiveStream(Http2StreamVisitor)
. If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
/**
* Notifies the listener that the given stream is now {@code CLOSED} in both directions and will no longer
* be accessible via {@link #forEachActiveStream(Http2StreamVisitor)}.
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
*/
void onStreamClosed(Http2Stream stream);
Notifies the listener that the given stream has now been removed from the connection and will no longer be returned via Http2Connection.stream(int)
. The connection may maintain inactive streams for some time before removing them. If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
/**
* Notifies the listener that the given stream has now been removed from the connection and
* will no longer be returned via {@link Http2Connection#stream(int)}. The connection may
* maintain inactive streams for some time before removing them.
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
*/
void onStreamRemoved(Http2Stream stream);
Called when a GOAWAY
frame was sent for the connection. If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
Params: - lastStreamId – the last known stream of the remote endpoint.
- errorCode – the error code, if abnormal closure.
- debugData – application-defined debug data.
/**
* Called when a {@code GOAWAY} frame was sent for the connection.
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
* @param lastStreamId the last known stream of the remote endpoint.
* @param errorCode the error code, if abnormal closure.
* @param debugData application-defined debug data.
*/
void onGoAwaySent(int lastStreamId, long errorCode, ByteBuf debugData);
Called when a GOAWAY
was received from the remote endpoint. This event handler duplicates Http2FrameListener.onGoAwayRead(ChannelHandlerContext, int, long, ByteBuf)
but is added here in order to simplify application logic for handling GOAWAY
in a uniform way. An application should generally not handle both events, but if it does this method is called second, after notifying the Http2FrameListener
. If a RuntimeException
is thrown it will be logged and not propagated.
Throwing from this method is not supported and is considered a programming error.
Params: - lastStreamId – the last known stream of the remote endpoint.
- errorCode – the error code, if abnormal closure.
- debugData – application-defined debug data.
/**
* Called when a {@code GOAWAY} was received from the remote endpoint. This event handler duplicates {@link
* Http2FrameListener#onGoAwayRead(io.netty.channel.ChannelHandlerContext, int, long, io.netty.buffer.ByteBuf)}
* but is added here in order to simplify application logic for handling {@code GOAWAY} in a uniform way. An
* application should generally not handle both events, but if it does this method is called second, after
* notifying the {@link Http2FrameListener}.
* <p>
* If a {@link RuntimeException} is thrown it will be logged and <strong>not propagated</strong>.
* Throwing from this method is not supported and is considered a programming error.
* @param lastStreamId the last known stream of the remote endpoint.
* @param errorCode the error code, if abnormal closure.
* @param debugData application-defined debug data.
*/
void onGoAwayReceived(int lastStreamId, long errorCode, ByteBuf debugData);
}
A view of the connection from one endpoint (local or remote).
/**
* A view of the connection from one endpoint (local or remote).
*/
interface Endpoint<F extends Http2FlowController> {
Increment and get the next generated stream id this endpoint. If negative, the stream IDs are
exhausted for this endpoint an no further streams may be created.
/**
* Increment and get the next generated stream id this endpoint. If negative, the stream IDs are
* exhausted for this endpoint an no further streams may be created.
*/
int incrementAndGetNextStreamId();
Indicates whether the given streamId is from the set of IDs used by this endpoint to
create new streams.
/**
* Indicates whether the given streamId is from the set of IDs used by this endpoint to
* create new streams.
*/
boolean isValidStreamId(int streamId);
Indicates whether or not this endpoint may have created the given stream. This is true
if isValidStreamId(int)
and streamId
<= lastStreamCreated()
. /**
* Indicates whether or not this endpoint may have created the given stream. This is {@code true} if
* {@link #isValidStreamId(int)} and {@code streamId} <= {@link #lastStreamCreated()}.
*/
boolean mayHaveCreatedStream(int streamId);
Indicates whether or not this endpoint created the given stream.
/**
* Indicates whether or not this endpoint created the given stream.
*/
boolean created(Http2Stream stream);
Indicates whether or a stream created by this endpoint can be opened without violating maxActiveStreams()
. /**
* Indicates whether or a stream created by this endpoint can be opened without violating
* {@link #maxActiveStreams()}.
*/
boolean canOpenStream();
Creates a stream initiated by this endpoint. This could fail for the following reasons:
- The requested stream ID is not the next sequential ID for this endpoint.
- The stream already exists.
canOpenStream()
is false
.
- The connection is marked as going away.
The initial state of the stream will be immediately set before notifying Listener
s. The state transition is sensitive to halfClosed
and is defined by Http2Stream.open(boolean)
.
Params: - streamId – The ID of the stream
- halfClosed – see
Http2Stream.open(boolean)
.
See Also:
/**
* Creates a stream initiated by this endpoint. This could fail for the following reasons:
* <ul>
* <li>The requested stream ID is not the next sequential ID for this endpoint.</li>
* <li>The stream already exists.</li>
* <li>{@link #canOpenStream()} is {@code false}.</li>
* <li>The connection is marked as going away.</li>
* </ul>
* <p>
* The initial state of the stream will be immediately set before notifying {@link Listener}s. The state
* transition is sensitive to {@code halfClosed} and is defined by {@link Http2Stream#open(boolean)}.
* @param streamId The ID of the stream
* @param halfClosed see {@link Http2Stream#open(boolean)}.
* @see Http2Stream#open(boolean)
*/
Http2Stream createStream(int streamId, boolean halfClosed) throws Http2Exception;
Creates a push stream in the reserved state for this endpoint and notifies all listeners.
This could fail for the following reasons:
- Server push is not allowed to the opposite endpoint.
- The requested stream ID is not the next sequential stream ID for this endpoint.
- The number of concurrent streams is above the allowed threshold for this endpoint.
- The connection is marked as going away.
- The parent stream ID does not exist or is not
OPEN
from the side sending the push promise.
- Could not set a valid priority for the new stream.
Params: - streamId – the ID of the push stream
- parent – the parent stream used to initiate the push stream.
/**
* Creates a push stream in the reserved state for this endpoint and notifies all listeners.
* This could fail for the following reasons:
* <ul>
* <li>Server push is not allowed to the opposite endpoint.</li>
* <li>The requested stream ID is not the next sequential stream ID for this endpoint.</li>
* <li>The number of concurrent streams is above the allowed threshold for this endpoint.</li>
* <li>The connection is marked as going away.</li>
* <li>The parent stream ID does not exist or is not {@code OPEN} from the side sending the push
* promise.</li>
* <li>Could not set a valid priority for the new stream.</li>
* </ul>
*
* @param streamId the ID of the push stream
* @param parent the parent stream used to initiate the push stream.
*/
Http2Stream reservePushStream(int streamId, Http2Stream parent) throws Http2Exception;
Indicates whether or not this endpoint is the server-side of the connection.
/**
* Indicates whether or not this endpoint is the server-side of the connection.
*/
boolean isServer();
This is the SETTINGS_ENABLE_PUSH value sent from the opposite endpoint. This method should only be called by Netty (not users) as a result of a receiving a SETTINGS
frame. /**
* This is the <a href="https://tools.ietf.org/html/rfc7540#section-6.5.2">SETTINGS_ENABLE_PUSH</a> value sent
* from the opposite endpoint. This method should only be called by Netty (not users) as a result of a
* receiving a {@code SETTINGS} frame.
*/
void allowPushTo(boolean allow);
This is the SETTINGS_ENABLE_PUSH value sent from the opposite endpoint. The initial value must be true
for the client endpoint and always false for a server endpoint. /**
* This is the <a href="https://tools.ietf.org/html/rfc7540#section-6.5.2">SETTINGS_ENABLE_PUSH</a> value sent
* from the opposite endpoint. The initial value must be {@code true} for the client endpoint and always false
* for a server endpoint.
*/
boolean allowPushTo();
Gets the number of active streams (i.e. OPEN
or HALF CLOSED
) that were created by this endpoint. /**
* Gets the number of active streams (i.e. {@code OPEN} or {@code HALF CLOSED}) that were created by this
* endpoint.
*/
int numActiveStreams();
Gets the maximum number of streams (created by this endpoint) that are allowed to be active at
the same time. This is the
SETTINGS_MAX_CONCURRENT_STREAMS
value sent from the opposite endpoint to restrict stream creation by this endpoint.
The default value returned by this method must be "unlimited".
/**
* Gets the maximum number of streams (created by this endpoint) that are allowed to be active at
* the same time. This is the
* <a href="https://tools.ietf.org/html/rfc7540#section-6.5.2">SETTINGS_MAX_CONCURRENT_STREAMS</a>
* value sent from the opposite endpoint to restrict stream creation by this endpoint.
* <p>
* The default value returned by this method must be "unlimited".
*/
int maxActiveStreams();
Sets the limit for SETTINGS_MAX_CONCURRENT_STREAMS
. Params: - maxActiveStreams – The maximum number of streams (created by this endpoint) that are allowed to be
active at once. This is the
SETTINGS_MAX_CONCURRENT_STREAMS value sent
from the opposite endpoint to restrict stream creation by this endpoint.
/**
* Sets the limit for {@code SETTINGS_MAX_CONCURRENT_STREAMS}.
* @param maxActiveStreams The maximum number of streams (created by this endpoint) that are allowed to be
* active at once. This is the
* <a href="https://tools.ietf.org/html/rfc7540#section-6.5.2">SETTINGS_MAX_CONCURRENT_STREAMS</a> value sent
* from the opposite endpoint to restrict stream creation by this endpoint.
*/
void maxActiveStreams(int maxActiveStreams);
Gets the ID of the stream last successfully created by this endpoint.
/**
* Gets the ID of the stream last successfully created by this endpoint.
*/
int lastStreamCreated();
If a GOAWAY was received for this endpoint, this will be the last stream ID from the GOAWAY frame. Otherwise, this will be -1
. /**
* If a GOAWAY was received for this endpoint, this will be the last stream ID from the
* GOAWAY frame. Otherwise, this will be {@code -1}.
*/
int lastStreamKnownByPeer();
Gets the flow controller for this endpoint.
/**
* Gets the flow controller for this endpoint.
*/
F flowController();
Sets the flow controller for this endpoint.
/**
* Sets the flow controller for this endpoint.
*/
void flowController(F flowController);
Gets the Endpoint
opposite this one. /**
* Gets the {@link Endpoint} opposite this one.
*/
Endpoint<? extends Http2FlowController> opposite();
}
A key to be used for associating application-defined properties with streams within this connection.
/**
* A key to be used for associating application-defined properties with streams within this connection.
*/
interface PropertyKey {
}
Close this connection. No more new streams can be created after this point and
all streams that exists (active or otherwise) will be closed and removed.
Note if iterating active streams via forEachActiveStream(Http2StreamVisitor)
and an exception is thrown it is necessary to call this method again to ensure the close completes.
Params: - promise – Will be completed when all streams have been removed, and listeners have been notified.
Returns: A future that will be completed when all streams have been removed, and listeners have been notified.
/**
* Close this connection. No more new streams can be created after this point and
* all streams that exists (active or otherwise) will be closed and removed.
* <p>Note if iterating active streams via {@link #forEachActiveStream(Http2StreamVisitor)} and an exception is
* thrown it is necessary to call this method again to ensure the close completes.
* @param promise Will be completed when all streams have been removed, and listeners have been notified.
* @return A future that will be completed when all streams have been removed, and listeners have been notified.
*/
Future<Void> close(Promise<Void> promise);
Creates a new key that is unique within this Http2Connection
. /**
* Creates a new key that is unique within this {@link Http2Connection}.
*/
PropertyKey newKey();
Adds a listener of stream life-cycle events.
/**
* Adds a listener of stream life-cycle events.
*/
void addListener(Listener listener);
Removes a listener of stream life-cycle events. If the same listener was added multiple times
then only the first occurrence gets removed.
/**
* Removes a listener of stream life-cycle events. If the same listener was added multiple times
* then only the first occurrence gets removed.
*/
void removeListener(Listener listener);
Gets the stream if it exists. If not, returns null
. /**
* Gets the stream if it exists. If not, returns {@code null}.
*/
Http2Stream stream(int streamId);
Indicates whether or not the given stream may have existed within this connection. This is a short form for calling Endpoint.mayHaveCreatedStream(int)
on both endpoints. /**
* Indicates whether or not the given stream may have existed within this connection. This is a short form
* for calling {@link Endpoint#mayHaveCreatedStream(int)} on both endpoints.
*/
boolean streamMayHaveExisted(int streamId);
Gets the stream object representing the connection, itself (i.e. stream zero). This object
always exists.
/**
* Gets the stream object representing the connection, itself (i.e. stream zero). This object
* always exists.
*/
Http2Stream connectionStream();
Gets the number of streams that are actively in use (i.e. OPEN
or HALF CLOSED
). /**
* Gets the number of streams that are actively in use (i.e. {@code OPEN} or {@code HALF CLOSED}).
*/
int numActiveStreams();
Provide a means of iterating over the collection of active streams.
Params: - visitor – The visitor which will visit each active stream.
Returns: The stream before iteration stopped or null
if iteration went past the end.
/**
* Provide a means of iterating over the collection of active streams.
*
* @param visitor The visitor which will visit each active stream.
* @return The stream before iteration stopped or {@code null} if iteration went past the end.
*/
Http2Stream forEachActiveStream(Http2StreamVisitor visitor) throws Http2Exception;
Indicates whether or not the local endpoint for this connection is the server.
/**
* Indicates whether or not the local endpoint for this connection is the server.
*/
boolean isServer();
Gets a view of this connection from the local Endpoint
. /**
* Gets a view of this connection from the local {@link Endpoint}.
*/
Endpoint<Http2LocalFlowController> local();
Gets a view of this connection from the remote Endpoint
. /**
* Gets a view of this connection from the remote {@link Endpoint}.
*/
Endpoint<Http2RemoteFlowController> remote();
Indicates whether or not a GOAWAY
was received from the remote endpoint. /**
* Indicates whether or not a {@code GOAWAY} was received from the remote endpoint.
*/
boolean goAwayReceived();
Indicates that a GOAWAY
was received from the remote endpoint and sets the last known stream. /**
* Indicates that a {@code GOAWAY} was received from the remote endpoint and sets the last known stream.
*/
void goAwayReceived(int lastKnownStream, long errorCode, ByteBuf message);
Indicates whether or not a GOAWAY
was sent to the remote endpoint. /**
* Indicates whether or not a {@code GOAWAY} was sent to the remote endpoint.
*/
boolean goAwaySent();
Indicates that a GOAWAY
was sent to the remote endpoint and sets the last known stream. /**
* Indicates that a {@code GOAWAY} was sent to the remote endpoint and sets the last known stream.
*/
void goAwaySent(int lastKnownStream, long errorCode, ByteBuf message);
}