Mercurial > hg > nginx-quic
annotate src/http/v3/ngx_http_v3_streams.c @ 8010:65c1fc5fae15 quic
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Now they are similar to HTTP/2 where they are called h2scf.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 23 Jul 2020 13:12:01 +0300 |
parents | 0d2b2664b41c |
children | 455a8536eaa7 |
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); |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
30 static ngx_int_t ngx_http_v3_send_settings(ngx_connection_t *c); |
7681 | 31 |
32 | |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
33 ngx_int_t |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
34 ngx_http_v3_init_connection(ngx_connection_t *c) |
7681 | 35 { |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
36 ngx_http_connection_t *hc; |
7681 | 37 ngx_http_v3_uni_stream_t *us; |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
38 ngx_http_v3_connection_t *h3c; |
7681 | 39 |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
40 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init connection"); |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
41 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
42 hc = c->data; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
43 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
44 if (c->qs == NULL) { |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
45 h3c = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_connection_t)); |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
46 if (h3c == NULL) { |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
47 return NGX_ERROR; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
48 } |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
49 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
50 h3c->hc = *hc; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
51 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
52 ngx_queue_init(&h3c->blocked); |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
53 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
54 c->data = h3c; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
55 return NGX_OK; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
56 } |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
57 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
58 h3c = c->qs->parent->data; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
59 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
60 if (!h3c->settings_sent) { |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
61 h3c->settings_sent = 1; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
62 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
63 if (ngx_http_v3_send_settings(c) != NGX_OK) { |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
64 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
65 "could not send settings"); |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
66 return NGX_ERROR; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
67 } |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
68 } |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
69 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
70 if ((c->qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0) { |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
71 return NGX_OK; |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
72 } |
7681 | 73 |
74 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t)); | |
75 if (us == NULL) { | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
76 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
77 NULL); |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
78 return NGX_ERROR; |
7681 | 79 } |
80 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
81 us->index = -1; |
7681 | 82 |
83 c->data = us; | |
84 | |
85 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
|
86 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
|
87 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
88 ngx_http_v3_read_uni_stream_type(c->read); |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
89 |
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
90 return NGX_DONE; |
7681 | 91 } |
92 | |
93 | |
94 static void | |
95 ngx_http_v3_close_uni_stream(ngx_connection_t *c) | |
96 { | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
97 ngx_pool_t *pool; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
98 ngx_http_v3_connection_t *h3c; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
99 ngx_http_v3_uni_stream_t *us; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
100 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
101 us = c->data; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
102 h3c = c->qs->parent->data; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
103 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
104 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
|
105 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
106 if (us->index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
107 h3c->known_streams[us->index] = NULL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
108 } |
7681 | 109 |
110 c->destroyed = 1; | |
111 | |
112 pool = c->pool; | |
113 | |
114 ngx_close_connection(c); | |
115 | |
116 ngx_destroy_pool(pool); | |
117 } | |
118 | |
119 | |
120 static void | |
121 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) | |
122 { | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
123 u_char ch; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
124 ssize_t n; |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
125 ngx_int_t index, rc; |
7681 | 126 ngx_connection_t *c; |
127 ngx_http_v3_connection_t *h3c; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
128 ngx_http_v3_uni_stream_t *us; |
7681 | 129 |
130 c = rev->data; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
131 us = c->data; |
7681 | 132 h3c = c->qs->parent->data; |
133 | |
134 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type"); | |
135 | |
136 while (rev->ready) { | |
137 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
138 n = c->recv(c, &ch, 1); |
7681 | 139 |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
140 if (n == NGX_AGAIN) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
141 break; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
142 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
143 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
144 if (n == 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
145 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; |
7681 | 146 goto failed; |
147 } | |
148 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
149 if (n != 1) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
150 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
151 goto failed; |
7681 | 152 } |
153 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
154 switch (ch) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
155 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
156 case NGX_HTTP_V3_STREAM_ENCODER: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
157 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
158 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
159 "http3 encoder stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
160 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
161 index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
162 us->handler = ngx_http_v3_parse_encoder; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
163 n = sizeof(ngx_http_v3_parse_encoder_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
164 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
165 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
166 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
167 case NGX_HTTP_V3_STREAM_DECODER: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
168 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
169 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
170 "http3 decoder stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
171 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
172 index = NGX_HTTP_V3_STREAM_CLIENT_DECODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
173 us->handler = ngx_http_v3_parse_decoder; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
174 n = sizeof(ngx_http_v3_parse_decoder_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
175 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
176 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
177 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
178 case NGX_HTTP_V3_STREAM_CONTROL: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
179 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
180 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
181 "http3 control stream"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
182 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
183 index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
184 us->handler = ngx_http_v3_parse_control; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
185 n = sizeof(ngx_http_v3_parse_control_t); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
186 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
187 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
188 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
189 default: |
7681 | 190 |
191 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
|
192 "http3 stream 0x%02xi", (ngx_int_t) ch); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
193 index = -1; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
194 n = 0; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
195 } |
7681 | 196 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
197 if (index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
198 if (h3c->known_streams[index]) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
199 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists"); |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
200 rc = NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
201 goto failed; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
202 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
203 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
204 us->index = index; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
205 h3c->known_streams[index] = c; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
206 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
207 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
208 if (n) { |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
209 us->data = ngx_pcalloc(c->pool, n); |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
210 if (us->data == NULL) { |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
211 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
212 goto failed; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
213 } |
7681 | 214 } |
215 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
216 rev->handler = ngx_http_v3_uni_read_handler; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
217 ngx_http_v3_uni_read_handler(rev); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
218 return; |
7681 | 219 } |
220 | |
221 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
222 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7681 | 223 goto failed; |
224 } | |
225 | |
226 return; | |
227 | |
228 failed: | |
229 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
230 ngx_http_v3_finalize_connection(c, rc, "could not read stream type"); |
7681 | 231 ngx_http_v3_close_uni_stream(c); |
232 } | |
233 | |
234 | |
235 static void | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
236 ngx_http_v3_uni_read_handler(ngx_event_t *rev) |
7681 | 237 { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
238 u_char buf[128]; |
7681 | 239 ssize_t n; |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
240 ngx_int_t rc, i; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
241 ngx_connection_t *c; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
242 ngx_http_v3_uni_stream_t *us; |
7681 | 243 |
244 c = rev->data; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
245 us = c->data; |
7681 | 246 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
247 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler"); |
7681 | 248 |
249 while (rev->ready) { | |
250 | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
251 n = c->recv(c, buf, sizeof(buf)); |
7681 | 252 |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
253 if (n == NGX_ERROR) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
254 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7681 | 255 goto failed; |
256 } | |
257 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
258 if (n == 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
259 if (us->index >= 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
260 rc = NGX_HTTP_V3_ERR_CLOSED_CRITICAL_STREAM; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
261 goto failed; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
262 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
263 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
264 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read eof"); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
265 ngx_http_v3_close_uni_stream(c); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
266 return; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
267 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
268 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
269 if (n == NGX_AGAIN) { |
7681 | 270 break; |
271 } | |
272 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
273 if (us->handler == NULL) { |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
274 continue; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
275 } |
7681 | 276 |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
277 for (i = 0; i < n; i++) { |
7681 | 278 |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
279 rc = us->handler(c, us->data, buf[i]); |
7681 | 280 |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
281 if (rc == NGX_DONE) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
282 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
283 "http3 read done"); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
284 ngx_http_v3_close_uni_stream(c); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
285 return; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
286 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
287 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
288 if (rc > 0) { |
7681 | 289 goto failed; |
290 } | |
291 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
292 if (rc != NGX_AGAIN) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
293 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
294 goto failed; |
7681 | 295 } |
296 } | |
297 } | |
298 | |
299 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
300 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
7681 | 301 goto failed; |
302 } | |
303 | |
304 return; | |
305 | |
306 failed: | |
307 | |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
308 ngx_http_v3_finalize_connection(c, rc, "stream error"); |
7681 | 309 ngx_http_v3_close_uni_stream(c); |
310 } | |
311 | |
312 | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
313 static void |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
314 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
|
315 { |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
316 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
|
317 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
318 c = wev->data; |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
319 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
320 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
|
321 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
322 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
7955
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
323 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
7951
diff
changeset
|
324 NULL); |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
325 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
|
326 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
327 } |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
328 |
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
329 |
7681 | 330 /* XXX async & buffered stream writes */ |
331 | |
332 static ngx_connection_t * | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
333 ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type) |
7681 | 334 { |
335 u_char buf[NGX_HTTP_V3_VARLEN_INT_LEN]; | |
336 size_t n; | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
337 ngx_int_t index; |
7681 | 338 ngx_connection_t *sc; |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
339 ngx_http_v3_connection_t *h3c; |
7681 | 340 ngx_http_v3_uni_stream_t *us; |
341 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
342 switch (type) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
343 case NGX_HTTP_V3_STREAM_ENCODER: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
344 index = NGX_HTTP_V3_STREAM_SERVER_ENCODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
345 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
346 case NGX_HTTP_V3_STREAM_DECODER: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
347 index = NGX_HTTP_V3_STREAM_SERVER_DECODER; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
348 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
349 case NGX_HTTP_V3_STREAM_CONTROL: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
350 index = NGX_HTTP_V3_STREAM_SERVER_CONTROL; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
351 break; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
352 default: |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
353 index = -1; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
354 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
355 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
356 h3c = c->qs->parent->data; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
357 |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
358 if (index >= 0) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
359 if (h3c->known_streams[index]) { |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
360 return h3c->known_streams[index]; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
361 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
362 } |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
363 |
7694
ac41c53e446d
Fixed HTTP/3 server stream creation.
Roman Arutyunyan <arut@nginx.com>
parents:
7692
diff
changeset
|
364 sc = ngx_quic_create_uni_stream(c); |
7681 | 365 if (sc == NULL) { |
366 return NULL; | |
367 } | |
368 | |
369 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
370 "http3 create uni stream, type:%ui", type); | |
371 | |
372 us = ngx_pcalloc(sc->pool, sizeof(ngx_http_v3_uni_stream_t)); | |
373 if (us == NULL) { | |
374 goto failed; | |
375 } | |
376 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
377 us->index = index; |
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
378 |
7681 | 379 sc->data = us; |
380 | |
7747
618a65de08b3
When closing a QUIC connection, wait for all streams to finish.
Roman Arutyunyan <arut@nginx.com>
parents:
7694
diff
changeset
|
381 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
|
382 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
|
383 |
7880
c101438c69a4
HTTP/3: prevent array access by negative index for unknown streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7839
diff
changeset
|
384 if (index >= 0) { |
c101438c69a4
HTTP/3: prevent array access by negative index for unknown streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7839
diff
changeset
|
385 h3c->known_streams[index] = sc; |
c101438c69a4
HTTP/3: prevent array access by negative index for unknown streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7839
diff
changeset
|
386 } |
7681 | 387 |
388 n = (u_char *) ngx_http_v3_encode_varlen_int(buf, type) - buf; | |
389 | |
390 if (sc->send(sc, buf, n) != (ssize_t) n) { | |
391 goto failed; | |
392 } | |
393 | |
394 return sc; | |
395 | |
396 failed: | |
397 | |
398 ngx_http_v3_close_uni_stream(sc); | |
399 | |
400 return NULL; | |
401 } | |
402 | |
403 | |
7999
0d2b2664b41c
QUIC: added "quic" listen parameter.
Roman Arutyunyan <arut@nginx.com>
parents:
7955
diff
changeset
|
404 static ngx_int_t |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
405 ngx_http_v3_send_settings(ngx_connection_t *c) |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
406 { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
407 u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 6]; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
408 size_t n; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
409 ngx_connection_t *cc; |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
410 ngx_http_v3_srv_conf_t *h3scf; |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
411 ngx_http_v3_connection_t *h3c; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
412 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
413 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send settings"); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
414 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
415 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
416 if (cc == NULL) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
417 return NGX_ERROR; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
418 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
419 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
420 h3c = c->qs->parent->data; |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
421 h3scf = ngx_http_get_module_srv_conf(h3c->hc.conf_ctx, ngx_http_v3_module); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
422 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
423 n = ngx_http_v3_encode_varlen_int(NULL, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
424 NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
425 n += ngx_http_v3_encode_varlen_int(NULL, h3scf->max_table_capacity); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
426 n += ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_PARAM_BLOCKED_STREAMS); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
427 n += ngx_http_v3_encode_varlen_int(NULL, h3scf->max_blocked_streams); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
428 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
429 p = (u_char *) ngx_http_v3_encode_varlen_int(buf, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
430 NGX_HTTP_V3_FRAME_SETTINGS); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
431 p = (u_char *) ngx_http_v3_encode_varlen_int(p, n); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
432 p = (u_char *) ngx_http_v3_encode_varlen_int(p, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
433 NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
434 p = (u_char *) ngx_http_v3_encode_varlen_int(p, h3scf->max_table_capacity); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
435 p = (u_char *) ngx_http_v3_encode_varlen_int(p, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
436 NGX_HTTP_V3_PARAM_BLOCKED_STREAMS); |
8010
65c1fc5fae15
HTTP/3: renamed server configuration variables from v3cf to h3scf.
Roman Arutyunyan <arut@nginx.com>
parents:
7999
diff
changeset
|
437 p = (u_char *) ngx_http_v3_encode_varlen_int(p, h3scf->max_blocked_streams); |
7951
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
438 n = p - buf; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
439 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
440 if (cc->send(cc, buf, n) != (ssize_t) n) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
441 goto failed; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
442 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
443 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
444 return NGX_OK; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
445 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
446 failed: |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
447 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
448 ngx_http_v3_close_uni_stream(cc); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
449 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
450 return NGX_ERROR; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
451 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
452 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
453 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
7880
diff
changeset
|
454 ngx_int_t |
7681 | 455 ngx_http_v3_client_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic, |
456 ngx_uint_t index, ngx_str_t *value) | |
457 { | |
458 u_char *p, buf[NGX_HTTP_V3_PREFIX_INT_LEN * 2]; | |
459 size_t n; | |
460 ngx_connection_t *ec; | |
461 | |
462 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
463 "http3 client ref insert, %s[%ui] \"%V\"", | |
464 dynamic ? "dynamic" : "static", index, value); | |
465 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
466 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 467 if (ec == NULL) { |
468 return NGX_ERROR; | |
469 } | |
470 | |
471 p = buf; | |
472 | |
473 *p = (dynamic ? 0x80 : 0xc0); | |
474 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 6); | |
475 | |
476 /* XXX option for huffman? */ | |
477 *p = 0; | |
478 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); | |
479 | |
480 n = p - buf; | |
481 | |
482 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
483 goto failed; | |
484 } | |
485 | |
486 if (ec->send(ec, value->data, value->len) != (ssize_t) value->len) { | |
487 goto failed; | |
488 } | |
489 | |
490 return NGX_OK; | |
491 | |
492 failed: | |
493 | |
494 ngx_http_v3_close_uni_stream(ec); | |
495 | |
496 return NGX_ERROR; | |
497 } | |
498 | |
499 | |
500 ngx_int_t | |
501 ngx_http_v3_client_insert(ngx_connection_t *c, ngx_str_t *name, | |
502 ngx_str_t *value) | |
503 { | |
504 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
505 size_t n; | |
506 ngx_connection_t *ec; | |
507 | |
508 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
509 "http3 client insert \"%V\":\"%V\"", name, value); | |
510 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
511 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 512 if (ec == NULL) { |
513 return NGX_ERROR; | |
514 } | |
515 | |
516 /* XXX option for huffman? */ | |
517 buf[0] = 0x40; | |
518 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, name->len, 5) - buf; | |
519 | |
520 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
521 goto failed; | |
522 } | |
523 | |
524 if (ec->send(ec, name->data, name->len) != (ssize_t) name->len) { | |
525 goto failed; | |
526 } | |
527 | |
528 /* XXX option for huffman? */ | |
529 buf[0] = 0; | |
530 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, value->len, 7) - buf; | |
531 | |
532 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
533 goto failed; | |
534 } | |
535 | |
536 if (ec->send(ec, value->data, value->len) != (ssize_t) value->len) { | |
537 goto failed; | |
538 } | |
539 | |
540 return NGX_OK; | |
541 | |
542 failed: | |
543 | |
544 ngx_http_v3_close_uni_stream(ec); | |
545 | |
546 return NGX_ERROR; | |
547 } | |
548 | |
549 | |
550 ngx_int_t | |
551 ngx_http_v3_client_set_capacity(ngx_connection_t *c, ngx_uint_t capacity) | |
552 { | |
553 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
554 size_t n; | |
555 ngx_connection_t *ec; | |
556 | |
557 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
558 "http3 client set capacity %ui", capacity); | |
559 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
560 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 561 if (ec == NULL) { |
562 return NGX_ERROR; | |
563 } | |
564 | |
565 buf[0] = 0x20; | |
566 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, capacity, 5) - buf; | |
567 | |
568 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
569 ngx_http_v3_close_uni_stream(ec); | |
570 return NGX_ERROR; | |
571 } | |
572 | |
573 return NGX_OK; | |
574 } | |
575 | |
576 | |
577 ngx_int_t | |
578 ngx_http_v3_client_duplicate(ngx_connection_t *c, ngx_uint_t index) | |
579 { | |
580 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
581 size_t n; | |
582 ngx_connection_t *ec; | |
583 | |
584 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
585 "http3 client duplicate %ui", index); | |
586 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
587 ec = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_ENCODER); |
7681 | 588 if (ec == NULL) { |
589 return NGX_ERROR; | |
590 } | |
591 | |
592 buf[0] = 0; | |
593 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, index, 5) - buf; | |
594 | |
595 if (ec->send(ec, buf, n) != (ssize_t) n) { | |
596 ngx_http_v3_close_uni_stream(ec); | |
597 return NGX_ERROR; | |
598 } | |
599 | |
600 return NGX_OK; | |
601 } | |
602 | |
603 | |
604 ngx_int_t | |
605 ngx_http_v3_client_ack_header(ngx_connection_t *c, ngx_uint_t stream_id) | |
606 { | |
607 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
608 size_t n; | |
609 ngx_connection_t *dc; | |
610 | |
611 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
612 "http3 client ack header %ui", stream_id); | |
613 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
614 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 615 if (dc == NULL) { |
616 return NGX_ERROR; | |
617 } | |
618 | |
619 buf[0] = 0x80; | |
620 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 7) - buf; | |
621 | |
622 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
623 ngx_http_v3_close_uni_stream(dc); | |
624 return NGX_ERROR; | |
625 } | |
626 | |
627 return NGX_OK; | |
628 } | |
629 | |
630 | |
631 ngx_int_t | |
632 ngx_http_v3_client_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id) | |
633 { | |
634 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
635 size_t n; | |
636 ngx_connection_t *dc; | |
637 | |
638 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
639 "http3 client cancel stream %ui", stream_id); | |
640 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
641 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 642 if (dc == NULL) { |
643 return NGX_ERROR; | |
644 } | |
645 | |
646 buf[0] = 0x40; | |
647 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, stream_id, 6) - buf; | |
648 | |
649 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
650 ngx_http_v3_close_uni_stream(dc); | |
651 return NGX_ERROR; | |
652 } | |
653 | |
654 return NGX_OK; | |
655 } | |
656 | |
657 | |
658 ngx_int_t | |
659 ngx_http_v3_client_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc) | |
660 { | |
661 u_char buf[NGX_HTTP_V3_PREFIX_INT_LEN]; | |
662 size_t n; | |
663 ngx_connection_t *dc; | |
664 | |
665 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
666 "http3 client increment insert count %ui", inc); | |
667 | |
7749
dadbc66e9fca
Simplifed handling HTTP/3 streams.
Roman Arutyunyan <arut@nginx.com>
parents:
7747
diff
changeset
|
668 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
7681 | 669 if (dc == NULL) { |
670 return NGX_ERROR; | |
671 } | |
672 | |
673 buf[0] = 0; | |
674 n = (u_char *) ngx_http_v3_encode_prefix_int(buf, inc, 6) - buf; | |
675 | |
676 if (dc->send(dc, buf, n) != (ssize_t) n) { | |
677 ngx_http_v3_close_uni_stream(dc); | |
678 return NGX_ERROR; | |
679 } | |
680 | |
681 return NGX_OK; | |
682 } |