2015-01-20 01:48:11 +01:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2015-03-20 18:04:38 +01:00
|
|
|
import io.netty.buffer.ByteBuf;
|
2016-02-06 04:02:49 +01:00
|
|
|
import io.netty.util.concurrent.Future;
|
|
|
|
import io.netty.util.concurrent.Promise;
|
2016-04-12 14:22:41 +02:00
|
|
|
import io.netty.util.internal.UnstableApi;
|
2015-03-20 18:04:38 +01:00
|
|
|
|
2015-01-20 01:48:11 +01:00
|
|
|
/**
|
|
|
|
* Manager for the state of an HTTP/2 connection with the remote end-point.
|
|
|
|
*/
|
2016-04-12 14:22:41 +02:00
|
|
|
@UnstableApi
|
2015-01-20 01:48:11 +01:00
|
|
|
public interface Http2Connection {
|
|
|
|
/**
|
|
|
|
* 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
|
2015-03-15 02:38:35 +01:00
|
|
|
* not yet be active (i.e. {@code OPEN} or {@code HALF CLOSED}).
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-20 18:04:38 +01:00
|
|
|
void onStreamAdded(Http2Stream stream);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2015-03-15 02:38:35 +01:00
|
|
|
* Notifies the listener that the given stream was made active (i.e. {@code OPEN} or {@code HALF CLOSED}).
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-20 18:04:38 +01:00
|
|
|
void onStreamActive(Http2Stream stream);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2015-05-05 00:15:44 +02:00
|
|
|
* 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}.
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-20 18:04:38 +01:00
|
|
|
void onStreamHalfClosed(Http2Stream stream);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2015-03-15 02:38:35 +01:00
|
|
|
* Notifies the listener that the given stream is now {@code CLOSED} in both directions and will no longer
|
2015-04-09 18:48:58 +02:00
|
|
|
* be accessible via {@link #forEachActiveStream(Http2StreamVisitor)}.
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-20 18:04:38 +01:00
|
|
|
void onStreamClosed(Http2Stream stream);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-20 18:04:38 +01:00
|
|
|
void onStreamRemoved(Http2Stream stream);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2015-03-20 18:04:38 +01:00
|
|
|
* Called when a {@code GOAWAY} frame was sent for the connection.
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-03-20 18:04:38 +01:00
|
|
|
* @param lastStreamId the last known stream of the remote endpoint.
|
|
|
|
* @param errorCode the error code, if abnormal closure.
|
|
|
|
* @param debugData application-defined debug data.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-20 18:04:38 +01:00
|
|
|
void onGoAwaySent(int lastStreamId, long errorCode, ByteBuf debugData);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
2015-03-20 02:36:24 +01:00
|
|
|
* application should generally not handle both events, but if it does this method is called second, after
|
2015-03-20 18:04:38 +01:00
|
|
|
* notifying the {@link Http2FrameListener}.
|
2015-04-09 21:30:16 +02:00
|
|
|
* <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.
|
2015-03-20 18:04:38 +01:00
|
|
|
* @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);
|
2015-01-20 01:48:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A view of the connection from one endpoint (local or remote).
|
|
|
|
*/
|
|
|
|
interface Endpoint<F extends Http2FlowController> {
|
|
|
|
/**
|
2016-01-20 04:36:39 +01:00
|
|
|
* Increment and get the next generated stream id this endpoint. If negative, the stream IDs are
|
2015-01-20 01:48:11 +01:00
|
|
|
* exhausted for this endpoint an no further streams may be created.
|
|
|
|
*/
|
2016-01-20 04:36:39 +01:00
|
|
|
int incrementAndGetNextStreamId();
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates whether the given streamId is from the set of IDs used by this endpoint to
|
|
|
|
* create new streams.
|
|
|
|
*/
|
2015-04-21 23:18:02 +02:00
|
|
|
boolean isValidStreamId(int streamId);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2015-11-20 21:12:16 +01:00
|
|
|
* Indicates whether or not this endpoint created the given stream.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-11-20 21:12:16 +01:00
|
|
|
boolean created(Http2Stream stream);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates whether or a stream created by this endpoint can be opened without violating
|
|
|
|
* {@link #maxActiveStreams()}.
|
|
|
|
*/
|
|
|
|
boolean canOpenStream();
|
2015-01-20 01:48:11 +01:00
|
|
|
|
2015-04-22 23:35:31 +02:00
|
|
|
/**
|
|
|
|
* 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>
|
2015-11-20 21:12:16 +01:00
|
|
|
* <li>{@link #canOpenStream()} is {@code false}.</li>
|
2015-04-22 23:35:31 +02:00
|
|
|
* <li>The connection is marked as going away.</li>
|
|
|
|
* </ul>
|
|
|
|
* <p>
|
2017-01-24 21:50:39 +01:00
|
|
|
* 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)}.
|
2015-04-22 23:35:31 +02:00
|
|
|
* @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;
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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>
|
2015-03-15 02:38:35 +01:00
|
|
|
* <li>The parent stream ID does not exist or is not {@code OPEN} from the side sending the push
|
2015-01-20 01:48:11 +01:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
boolean isServer();
|
|
|
|
|
|
|
|
/**
|
2016-09-16 15:57:33 +02:00
|
|
|
* 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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
|
|
|
void allowPushTo(boolean allow);
|
|
|
|
|
|
|
|
/**
|
2016-09-16 15:57:33 +02:00
|
|
|
* 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
|
2015-01-20 01:48:11 +01:00
|
|
|
* for a server endpoint.
|
|
|
|
*/
|
|
|
|
boolean allowPushTo();
|
|
|
|
|
|
|
|
/**
|
2015-03-15 02:38:35 +01:00
|
|
|
* Gets the number of active streams (i.e. {@code OPEN} or {@code HALF CLOSED}) that were created by this
|
|
|
|
* endpoint.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
|
|
|
int numActiveStreams();
|
|
|
|
|
|
|
|
/**
|
2015-03-15 02:38:35 +01:00
|
|
|
* Gets the maximum number of streams (created by this endpoint) that are allowed to be active at
|
2016-09-16 15:57:33 +02:00
|
|
|
* 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".
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-03-15 02:38:35 +01:00
|
|
|
int maxActiveStreams();
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2017-01-24 21:50:39 +01:00
|
|
|
* Sets the limit for {@code SETTINGS_MAX_CONCURRENT_STREAMS}.
|
2016-08-09 22:10:02 +02:00
|
|
|
* @param maxActiveStreams The maximum number of streams (created by this endpoint) that are allowed to be
|
2016-09-16 15:57:33 +02:00
|
|
|
* 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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2017-01-24 21:50:39 +01:00
|
|
|
void maxActiveStreams(int maxActiveStreams);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
2015-03-20 02:36:24 +01:00
|
|
|
* GOAWAY frame. Otherwise, this will be {@code -1}.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-05-03 17:49:49 +02:00
|
|
|
int lastStreamKnownByPeer();
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the flow controller for this endpoint.
|
|
|
|
*/
|
|
|
|
F flowController();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the flow controller for this endpoint.
|
|
|
|
*/
|
|
|
|
void flowController(F flowController);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the {@link Endpoint} opposite this one.
|
|
|
|
*/
|
|
|
|
Endpoint<? extends Http2FlowController> opposite();
|
|
|
|
}
|
|
|
|
|
2015-04-06 21:55:20 +02:00
|
|
|
/**
|
|
|
|
* A key to be used for associating application-defined properties with streams within this connection.
|
|
|
|
*/
|
|
|
|
interface PropertyKey {
|
|
|
|
}
|
|
|
|
|
2016-02-06 04:02:49 +01:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2015-04-06 21:55:20 +02:00
|
|
|
/**
|
|
|
|
* Creates a new key that is unique within this {@link Http2Connection}.
|
|
|
|
*/
|
|
|
|
PropertyKey newKey();
|
|
|
|
|
2015-01-20 01:48:11 +01:00
|
|
|
/**
|
2015-04-03 05:28:28 +02:00
|
|
|
* Adds a listener of stream life-cycle events.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
|
|
|
void addListener(Listener listener);
|
|
|
|
|
|
|
|
/**
|
2015-04-03 05:28:28 +02:00
|
|
|
* Removes a listener of stream life-cycle events. If the same listener was added multiple times
|
2017-04-19 22:37:03 +02:00
|
|
|
* then only the first occurrence gets removed.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
|
|
|
void removeListener(Listener listener);
|
|
|
|
|
|
|
|
/**
|
2015-04-21 23:18:02 +02:00
|
|
|
* Gets the stream if it exists. If not, returns {@code null}.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-04-21 23:18:02 +02:00
|
|
|
Http2Stream stream(int streamId);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
2015-04-21 23:18:02 +02:00
|
|
|
* 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.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2015-04-21 23:18:02 +02:00
|
|
|
boolean streamMayHaveExisted(int streamId);
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the stream object representing the connection, itself (i.e. stream zero). This object
|
|
|
|
* always exists.
|
|
|
|
*/
|
|
|
|
Http2Stream connectionStream();
|
|
|
|
|
|
|
|
/**
|
2015-03-15 02:38:35 +01:00
|
|
|
* Gets the number of streams that are actively in use (i.e. {@code OPEN} or {@code HALF CLOSED}).
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
|
|
|
int numActiveStreams();
|
|
|
|
|
|
|
|
/**
|
2015-03-28 21:32:19 +01:00
|
|
|
* 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.
|
|
|
|
*/
|
2015-04-09 18:48:58 +02:00
|
|
|
Http2Stream forEachActiveStream(Http2StreamVisitor visitor) throws Http2Exception;
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates whether or not the local endpoint for this connection is the server.
|
|
|
|
*/
|
|
|
|
boolean isServer();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a view of this connection from the local {@link Endpoint}.
|
|
|
|
*/
|
|
|
|
Endpoint<Http2LocalFlowController> local();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a view of this connection from the remote {@link Endpoint}.
|
|
|
|
*/
|
|
|
|
Endpoint<Http2RemoteFlowController> remote();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates whether or not a {@code GOAWAY} was received from the remote endpoint.
|
|
|
|
*/
|
|
|
|
boolean goAwayReceived();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates that a {@code GOAWAY} was received from the remote endpoint and sets the last known stream.
|
2018-07-04 04:51:16 +02:00
|
|
|
* @param lastKnownStream The Last-Stream-ID in the
|
|
|
|
* <a href="https://tools.ietf.org/html/rfc7540#section-6.8">GOAWAY</a> frame.
|
|
|
|
* @param errorCode the Error Code in the
|
|
|
|
* <a href="https://tools.ietf.org/html/rfc7540#section-6.8">GOAWAY</a> frame.
|
|
|
|
* @param message The Additional Debug Data in the
|
|
|
|
* <a href="https://tools.ietf.org/html/rfc7540#section-6.8">GOAWAY</a> frame. Note that reference count ownership
|
|
|
|
* belongs to the caller (ownership is not transferred to this method).
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2018-07-04 04:51:16 +02:00
|
|
|
void goAwayReceived(int lastKnownStream, long errorCode, ByteBuf message) throws Http2Exception;
|
2015-01-20 01:48:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates whether or not a {@code GOAWAY} was sent to the remote endpoint.
|
|
|
|
*/
|
|
|
|
boolean goAwaySent();
|
|
|
|
|
|
|
|
/**
|
2018-07-04 04:51:16 +02:00
|
|
|
* Updates the local state of this {@link Http2Connection} as a result of a {@code GOAWAY} to send to the remote
|
|
|
|
* endpoint.
|
|
|
|
* @param lastKnownStream The Last-Stream-ID in the
|
|
|
|
* <a href="https://tools.ietf.org/html/rfc7540#section-6.8">GOAWAY</a> frame.
|
|
|
|
* @param errorCode the Error Code in the
|
|
|
|
* <a href="https://tools.ietf.org/html/rfc7540#section-6.8">GOAWAY</a> frame.
|
|
|
|
* <a href="https://tools.ietf.org/html/rfc7540#section-6.8">GOAWAY</a> frame. Note that reference count ownership
|
|
|
|
* belongs to the caller (ownership is not transferred to this method).
|
|
|
|
* @return {@code true} if the corresponding {@code GOAWAY} frame should be sent to the remote endpoint.
|
2015-01-20 01:48:11 +01:00
|
|
|
*/
|
2018-07-04 04:51:16 +02:00
|
|
|
boolean goAwaySent(int lastKnownStream, long errorCode, ByteBuf message) throws Http2Exception;
|
2015-01-20 01:48:11 +01:00
|
|
|
}
|