1 module hunt.http.codec.http.stream.Stream;
2 
3 import hunt.http.codec.http.frame.DataFrame;
4 import hunt.http.codec.http.frame.HeadersFrame;
5 import hunt.http.codec.http.frame.PushPromiseFrame;
6 import hunt.http.codec.http.frame.ResetFrame;
7 import hunt.http.codec.http.stream.Session;
8 
9 import hunt.util.Common;
10 import hunt.concurrency.Promise;
11 
12 
13 alias StreamListener = Stream.Listener;
14 
15 /**
16  * <p>
17  * A {@link Stream} represents a bidirectional exchange of data on top of a
18  * {@link Session}.
19  * </p>
20  * <p>
21  * Differently from socket streams, where the input and output streams are
22  * permanently associated with the socket (and hence with the connection that
23  * the socket represents), there can be multiple HTTP/2 streams present
24  * concurrent for a HTTP/2 session.
25  * </p>
26  * <p>
27  * A {@link Stream} maps to a HTTP request/response cycle, and after the
28  * request/response cycle is completed, the stream is closed and removed from
29  * the session.
30  * </p>
31  * <p>
32  * Like {@link Session}, {@link Stream} is the active part and by calling its
33  * API applications can generate events on the stream; conversely,
34  * {@link Stream.Listener} is the passive part, and its callbacks are invoked
35  * when events happen on the stream.
36  * </p>
37  *
38  * @see Stream.Listener
39  */
40 interface Stream {
41     /**
42      * @return the stream unique id
43      */
44     int getId();
45 
46     /**
47      * @return the session this stream is associated to
48      */
49     Session getSession();
50 
51     /**
52      * <p>Sends the given HEADERS {@code frame} representing a HTTP response.</p>
53      *
54      * @param frame    the HEADERS frame to send
55      * @param callback the callback that gets notified when the frame has been sent
56      */
57     void headers(HeadersFrame frame, Callback callback);
58 
59     /**
60      * <p>Sends the given PUSH_PROMISE {@code frame}.</p>
61      *
62      * @param frame    the PUSH_PROMISE frame to send
63      * @param promise  the promise that gets notified of the pushed stream creation
64      * @param listener the listener that gets notified of stream events
65      */
66     void push(PushPromiseFrame frame, Promise!Stream promise, Listener listener);
67 
68     /**
69      * <p>Sends the given DATA {@code frame}.</p>
70      *
71      * @param frame    the DATA frame to send
72      * @param callback the callback that gets notified when the frame has been sent
73      */
74     void data(DataFrame frame, Callback callback);
75 
76     /**
77      * <p>Sends the given RST_STREAM {@code frame}.</p>
78      *
79      * @param frame    the RST_FRAME to send
80      * @param callback the callback that gets notified when the frame has been sent
81      */
82     void reset(ResetFrame frame, Callback callback);
83 
84     /**
85      * @param key the attribute key
86      * @return an arbitrary object associated with the given key to this stream
87      * or null if no object can be found for the given key.
88      * @see #setAttribute(string, Object)
89      */
90     Object getAttribute(string key);
91 
92     /**
93      * @param key   the attribute key
94      * @param value an arbitrary object to associate with the given key to this stream
95      * @see #getAttribute(string)
96      * @see #removeAttribute(string)
97      */
98     void setAttribute(string key, Object value);
99 
100     /**
101      * @param key the attribute key
102      * @return the arbitrary object associated with the given key to this stream
103      * @see #setAttribute(string, Object)
104      */
105     Object removeAttribute(string key);
106 
107     /**
108      * @return whether this stream has been reset
109      */
110     bool isReset();
111 
112     /**
113      * @return whether this stream is closed, both locally and remotely.
114      */
115     bool isClosed();
116 
117     /**
118      * @return the stream idle timeout
119      * @see #setIdleTimeout(long)
120      */
121     // long getIdleTimeout();
122 
123     /**
124      * @param idleTimeout the stream idle timeout
125      * @see #getIdleTimeout()
126      * @see Stream.Listener#onIdleTimeout(Stream, Exception)
127      */
128     // void setIdleTimeout(long idleTimeout);
129 
130     string toString();
131 
132     /**
133      * <p>A {@link Stream.Listener} is the passive counterpart of a {@link Stream} and receives
134      * events happening on a HTTP/2 stream.</p>
135      *
136      * @see Stream
137      */
138     interface Listener {
139         /**
140          * <p>Callback method invoked when a HEADERS frame representing the HTTP response has been received.</p>
141          *
142          * @param stream the stream
143          * @param frame  the HEADERS frame received
144          */
145         void onHeaders(Stream stream, HeadersFrame frame);
146 
147         /**
148          * <p>Callback method invoked when a PUSH_PROMISE frame has been received.</p>
149          *
150          * @param stream the stream
151          * @param frame  the PUSH_PROMISE frame received
152          * @return a Stream.Listener that will be notified of pushed stream events
153          */
154         Listener onPush(Stream stream, PushPromiseFrame frame);
155 
156         /**
157          * <p>Callback method invoked when a DATA frame has been received.</p>
158          *
159          * @param stream   the stream
160          * @param frame    the DATA frame received
161          * @param callback the callback to complete when the bytes of the DATA frame have been consumed
162          */
163         void onData(Stream stream, DataFrame frame, Callback callback);
164 
165         void onReset(Stream stream, ResetFrame frame, Callback callback);
166 
167         // void onReset(Stream stream, ResetFrame frame, Callback callback) {
168         //     try {
169         //         onReset(stream, frame);
170         //         callback.succeeded();
171         //     } catch (Exception x) {
172         //         callback.failed(x);
173         //     }
174         // }
175 
176         /**
177          * <p>Callback method invoked when a RST_STREAM frame has been received for this stream.</p>
178          *
179          * @param stream the stream
180          * @param frame  the RST_FRAME received
181          * @see Session.Listener#onReset(Session, ResetFrame)
182          */
183         void onReset(Stream stream, ResetFrame frame);
184 
185         /**
186          * <p>Callback method invoked when the stream exceeds its idle timeout.</p>
187          *
188          * @param stream the stream
189          * @param x      the timeout failure
190          * @see #getIdleTimeout()
191          * @deprecated use {@link #onIdleTimeout(Stream, Exception)} instead
192          */
193         // deprecated("")
194         // default void onTimeout(Stream stream, Exception x) {
195         // }
196 
197         /**
198          * <p>Callback method invoked when the stream exceeds its idle timeout.</p>
199          *
200          * @param stream the stream
201          * @param x      the timeout failure
202          * @return true to reset the stream, false to ignore the idle timeout
203          * @see #getIdleTimeout()
204          */
205         bool onIdleTimeout(Stream stream, Exception x);
206         
207         string toString();
208 
209 
210         /**
211          * <p>Empty implementation of {@link Listener}</p>
212          */
213         static class Adapter : Listener {
214             
215             void onHeaders(Stream stream, HeadersFrame frame) {
216             }
217 
218             
219             Listener onPush(Stream stream, PushPromiseFrame frame) {
220                 return null;
221             }
222 
223             
224             void onData(Stream stream, DataFrame frame, Callback callback) {
225                 callback.succeeded();
226             }
227 
228             void onReset(Stream stream, ResetFrame frame, Callback callback) {
229                 try {
230                     onReset(stream, frame);
231                     callback.succeeded();
232                 } catch (Exception x) {
233                     callback.failed(x);
234                 }
235             }
236 
237             void onReset(Stream stream, ResetFrame frame) {
238             }
239 
240             void onTimeout(Stream stream, Exception x) {
241             }
242 
243             
244             bool onIdleTimeout(Stream stream, Exception x) {
245                 return true;
246             }
247 
248 
249 			override string toString()
250 			{
251 				return super.toString();
252 			}
253         }
254     }
255 }