mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
Chunked response body in HTTP/3.
This commit is contained in:
parent
81f7cff632
commit
80a38580bd
@ -18,7 +18,7 @@ typedef struct {
|
|||||||
|
|
||||||
static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf);
|
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,
|
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 = {
|
static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
|
||||||
@ -106,6 +106,7 @@ ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
{
|
{
|
||||||
u_char *chunk;
|
u_char *chunk;
|
||||||
off_t size;
|
off_t size;
|
||||||
|
size_t n;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_chain_t *out, *cl, *tl, **ll;
|
ngx_chain_t *out, *cl, *tl, **ll;
|
||||||
@ -161,29 +162,50 @@ ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
chunk = b->start;
|
chunk = b->start;
|
||||||
|
|
||||||
if (chunk == NULL) {
|
if (chunk == NULL) {
|
||||||
/* the "0000000000000000" is 64-bit hexadecimal string */
|
|
||||||
|
|
||||||
chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1);
|
#if (NGX_HTTP_V3)
|
||||||
|
if (r->http_version == NGX_HTTP_VERSION_30) {
|
||||||
|
n = NGX_HTTP_V3_VARLEN_INT_LEN * 2;
|
||||||
|
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* the "0000000000000000" is 64-bit hexadecimal string */
|
||||||
|
n = sizeof("0000000000000000" CRLF) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = ngx_palloc(r->pool, n);
|
||||||
if (chunk == NULL) {
|
if (chunk == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
b->start = chunk;
|
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->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
|
||||||
b->memory = 0;
|
b->memory = 0;
|
||||||
b->temporary = 1;
|
b->temporary = 1;
|
||||||
b->pos = chunk;
|
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;
|
tl->next = out;
|
||||||
out = tl;
|
out = tl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl->buf->last_buf) {
|
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) {
|
if (tl == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -192,11 +214,12 @@ ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
|
|
||||||
*ll = tl;
|
*ll = tl;
|
||||||
|
|
||||||
if (size == 0) {
|
} else if (size > 0
|
||||||
tl->buf->pos += 2;
|
#if (NGX_HTTP_V3)
|
||||||
}
|
&& r->http_version != NGX_HTTP_VERSION_30
|
||||||
|
#endif
|
||||||
} else if (size > 0) {
|
)
|
||||||
|
{
|
||||||
tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
|
tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
|
||||||
if (tl == NULL) {
|
if (tl == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@ -227,7 +250,7 @@ ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
|
|
||||||
static ngx_chain_t *
|
static ngx_chain_t *
|
||||||
ngx_http_chunked_create_trailers(ngx_http_request_t *r,
|
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;
|
size_t len;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
@ -236,6 +259,12 @@ ngx_http_chunked_create_trailers(ngx_http_request_t *r,
|
|||||||
ngx_list_part_t *part;
|
ngx_list_part_t *part;
|
||||||
ngx_table_elt_t *header;
|
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;
|
len = 0;
|
||||||
|
|
||||||
part = &r->headers_out.trailers.part;
|
part = &r->headers_out.trailers.part;
|
||||||
@ -288,7 +317,10 @@ ngx_http_chunked_create_trailers(ngx_http_request_t *r,
|
|||||||
|
|
||||||
b->last = b->pos;
|
b->last = b->pos;
|
||||||
|
|
||||||
*b->last++ = CR; *b->last++ = LF;
|
if (size > 0) {
|
||||||
|
*b->last++ = CR; *b->last++ = LF;
|
||||||
|
}
|
||||||
|
|
||||||
*b->last++ = '0';
|
*b->last++ = '0';
|
||||||
*b->last++ = CR; *b->last++ = LF;
|
*b->last++ = CR; *b->last++ = LF;
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ typedef struct {
|
|||||||
|
|
||||||
ngx_int_t ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b);
|
ngx_int_t ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b);
|
||||||
ngx_chain_t *ngx_http_v3_create_header(ngx_http_request_t *r);
|
ngx_chain_t *ngx_http_v3_create_header(ngx_http_request_t *r);
|
||||||
|
ngx_chain_t *ngx_http_v3_create_trailers(ngx_http_request_t *r);
|
||||||
|
|
||||||
uintptr_t ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value);
|
uintptr_t ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value);
|
||||||
uintptr_t ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value,
|
uintptr_t ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value,
|
||||||
|
@ -258,11 +258,6 @@ ngx_http_v3_create_header(ngx_http_request_t *r)
|
|||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header");
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header");
|
||||||
|
|
||||||
/* XXX support chunked body in the chunked filter */
|
|
||||||
if (!r->header_only && r->headers_out.content_length_n == -1) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = 2;
|
len = 2;
|
||||||
|
|
||||||
if (r->headers_out.status == NGX_HTTP_OK) {
|
if (r->headers_out.status == NGX_HTTP_OK) {
|
||||||
@ -578,3 +573,33 @@ ngx_http_v3_create_header(ngx_http_request_t *r)
|
|||||||
|
|
||||||
return hl;
|
return hl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngx_chain_t *
|
||||||
|
ngx_http_v3_create_trailers(ngx_http_request_t *r)
|
||||||
|
{
|
||||||
|
ngx_buf_t *b;
|
||||||
|
ngx_chain_t *cl;
|
||||||
|
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"http3 create trailers");
|
||||||
|
|
||||||
|
/* XXX */
|
||||||
|
|
||||||
|
b = ngx_calloc_buf(r->pool);
|
||||||
|
if (b == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b->last_buf = 1;
|
||||||
|
|
||||||
|
cl = ngx_alloc_chain_link(r->pool);
|
||||||
|
if (cl == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl->buf = b;
|
||||||
|
cl->next = NULL;
|
||||||
|
|
||||||
|
return cl;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user