Mercurial > hg > nginx-quic
annotate src/http/v3/ngx_http_v3_streams.c @ 7839:44cac24aaa44 quic
Assign connection number to every QUIC stream log.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 23 Apr 2020 18:05:05 +0300 |
parents | dadbc66e9fca |
children | c101438c69a4 |
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 | |
24 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c); | |
25 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
|
26 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
|
27 static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev); |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
28 static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c, |
7681 | 29 ngx_uint_t type); |
30 | |
31 | |
32 void | |
33 ngx_http_v3_handle_client_uni_stream(ngx_connection_t *c) | |
34 { | |
35 ngx_http_v3_uni_stream_t *us; | |
36 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
37 ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
38 ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
39 ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
40 |
7681 | 41 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
42 "http3 new uni stream id:0x%uxL", c->qs->id); |
7681 | 43 |
44 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t)); | |
45 if (us == NULL) { | |
46 ngx_http_v3_close_uni_stream(c); | |
47 return; | |
48 } | |
49 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
50 us->index = -1; |
7681 | 51 |
52 c->data = us; | |
53 | |
54 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
|
55 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
|
56 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
57 ngx_http_v3_read_uni_stream_type(c->read); |
7681 | 58 } |
59 | |
60 | |
61 static void | |
62 ngx_http_v3_close_uni_stream(ngx_connection_t *c) | |
63 { | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
64 ngx_pool_t *pool; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
65 ngx_http_v3_connection_t *h3c; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
66 ngx_http_v3_uni_stream_t *us; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
67 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
68 us = c->data; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
69 h3c = c->qs->parent->data; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
70 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
71 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
|
72 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
73 if (us->index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
74 h3c->known_streams[us->index] = NULL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
75 } |
7681 | 76 |
77 c->destroyed = 1; | |
78 | |
79 pool = c->pool; | |
80 | |
81 ngx_close_connection(c); | |
82 | |
83 ngx_destroy_pool(pool); | |
84 } | |
85 | |
86 | |
87 static void | |
88 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) | |
89 { | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
90 u_char ch; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
91 ssize_t n; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
92 ngx_int_t index; |
7681 | 93 ngx_connection_t *c; |
94 ngx_http_v3_connection_t *h3c; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
95 ngx_http_v3_uni_stream_t *us; |
7681 | 96 |
97 c = rev->data; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
98 us = c->data; |
7681 | 99 h3c = c->qs->parent->data; |
100 | |
101 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type"); | |
102 | |
103 while (rev->ready) { | |
104 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
105 n = c->recv(c, &ch, 1); |
7681 | 106 |
107 if (n == NGX_ERROR) { | |
108 goto failed; | |
109 } | |
110 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
111 if (n == NGX_AGAIN || n != 1) { |
7681 | 112 break; |
113 } | |
114 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
115 switch (ch) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
116 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
117 case NGX_HTTP_V3_STREAM_ENCODER: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
118 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
119 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
120 "http3 encoder stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
121 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
122 index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
123 us->handler = ngx_http_v3_parse_encoder; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
124 n = sizeof(ngx_http_v3_parse_encoder_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
125 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
126 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
127 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
128 case NGX_HTTP_V3_STREAM_DECODER: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
129 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
130 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
131 "http3 decoder stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
132 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
133 index = NGX_HTTP_V3_STREAM_CLIENT_DECODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
134 us->handler = ngx_http_v3_parse_decoder; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
135 n = sizeof(ngx_http_v3_parse_decoder_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
136 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
137 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
138 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
139 case NGX_HTTP_V3_STREAM_CONTROL: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
140 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
141 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
142 "http3 control stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
143 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
144 index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
145 us->handler = ngx_http_v3_parse_control; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
146 n = sizeof(ngx_http_v3_parse_control_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
147 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
148 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
149 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
150 default: |
7681 | 151 |
152 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
|
153 "http3 stream 0x%02xi", (ngx_int_t) ch); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
154 index = -1; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
155 n = 0; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
156 } |
7681 | 157 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
158 if (index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
159 if (h3c->known_streams[index]) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
160 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists"); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
161 goto failed; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
162 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
163 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
164 us->index = index; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
165 h3c->known_streams[index] = c; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
166 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
167 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
168 if (n) { |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
169 us->data = ngx_pcalloc(c->pool, n); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
170 if (us->data == NULL) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
171 goto failed; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
172 } |
7681 | 173 } |
174 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
175 rev->handler = ngx_http_v3_uni_read_handler; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
176 ngx_http_v3_uni_read_handler(rev); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
177 return; |
7681 | 178 } |
179 | |
180 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
181 goto failed; | |
182 } | |
183 | |
184 return; | |
185 | |
186 failed: | |
187 | |
188 ngx_http_v3_close_uni_stream(c); | |
189 } | |
190 | |
191 | |
192 static void | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
193 ngx_http_v3_uni_read_handler(ngx_event_t *rev) |
7681 | 194 { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
195 u_char buf[128]; |
7681 | 196 ssize_t n; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
197 ngx_int_t rc, i; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
198 ngx_connection_t *c; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
199 ngx_http_v3_uni_stream_t *us; |
7681 | 200 |
201 c = rev->data; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
202 us = c->data; |
7681 | 203 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
204 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler"); |
7681 | 205 |
206 while (rev->ready) { | |
207 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
208 n = c->recv(c, buf, sizeof(buf)); |
7681 | 209 |
210 if (n == NGX_ERROR || n == 0) { | |
211 goto failed; | |
212 } | |
213 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
214 if (n == NGX_AGAIN) { |
7681 | 215 break; |
216 } | |
217 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
218 if (us->handler == NULL) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
219 continue; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
220 } |
7681 | 221 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
222 for (i = 0; i < n; i++) { |
7681 | 223 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
224 rc = us->handler(c, us->data, buf[i]); |
7681 | 225 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
226 if (rc == NGX_ERROR) { |
7681 | 227 goto failed; |
228 } | |
229 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
230 if (rc == NGX_DONE) { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
231 goto done; |
7681 | 232 } |
233 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
234 /* rc == NGX_AGAIN */ |
7681 | 235 } |
236 } | |
237 | |
238 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
239 goto failed; | |
240 } | |
241 | |
242 return; | |
243 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
244 done: |
7681 | 245 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
246 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read done"); |
7681 | 247 |
248 failed: | |
249 | |
250 ngx_http_v3_close_uni_stream(c); | |
251 } | |
252 | |
253 | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
254 static void |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
255 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
|
256 { |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
257 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
|
258 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
259 c = wev->data; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
260 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
261 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
|
262 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
263 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
264 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
|
265 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
266 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
267 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
268 |
7681 | 269 /* XXX async & buffered stream writes */ |
270 | |
271 static ngx_connection_t * | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
272 ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type) |
7681 | 273 { |
274 u_char buf[NGX_HTTP_V3_VARLEN_INT_LEN]; | |
275 size_t n; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
276 ngx_int_t index; |
7681 | 277 ngx_connection_t *sc; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
278 ngx_http_v3_connection_t *h3c; |
7681 | 279 ngx_http_v3_uni_stream_t *us; |
280 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
281 switch (type) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
282 case NGX_HTTP_V3_STREAM_ENCODER: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
283 index = NGX_HTTP_V3_STREAM_SERVER_ENCODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
284 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
285 case NGX_HTTP_V3_STREAM_DECODER: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
286 index = NGX_HTTP_V3_STREAM_SERVER_DECODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
287 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
288 case NGX_HTTP_V3_STREAM_CONTROL: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
289 index = NGX_HTTP_V3_STREAM_SERVER_CONTROL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
290 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
291 default: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
292 index = -1; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
293 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
294 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
295 h3c = c->qs->parent->data; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
296 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
297 if (index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
298 if (h3c->known_streams[index]) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
299 return h3c->known_streams[index]; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
300 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
301 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
302 |
7694
ac41c53e446d
Fixed HTTP/3 server stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
7692
diff
changeset
|
303 sc = ngx_quic_create_uni_stream(c); |
7681 | 304 if (sc == NULL) { |
305 return NULL; | |
306 } | |
307 | |
308 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
309 "http3 create uni stream, type:%ui", type); | |
310 | |
311 us = ngx_pcalloc(sc->pool, sizeof(ngx_http_v3_uni_stream_t)); | |
312 if (us == NULL) { | |
313 goto failed; | |
314 } | |
315 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
316 us->index = index; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
317 |
7681 | 318 sc->data = us; |
319 | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
320 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
|
321 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
|
322 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
323 h3c->known_streams[index] = sc; |
7681 | 324 |
325 n = (u_char *) ngx_http_v3_encode_varlen_int(buf, type) - buf; | |
326 | |
327 if (sc->send(sc, buf, n) != (ssize_t) n) { | |
328 goto failed; | |
329 } | |
330 | |
331 return sc; | |
332 | |
333 failed: | |
334 | |
335 ngx_http_v3_close_uni_stream(sc); | |
336 | |
337 return NULL; | |
338 } | |
339 | |
340 | |
341 ngx_int_t | |
342 ngx_http_v3_client_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic, | |
343 ngx_uint_t index, ngx_str_t *value) | |
344 { | |
345 u_char *p, buf[NGX_HTTP_V3_PREFIX_INT_LEN * 2]; | |
346 size_t n; | |
347 ngx_connection_t *ec; | |
348 | |
349 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
350 "http3 client ref insert, %s[%ui] \"%V\"", | |
351 dynamic ? "dynamic" : "static", index, value); | |
352 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
353 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 354 if (ec == NULL) { |
355 return NGX_ERROR; | |
356 } | |
357 | |
358 p = buf; | |
359 | |
360 *p = (dynamic ? 0x80 : 0xc0); | |
361 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 6); | |
362 | |
363 /* XXX option for huffman? */ | |
364 *p = 0; | |
365 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); | |
366 | |
367 n = p - buf; | |
368 | |
369 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
370 goto failed; | |
371 } | |
372 | |
373 if (ec->send(ec, value->data, value->len) != (ssize_t) value->len) { | |
374 goto failed; | |
375 } | |
376 | |
377 return NGX_OK; | |
378 | |
379 failed: | |
380 | |
381 ngx_http_v3_close_uni_stream(ec); | |
382 | |
383 return NGX_ERROR; | |
384 } | |
385 | |
386 | |
387 ngx_int_t | |
388 ngx_http_v3_client_insert(ngx_connection_t *c, ngx_str_t *name, | |
389 ngx_str_t *value) | |
390 { | |
391 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
392 size_t n; | |
393 ngx_connection_t *ec; | |
394 | |
395 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
396 "http3 client insert \"%V\":\"%V\"", name, value); | |
397 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
398 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 399 if (ec == NULL) { |
400 return NGX_ERROR; | |
401 } | |
402 | |
403 /* XXX option for huffman? */ | |
404 buf[0] = 0x40; | |
405 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, name->len, 5) - buf; | |
406 | |
407 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
408 goto failed; | |
409 } | |
410 | |
411 if (ec->send(ec, name->data, name->len) != (ssize_t) name->len) { | |
412 goto failed; | |
413 } | |
414 | |
415 /* XXX option for huffman? */ | |
416 buf[0] = 0; | |
417 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, value->len, 7) - buf; | |
418 | |
419 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
420 goto failed; | |
421 } | |
422 | |
423 if (ec->send(ec, value->data, value->len) != (ssize_t) value->len) { | |
424 goto failed; | |
425 } | |
426 | |
427 return NGX_OK; | |
428 | |
429 failed: | |
430 | |
431 ngx_http_v3_close_uni_stream(ec); | |
432 | |
433 return NGX_ERROR; | |
434 } | |
435 | |
436 | |
437 ngx_int_t | |
438 ngx_http_v3_client_set_capacity(ngx_connection_t *c, ngx_uint_t capacity) | |
439 { | |
440 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
441 size_t n; | |
442 ngx_connection_t *ec; | |
443 | |
444 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
445 "http3 client set capacity %ui", capacity); | |
446 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
447 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 448 if (ec == NULL) { |
449 return NGX_ERROR; | |
450 } | |
451 | |
452 buf[0] = 0x20; | |
453 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, capacity, 5) - buf; | |
454 | |
455 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
456 ngx_http_v3_close_uni_stream(ec); | |
457 return NGX_ERROR; | |
458 } | |
459 | |
460 return NGX_OK; | |
461 } | |
462 | |
463 | |
464 ngx_int_t | |
465 ngx_http_v3_client_duplicate(ngx_connection_t *c, ngx_uint_t index) | |
466 { | |
467 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
468 size_t n; | |
469 ngx_connection_t *ec; | |
470 | |
471 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
472 "http3 client duplicate %ui", index); | |
473 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
474 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 475 if (ec == NULL) { |
476 return NGX_ERROR; | |
477 } | |
478 | |
479 buf[0] = 0; | |
480 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, index, 5) - buf; | |
481 | |
482 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
483 ngx_http_v3_close_uni_stream(ec); | |
484 return NGX_ERROR; | |
485 } | |
486 | |
487 return NGX_OK; | |
488 } | |
489 | |
490 | |
491 ngx_int_t | |
492 ngx_http_v3_client_ack_header(ngx_connection_t *c, ngx_uint_t stream_id) | |
493 { | |
494 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
495 size_t n; | |
496 ngx_connection_t *dc; | |
497 | |
498 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
499 "http3 client ack header %ui", stream_id); | |
500 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
501 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 502 if (dc == NULL) { |
503 return NGX_ERROR; | |
504 } | |
505 | |
506 buf[0] = 0x80; | |
507 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 7) - buf; | |
508 | |
509 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
510 ngx_http_v3_close_uni_stream(dc); | |
511 return NGX_ERROR; | |
512 } | |
513 | |
514 return NGX_OK; | |
515 } | |
516 | |
517 | |
518 ngx_int_t | |
519 ngx_http_v3_client_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id) | |
520 { | |
521 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
522 size_t n; | |
523 ngx_connection_t *dc; | |
524 | |
525 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
526 "http3 client cancel stream %ui", stream_id); | |
527 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
528 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 529 if (dc == NULL) { |
530 return NGX_ERROR; | |
531 } | |
532 | |
533 buf[0] = 0x40; | |
534 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 6) - buf; | |
535 | |
536 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
537 ngx_http_v3_close_uni_stream(dc); | |
538 return NGX_ERROR; | |
539 } | |
540 | |
541 return NGX_OK; | |
542 } | |
543 | |
544 | |
545 ngx_int_t | |
546 ngx_http_v3_client_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc) | |
547 { | |
548 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
549 size_t n; | |
550 ngx_connection_t *dc; | |
551 | |
552 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
553 "http3 client increment insert count %ui", inc); | |
554 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
555 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 556 if (dc == NULL) { |
557 return NGX_ERROR; | |
558 } | |
559 | |
560 buf[0] = 0; | |
561 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, inc, 6) - buf; | |
562 | |
563 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
564 ngx_http_v3_close_uni_stream(dc); | |
565 return NGX_ERROR; | |
566 } | |
567 | |
568 return NGX_OK; | |
569 } |