diff options
author | Zhidao HONG <z.hong@f5.com> | 2024-06-11 17:59:00 +0800 |
---|---|---|
committer | Zhidao HONG <z.hong@f5.com> | 2024-06-20 10:39:55 +0800 |
commit | 64f4c78bf441fa9e021d905a03d374d0a9e05e8d (patch) | |
tree | e4d12f7eb8a085ae8f58f313a98c761d6594660a /src/nxt_http_request.c | |
parent | f80a36a60d61ecd5621d33af37aed35fd074f982 (diff) | |
download | unit-64f4c78bf441fa9e021d905a03d374d0a9e05e8d.tar.gz unit-64f4c78bf441fa9e021d905a03d374d0a9e05e8d.tar.bz2 |
http: Support chunked request bodies
This is a temporary support for chunked request bodies by converting
to Content-Length. This allows for processing of such requests until
a more permanent solution is developed.
A new configuration option "chunked_transform" has been added to enable
this feature. The option can be set as follows:
{
"settings": {
"chunked_transform": true
}
}
By default, this option is set to false, which retains the current
behaviour of rejecting chunked requests with a '411 Length Required'
status code.
Please note that this is an experimental implementation.
Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'src/nxt_http_request.c')
-rw-r--r-- | src/nxt_http_request.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 425a4607..54d1bd27 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -540,15 +540,58 @@ static const nxt_http_request_state_t nxt_http_request_body_state }; +static nxt_int_t +nxt_http_request_chunked_transform(nxt_http_request_t *r) +{ + size_t size; + u_char *p, *end; + nxt_http_field_t *f; + + r->chunked_field->skip = 1; + + size = r->body->file_end; + + f = nxt_list_zero_add(r->fields); + if (nxt_slow_path(f == NULL)) { + return NXT_ERROR; + } + + nxt_http_field_name_set(f, "Content-Length"); + + p = nxt_mp_nget(r->mem_pool, NXT_OFF_T_LEN); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + f->value = p; + end = nxt_sprintf(p, p + NXT_OFF_T_LEN, "%uz", size); + f->value_length = end - p; + + r->content_length = f; + r->content_length_n = size; + + return NXT_OK; +} + + static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data) { + nxt_int_t ret; nxt_http_action_t *action; nxt_http_request_t *r; r = obj; action = r->conf->socket_conf->action; + if (r->chunked) { + ret = nxt_http_request_chunked_transform(r); + if (nxt_slow_path(ret != NXT_OK)) { + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + return; + } + } + nxt_http_request_action(task, r, action); } |