Mercurial > hg > nginx
diff src/http/modules/ngx_http_chunked_filter_module.c @ 8292:46e3542d51b3 quic
Chunked response body in HTTP/3.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 27 Mar 2020 19:46:54 +0300 |
parents | 1b068a4e82d8 |
children | ef83990f0e25 |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_chunked_filter_module.c +++ b/src/http/modules/ngx_http_chunked_filter_module.c @@ -18,7 +18,7 @@ typedef struct { static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); static ngx_chain_t *ngx_http_chunked_create_trailers(ngx_http_request_t *r, - ngx_http_chunked_filter_ctx_t *ctx); + ngx_http_chunked_filter_ctx_t *ctx, size_t size); static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { @@ -106,6 +106,7 @@ ngx_http_chunked_body_filter(ngx_http_re { u_char *chunk; off_t size; + size_t n; ngx_int_t rc; ngx_buf_t *b; ngx_chain_t *out, *cl, *tl, **ll; @@ -161,29 +162,50 @@ ngx_http_chunked_body_filter(ngx_http_re chunk = b->start; if (chunk == NULL) { - /* the "0000000000000000" is 64-bit hexadecimal string */ + +#if (NGX_HTTP_V3) + if (r->http_version == NGX_HTTP_VERSION_30) { + n = NGX_HTTP_V3_VARLEN_INT_LEN * 2; - chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1); + } else +#endif + { + /* the "0000000000000000" is 64-bit hexadecimal string */ + n = sizeof("0000000000000000" CRLF) - 1; + } + + chunk = ngx_palloc(r->pool, n); if (chunk == NULL) { return NGX_ERROR; } b->start = chunk; - b->end = chunk + sizeof("0000000000000000" CRLF) - 1; + b->end = chunk + n; } b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module; b->memory = 0; b->temporary = 1; b->pos = chunk; - b->last = ngx_sprintf(chunk, "%xO" CRLF, size); + +#if (NGX_HTTP_V3) + if (r->http_version == NGX_HTTP_VERSION_30) { + b->last = (u_char *) ngx_http_v3_encode_varlen_int(chunk, + NGX_HTTP_V3_FRAME_DATA); + b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, size); + + } else +#endif + { + b->last = ngx_sprintf(chunk, "%xO" CRLF, size); + } tl->next = out; out = tl; } if (cl->buf->last_buf) { - tl = ngx_http_chunked_create_trailers(r, ctx); + tl = ngx_http_chunked_create_trailers(r, ctx, size); if (tl == NULL) { return NGX_ERROR; } @@ -192,11 +214,12 @@ ngx_http_chunked_body_filter(ngx_http_re *ll = tl; - if (size == 0) { - tl->buf->pos += 2; - } - - } else if (size > 0) { + } else if (size > 0 +#if (NGX_HTTP_V3) + && r->http_version != NGX_HTTP_VERSION_30 +#endif + ) + { tl = ngx_chain_get_free_buf(r->pool, &ctx->free); if (tl == NULL) { return NGX_ERROR; @@ -227,7 +250,7 @@ ngx_http_chunked_body_filter(ngx_http_re static ngx_chain_t * ngx_http_chunked_create_trailers(ngx_http_request_t *r, - ngx_http_chunked_filter_ctx_t *ctx) + ngx_http_chunked_filter_ctx_t *ctx, size_t size) { size_t len; ngx_buf_t *b; @@ -236,6 +259,12 @@ ngx_http_chunked_create_trailers(ngx_htt ngx_list_part_t *part; ngx_table_elt_t *header; +#if (NGX_HTTP_V3) + if (r->http_version == NGX_HTTP_VERSION_30) { + return ngx_http_v3_create_trailers(r); + } +#endif + len = 0; part = &r->headers_out.trailers.part; @@ -288,7 +317,10 @@ ngx_http_chunked_create_trailers(ngx_htt b->last = b->pos; - *b->last++ = CR; *b->last++ = LF; + if (size > 0) { + *b->last++ = CR; *b->last++ = LF; + } + *b->last++ = '0'; *b->last++ = CR; *b->last++ = LF;