View Javadoc
1   /*
2    * Copyright 2014 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at:
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software distributed under the License
11   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing permissions and limitations under
13   * the License.
14   */
15  
16  package io.netty.handler.codec.http2;
17  
18  import java.util.Collection;
19  
20  /**
21   * Manager for the state of an HTTP/2 connection with the remote end-point.
22   */
23  public interface Http2Connection {
24  
25      /**
26       * Listener for life-cycle events for streams in this connection.
27       */
28      interface Listener {
29          /**
30           * Notifies the listener that the given stream was added to the connection. This stream may
31           * not yet be active (i.e. open/half-closed).
32           */
33          void streamAdded(Http2Stream stream);
34  
35          /**
36           * Notifies the listener that the given stream was made active (i.e. open in at least one
37           * direction).
38           */
39          void streamActive(Http2Stream stream);
40  
41          /**
42           * Notifies the listener that the given stream is now half-closed. The stream can be
43           * inspected to determine which side is closed.
44           */
45          void streamHalfClosed(Http2Stream stream);
46  
47          /**
48           * Notifies the listener that the given stream is now closed in both directions.
49           */
50          void streamInactive(Http2Stream stream);
51  
52          /**
53           * Notifies the listener that the given stream has now been removed from the connection and
54           * will no longer be returned via {@link Http2Connection#stream(int)}. The connection may
55           * maintain inactive streams for some time before removing them.
56           */
57          void streamRemoved(Http2Stream stream);
58  
59          /**
60           * Notifies the listener that a priority tree parent change has occurred. This method will be invoked
61           * in a top down order relative to the priority tree. This method will also be invoked after all tree
62           * structure changes have been made and the tree is in steady state relative to the priority change
63           * which caused the tree structure to change.
64           * @param stream The stream which had a parent change (new parent and children will be steady state)
65           * @param oldParent The old parent which {@code stream} used to be a child of (may be {@code null})
66           */
67          void priorityTreeParentChanged(Http2Stream stream, Http2Stream oldParent);
68  
69          /**
70           * Notifies the listener that a parent dependency is about to change
71           * This is called while the tree is being restructured and so the tree
72           * structure is not necessarily steady state.
73           * @param stream The stream which the parent is about to change to {@code newParent}
74           * @param newParent The stream which will be the parent of {@code stream}
75           */
76          void priorityTreeParentChanging(Http2Stream stream, Http2Stream newParent);
77  
78          /**
79           * Notifies the listener that the weight has changed for {@code stream}
80           * @param stream The stream which the weight has changed
81           * @param oldWeight The old weight for {@code stream}
82           */
83          void onWeightChanged(Http2Stream stream, short oldWeight);
84  
85          /**
86           * Called when a GO_AWAY frame has either been sent or received for the connection.
87           */
88          void goingAway();
89      }
90  
91      /**
92       * A view of the connection from one endpoint (local or remote).
93       */
94      interface Endpoint<F extends Http2FlowController> {
95  
96          /**
97           * Returns the next valid streamId for this endpoint. If negative, the stream IDs are
98           * exhausted for this endpoint an no further streams may be created.
99           */
100         int nextStreamId();
101 
102         /**
103          * Indicates whether the given streamId is from the set of IDs used by this endpoint to
104          * create new streams.
105          */
106         boolean createdStreamId(int streamId);
107 
108         /**
109          * Indicates whether or not this endpoint is currently accepting new streams. This will be
110          * be false if {@link #numActiveStreams()} + 1 >= {@link #maxStreams()} or if the stream IDs
111          * for this endpoint have been exhausted (i.e. {@link #nextStreamId()} < 0).
112          */
113         boolean acceptingNewStreams();
114 
115         /**
116          * Creates a stream initiated by this endpoint. This could fail for the following reasons:
117          * <ul>
118          * <li>The requested stream ID is not the next sequential ID for this endpoint.</li>
119          * <li>The stream already exists.</li>
120          * <li>The number of concurrent streams is above the allowed threshold for this endpoint.</li>
121          * <li>The connection is marked as going away.</li>
122          * </ul>
123          * <p>
124          * The caller is expected to {@link Http2Stream#open(boolean)} the stream.
125          * @param streamId The ID of the stream
126          * @see Http2Stream#open(boolean)
127          */
128         Http2Stream createStream(int streamId) throws Http2Exception;
129 
130         /**
131          * Creates a push stream in the reserved state for this endpoint and notifies all listeners.
132          * This could fail for the following reasons:
133          * <ul>
134          * <li>Server push is not allowed to the opposite endpoint.</li>
135          * <li>The requested stream ID is not the next sequential stream ID for this endpoint.</li>
136          * <li>The number of concurrent streams is above the allowed threshold for this endpoint.</li>
137          * <li>The connection is marked as going away.</li>
138          * <li>The parent stream ID does not exist or is not open from the side sending the push
139          * promise.</li>
140          * <li>Could not set a valid priority for the new stream.</li>
141          * </ul>
142          *
143          * @param streamId the ID of the push stream
144          * @param parent the parent stream used to initiate the push stream.
145          */
146         Http2Stream reservePushStream(int streamId, Http2Stream parent) throws Http2Exception;
147 
148         /**
149          * Indicates whether or not this endpoint is the server-side of the connection.
150          */
151         boolean isServer();
152 
153         /**
154          * Sets whether server push is allowed to this endpoint.
155          */
156         void allowPushTo(boolean allow);
157 
158         /**
159          * Gets whether or not server push is allowed to this endpoint. This is always false
160          * for a server endpoint.
161          */
162         boolean allowPushTo();
163 
164         /**
165          * Gets the number of currently active streams that were created by this endpoint.
166          */
167         int numActiveStreams();
168 
169         /**
170          * Gets the maximum number of concurrent streams allowed by this endpoint.
171          */
172         int maxStreams();
173 
174         /**
175          * Sets the maximum number of concurrent streams allowed by this endpoint.
176          */
177         void maxStreams(int maxStreams);
178 
179         /**
180          * Gets the ID of the stream last successfully created by this endpoint.
181          */
182         int lastStreamCreated();
183 
184         /**
185          * Gets the last stream created by this endpoint that is "known" by the opposite endpoint.
186          * If a GOAWAY was received for this endpoint, this will be the last stream ID from the
187          * GOAWAY frame. Otherwise, this will be same as {@link #lastStreamCreated()}.
188          */
189         int lastKnownStream();
190 
191         /**
192          * Gets the flow controller for this endpoint.
193          */
194         F flowController();
195 
196         /**
197          * Sets the flow controller for this endpoint.
198          */
199         void flowController(F flowController);
200 
201         /**
202          * Gets the {@link Endpoint} opposite this one.
203          */
204         Endpoint<? extends Http2FlowController> opposite();
205     }
206 
207     /**
208      * Adds a listener of stream life-cycle events. Adding the same listener multiple times has no effect.
209      */
210     void addListener(Listener listener);
211 
212     /**
213      * Removes a listener of stream life-cycle events.
214      */
215     void removeListener(Listener listener);
216 
217     /**
218      * Attempts to get the stream for the given ID. If it doesn't exist, throws.
219      */
220     Http2Stream requireStream(int streamId) throws Http2Exception;
221 
222     /**
223      * Gets the stream if it exists. If not, returns {@code null}.
224      */
225     Http2Stream stream(int streamId);
226 
227     /**
228      * Gets the stream object representing the connection, itself (i.e. stream zero). This object
229      * always exists.
230      */
231     Http2Stream connectionStream();
232 
233     /**
234      * Gets the number of streams that actively in use. It is possible for a stream to be closed
235      * but still be considered active (e.g. there is still pending data to be written).
236      */
237     int numActiveStreams();
238 
239     /**
240      * Gets all streams that are actively in use. The returned collection is
241      * sorted by priority.
242      */
243     Collection<Http2Stream> activeStreams();
244 
245     /**
246      * Indicates that the given stream is no longer actively in use. If this stream was active,
247      * after calling this method it will no longer appear in the list returned by
248      * {@link #activeStreams()} and {@link #numActiveStreams()} will be decremented. In addition,
249      * all listeners will be notified of this event via
250      * {@link Listener#streamInactive(Http2Stream)}.
251      */
252     void deactivate(Http2Stream stream);
253 
254     /**
255      * Indicates whether or not the local endpoint for this connection is the server.
256      */
257     boolean isServer();
258 
259     /**
260      * Gets a view of this connection from the local {@link Endpoint}.
261      */
262     Endpoint<Http2LocalFlowController> local();
263 
264     /**
265      * Creates a new stream initiated by the local endpoint
266      * @see Endpoint#createStream(int)
267      */
268     Http2Stream createLocalStream(int streamId) throws Http2Exception;
269 
270     /**
271      * Gets a view of this connection from the remote {@link Endpoint}.
272      */
273     Endpoint<Http2RemoteFlowController> remote();
274 
275     /**
276      * Creates a new stream initiated by the remote endpoint.
277      * @see Endpoint#createStream(int)
278      */
279     Http2Stream createRemoteStream(int streamId) throws Http2Exception;
280 
281     /**
282      * Indicates whether or not a {@code GOAWAY} was received from the remote endpoint.
283      */
284     boolean goAwayReceived();
285 
286     /**
287      * Indicates that a {@code GOAWAY} was received from the remote endpoint and sets the last known stream.
288      */
289     void goAwayReceived(int lastKnownStream);
290 
291     /**
292      * Indicates whether or not a {@code GOAWAY} was sent to the remote endpoint.
293      */
294     boolean goAwaySent();
295 
296     /**
297      * Indicates that a {@code GOAWAY} was sent to the remote endpoint and sets the last known stream.
298      */
299     void goAwaySent(int lastKnownStream);
300 
301     /**
302      * Indicates whether or not either endpoint has received a GOAWAY.
303      */
304     boolean isGoAway();
305 }