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