Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_chunked_filter_module.c @ 8205:ef83990f0e25 quic
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.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 10 Nov 2020 20:42:45 +0000 |
parents | 46e3542d51b3 |
children | b80d9179ba2a |
comparison
equal
deleted
inserted
replaced
8204:831d1960826f | 8205:ef83990f0e25 |
---|---|
16 } ngx_http_chunked_filter_ctx_t; | 16 } ngx_http_chunked_filter_ctx_t; |
17 | 17 |
18 | 18 |
19 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); | 19 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); |
20 static ngx_chain_t *ngx_http_chunked_create_trailers(ngx_http_request_t *r, | 20 static ngx_chain_t *ngx_http_chunked_create_trailers(ngx_http_request_t *r, |
21 ngx_http_chunked_filter_ctx_t *ctx, size_t size); | 21 ngx_http_chunked_filter_ctx_t *ctx); |
22 | 22 |
23 | 23 |
24 static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { | 24 static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { |
25 NULL, /* preconfiguration */ | 25 NULL, /* preconfiguration */ |
26 ngx_http_chunked_filter_init, /* postconfiguration */ | 26 ngx_http_chunked_filter_init, /* postconfiguration */ |
202 | 202 |
203 tl->next = out; | 203 tl->next = out; |
204 out = tl; | 204 out = tl; |
205 } | 205 } |
206 | 206 |
207 #if (NGX_HTTP_V3) | |
208 if (r->http_version == NGX_HTTP_VERSION_30) { | |
209 | |
210 if (cl->buf->last_buf) { | |
211 tl = ngx_http_v3_create_trailers(r); | |
212 if (tl == NULL) { | |
213 return NGX_ERROR; | |
214 } | |
215 | |
216 cl->buf->last_buf = 0; | |
217 | |
218 *ll = tl; | |
219 } | |
220 | |
221 } else | |
222 #endif | |
223 | |
207 if (cl->buf->last_buf) { | 224 if (cl->buf->last_buf) { |
208 tl = ngx_http_chunked_create_trailers(r, ctx, size); | 225 tl = ngx_http_chunked_create_trailers(r, ctx); |
209 if (tl == NULL) { | 226 if (tl == NULL) { |
210 return NGX_ERROR; | 227 return NGX_ERROR; |
211 } | 228 } |
212 | 229 |
213 cl->buf->last_buf = 0; | 230 cl->buf->last_buf = 0; |
214 | 231 |
215 *ll = tl; | 232 *ll = tl; |
216 | 233 |
217 } else if (size > 0 | 234 if (size == 0) { |
218 #if (NGX_HTTP_V3) | 235 tl->buf->pos += 2; |
219 && r->http_version != NGX_HTTP_VERSION_30 | 236 } |
220 #endif | 237 |
221 ) | 238 } else if (size > 0) { |
222 { | |
223 tl = ngx_chain_get_free_buf(r->pool, &ctx->free); | 239 tl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
224 if (tl == NULL) { | 240 if (tl == NULL) { |
225 return NGX_ERROR; | 241 return NGX_ERROR; |
226 } | 242 } |
227 | 243 |
248 } | 264 } |
249 | 265 |
250 | 266 |
251 static ngx_chain_t * | 267 static ngx_chain_t * |
252 ngx_http_chunked_create_trailers(ngx_http_request_t *r, | 268 ngx_http_chunked_create_trailers(ngx_http_request_t *r, |
253 ngx_http_chunked_filter_ctx_t *ctx, size_t size) | 269 ngx_http_chunked_filter_ctx_t *ctx) |
254 { | 270 { |
255 size_t len; | 271 size_t len; |
256 ngx_buf_t *b; | 272 ngx_buf_t *b; |
257 ngx_uint_t i; | 273 ngx_uint_t i; |
258 ngx_chain_t *cl; | 274 ngx_chain_t *cl; |
259 ngx_list_part_t *part; | 275 ngx_list_part_t *part; |
260 ngx_table_elt_t *header; | 276 ngx_table_elt_t *header; |
261 | 277 |
262 #if (NGX_HTTP_V3) | |
263 if (r->http_version == NGX_HTTP_VERSION_30) { | |
264 return ngx_http_v3_create_trailers(r); | |
265 } | |
266 #endif | |
267 | |
268 len = 0; | 278 len = 0; |
269 | 279 |
270 part = &r->headers_out.trailers.part; | 280 part = &r->headers_out.trailers.part; |
271 header = part->elts; | 281 header = part->elts; |
272 | 282 |
315 return NULL; | 325 return NULL; |
316 } | 326 } |
317 | 327 |
318 b->last = b->pos; | 328 b->last = b->pos; |
319 | 329 |
320 if (size > 0) { | 330 *b->last++ = CR; *b->last++ = LF; |
321 *b->last++ = CR; *b->last++ = LF; | |
322 } | |
323 | |
324 *b->last++ = '0'; | 331 *b->last++ = '0'; |
325 *b->last++ = CR; *b->last++ = LF; | 332 *b->last++ = CR; *b->last++ = LF; |
326 | 333 |
327 part = &r->headers_out.trailers.part; | 334 part = &r->headers_out.trailers.part; |
328 header = part->elts; | 335 header = part->elts; |