summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_http_request.c
diff options
context:
space:
mode:
authorZhidao HONG <z.hong@f5.com>2024-06-11 17:59:00 +0800
committerZhidao HONG <z.hong@f5.com>2024-06-20 10:39:55 +0800
commit64f4c78bf441fa9e021d905a03d374d0a9e05e8d (patch)
treee4d12f7eb8a085ae8f58f313a98c761d6594660a /src/nxt_http_request.c
parentf80a36a60d61ecd5621d33af37aed35fd074f982 (diff)
downloadunit-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.c43
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);
}