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 * https://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 io.netty.util.internal.UnstableApi;
19
20 /**
21 * A single stream within an HTTP2 connection. Streams are compared to each other by priority.
22 */
23 @UnstableApi
24 public interface Http2Stream {
25
26 /**
27 * The allowed states of an HTTP2 stream.
28 */
29 enum State {
30 IDLE(false, false),
31 RESERVED_LOCAL(false, false),
32 RESERVED_REMOTE(false, false),
33 OPEN(true, true),
34 HALF_CLOSED_LOCAL(false, true),
35 HALF_CLOSED_REMOTE(true, false),
36 CLOSED(false, false);
37
38 private final boolean localSideOpen;
39 private final boolean remoteSideOpen;
40
41 State(boolean localSideOpen, boolean remoteSideOpen) {
42 this.localSideOpen = localSideOpen;
43 this.remoteSideOpen = remoteSideOpen;
44 }
45
46 /**
47 * Indicates whether the local side of this stream is open (i.e. the state is either
48 * {@link State#OPEN} or {@link State#HALF_CLOSED_REMOTE}).
49 */
50 public boolean localSideOpen() {
51 return localSideOpen;
52 }
53
54 /**
55 * Indicates whether the remote side of this stream is open (i.e. the state is either
56 * {@link State#OPEN} or {@link State#HALF_CLOSED_LOCAL}).
57 */
58 public boolean remoteSideOpen() {
59 return remoteSideOpen;
60 }
61 }
62
63 /**
64 * Gets the unique identifier for this stream within the connection.
65 */
66 int id();
67
68 /**
69 * Gets the state of this stream.
70 */
71 State state();
72
73 /**
74 * Opens this stream, making it available via {@link Http2Connection#forEachActiveStream(Http2StreamVisitor)} and
75 * transition state to:
76 * <ul>
77 * <li>{@link State#OPEN} if {@link #state()} is {@link State#IDLE} and {@code halfClosed} is {@code false}.</li>
78 * <li>{@link State#HALF_CLOSED_LOCAL} if {@link #state()} is {@link State#IDLE} and {@code halfClosed}
79 * is {@code true} and the stream is local. In this state, {@link #isHeadersSent()} is {@code true}</li>
80 * <li>{@link State#HALF_CLOSED_REMOTE} if {@link #state()} is {@link State#IDLE} and {@code halfClosed}
81 * is {@code true} and the stream is remote. In this state, {@link #isHeadersReceived()} is {@code true}</li>
82 * <li>{@link State#RESERVED_LOCAL} if {@link #state()} is {@link State#HALF_CLOSED_REMOTE}.</li>
83 * <li>{@link State#RESERVED_REMOTE} if {@link #state()} is {@link State#HALF_CLOSED_LOCAL}.</li>
84 * </ul>
85 */
86 Http2Stream open(boolean halfClosed) throws Http2Exception;
87
88 /**
89 * Closes the stream.
90 */
91 Http2Stream close();
92
93 /**
94 * Closes the local side of this stream. If this makes the stream closed, the child is closed as
95 * well.
96 */
97 Http2Stream closeLocalSide();
98
99 /**
100 * Closes the remote side of this stream. If this makes the stream closed, the child is closed
101 * as well.
102 */
103 Http2Stream closeRemoteSide();
104
105 /**
106 * Indicates whether a {@code RST_STREAM} frame has been sent from the local endpoint for this stream.
107 */
108 boolean isResetSent();
109
110 /**
111 * Sets the flag indicating that a {@code RST_STREAM} frame has been sent from the local endpoint
112 * for this stream. This does not affect the stream state.
113 */
114 Http2Stream resetSent();
115
116 /**
117 * Associates the application-defined data with this stream.
118 * @return The value that was previously associated with {@code key}, or {@code null} if there was none.
119 */
120 <V> V setProperty(Http2Connection.PropertyKey key, V value);
121
122 /**
123 * Returns application-defined data if any was associated with this stream.
124 */
125 <V> V getProperty(Http2Connection.PropertyKey key);
126
127 /**
128 * Returns and removes application-defined data if any was associated with this stream.
129 */
130 <V> V removeProperty(Http2Connection.PropertyKey key);
131
132 /**
133 * Indicates that headers have been sent to the remote endpoint on this stream. The first call to this method would
134 * be for the initial headers (see {@link #isHeadersSent()}} and the second call would indicate the trailers
135 * (see {@link #isTrailersReceived()}).
136 * @param isInformational {@code true} if the headers contain an informational status code (for responses only).
137 */
138 Http2Stream headersSent(boolean isInformational);
139
140 /**
141 * Indicates whether or not headers were sent to the remote endpoint.
142 */
143 boolean isHeadersSent();
144
145 /**
146 * Indicates whether or not trailers were sent to the remote endpoint.
147 */
148 boolean isTrailersSent();
149
150 /**
151 * Indicates that headers have been received. The first call to this method would be for the initial headers
152 * (see {@link #isHeadersReceived()}} and the second call would indicate the trailers
153 * (see {@link #isTrailersReceived()}).
154 * @param isInformational {@code true} if the headers contain an informational status code (for responses only).
155 */
156 Http2Stream headersReceived(boolean isInformational);
157
158 /**
159 * Indicates whether or not the initial headers have been received.
160 */
161 boolean isHeadersReceived();
162
163 /**
164 * Indicates whether or not the trailers have been received.
165 */
166 boolean isTrailersReceived();
167
168 /**
169 * Indicates that a push promise was sent to the remote endpoint.
170 */
171 Http2Stream pushPromiseSent();
172
173 /**
174 * Indicates whether or not a push promise was sent to the remote endpoint.
175 */
176 boolean isPushPromiseSent();
177 }