Mercurial > hg > nginx-quic
annotate src/http/v3/ngx_http_v3_streams.c @ 8350:6bb924b00e30 quic
HTTP/3: fixed server push.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Wed, 10 Mar 2021 17:56:34 +0300 |
parents | e1eb7f4ca9f1 |
children | 5cb5b568282b |
rev | line source |
---|---|
7681 | 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 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
13 typedef ngx_int_t (*ngx_http_v3_handler_pt)(ngx_connection_t *c, void *data, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
14 u_char ch); |
7681 | 15 |
16 | |
17 typedef struct { | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
18 ngx_http_v3_handler_pt handler; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
19 void *data; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
20 ngx_int_t index; |
7681 | 21 } ngx_http_v3_uni_stream_t; |
22 | |
23 | |
8015 | 24 typedef struct { |
25 ngx_queue_t queue; | |
26 uint64_t id; | |
27 ngx_connection_t *connection; | |
28 ngx_uint_t *npushing; | |
29 } ngx_http_v3_push_t; | |
30 | |
31 | |
7681 | 32 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c); |
33 static void ngx_http_v3_read_uni_stream_type(ngx_event_t *rev); | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
34 static void ngx_http_v3_uni_read_handler(ngx_event_t *rev); |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
35 static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev); |
8015 | 36 static void ngx_http_v3_push_cleanup(void *data); |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
37 static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c, |
7681 | 38 ngx_uint_t type); |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
39 static ngx_int_t ngx_http_v3_send_settings(ngx_connection_t *c); |
7681 | 40 |
41 | |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
42 ngx_int_t |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
43 ngx_http_v3_init_session(ngx_connection_t *c) |
7681 | 44 { |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
45 ngx_connection_t *pc; |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
46 ngx_http_connection_t *phc; |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
47 ngx_http_v3_connection_t *h3c; |
7681 | 48 |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
49 pc = c->quic->parent; |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
50 phc = pc->data; |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
51 |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
52 if (phc->http3) { |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
53 return NGX_OK; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
54 } |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
55 |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
56 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init session"); |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
57 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
58 h3c = ngx_pcalloc(pc->pool, sizeof(ngx_http_v3_connection_t)); |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
59 if (h3c == NULL) { |
8013
455a8536eaa7
QUIC: limited the number of server-initiated streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8010
diff
changeset
|
60 return NGX_ERROR; |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
61 } |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
62 |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
63 h3c->hc = *phc; |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
64 h3c->hc.http3 = 1; |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
65 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
66 ngx_queue_init(&h3c->blocked); |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
67 ngx_queue_init(&h3c->pushing); |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
68 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
69 pc->data = h3c; |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
70 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
71 return ngx_http_v3_send_settings(c); |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
72 } |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
73 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
74 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
75 void |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
76 ngx_http_v3_init_uni_stream(ngx_connection_t *c) |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
77 { |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
78 ngx_http_v3_uni_stream_t *us; |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
79 |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
80 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init uni stream"); |
7681 | 81 |
82 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t)); | |
83 if (us == NULL) { | |
8272
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
84 ngx_http_close_connection(c); |
e1eb7f4ca9f1
HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8200
diff
changeset
|
85 return; |
7681 | 86 } |
87 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
88 us->index = -1; |
7681 | 89 |
90 c->data = us; | |
91 | |
92 c->read->handler = ngx_http_v3_read_uni_stream_type; | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
93 c->write->handler = ngx_http_v3_dummy_write_handler; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
94 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
95 ngx_http_v3_read_uni_stream_type(c->read); |
7681 | 96 } |
97 | |
98 | |
99 static void | |
100 ngx_http_v3_close_uni_stream(ngx_connection_t *c) | |
101 { | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
102 ngx_pool_t *pool; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
103 ngx_http_v3_connection_t *h3c; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
104 ngx_http_v3_uni_stream_t *us; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
105 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
106 us = c->data; |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
107 h3c = c->quic->parent->data; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
108 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
109 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 close stream"); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
110 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
111 if (us->index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
112 h3c->known_streams[us->index] = NULL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
113 } |
7681 | 114 |
115 c->destroyed = 1; | |
116 | |
117 pool = c->pool; | |
118 | |
119 ngx_close_connection(c); | |
120 | |
121 ngx_destroy_pool(pool); | |
122 } | |
123 | |
124 | |
125 static void | |
126 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) | |
127 { | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
128 u_char ch; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
129 ssize_t n; |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
130 ngx_int_t index, rc; |
7681 | 131 ngx_connection_t *c; |
132 ngx_http_v3_connection_t *h3c; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
133 ngx_http_v3_uni_stream_t *us; |
7681 | 134 |
135 c = rev->data; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
136 us = c->data; |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
137 h3c = c->quic->parent->data; |
7681 | 138 |
139 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type"); | |
140 | |
141 while (rev->ready) { | |
142 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
143 n = c->recv(c, &ch, 1); |
7681 | 144 |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
145 if (n == NGX_AGAIN) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
146 break; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
147 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
148 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
149 if (n == 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
150 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; |
7681 | 151 goto failed; |
152 } | |
153 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
154 if (n != 1) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
155 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
156 goto failed; |
7681 | 157 } |
158 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
159 switch (ch) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
160 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
161 case NGX_HTTP_V3_STREAM_ENCODER: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
162 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
163 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
164 "http3 encoder stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
165 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
166 index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
167 us->handler = ngx_http_v3_parse_encoder; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
168 n = sizeof(ngx_http_v3_parse_encoder_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
169 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
170 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
171 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
172 case NGX_HTTP_V3_STREAM_DECODER: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
173 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
174 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
175 "http3 decoder stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
176 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
177 index = NGX_HTTP_V3_STREAM_CLIENT_DECODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
178 us->handler = ngx_http_v3_parse_decoder; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
179 n = sizeof(ngx_http_v3_parse_decoder_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
180 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
181 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
182 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
183 case NGX_HTTP_V3_STREAM_CONTROL: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
184 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
185 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
186 "http3 control stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
187 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
188 index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
189 us->handler = ngx_http_v3_parse_control; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
190 n = sizeof(ngx_http_v3_parse_control_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
191 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
192 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
193 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
194 default: |
7681 | 195 |
196 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
197 "http3 stream 0x%02xi", (ngx_int_t) ch); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
198 index = -1; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
199 n = 0; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
200 } |
7681 | 201 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
202 if (index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
203 if (h3c->known_streams[index]) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
204 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists"); |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
205 rc = NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
206 goto failed; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
207 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
208 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
209 us->index = index; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
210 h3c->known_streams[index] = c; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
211 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
212 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
213 if (n) { |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
214 us->data = ngx_pcalloc(c->pool, n); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
215 if (us->data == NULL) { |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
216 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
217 goto failed; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
218 } |
7681 | 219 } |
220 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
221 rev->handler = ngx_http_v3_uni_read_handler; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
222 ngx_http_v3_uni_read_handler(rev); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
223 return; |
7681 | 224 } |
225 | |
226 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
227 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7681 | 228 goto failed; |
229 } | |
230 | |
231 return; | |
232 | |
233 failed: | |
234 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
235 ngx_http_v3_finalize_connection(c, rc, "could not read stream type"); |
7681 | 236 ngx_http_v3_close_uni_stream(c); |
237 } | |
238 | |
239 | |
240 static void | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
241 ngx_http_v3_uni_read_handler(ngx_event_t *rev) |
7681 | 242 { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
243 u_char buf[128]; |
7681 | 244 ssize_t n; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
245 ngx_int_t rc, i; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
246 ngx_connection_t *c; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
247 ngx_http_v3_uni_stream_t *us; |
7681 | 248 |
249 c = rev->data; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
250 us = c->data; |
7681 | 251 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
252 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler"); |
7681 | 253 |
254 while (rev->ready) { | |
255 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
256 n = c->recv(c, buf, sizeof(buf)); |
7681 | 257 |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
258 if (n == NGX_ERROR) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
259 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7681 | 260 goto failed; |
261 } | |
262 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
263 if (n == 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
264 if (us->index >= 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
265 rc = NGX_HTTP_V3_ERR_CLOSED_CRITICAL_STREAM; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
266 goto failed; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
267 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
268 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
269 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read eof"); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
270 ngx_http_v3_close_uni_stream(c); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
271 return; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
272 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
273 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
274 if (n == NGX_AGAIN) { |
7681 | 275 break; |
276 } | |
277 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
278 if (us->handler == NULL) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
279 continue; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
280 } |
7681 | 281 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
282 for (i = 0; i < n; i++) { |
7681 | 283 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
284 rc = us->handler(c, us->data, buf[i]); |
7681 | 285 |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
286 if (rc == NGX_DONE) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
287 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
288 "http3 read done"); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
289 ngx_http_v3_close_uni_stream(c); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
290 return; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
291 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
292 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
293 if (rc > 0) { |
7681 | 294 goto failed; |
295 } | |
296 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
297 if (rc != NGX_AGAIN) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
298 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
299 goto failed; |
7681 | 300 } |
301 } | |
302 } | |
303 | |
304 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
305 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7681 | 306 goto failed; |
307 } | |
308 | |
309 return; | |
310 | |
311 failed: | |
312 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
313 ngx_http_v3_finalize_connection(c, rc, "stream error"); |
7681 | 314 ngx_http_v3_close_uni_stream(c); |
315 } | |
316 | |
317 | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
318 static void |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
319 ngx_http_v3_dummy_write_handler(ngx_event_t *wev) |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
320 { |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
321 ngx_connection_t *c; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
322 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
323 c = wev->data; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
324 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
325 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy write handler"); |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
326 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
327 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
328 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
329 NULL); |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
330 ngx_http_v3_close_uni_stream(c); |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
331 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
332 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
333 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
334 |
7681 | 335 /* XXX async & buffered stream writes */ |
336 | |
8015 | 337 ngx_connection_t * |
338 ngx_http_v3_create_push_stream(ngx_connection_t *c, uint64_t push_id) | |
339 { | |
340 u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 2]; | |
341 size_t n; | |
342 ngx_connection_t *sc; | |
343 ngx_pool_cleanup_t *cln; | |
344 ngx_http_v3_push_t *push; | |
345 ngx_http_v3_connection_t *h3c; | |
346 | |
347 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
348 "http3 create push stream id:%uL", push_id); | |
349 | |
350 sc = ngx_quic_open_stream(c, 0); | |
351 if (sc == NULL) { | |
352 return NULL; | |
353 } | |
354 | |
355 p = buf; | |
356 p = (u_char *) ngx_http_v3_encode_varlen_int(p, NGX_HTTP_V3_STREAM_PUSH); | |
357 p = (u_char *) ngx_http_v3_encode_varlen_int(p, push_id); | |
358 n = p - buf; | |
359 | |
360 if (sc->send(sc, buf, n) != (ssize_t) n) { | |
361 goto failed; | |
362 } | |
363 | |
364 cln = ngx_pool_cleanup_add(sc->pool, sizeof(ngx_http_v3_push_t)); | |
365 if (cln == NULL) { | |
366 goto failed; | |
367 } | |
368 | |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
369 h3c = c->quic->parent->data; |
8015 | 370 h3c->npushing++; |
371 | |
372 cln->handler = ngx_http_v3_push_cleanup; | |
373 | |
374 push = cln->data; | |
375 push->id = push_id; | |
376 push->connection = sc; | |
377 push->npushing = &h3c->npushing; | |
378 | |
379 ngx_queue_insert_tail(&h3c->pushing, &push->queue); | |
380 | |
381 return sc; | |
382 | |
383 failed: | |
384 | |
385 ngx_http_v3_close_uni_stream(sc); | |
386 | |
387 return NULL; | |
388 } | |
389 | |
390 | |
391 static void | |
392 ngx_http_v3_push_cleanup(void *data) | |
393 { | |
394 ngx_http_v3_push_t *push = data; | |
395 | |
396 ngx_queue_remove(&push->queue); | |
397 (*push->npushing)--; | |
398 } | |
399 | |
400 | |
7681 | 401 static ngx_connection_t * |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
402 ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type) |
7681 | 403 { |
404 u_char buf[NGX_HTTP_V3_VARLEN_INT_LEN]; | |
405 size_t n; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
406 ngx_int_t index; |
7681 | 407 ngx_connection_t *sc; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
408 ngx_http_v3_connection_t *h3c; |
7681 | 409 ngx_http_v3_uni_stream_t *us; |
410 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
411 switch (type) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
412 case NGX_HTTP_V3_STREAM_ENCODER: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
413 index = NGX_HTTP_V3_STREAM_SERVER_ENCODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
414 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
415 case NGX_HTTP_V3_STREAM_DECODER: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
416 index = NGX_HTTP_V3_STREAM_SERVER_DECODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
417 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
418 case NGX_HTTP_V3_STREAM_CONTROL: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
419 index = NGX_HTTP_V3_STREAM_SERVER_CONTROL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
420 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
421 default: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
422 index = -1; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
423 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
424 |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
425 h3c = c->quic->parent->data; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
426 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
427 if (index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
428 if (h3c->known_streams[index]) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
429 return h3c->known_streams[index]; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
430 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
431 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
432 |
8013
455a8536eaa7
QUIC: limited the number of server-initiated streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8010
diff
changeset
|
433 sc = ngx_quic_open_stream(c, 0); |
7681 | 434 if (sc == NULL) { |
435 return NULL; | |
436 } | |
437 | |
438 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
439 "http3 create uni stream, type:%ui", type); | |
440 | |
441 us = ngx_pcalloc(sc->pool, sizeof(ngx_http_v3_uni_stream_t)); | |
442 if (us == NULL) { | |
443 goto failed; | |
444 } | |
445 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
446 us->index = index; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
447 |
7681 | 448 sc->data = us; |
449 | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
450 sc->read->handler = ngx_http_v3_uni_read_handler; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
451 sc->write->handler = ngx_http_v3_dummy_write_handler; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
452 |
7880
c101438c69a4
HTTP/3: prevent array access by negative index for unknown streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7839
diff
changeset
|
453 if (index >= 0) { |
c101438c69a4
HTTP/3: prevent array access by negative index for unknown streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7839
diff
changeset
|
454 h3c->known_streams[index] = sc; |
c101438c69a4
HTTP/3: prevent array access by negative index for unknown streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7839
diff
changeset
|
455 } |
7681 | 456 |
457 n = (u_char *) ngx_http_v3_encode_varlen_int(buf, type) - buf; | |
458 | |
459 if (sc->send(sc, buf, n) != (ssize_t) n) { | |
460 goto failed; | |
461 } | |
462 | |
463 return sc; | |
464 | |
465 failed: | |
466 | |
467 ngx_http_v3_close_uni_stream(sc); | |
468 | |
469 return NULL; | |
470 } | |
471 | |
472 | |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
473 static ngx_int_t |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
474 ngx_http_v3_send_settings(ngx_connection_t *c) |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
475 { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
476 u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 6]; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
477 size_t n; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
478 ngx_connection_t *cc; |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
479 ngx_http_v3_srv_conf_t *h3scf; |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
480 ngx_http_v3_connection_t *h3c; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
481 |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
482 h3c = c->quic->parent->data; |
8013
455a8536eaa7
QUIC: limited the number of server-initiated streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8010
diff
changeset
|
483 |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
484 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send settings"); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
485 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
486 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
487 if (cc == NULL) { |
8013
455a8536eaa7
QUIC: limited the number of server-initiated streams.
Roman Arutyunyan <arut@nginx.com>
parents:
8010
diff
changeset
|
488 return NGX_DECLINED; |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
489 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
490 |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
491 h3scf = ngx_http_get_module_srv_conf(h3c->hc.conf_ctx, ngx_http_v3_module); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
492 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
493 n = ngx_http_v3_encode_varlen_int(NULL, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
494 NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
495 n += ngx_http_v3_encode_varlen_int(NULL, h3scf->max_table_capacity); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
496 n += ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_PARAM_BLOCKED_STREAMS); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
497 n += ngx_http_v3_encode_varlen_int(NULL, h3scf->max_blocked_streams); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
498 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
499 p = (u_char *) ngx_http_v3_encode_varlen_int(buf, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
500 NGX_HTTP_V3_FRAME_SETTINGS); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
501 p = (u_char *) ngx_http_v3_encode_varlen_int(p, n); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
502 p = (u_char *) ngx_http_v3_encode_varlen_int(p, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
503 NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
504 p = (u_char *) ngx_http_v3_encode_varlen_int(p, h3scf->max_table_capacity); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
505 p = (u_char *) ngx_http_v3_encode_varlen_int(p, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
506 NGX_HTTP_V3_PARAM_BLOCKED_STREAMS); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
507 p = (u_char *) ngx_http_v3_encode_varlen_int(p, h3scf->max_blocked_streams); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
508 n = p - buf; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
509 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
510 if (cc->send(cc, buf, n) != (ssize_t) n) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
511 goto failed; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
512 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
513 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
514 return NGX_OK; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
515 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
516 failed: |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
517 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
518 ngx_http_v3_close_uni_stream(cc); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
519 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
520 return NGX_ERROR; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
521 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
522 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
523 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
524 ngx_int_t |
7681 | 525 ngx_http_v3_client_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic, |
526 ngx_uint_t index, ngx_str_t *value) | |
527 { | |
528 u_char *p, buf[NGX_HTTP_V3_PREFIX_INT_LEN * 2]; | |
529 size_t n; | |
530 ngx_connection_t *ec; | |
531 | |
532 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
533 "http3 client ref insert, %s[%ui] \"%V\"", | |
534 dynamic ? "dynamic" : "static", index, value); | |
535 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
536 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 537 if (ec == NULL) { |
538 return NGX_ERROR; | |
539 } | |
540 | |
541 p = buf; | |
542 | |
543 *p = (dynamic ? 0x80 : 0xc0); | |
544 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 6); | |
545 | |
546 /* XXX option for huffman? */ | |
547 *p = 0; | |
548 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); | |
549 | |
550 n = p - buf; | |
551 | |
552 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
553 goto failed; | |
554 } | |
555 | |
556 if (ec->send(ec, value->data, value->len) != (ssize_t) value->len) { | |
557 goto failed; | |
558 } | |
559 | |
560 return NGX_OK; | |
561 | |
562 failed: | |
563 | |
564 ngx_http_v3_close_uni_stream(ec); | |
565 | |
566 return NGX_ERROR; | |
567 } | |
568 | |
569 | |
570 ngx_int_t | |
571 ngx_http_v3_client_insert(ngx_connection_t *c, ngx_str_t *name, | |
572 ngx_str_t *value) | |
573 { | |
574 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
575 size_t n; | |
576 ngx_connection_t *ec; | |
577 | |
578 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
579 "http3 client insert \"%V\":\"%V\"", name, value); | |
580 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
581 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 582 if (ec == NULL) { |
583 return NGX_ERROR; | |
584 } | |
585 | |
586 /* XXX option for huffman? */ | |
587 buf[0] = 0x40; | |
588 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, name->len, 5) - buf; | |
589 | |
590 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
591 goto failed; | |
592 } | |
593 | |
594 if (ec->send(ec, name->data, name->len) != (ssize_t) name->len) { | |
595 goto failed; | |
596 } | |
597 | |
598 /* XXX option for huffman? */ | |
599 buf[0] = 0; | |
600 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, value->len, 7) - buf; | |
601 | |
602 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
603 goto failed; | |
604 } | |
605 | |
606 if (ec->send(ec, value->data, value->len) != (ssize_t) value->len) { | |
607 goto failed; | |
608 } | |
609 | |
610 return NGX_OK; | |
611 | |
612 failed: | |
613 | |
614 ngx_http_v3_close_uni_stream(ec); | |
615 | |
616 return NGX_ERROR; | |
617 } | |
618 | |
619 | |
620 ngx_int_t | |
621 ngx_http_v3_client_set_capacity(ngx_connection_t *c, ngx_uint_t capacity) | |
622 { | |
623 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
624 size_t n; | |
625 ngx_connection_t *ec; | |
626 | |
627 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
628 "http3 client set capacity %ui", capacity); | |
629 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
630 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 631 if (ec == NULL) { |
632 return NGX_ERROR; | |
633 } | |
634 | |
635 buf[0] = 0x20; | |
636 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, capacity, 5) - buf; | |
637 | |
638 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
639 ngx_http_v3_close_uni_stream(ec); | |
640 return NGX_ERROR; | |
641 } | |
642 | |
643 return NGX_OK; | |
644 } | |
645 | |
646 | |
647 ngx_int_t | |
648 ngx_http_v3_client_duplicate(ngx_connection_t *c, ngx_uint_t index) | |
649 { | |
650 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
651 size_t n; | |
652 ngx_connection_t *ec; | |
653 | |
654 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
655 "http3 client duplicate %ui", index); | |
656 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
657 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 658 if (ec == NULL) { |
659 return NGX_ERROR; | |
660 } | |
661 | |
662 buf[0] = 0; | |
663 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, index, 5) - buf; | |
664 | |
665 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
666 ngx_http_v3_close_uni_stream(ec); | |
667 return NGX_ERROR; | |
668 } | |
669 | |
670 return NGX_OK; | |
671 } | |
672 | |
673 | |
674 ngx_int_t | |
675 ngx_http_v3_client_ack_header(ngx_connection_t *c, ngx_uint_t stream_id) | |
676 { | |
677 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
678 size_t n; | |
679 ngx_connection_t *dc; | |
680 | |
681 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
682 "http3 client ack header %ui", stream_id); | |
683 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
684 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 685 if (dc == NULL) { |
686 return NGX_ERROR; | |
687 } | |
688 | |
689 buf[0] = 0x80; | |
690 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 7) - buf; | |
691 | |
692 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
693 ngx_http_v3_close_uni_stream(dc); | |
694 return NGX_ERROR; | |
695 } | |
696 | |
697 return NGX_OK; | |
698 } | |
699 | |
700 | |
701 ngx_int_t | |
702 ngx_http_v3_client_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id) | |
703 { | |
704 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
705 size_t n; | |
706 ngx_connection_t *dc; | |
707 | |
708 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
709 "http3 client cancel stream %ui", stream_id); | |
710 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
711 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 712 if (dc == NULL) { |
713 return NGX_ERROR; | |
714 } | |
715 | |
716 buf[0] = 0x40; | |
717 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 6) - buf; | |
718 | |
719 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
720 ngx_http_v3_close_uni_stream(dc); | |
721 return NGX_ERROR; | |
722 } | |
723 | |
724 return NGX_OK; | |
725 } | |
726 | |
727 | |
728 ngx_int_t | |
729 ngx_http_v3_client_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc) | |
730 { | |
731 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
732 size_t n; | |
733 ngx_connection_t *dc; | |
734 | |
735 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
736 "http3 client increment insert count %ui", inc); | |
737 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
738 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 739 if (dc == NULL) { |
740 return NGX_ERROR; | |
741 } | |
742 | |
743 buf[0] = 0; | |
744 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, inc, 6) - buf; | |
745 | |
746 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
747 ngx_http_v3_close_uni_stream(dc); | |
748 return NGX_ERROR; | |
749 } | |
750 | |
751 return NGX_OK; | |
752 } | |
8015 | 753 |
754 | |
755 ngx_int_t | |
756 ngx_http_v3_set_max_push_id(ngx_connection_t *c, uint64_t max_push_id) | |
757 { | |
758 ngx_http_v3_connection_t *h3c; | |
759 | |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
760 h3c = c->quic->parent->data; |
8015 | 761 |
762 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
763 "http3 MAX_PUSH_ID:%uL", max_push_id); | |
764 | |
765 if (max_push_id < h3c->max_push_id) { | |
766 return NGX_HTTP_V3_ERR_ID_ERROR; | |
767 } | |
768 | |
769 h3c->max_push_id = max_push_id; | |
770 | |
771 return NGX_OK; | |
772 } | |
773 | |
774 | |
775 ngx_int_t | |
776 ngx_http_v3_cancel_push(ngx_connection_t *c, uint64_t push_id) | |
777 { | |
778 ngx_queue_t *q; | |
779 ngx_http_request_t *r; | |
780 ngx_http_v3_push_t *push; | |
781 ngx_http_v3_connection_t *h3c; | |
782 | |
8200
279ad36f2f4b
QUIC: renamed c->qs to c->quic.
Roman Arutyunyan <arut@nginx.com>
parents:
8015
diff
changeset
|
783 h3c = c->quic->parent->data; |
8015 | 784 |
785 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
786 "http3 CANCEL_PUSH:%uL", push_id); | |
787 | |
788 if (push_id >= h3c->next_push_id) { | |
789 return NGX_HTTP_V3_ERR_ID_ERROR; | |
790 } | |
791 | |
792 for (q = ngx_queue_head(&h3c->pushing); | |
793 q != ngx_queue_sentinel(&h3c->pushing); | |
794 q = ngx_queue_next(&h3c->pushing)) | |
795 { | |
796 push = (ngx_http_v3_push_t *) q; | |
797 | |
798 if (push->id != push_id) { | |
799 continue; | |
800 } | |
801 | |
802 r = push->connection->data; | |
803 | |
804 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
805 "http3 cancel push"); | |
806 | |
807 ngx_http_finalize_request(r, NGX_HTTP_CLOSE); | |
808 | |
809 break; | |
810 } | |
811 | |
812 return NGX_OK; | |
813 } |