comparison src/http/v3/ngx_http_v3_uni.c @ 8714:18d23ed15eef quic

HTTP/3: renamed files. ngx_http_v3_tables.h and ngx_http_v3_tables.c are renamed to ngx_http_v3_table.h and ngx_http_v3_table.c to better match HTTP/2 code. ngx_http_v3_streams.h and ngx_http_v3_streams.c are renamed to ngx_http_v3_uni.h and ngx_http_v3_uni.c to better match their content.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 07 Dec 2021 13:01:28 +0300
parents src/http/v3/ngx_http_v3_streams.c@d6ef13c5fd8e
children 3436b441239b
comparison
equal deleted inserted replaced
8713:d6ef13c5fd8e 8714:18d23ed15eef
1
2 /*
3 * Copyright (C) Roman Arutyunyan
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_http.h>
11
12
13 typedef struct {
14 ngx_http_v3_parse_uni_t parse;
15 ngx_int_t index;
16 } ngx_http_v3_uni_stream_t;
17
18
19 typedef struct {
20 ngx_queue_t queue;
21 uint64_t id;
22 ngx_connection_t *connection;
23 ngx_uint_t *npushing;
24 } ngx_http_v3_push_t;
25
26
27 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
28 static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
29 static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev);
30 static void ngx_http_v3_push_cleanup(void *data);
31 static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c,
32 ngx_uint_t type);
33
34
35 void
36 ngx_http_v3_init_uni_stream(ngx_connection_t *c)
37 {
38 uint64_t n;
39 ngx_http_v3_uni_stream_t *us;
40
41 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init uni stream");
42
43 n = c->quic->id >> 2;
44
45 if (n >= NGX_HTTP_V3_MAX_UNI_STREAMS) {
46 ngx_http_v3_finalize_connection(c,
47 NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR,
48 "reached maximum number of uni streams");
49 c->data = NULL;
50 ngx_http_v3_close_uni_stream(c);
51 return;
52 }
53
54 c->quic->cancelable = 1;
55
56 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t));
57 if (us == NULL) {
58 ngx_http_v3_finalize_connection(c,
59 NGX_HTTP_V3_ERR_INTERNAL_ERROR,
60 "memory allocation error");
61 c->data = NULL;
62 ngx_http_v3_close_uni_stream(c);
63 return;
64 }
65
66 us->index = -1;
67
68 c->data = us;
69
70 c->read->handler = ngx_http_v3_uni_read_handler;
71 c->write->handler = ngx_http_v3_dummy_write_handler;
72
73 ngx_http_v3_uni_read_handler(c->read);
74 }
75
76
77 static void
78 ngx_http_v3_close_uni_stream(ngx_connection_t *c)
79 {
80 ngx_pool_t *pool;
81 ngx_http_v3_session_t *h3c;
82 ngx_http_v3_uni_stream_t *us;
83
84 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 close stream");
85
86 us = c->data;
87
88 if (us && us->index >= 0) {
89 h3c = ngx_http_v3_get_session(c);
90 h3c->known_streams[us->index] = NULL;
91 }
92
93 c->destroyed = 1;
94
95 pool = c->pool;
96
97 ngx_close_connection(c);
98
99 ngx_destroy_pool(pool);
100 }
101
102
103 ngx_int_t
104 ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t type)
105 {
106 ngx_int_t index;
107 ngx_http_v3_session_t *h3c;
108 ngx_http_v3_uni_stream_t *us;
109
110 h3c = ngx_http_v3_get_session(c);
111
112 switch (type) {
113
114 case NGX_HTTP_V3_STREAM_ENCODER:
115
116 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
117 "http3 encoder stream");
118 index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER;
119 break;
120
121 case NGX_HTTP_V3_STREAM_DECODER:
122
123 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
124 "http3 decoder stream");
125 index = NGX_HTTP_V3_STREAM_CLIENT_DECODER;
126 break;
127
128 case NGX_HTTP_V3_STREAM_CONTROL:
129
130 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
131 "http3 control stream");
132 index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL;
133
134 break;
135
136 default:
137
138 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
139 "http3 stream 0x%02xL", type);
140
141 if (h3c->known_streams[NGX_HTTP_V3_STREAM_CLIENT_ENCODER] == NULL
142 || h3c->known_streams[NGX_HTTP_V3_STREAM_CLIENT_DECODER] == NULL
143 || h3c->known_streams[NGX_HTTP_V3_STREAM_CLIENT_CONTROL] == NULL)
144 {
145 ngx_log_error(NGX_LOG_INFO, c->log, 0, "missing mandatory stream");
146 return NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR;
147 }
148
149 index = -1;
150 }
151
152 if (index >= 0) {
153 if (h3c->known_streams[index]) {
154 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists");
155 return NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR;
156 }
157
158 h3c->known_streams[index] = c;
159
160 us = c->data;
161 us->index = index;
162 }
163
164 return NGX_OK;
165 }
166
167
168 static void
169 ngx_http_v3_uni_read_handler(ngx_event_t *rev)
170 {
171 u_char buf[128];
172 ssize_t n;
173 ngx_buf_t b;
174 ngx_int_t rc;
175 ngx_connection_t *c;
176 ngx_http_v3_session_t *h3c;
177 ngx_http_v3_uni_stream_t *us;
178
179 c = rev->data;
180 us = c->data;
181
182 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler");
183
184 ngx_memzero(&b, sizeof(ngx_buf_t));
185
186 while (rev->ready) {
187
188 n = c->recv(c, buf, sizeof(buf));
189
190 if (n == NGX_ERROR) {
191 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
192 goto failed;
193 }
194
195 if (n == 0) {
196 if (us->index >= 0) {
197 rc = NGX_HTTP_V3_ERR_CLOSED_CRITICAL_STREAM;
198 goto failed;
199 }
200
201 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read eof");
202 ngx_http_v3_close_uni_stream(c);
203 return;
204 }
205
206 if (n == NGX_AGAIN) {
207 break;
208 }
209
210 b.pos = buf;
211 b.last = buf + n;
212
213 h3c = ngx_http_v3_get_session(c);
214 h3c->total_bytes += n;
215
216 if (ngx_http_v3_check_flood(c) != NGX_OK) {
217 ngx_http_v3_close_uni_stream(c);
218 return;
219 }
220
221 rc = ngx_http_v3_parse_uni(c, &us->parse, &b);
222
223 if (rc == NGX_DONE) {
224 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
225 "http3 read done");
226 ngx_http_v3_close_uni_stream(c);
227 return;
228 }
229
230 if (rc > 0) {
231 goto failed;
232 }
233
234 if (rc != NGX_AGAIN) {
235 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR;
236 goto failed;
237 }
238 }
239
240 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
241 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
242 goto failed;
243 }
244
245 return;
246
247 failed:
248
249 ngx_http_v3_finalize_connection(c, rc, "stream error");
250 ngx_http_v3_close_uni_stream(c);
251 }
252
253
254 static void
255 ngx_http_v3_dummy_write_handler(ngx_event_t *wev)
256 {
257 ngx_connection_t *c;
258
259 c = wev->data;
260
261 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy write handler");
262
263 if (ngx_handle_write_event(wev, 0) != NGX_OK) {
264 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
265 NULL);
266 ngx_http_v3_close_uni_stream(c);
267 }
268 }
269
270
271 /* XXX async & buffered stream writes */
272
273 ngx_connection_t *
274 ngx_http_v3_create_push_stream(ngx_connection_t *c, uint64_t push_id)
275 {
276 u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 2];
277 size_t n;
278 ngx_connection_t *sc;
279 ngx_pool_cleanup_t *cln;
280 ngx_http_v3_push_t *push;
281 ngx_http_v3_session_t *h3c;
282
283 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
284 "http3 create push stream id:%uL", push_id);
285
286 sc = ngx_quic_open_stream(c, 0);
287 if (sc == NULL) {
288 goto failed;
289 }
290
291 p = buf;
292 p = (u_char *) ngx_http_v3_encode_varlen_int(p, NGX_HTTP_V3_STREAM_PUSH);
293 p = (u_char *) ngx_http_v3_encode_varlen_int(p, push_id);
294 n = p - buf;
295
296 h3c = ngx_http_v3_get_session(c);
297 h3c->total_bytes += n;
298
299 if (sc->send(sc, buf, n) != (ssize_t) n) {
300 goto failed;
301 }
302
303 cln = ngx_pool_cleanup_add(sc->pool, sizeof(ngx_http_v3_push_t));
304 if (cln == NULL) {
305 goto failed;
306 }
307
308 h3c->npushing++;
309
310 cln->handler = ngx_http_v3_push_cleanup;
311
312 push = cln->data;
313 push->id = push_id;
314 push->connection = sc;
315 push->npushing = &h3c->npushing;
316
317 ngx_queue_insert_tail(&h3c->pushing, &push->queue);
318
319 return sc;
320
321 failed:
322
323 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to create push stream");
324
325 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR,
326 "failed to create push stream");
327 if (sc) {
328 ngx_http_v3_close_uni_stream(sc);
329 }
330
331 return NULL;
332 }
333
334
335 static void
336 ngx_http_v3_push_cleanup(void *data)
337 {
338 ngx_http_v3_push_t *push = data;
339
340 ngx_queue_remove(&push->queue);
341 (*push->npushing)--;
342 }
343
344
345 static ngx_connection_t *
346 ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type)
347 {
348 u_char buf[NGX_HTTP_V3_VARLEN_INT_LEN];
349 size_t n;
350 ngx_int_t index;
351 ngx_connection_t *sc;
352 ngx_http_v3_session_t *h3c;
353 ngx_http_v3_uni_stream_t *us;
354
355 switch (type) {
356 case NGX_HTTP_V3_STREAM_ENCODER:
357 index = NGX_HTTP_V3_STREAM_SERVER_ENCODER;
358 break;
359 case NGX_HTTP_V3_STREAM_DECODER:
360 index = NGX_HTTP_V3_STREAM_SERVER_DECODER;
361 break;
362 case NGX_HTTP_V3_STREAM_CONTROL:
363 index = NGX_HTTP_V3_STREAM_SERVER_CONTROL;
364 break;
365 default:
366 index = -1;
367 }
368
369 h3c = ngx_http_v3_get_session(c);
370
371 if (index >= 0) {
372 if (h3c->known_streams[index]) {
373 return h3c->known_streams[index];
374 }
375 }
376
377 sc = ngx_quic_open_stream(c, 0);
378 if (sc == NULL) {
379 goto failed;
380 }
381
382 sc->quic->cancelable = 1;
383
384 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
385 "http3 create uni stream, type:%ui", type);
386
387 us = ngx_pcalloc(sc->pool, sizeof(ngx_http_v3_uni_stream_t));
388 if (us == NULL) {
389 goto failed;
390 }
391
392 us->index = index;
393
394 sc->data = us;
395
396 sc->read->handler = ngx_http_v3_uni_read_handler;
397 sc->write->handler = ngx_http_v3_dummy_write_handler;
398
399 if (index >= 0) {
400 h3c->known_streams[index] = sc;
401 }
402
403 n = (u_char *) ngx_http_v3_encode_varlen_int(buf, type) - buf;
404
405 h3c = ngx_http_v3_get_session(c);
406 h3c->total_bytes += n;
407
408 if (sc->send(sc, buf, n) != (ssize_t) n) {
409 goto failed;
410 }
411
412 return sc;
413
414 failed:
415
416 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to create server stream");
417
418 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR,
419 "failed to create server stream");
420 if (sc) {
421 ngx_http_v3_close_uni_stream(sc);
422 }
423
424 return NULL;
425 }
426
427
428 ngx_int_t
429 ngx_http_v3_send_settings(ngx_connection_t *c)
430 {
431 u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 6];
432 size_t n;
433 ngx_connection_t *cc;
434 ngx_http_v3_session_t *h3c;
435 ngx_http_v3_srv_conf_t *h3scf;
436
437 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send settings");
438
439 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL);
440 if (cc == NULL) {
441 return NGX_ERROR;
442 }
443
444 h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
445
446 n = ngx_http_v3_encode_varlen_int(NULL,
447 NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY);
448 n += ngx_http_v3_encode_varlen_int(NULL, h3scf->max_table_capacity);
449 n += ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_PARAM_BLOCKED_STREAMS);
450 n += ngx_http_v3_encode_varlen_int(NULL, h3scf->max_blocked_streams);
451
452 p = (u_char *) ngx_http_v3_encode_varlen_int(buf,
453 NGX_HTTP_V3_FRAME_SETTINGS);
454 p = (u_char *) ngx_http_v3_encode_varlen_int(p, n);
455 p = (u_char *) ngx_http_v3_encode_varlen_int(p,
456 NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY);
457 p = (u_char *) ngx_http_v3_encode_varlen_int(p, h3scf->max_table_capacity);
458 p = (u_char *) ngx_http_v3_encode_varlen_int(p,
459 NGX_HTTP_V3_PARAM_BLOCKED_STREAMS);
460 p = (u_char *) ngx_http_v3_encode_varlen_int(p, h3scf->max_blocked_streams);
461 n = p - buf;
462
463 h3c = ngx_http_v3_get_session(c);
464 h3c->total_bytes += n;
465
466 if (cc->send(cc, buf, n) != (ssize_t) n) {
467 goto failed;
468 }
469
470 return NGX_OK;
471
472 failed:
473
474 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to send settings");
475
476 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD,
477 "failed to send settings");
478 ngx_http_v3_close_uni_stream(cc);
479
480 return NGX_ERROR;
481 }
482
483
484 ngx_int_t
485 ngx_http_v3_send_goaway(ngx_connection_t *c, uint64_t id)
486 {
487 u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 3];
488 size_t n;
489 ngx_connection_t *cc;
490 ngx_http_v3_session_t *h3c;
491
492 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send goaway %uL", id);
493
494 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL);
495 if (cc == NULL) {
496 return NGX_ERROR;
497 }
498
499 n = ngx_http_v3_encode_varlen_int(NULL, id);
500 p = (u_char *) ngx_http_v3_encode_varlen_int(buf, NGX_HTTP_V3_FRAME_GOAWAY);
501 p = (u_char *) ngx_http_v3_encode_varlen_int(p, n);
502 p = (u_char *) ngx_http_v3_encode_varlen_int(p, id);
503 n = p - buf;
504
505 h3c = ngx_http_v3_get_session(c);
506 h3c->total_bytes += n;
507
508 if (cc->send(cc, buf, n) != (ssize_t) n) {
509 goto failed;
510 }
511
512 return NGX_OK;
513
514 failed:
515
516 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to send goaway");
517
518 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD,
519 "failed to send goaway");
520 ngx_http_v3_close_uni_stream(cc);
521
522 return NGX_ERROR;
523 }
524
525
526 ngx_int_t
527 ngx_http_v3_send_ack_section(ngx_connection_t *c, ngx_uint_t stream_id)
528 {
529 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN];
530 size_t n;
531 ngx_connection_t *dc;
532 ngx_http_v3_session_t *h3c;
533
534 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
535 "http3 send section acknowledgement %ui", stream_id);
536
537 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER);
538 if (dc == NULL) {
539 return NGX_ERROR;
540 }
541
542 buf[0] = 0x80;
543 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 7) - buf;
544
545 h3c = ngx_http_v3_get_session(c);
546 h3c->total_bytes += n;
547
548 if (dc->send(dc, buf, n) != (ssize_t) n) {
549 goto failed;
550 }
551
552 return NGX_OK;
553
554 failed:
555
556 ngx_log_error(NGX_LOG_ERR, c->log, 0,
557 "failed to send section acknowledgement");
558
559 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD,
560 "failed to send section acknowledgement");
561 ngx_http_v3_close_uni_stream(dc);
562
563 return NGX_ERROR;
564 }
565
566
567 ngx_int_t
568 ngx_http_v3_send_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id)
569 {
570 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN];
571 size_t n;
572 ngx_connection_t *dc;
573 ngx_http_v3_session_t *h3c;
574
575 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
576 "http3 send stream cancellation %ui", stream_id);
577
578 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER);
579 if (dc == NULL) {
580 return NGX_ERROR;
581 }
582
583 buf[0] = 0x40;
584 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 6) - buf;
585
586 h3c = ngx_http_v3_get_session(c);
587 h3c->total_bytes += n;
588
589 if (dc->send(dc, buf, n) != (ssize_t) n) {
590 goto failed;
591 }
592
593 return NGX_OK;
594
595 failed:
596
597 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to send stream cancellation");
598
599 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD,
600 "failed to send stream cancellation");
601 ngx_http_v3_close_uni_stream(dc);
602
603 return NGX_ERROR;
604 }
605
606
607 ngx_int_t
608 ngx_http_v3_send_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc)
609 {
610 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN];
611 size_t n;
612 ngx_connection_t *dc;
613 ngx_http_v3_session_t *h3c;
614
615 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
616 "http3 send insert count increment %ui", inc);
617
618 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER);
619 if (dc == NULL) {
620 return NGX_ERROR;
621 }
622
623 buf[0] = 0;
624 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, inc, 6) - buf;
625
626 h3c = ngx_http_v3_get_session(c);
627 h3c->total_bytes += n;
628
629 if (dc->send(dc, buf, n) != (ssize_t) n) {
630 goto failed;
631 }
632
633 return NGX_OK;
634
635 failed:
636
637 ngx_log_error(NGX_LOG_ERR, c->log, 0,
638 "failed to send insert count increment");
639
640 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD,
641 "failed to send insert count increment");
642 ngx_http_v3_close_uni_stream(dc);
643
644 return NGX_ERROR;
645 }
646
647
648 ngx_int_t
649 ngx_http_v3_set_max_push_id(ngx_connection_t *c, uint64_t max_push_id)
650 {
651 ngx_http_v3_session_t *h3c;
652
653 h3c = ngx_http_v3_get_session(c);
654
655 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
656 "http3 MAX_PUSH_ID:%uL", max_push_id);
657
658 if (h3c->max_push_id != (uint64_t) -1 && max_push_id < h3c->max_push_id) {
659 return NGX_HTTP_V3_ERR_ID_ERROR;
660 }
661
662 h3c->max_push_id = max_push_id;
663
664 return NGX_OK;
665 }
666
667
668 ngx_int_t
669 ngx_http_v3_goaway(ngx_connection_t *c, uint64_t push_id)
670 {
671 ngx_http_v3_session_t *h3c;
672
673 h3c = ngx_http_v3_get_session(c);
674
675 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 GOAWAY:%uL", push_id);
676
677 h3c->goaway_push_id = push_id;
678
679 return NGX_OK;
680 }
681
682
683 ngx_int_t
684 ngx_http_v3_cancel_push(ngx_connection_t *c, uint64_t push_id)
685 {
686 ngx_queue_t *q;
687 ngx_http_request_t *r;
688 ngx_http_v3_push_t *push;
689 ngx_http_v3_session_t *h3c;
690
691 h3c = ngx_http_v3_get_session(c);
692
693 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
694 "http3 CANCEL_PUSH:%uL", push_id);
695
696 if (push_id >= h3c->next_push_id) {
697 return NGX_HTTP_V3_ERR_ID_ERROR;
698 }
699
700 for (q = ngx_queue_head(&h3c->pushing);
701 q != ngx_queue_sentinel(&h3c->pushing);
702 q = ngx_queue_next(&h3c->pushing))
703 {
704 push = (ngx_http_v3_push_t *) q;
705
706 if (push->id != push_id) {
707 continue;
708 }
709
710 r = push->connection->data;
711
712 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
713 "http3 cancel push");
714
715 ngx_http_finalize_request(r, NGX_HTTP_CLOSE);
716
717 break;
718 }
719
720 return NGX_OK;
721 }
722
723
724 ngx_int_t
725 ngx_http_v3_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id)
726 {
727 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
728 "http3 cancel stream %ui", stream_id);
729
730 /* we do not use dynamic tables */
731
732 return NGX_OK;
733 }