aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2020-11-10 20:42:45 +0000
committerRoman Arutyunyan <arut@nginx.com>2020-11-10 20:42:45 +0000
commiteb8f476d599306507300a82b4a26d2a2476b748c (patch)
tree031017c8d7c046ae3d280143b6e497baa8328d84 /src
parent5bbc3f1967a8ac1cce0f16b428f156301b81beb9 (diff)
downloadnginx-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.c45
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;