Mercurial > hg > nginx-quic
comparison src/http/v3/ngx_http_v3_filter_module.c @ 8542:8e8cdb7bfb17 quic
HTTP/3: response trailers support.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 13 Jul 2021 22:44:03 +0300 |
parents | 0ac25efb2da3 |
children | 07f90cb79fec |
comparison
equal
deleted
inserted
replaced
8541:7f29db5294bd | 8542:8e8cdb7bfb17 |
---|---|
47 static void ngx_http_v3_push_request_handler(ngx_event_t *ev); | 47 static void ngx_http_v3_push_request_handler(ngx_event_t *ev); |
48 static ngx_chain_t *ngx_http_v3_create_push_promise(ngx_http_request_t *r, | 48 static ngx_chain_t *ngx_http_v3_create_push_promise(ngx_http_request_t *r, |
49 ngx_str_t *path, uint64_t push_id); | 49 ngx_str_t *path, uint64_t push_id); |
50 static ngx_int_t ngx_http_v3_body_filter(ngx_http_request_t *r, | 50 static ngx_int_t ngx_http_v3_body_filter(ngx_http_request_t *r, |
51 ngx_chain_t *in); | 51 ngx_chain_t *in); |
52 static ngx_chain_t *ngx_http_v3_create_trailers(ngx_http_request_t *r); | 52 static ngx_chain_t *ngx_http_v3_create_trailers(ngx_http_request_t *r, |
53 ngx_http_v3_filter_ctx_t *ctx); | |
53 static ngx_int_t ngx_http_v3_filter_init(ngx_conf_t *cf); | 54 static ngx_int_t ngx_http_v3_filter_init(ngx_conf_t *cf); |
54 | 55 |
55 | 56 |
56 static ngx_http_module_t ngx_http_v3_filter_module_ctx = { | 57 static ngx_http_module_t ngx_http_v3_filter_module_ctx = { |
57 NULL, /* preconfiguration */ | 58 NULL, /* preconfiguration */ |
513 hl->next = cl; | 514 hl->next = cl; |
514 | 515 |
515 *ll = hl; | 516 *ll = hl; |
516 ll = &cl->next; | 517 ll = &cl->next; |
517 | 518 |
518 if (r->headers_out.content_length_n >= 0 && !r->header_only) { | 519 if (r->headers_out.content_length_n >= 0 |
520 && !r->header_only && !r->expect_trailers) | |
521 { | |
519 len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_DATA) | 522 len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_DATA) |
520 + ngx_http_v3_encode_varlen_int(NULL, | 523 + ngx_http_v3_encode_varlen_int(NULL, |
521 r->headers_out.content_length_n); | 524 r->headers_out.content_length_n); |
522 | 525 |
523 b = ngx_create_temp_buf(c->pool, len); | 526 b = ngx_create_temp_buf(c->pool, len); |
1301 tl->next = out; | 1304 tl->next = out; |
1302 out = tl; | 1305 out = tl; |
1303 } | 1306 } |
1304 | 1307 |
1305 if (cl->buf->last_buf) { | 1308 if (cl->buf->last_buf) { |
1306 tl = ngx_http_v3_create_trailers(r); | 1309 tl = ngx_http_v3_create_trailers(r, ctx); |
1307 if (tl == NULL) { | 1310 if (tl == NULL) { |
1308 return NGX_ERROR; | 1311 return NGX_ERROR; |
1309 } | 1312 } |
1310 | 1313 |
1311 cl->buf->last_buf = 0; | 1314 cl->buf->last_buf = 0; |
1324 return rc; | 1327 return rc; |
1325 } | 1328 } |
1326 | 1329 |
1327 | 1330 |
1328 static ngx_chain_t * | 1331 static ngx_chain_t * |
1329 ngx_http_v3_create_trailers(ngx_http_request_t *r) | 1332 ngx_http_v3_create_trailers(ngx_http_request_t *r, |
1333 ngx_http_v3_filter_ctx_t *ctx) | |
1330 { | 1334 { |
1331 ngx_buf_t *b; | 1335 size_t len, n; |
1332 ngx_chain_t *cl; | 1336 u_char *p; |
1333 | 1337 ngx_buf_t *b; |
1334 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1338 ngx_uint_t i; |
1335 "http3 create trailers"); | 1339 ngx_chain_t *cl, *hl; |
1336 | 1340 ngx_list_part_t *part; |
1337 /* XXX */ | 1341 ngx_table_elt_t *header; |
1338 | 1342 |
1339 b = ngx_calloc_buf(r->pool); | 1343 len = 0; |
1340 if (b == NULL) { | 1344 |
1341 return NULL; | 1345 part = &r->headers_out.trailers.part; |
1342 } | 1346 header = part->elts; |
1343 | 1347 |
1344 b->last_buf = 1; | 1348 for (i = 0; /* void */; i++) { |
1345 | 1349 |
1346 cl = ngx_alloc_chain_link(r->pool); | 1350 if (i >= part->nelts) { |
1351 if (part->next == NULL) { | |
1352 break; | |
1353 } | |
1354 | |
1355 part = part->next; | |
1356 header = part->elts; | |
1357 i = 0; | |
1358 } | |
1359 | |
1360 if (header[i].hash == 0) { | |
1361 continue; | |
1362 } | |
1363 | |
1364 len += ngx_http_v3_encode_field_l(NULL, &header[i].key, | |
1365 &header[i].value); | |
1366 } | |
1367 | |
1368 cl = ngx_chain_get_free_buf(r->pool, &ctx->free); | |
1347 if (cl == NULL) { | 1369 if (cl == NULL) { |
1348 return NULL; | 1370 return NULL; |
1349 } | 1371 } |
1350 | 1372 |
1351 cl->buf = b; | 1373 b = cl->buf; |
1352 cl->next = NULL; | 1374 |
1353 | 1375 b->tag = (ngx_buf_tag_t) &ngx_http_v3_filter_module; |
1354 return cl; | 1376 b->memory = 0; |
1377 b->last_buf = 1; | |
1378 | |
1379 if (len == 0) { | |
1380 b->temporary = 0; | |
1381 b->pos = b->last = NULL; | |
1382 return cl; | |
1383 } | |
1384 | |
1385 b->temporary = 1; | |
1386 | |
1387 len += ngx_http_v3_encode_field_section_prefix(NULL, 0, 0, 0); | |
1388 | |
1389 b->pos = ngx_palloc(r->pool, len); | |
1390 if (b->pos == NULL) { | |
1391 return NULL; | |
1392 } | |
1393 | |
1394 b->last = (u_char *) ngx_http_v3_encode_field_section_prefix(b->pos, | |
1395 0, 0, 0); | |
1396 | |
1397 part = &r->headers_out.trailers.part; | |
1398 header = part->elts; | |
1399 | |
1400 for (i = 0; /* void */; i++) { | |
1401 | |
1402 if (i >= part->nelts) { | |
1403 if (part->next == NULL) { | |
1404 break; | |
1405 } | |
1406 | |
1407 part = part->next; | |
1408 header = part->elts; | |
1409 i = 0; | |
1410 } | |
1411 | |
1412 if (header[i].hash == 0) { | |
1413 continue; | |
1414 } | |
1415 | |
1416 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1417 "http3 trailer: \"%V: %V\"", | |
1418 &header[i].key, &header[i].value); | |
1419 | |
1420 b->last = (u_char *) ngx_http_v3_encode_field_l(b->last, | |
1421 &header[i].key, | |
1422 &header[i].value); | |
1423 } | |
1424 | |
1425 n = b->last - b->pos; | |
1426 | |
1427 hl = ngx_chain_get_free_buf(r->pool, &ctx->free); | |
1428 if (hl == NULL) { | |
1429 return NULL; | |
1430 } | |
1431 | |
1432 b = hl->buf; | |
1433 p = b->start; | |
1434 | |
1435 if (p == NULL) { | |
1436 p = ngx_palloc(r->pool, NGX_HTTP_V3_VARLEN_INT_LEN * 2); | |
1437 if (p == NULL) { | |
1438 return NULL; | |
1439 } | |
1440 | |
1441 b->start = p; | |
1442 b->end = p + NGX_HTTP_V3_VARLEN_INT_LEN * 2; | |
1443 } | |
1444 | |
1445 b->tag = (ngx_buf_tag_t) &ngx_http_v3_filter_module; | |
1446 b->memory = 0; | |
1447 b->temporary = 1; | |
1448 b->pos = p; | |
1449 | |
1450 b->last = (u_char *) ngx_http_v3_encode_varlen_int(p, | |
1451 NGX_HTTP_V3_FRAME_HEADERS); | |
1452 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, n); | |
1453 | |
1454 hl->next = cl; | |
1455 | |
1456 return hl; | |
1355 } | 1457 } |
1356 | 1458 |
1357 | 1459 |
1358 static ngx_int_t | 1460 static ngx_int_t |
1359 ngx_http_v3_filter_init(ngx_conf_t *cf) | 1461 ngx_http_v3_filter_init(ngx_conf_t *cf) |