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