Nexus HTTP/3
A QUIC and HTTP/3 library
stream_state.hpp
1 #pragma once
2 
3 #include <variant>
4 #include <nexus/error_code.hpp>
5 #include <nexus/quic/stream_id.hpp>
6 
7 struct lsquic_stream;
8 
9 namespace nexus::quic::detail {
10 
11 struct connection_impl;
12 struct stream_impl;
13 
14 struct stream_header_read_operation;
15 struct stream_header_write_operation;
16 struct stream_data_operation;
17 struct stream_accept_operation;
18 struct stream_connect_operation;
19 struct stream_close_operation;
20 
23 namespace sending_stream_state {
24 
25 using header_operation = stream_header_write_operation;
26 using data_operation = stream_data_operation;
27 
28 struct expecting_header {};
29 struct header {
30  header_operation* op = nullptr;
31 };
32 struct expecting_body {};
33 struct body {
34  data_operation* op = nullptr;
35 };
36 struct shutdown {};
37 
38 using variant = std::variant<expecting_header, header,
39  expecting_body, body,
40  shutdown>;
41 
42 // sending stream events
43 void write_header(variant& state, lsquic_stream* handle, header_operation& op);
44 void write_body(variant& state, lsquic_stream* handle, data_operation& op);
45 void on_write_header(variant& state, lsquic_stream* handle);
46 void on_write_body(variant& state, lsquic_stream* handle);
47 void on_write(variant& state, lsquic_stream* handle);
48 int cancel(variant& state, error_code ec);
49 void destroy(variant& state);
50 
51 } // namespace sending_stream_state
52 
55 namespace receiving_stream_state {
56 
57 using header_operation = stream_header_read_operation;
58 using data_operation = stream_data_operation;
59 
60 struct expecting_header {};
61 struct header {
62  header_operation* op = nullptr;
63 };
64 struct expecting_body {};
65 struct body {
66  data_operation* op = nullptr;
67 };
68 struct shutdown {};
69 
70 using variant = std::variant<expecting_header, header,
71  expecting_body, body,
72  shutdown>;
73 
74 // receiving stream events
75 void read_header(variant& state, lsquic_stream* handle, header_operation* op);
76 void read_body(variant& state, lsquic_stream* handle, data_operation* op);
77 void on_read_header(variant& state, error_code ec);
78 void on_read_body(variant& state, error_code ec);
79 void on_read(variant& state, lsquic_stream* handle);
80 int cancel(variant& state, error_code ec);
81 void destroy(variant& state);
82 
83 } // namespace receiving_stream_state
84 
86 namespace stream_state {
87 
90 struct accepting {
91  stream_accept_operation* op = nullptr;
92 };
93 
96 struct connecting {
97  stream_connect_operation* op = nullptr;
98 };
99 
101 struct open {
102  lsquic_stream& handle;
103 
104  receiving_stream_state::variant in;
105  sending_stream_state::variant out;
106 
107  struct quic_tag {};
108  open(lsquic_stream& handle, quic_tag) noexcept
109  : handle(handle),
110  in(receiving_stream_state::expecting_body{}),
111  out(sending_stream_state::expecting_body{})
112  {}
113 
114  struct h3_tag {};
115  open(lsquic_stream& handle, h3_tag) noexcept
116  : handle(handle),
117  in(receiving_stream_state::expecting_header{}),
118  out(sending_stream_state::expecting_header{})
119  {}
120 };
121 
124 struct closing {
125  stream_close_operation* op = nullptr;
126 };
127 
129 struct error {
130  error_code ec;
131 };
132 
134 struct closed {
135 };
136 
137 using variant = std::variant<accepting, connecting, open,
138  closing, error, closed>;
139 
141 enum class transition {
142  none,
143  accepting_to_closed,
144  connecting_to_closed,
145  open_to_closing,
146  open_to_closed,
147  open_to_error,
148  closing_to_closed,
149  error_to_closed,
150 };
151 
152 // stream accessors
153 bool is_open(const variant& state);
154 stream_id id(const variant& state, error_code& ec);
155 
156 // stream events
157 void connect(variant& state, stream_connect_operation& op);
158 void on_connect(variant& state, lsquic_stream* handle, bool is_http);
159 
160 void accept(variant& state, stream_accept_operation& op);
161 void on_accept(variant& state, lsquic_stream* handle, bool is_http);
162 
163 bool read(variant& state, stream_data_operation& op);
164 bool read_headers(variant& state, stream_header_read_operation& op);
165 void on_read(variant& state);
166 
167 bool write(variant& state, stream_data_operation& op);
168 bool write_headers(variant& state, stream_header_write_operation& op);
169 void on_write(variant& state);
170 
171 void flush(variant& state, error_code& ec);
172 void shutdown(variant& state, int how, error_code& ec);
173 int cancel(variant& state, error_code ec);
174 
175 transition close(variant& state, stream_close_operation& op);
176 transition on_close(variant& state);
177 transition on_error(variant& state, error_code ec);
178 transition reset(variant& state);
179 
180 void destroy(variant& state);
181 
182 } // namespace stream_state
183 
184 } // namespace nexus::quic::detail
error
global error codes
Definition: error.hpp:11
uint64_t stream_id
stream identifier that is unique to a connection
Definition: stream_id.hpp:8