# HG changeset patch # User Roman Arutyunyan # Date 1605040965 0 # Node ID ef83990f0e25f6143f1211a524e99c5a821ea3ac # Parent 831d1960826f2de7958a5d9d2f0462e23ff63def Fixed generating chunked response after 46e3542d51b3. If trailers were missing and a chain carrying the last_buf flag had no data in it, then last HTTP/1 chunk was broken. The problem was introduced while implementing HTTP/3 response body generation. The change fixes the issue and reduces diff to the mainline nginx. diff --git a/src/http/modules/ngx_http_chunked_filter_module.c b/src/http/modules/ngx_http_chunked_filter_module.c --- 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, size_t size); + ngx_http_chunked_filter_ctx_t *ctx); static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { @@ -204,8 +204,25 @@ ngx_http_chunked_body_filter(ngx_http_re out = tl; } +#if (NGX_HTTP_V3) + if (r->http_version == NGX_HTTP_VERSION_30) { + + if (cl->buf->last_buf) { + tl = ngx_http_v3_create_trailers(r); + if (tl == NULL) { + return NGX_ERROR; + } + + cl->buf->last_buf = 0; + + *ll = tl; + } + + } else +#endif + if (cl->buf->last_buf) { - tl = ngx_http_chunked_create_trailers(r, ctx, size); + tl = ngx_http_chunked_create_trailers(r, ctx); if (tl == NULL) { return NGX_ERROR; } @@ -214,12 +231,11 @@ ngx_http_chunked_body_filter(ngx_http_re *ll = tl; - } else if (size > 0 -#if (NGX_HTTP_V3) - && r->http_version != NGX_HTTP_VERSION_30 -#endif - ) - { + if (size == 0) { + tl->buf->pos += 2; + } + + } else if (size > 0) { tl = ngx_chain_get_free_buf(r->pool, &ctx->free); if (tl == NULL) { return NGX_ERROR; @@ -250,7 +266,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, size_t size) + ngx_http_chunked_filter_ctx_t *ctx) { size_t len; ngx_buf_t *b; @@ -259,12 +275,6 @@ 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; @@ -317,10 +327,7 @@ ngx_http_chunked_create_trailers(ngx_htt b->last = b->pos; - if (size > 0) { - *b->last++ = CR; *b->last++ = LF; - } - + *b->last++ = CR; *b->last++ = LF; *b->last++ = '0'; *b->last++ = CR; *b->last++ = LF;