diff options
author | Roman Arutyunyan <arut@nginx.com> | 2020-11-10 20:42:45 +0000 |
---|---|---|
committer | Roman Arutyunyan <arut@nginx.com> | 2020-11-10 20:42:45 +0000 |
commit | eb8f476d599306507300a82b4a26d2a2476b748c (patch) | |
tree | 031017c8d7c046ae3d280143b6e497baa8328d84 /src | |
parent | 5bbc3f1967a8ac1cce0f16b428f156301b81beb9 (diff) | |
download | nginx-eb8f476d599306507300a82b4a26d2a2476b748c.tar.gz nginx-eb8f476d599306507300a82b4a26d2a2476b748c.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/http/modules/ngx_http_chunked_filter_module.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/src/http/modules/ngx_http_chunked_filter_module.c b/src/http/modules/ngx_http_chunked_filter_module.c index 87b032496..371559e2f 100644 --- 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_request_t *r, ngx_chain_t *in) 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_request_t *r, ngx_chain_t *in) *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_request_t *r, ngx_chain_t *in) 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_http_request_t *r, 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_http_request_t *r, 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; |