comparison src/http/v3/ngx_http_v3_tables.c @ 8215:38c0898b6df7 quic

HTTP/3.
author Roman Arutyunyan <arut@nginx.com>
date Fri, 13 Mar 2020 19:36:33 +0300
parents
children 268f4389130d
comparison
equal deleted inserted replaced
8214:6fd2cce50fe2 8215:38c0898b6df7
1
2 /*
3 * Copyright (C) Roman Arutyunyan
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_http.h>
11
12
13 static ngx_array_t *ngx_http_v3_get_dynamic_table(ngx_connection_t *c);
14 static ngx_int_t ngx_http_v3_new_header(ngx_connection_t *c);
15
16
17 static ngx_http_v3_header_t ngx_http_v3_static_table[] = {
18
19 { ngx_string(":authority"), ngx_string("") },
20 { ngx_string(":path"), ngx_string("/") },
21 { ngx_string("age"), ngx_string("0") },
22 { ngx_string("content-disposition"), ngx_string("") },
23 { ngx_string("content-length"), ngx_string("0") },
24 { ngx_string("cookie"), ngx_string("") },
25 { ngx_string("date"), ngx_string("") },
26 { ngx_string("etag"), ngx_string("") },
27 { ngx_string("if-modified-since"), ngx_string("") },
28 { ngx_string("if-none-match"), ngx_string("") },
29 { ngx_string("last-modified"), ngx_string("") },
30 { ngx_string("link"), ngx_string("") },
31 { ngx_string("location"), ngx_string("") },
32 { ngx_string("referer"), ngx_string("") },
33 { ngx_string("set-cookie"), ngx_string("") },
34 { ngx_string(":method"), ngx_string("CONNECT") },
35 { ngx_string(":method"), ngx_string("DELETE") },
36 { ngx_string(":method"), ngx_string("GET") },
37 { ngx_string(":method"), ngx_string("HEAD") },
38 { ngx_string(":method"), ngx_string("OPTIONS") },
39 { ngx_string(":method"), ngx_string("POST") },
40 { ngx_string(":method"), ngx_string("PUT") },
41 { ngx_string(":scheme"), ngx_string("http") },
42 { ngx_string(":scheme"), ngx_string("https") },
43 { ngx_string(":status"), ngx_string("103") },
44 { ngx_string(":status"), ngx_string("200") },
45 { ngx_string(":status"), ngx_string("304") },
46 { ngx_string(":status"), ngx_string("404") },
47 { ngx_string(":status"), ngx_string("503") },
48 { ngx_string("accept"), ngx_string("*/*") },
49 { ngx_string("accept"),
50 ngx_string("application/dns-message ") },
51 { ngx_string("accept-encoding"), ngx_string("gzip,") },
52 { ngx_string("accept-ranges"), ngx_string("bytes") },
53 { ngx_string("access-control-allow-headers"),
54 ngx_string("cache-control") },
55 { ngx_string("access-control-allow-headers"),
56 ngx_string("content-type") },
57 { ngx_string("access-control-allow-origin"),
58 ngx_string("*") },
59 { ngx_string("cache-control"), ngx_string("max-age=0") },
60 { ngx_string("cache-control"), ngx_string("max-age=2592000") },
61 { ngx_string("cache-control"), ngx_string("max-age=604800") },
62 { ngx_string("cache-control"), ngx_string("no-cache") },
63 { ngx_string("cache-control"), ngx_string("no-store") },
64 { ngx_string("cache-control"),
65 ngx_string("public, max-age=31536000 ") },
66 { ngx_string("content-encoding"), ngx_string("br") },
67 { ngx_string("content-encoding"), ngx_string("gzip") },
68 { ngx_string("content-type"),
69 ngx_string("application/dns-message") },
70 { ngx_string("content-type"),
71 ngx_string("application/javascript") },
72 { ngx_string("content-type"), ngx_string("application/json") },
73 { ngx_string("content-type"),
74 ngx_string("application/x-www-form-urlencoded") },
75 { ngx_string("content-type"), ngx_string("image/gif") },
76 { ngx_string("content-type"), ngx_string("image/jpeg") },
77 { ngx_string("content-type"), ngx_string("image/png") },
78 { ngx_string("content-type"), ngx_string("text/css") },
79 { ngx_string("content-type"),
80 ngx_string("text/html;charset=utf-8") },
81 { ngx_string("content-type"), ngx_string("text/plain") },
82 { ngx_string("content-type"),
83 ngx_string("text/plain;charset=utf-8") },
84 { ngx_string("range"), ngx_string("bytes=0-") },
85 { ngx_string("strict-transport-security"),
86 ngx_string("max-age=31536000") },
87 { ngx_string("strict-transport-security"),
88 ngx_string("max-age=31536000;includesubdomains") },
89 { ngx_string("strict-transport-security"),
90 ngx_string("max-age=31536000;includesubdomains;preload") },
91 { ngx_string("vary"), ngx_string("accept-encoding") },
92 { ngx_string("vary"), ngx_string("origin") },
93 { ngx_string("x-content-type-options"),ngx_string("nosniff") },
94 { ngx_string("x-xss-protection"), ngx_string("1;mode=block") },
95 { ngx_string(":status"), ngx_string("100") },
96 { ngx_string(":status"), ngx_string("204") },
97 { ngx_string(":status"), ngx_string("206") },
98 { ngx_string(":status"), ngx_string("302") },
99 { ngx_string(":status"), ngx_string("400") },
100 { ngx_string(":status"), ngx_string("403") },
101 { ngx_string(":status"), ngx_string("421") },
102 { ngx_string(":status"), ngx_string("425") },
103 { ngx_string(":status"), ngx_string("500") },
104 { ngx_string("accept-language"), ngx_string("") },
105 { ngx_string("access-control-allow-credentials"),
106 ngx_string("FALSE") },
107 { ngx_string("access-control-allow-credentials"),
108 ngx_string("TRUE") },
109 { ngx_string("access-control-allow-headers"),
110 ngx_string("*") },
111 { ngx_string("access-control-allow-methods"),
112 ngx_string("get") },
113 { ngx_string("access-control-allow-methods"),
114 ngx_string("get, post, options") },
115 { ngx_string("access-control-allow-methods"),
116 ngx_string("options") },
117 { ngx_string("access-control-expose-headers"),
118 ngx_string("content-length") },
119 { ngx_string("access-control-request-headers"),
120 ngx_string("content-type") },
121 { ngx_string("access-control-request-method"),
122 ngx_string("get") },
123 { ngx_string("access-control-request-method"),
124 ngx_string("post") },
125 { ngx_string("alt-svc"), ngx_string("clear") },
126 { ngx_string("horization"), ngx_string("") },
127 { ngx_string("content-security-policy"),
128 ngx_string("script-src") },
129 { ngx_string("early-data"), ngx_string("1") },
130 { ngx_string("expect-ct"), ngx_string("") },
131 { ngx_string("forwarded"), ngx_string("") },
132 { ngx_string("if-range"), ngx_string("") },
133 { ngx_string("origin"), ngx_string("") },
134 { ngx_string("purpose"), ngx_string("prefetch") },
135 { ngx_string("server"), ngx_string("") },
136 { ngx_string("timing-allow-origin"), ngx_string("*") },
137 { ngx_string("upgrade-insecure-requests"),
138 ngx_string("1") },
139 { ngx_string("user-agent"), ngx_string("") },
140 { ngx_string("x-forwarded-for"), ngx_string("") },
141 { ngx_string("x-frame-options"), ngx_string("deny") },
142 { ngx_string("x-frame-options"), ngx_string("sameorigin") }
143 };
144
145
146 ngx_int_t
147 ngx_http_v3_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic,
148 ngx_uint_t index, ngx_str_t *value)
149 {
150 ngx_array_t *dt;
151 ngx_http_v3_header_t *ref, *h;
152
153 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
154 "http3 ref insert %s[$ui] \"%V\"",
155 dynamic ? "dynamic" : "static", index, value);
156
157 ref = ngx_http_v3_lookup_table(c, dynamic, index);
158 if (ref == NULL) {
159 return NGX_ERROR;
160 }
161
162 dt = ngx_http_v3_get_dynamic_table(c);
163 if (dt == NULL) {
164 return NGX_ERROR;
165 }
166
167 h = ngx_array_push(dt);
168 if (h == NULL) {
169 return NGX_ERROR;
170 }
171
172 h->name = ref->name;
173 h->value = *value;
174
175 if (ngx_http_v3_new_header(c) != NGX_OK) {
176 return NGX_ERROR;
177 }
178
179 return NGX_OK;
180 }
181
182
183 ngx_int_t
184 ngx_http_v3_insert(ngx_connection_t *c, ngx_str_t *name,
185 ngx_str_t *value)
186 {
187 ngx_array_t *dt;
188 ngx_http_v3_header_t *h;
189
190 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
191 "http3 insert \"%V\":\"%V\"", name, value);
192
193 dt = ngx_http_v3_get_dynamic_table(c);
194 if (dt == NULL) {
195 return NGX_ERROR;
196 }
197
198 h = ngx_array_push(dt);
199 if (h == NULL) {
200 return NGX_ERROR;
201 }
202
203 h->name = *name;
204 h->value = *value;
205
206 if (ngx_http_v3_new_header(c) != NGX_OK) {
207 return NGX_ERROR;
208 }
209
210 return NGX_OK;
211 }
212
213
214 ngx_int_t
215 ngx_http_v3_set_capacity(ngx_connection_t *c, ngx_uint_t capacity)
216 {
217 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
218 "http3 set capacity %ui", capacity);
219
220 /* XXX ignore capacity */
221
222 return NGX_OK;
223 }
224
225
226 ngx_int_t
227 ngx_http_v3_duplicate(ngx_connection_t *c, ngx_uint_t index)
228 {
229 ngx_array_t *dt;
230 ngx_http_v3_header_t *ref, *h;
231
232 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 duplicate %ui", index);
233
234 ref = ngx_http_v3_lookup_table(c, 1, index);
235 if (ref == NULL) {
236 return NGX_ERROR;
237 }
238
239 dt = ngx_http_v3_get_dynamic_table(c);
240 if (dt == NULL) {
241 return NGX_ERROR;
242 }
243
244 h = ngx_array_push(dt);
245 if (h == NULL) {
246 return NGX_ERROR;
247 }
248
249 *h = *ref;
250
251 if (ngx_http_v3_new_header(c) != NGX_OK) {
252 return NGX_ERROR;
253 }
254
255 return NGX_OK;
256 }
257
258
259 ngx_int_t
260 ngx_http_v3_ack_header(ngx_connection_t *c, ngx_uint_t stream_id)
261 {
262 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
263 "http3 ack header %ui", stream_id);
264
265 /* XXX */
266
267 return NGX_OK;
268 }
269
270
271 ngx_int_t
272 ngx_http_v3_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id)
273 {
274 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
275 "http3 cancel stream %ui", stream_id);
276
277 /* XXX */
278
279 return NGX_OK;
280 }
281
282
283 ngx_int_t
284 ngx_http_v3_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc)
285 {
286 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
287 "http3 increment insert count %ui", inc);
288
289 /* XXX */
290
291 return NGX_OK;
292 }
293
294
295 static ngx_array_t *
296 ngx_http_v3_get_dynamic_table(ngx_connection_t *c)
297 {
298 ngx_connection_t *pc;
299 ngx_http_v3_connection_t *h3c;
300
301 pc = c->qs->parent;
302 h3c = pc->data;
303
304 if (h3c->dynamic) {
305 return h3c->dynamic;
306 }
307
308 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create dynamic table");
309
310 h3c->dynamic = ngx_array_create(pc->pool, 1, sizeof(ngx_http_v3_header_t));
311
312 return h3c->dynamic;
313 }
314
315
316 ngx_http_v3_header_t *
317 ngx_http_v3_lookup_table(ngx_connection_t *c, ngx_uint_t dynamic,
318 ngx_uint_t index)
319 {
320 ngx_uint_t nelts;
321 ngx_array_t *dt;
322 ngx_http_v3_header_t *table;
323
324 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 lookup %s[%ui]",
325 dynamic ? "dynamic" : "static", index);
326
327 if (dynamic) {
328 dt = ngx_http_v3_get_dynamic_table(c);
329 if (dt == NULL) {
330 return NULL;
331 }
332
333 table = dt->elts;
334 nelts = dt->nelts;
335
336 } else {
337 table = ngx_http_v3_static_table;
338 nelts = sizeof(ngx_http_v3_static_table)
339 / sizeof(ngx_http_v3_static_table[0]);
340 }
341
342 if (index >= nelts) {
343 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
344 "http3 lookup out of bounds: %ui", nelts);
345 return NULL;
346 }
347
348 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 lookup \"%V\":\"%V\"",
349 &table[index].name, &table[index].value);
350
351 return &table[index];
352 }
353
354
355 ngx_int_t
356 ngx_http_v3_check_insert_count(ngx_connection_t *c, ngx_uint_t insert_count)
357 {
358 size_t n;
359 ngx_http_v3_connection_t *h3c;
360
361 h3c = c->qs->parent->data;
362 n = h3c->dynamic ? h3c->dynamic->nelts : 0;
363
364 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
365 "http3 check insert count %ui/%ui", insert_count, n);
366
367 if (n < insert_count) {
368 /* XXX how to get notified? */
369 /* XXX wake all streams on any arrival to the encoder stream? */
370 return NGX_AGAIN;
371 }
372
373 return NGX_OK;
374 }
375
376
377 static ngx_int_t
378 ngx_http_v3_new_header(ngx_connection_t *c)
379 {
380 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 new dynamic header");
381
382 /* XXX report all waiting streams of a new header */
383
384 return NGX_OK;
385 }