comparison src/http/v3/ngx_http_v3_streams.c @ 8772:345370fdd32d quic

HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c. Previously it was parsed in ngx_http_v3_streams.c, while the streams were parsed in ngx_http_v3_parse.c. Now all parsing is done in one file. This simplifies parsing API and cleans up ngx_http_v3_streams.c.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 05 May 2021 15:00:17 +0300
parents 0981329169ea
children f4d3f5d93a82
comparison
equal deleted inserted replaced
8771:0981329169ea 8772:345370fdd32d
8 #include <ngx_config.h> 8 #include <ngx_config.h>
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_http.h> 10 #include <ngx_http.h>
11 11
12 12
13 typedef ngx_int_t (*ngx_http_v3_handler_pt)(ngx_connection_t *c, void *data,
14 u_char ch);
15
16
17 typedef struct { 13 typedef struct {
18 ngx_http_v3_handler_pt handler; 14 ngx_http_v3_parse_uni_t parse;
19 void *data;
20 ngx_int_t index; 15 ngx_int_t index;
21 } ngx_http_v3_uni_stream_t; 16 } ngx_http_v3_uni_stream_t;
22 17
23 18
24 typedef struct { 19 typedef struct {
30 25
31 26
32 static void ngx_http_v3_keepalive_handler(ngx_event_t *ev); 27 static void ngx_http_v3_keepalive_handler(ngx_event_t *ev);
33 static void ngx_http_v3_cleanup_session(void *data); 28 static void ngx_http_v3_cleanup_session(void *data);
34 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c); 29 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
35 static void ngx_http_v3_read_uni_stream_type(ngx_event_t *rev);
36 static void ngx_http_v3_uni_read_handler(ngx_event_t *rev); 30 static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
37 static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev); 31 static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev);
38 static void ngx_http_v3_push_cleanup(void *data); 32 static void ngx_http_v3_push_cleanup(void *data);
39 static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c, 33 static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c,
40 ngx_uint_t type); 34 ngx_uint_t type);
129 123
130 us->index = -1; 124 us->index = -1;
131 125
132 c->data = us; 126 c->data = us;
133 127
134 c->read->handler = ngx_http_v3_read_uni_stream_type; 128 c->read->handler = ngx_http_v3_uni_read_handler;
135 c->write->handler = ngx_http_v3_dummy_write_handler; 129 c->write->handler = ngx_http_v3_dummy_write_handler;
136 130
137 ngx_http_v3_read_uni_stream_type(c->read); 131 ngx_http_v3_uni_read_handler(c->read);
138 } 132 }
139 133
140 134
141 static void 135 static void
142 ngx_http_v3_close_uni_stream(ngx_connection_t *c) 136 ngx_http_v3_close_uni_stream(ngx_connection_t *c)
162 156
163 ngx_destroy_pool(pool); 157 ngx_destroy_pool(pool);
164 } 158 }
165 159
166 160
167 static void 161 ngx_int_t
168 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) 162 ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t type)
169 { 163 {
170 u_char ch; 164 ngx_int_t index;
171 ssize_t n;
172 ngx_int_t index, rc;
173 ngx_connection_t *c;
174 ngx_http_v3_session_t *h3c; 165 ngx_http_v3_session_t *h3c;
175 ngx_http_v3_uni_stream_t *us; 166 ngx_http_v3_uni_stream_t *us;
176 167
177 c = rev->data; 168 switch (type) {
178 us = c->data; 169
179 h3c = ngx_http_v3_get_session(c); 170 case NGX_HTTP_V3_STREAM_ENCODER:
180 171
181 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type"); 172 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
182 173 "http3 encoder stream");
183 while (rev->ready) { 174 index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER;
184 175 break;
185 n = c->recv(c, &ch, 1); 176
186 177 case NGX_HTTP_V3_STREAM_DECODER:
187 if (n == NGX_AGAIN) { 178
188 break; 179 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
180 "http3 decoder stream");
181 index = NGX_HTTP_V3_STREAM_CLIENT_DECODER;
182 break;
183
184 case NGX_HTTP_V3_STREAM_CONTROL:
185
186 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
187 "http3 control stream");
188 index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL;
189
190 break;
191
192 default:
193
194 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
195 "http3 stream 0x%02xL", type);
196 index = -1;
197 }
198
199 if (index >= 0) {
200 h3c = ngx_http_v3_get_session(c);
201
202 if (h3c->known_streams[index]) {
203 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists");
204 return NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR;
189 } 205 }
190 206
191 if (n == 0) { 207 h3c->known_streams[index] = c;
192 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; 208
193 goto failed; 209 us = c->data;
194 } 210 us->index = index;
195 211 }
196 if (n != 1) { 212
197 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; 213 return NGX_OK;
198 goto failed;
199 }
200
201 switch (ch) {
202
203 case NGX_HTTP_V3_STREAM_ENCODER:
204
205 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
206 "http3 encoder stream");
207
208 index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER;
209 us->handler = ngx_http_v3_parse_encoder;
210 n = sizeof(ngx_http_v3_parse_encoder_t);
211
212 break;
213
214 case NGX_HTTP_V3_STREAM_DECODER:
215
216 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
217 "http3 decoder stream");
218
219 index = NGX_HTTP_V3_STREAM_CLIENT_DECODER;
220 us->handler = ngx_http_v3_parse_decoder;
221 n = sizeof(ngx_http_v3_parse_decoder_t);
222
223 break;
224
225 case NGX_HTTP_V3_STREAM_CONTROL:
226
227 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
228 "http3 control stream");
229
230 index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL;
231 us->handler = ngx_http_v3_parse_control;
232 n = sizeof(ngx_http_v3_parse_control_t);
233
234 break;
235
236 default:
237
238 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
239 "http3 stream 0x%02xi", (ngx_int_t) ch);
240 index = -1;
241 n = 0;
242 }
243
244 if (index >= 0) {
245 if (h3c->known_streams[index]) {
246 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists");
247 rc = NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR;
248 goto failed;
249 }
250
251 us->index = index;
252 h3c->known_streams[index] = c;
253 }
254
255 if (n) {
256 us->data = ngx_pcalloc(c->pool, n);
257 if (us->data == NULL) {
258 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
259 goto failed;
260 }
261 }
262
263 rev->handler = ngx_http_v3_uni_read_handler;
264 ngx_http_v3_uni_read_handler(rev);
265 return;
266 }
267
268 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
269 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
270 goto failed;
271 }
272
273 return;
274
275 failed:
276
277 ngx_http_v3_finalize_connection(c, rc, "could not read stream type");
278 ngx_http_v3_close_uni_stream(c);
279 } 214 }
280 215
281 216
282 static void 217 static void
283 ngx_http_v3_uni_read_handler(ngx_event_t *rev) 218 ngx_http_v3_uni_read_handler(ngx_event_t *rev)
315 250
316 if (n == NGX_AGAIN) { 251 if (n == NGX_AGAIN) {
317 break; 252 break;
318 } 253 }
319 254
320 if (us->handler == NULL) {
321 continue;
322 }
323
324 for (i = 0; i < n; i++) { 255 for (i = 0; i < n; i++) {
325 256
326 rc = us->handler(c, us->data, buf[i]); 257 rc = ngx_http_v3_parse_uni(c, &us->parse, buf[i]);
327 258
328 if (rc == NGX_DONE) { 259 if (rc == NGX_DONE) {
329 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 260 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
330 "http3 read done"); 261 "http3 read done");
331 ngx_http_v3_close_uni_stream(c); 262 ngx_http_v3_close_uni_stream(c);