From 8ff606fbca688072585325ee5a4ddb56cc034575 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 28 Feb 2024 20:46:18 +0000 Subject: Configuration: Fix check in nxt_conf_json_parse_value() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we compile Unit with -Wstrict-overflow=5 (as we do with clang) then we get the following warning cc -c -pipe -fPIC -fvisibility=hidden -O0 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wstrict-overflow=5 -Wmissing-prototypes -g -I src -I build/include \ \ \ -o build/src/nxt_conf.o \ -MMD -MF build/src/nxt_conf.dep -MT build/src/nxt_conf.o \ src/nxt_conf.c src/nxt_conf.c: In function ‘nxt_conf_json_parse_value’: src/nxt_conf.c:1444:5: warning: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Wstrict-overflow] 1444 | if (nxt_fast_path((ch - '0') <= 9)) { | Does this actually cause an issue?... well, yes. Using this minimal test config to show the problem { "listeners": { "[::1]:8080": { "pass": --100 } } } With the above if () statement that triggers the warning, my assumption here is that we only want a digit now. '0' - '9'. ch is a u_char, however if ch is any character with an ASCII code < 48 ('0') e.g if ch is '-' (45) then we get 45 - 48 = -3, through arithmetic conversion, which makes the if () statement true (when it shouldn't) then at some point we get the following error returned from the controller { "error": "Memory allocation failed." } Instead of the expected { "error": "Invalid JSON.", "detail": "A valid JSON value is expected here. It must be either a literal (null, true, or false), a number, a string (in double quotes \"\"), an array (with brackets []), or an object (with braces {}).", "location": { "offset": 234, "line": 15, "column": 27 } } Casting the result of (ch - '0') to u_char resolves this issue, this makes the above calculation come out as 253 (relying on unsigned integer wraparound) which was probably the intended way for it to work. Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 008cb968..9ae25172 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -1441,7 +1441,7 @@ nxt_conf_json_parse_value(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start, goto error; } - if (nxt_fast_path((ch - '0') <= 9)) { + if (nxt_fast_path((u_char)(ch - '0') <= 9)) { p = nxt_conf_json_parse_number(mp, value, start, end, error); if (nxt_slow_path(p == NULL)) { -- cgit From 4eb008bb17f37f6dacfb101fe0a686bc10114b9d Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Sat, 30 Sep 2023 14:51:34 +0100 Subject: Remove unused nxt_vector_t API This is unused, yet a community member just spent time finding and fixing a bug in it only to be told it's unused. Just get rid of the thing. Link: Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_main.h | 1 - src/nxt_vector.c | 156 ------------------------------------------------------- src/nxt_vector.h | 65 ----------------------- 3 files changed, 222 deletions(-) delete mode 100644 src/nxt_vector.c delete mode 100644 src/nxt_vector.h (limited to 'src') diff --git a/src/nxt_main.h b/src/nxt_main.h index aa96256e..7880e55f 100644 --- a/src/nxt_main.h +++ b/src/nxt_main.h @@ -104,7 +104,6 @@ typedef struct { #include #include -#include #include #include diff --git a/src/nxt_vector.c b/src/nxt_vector.c deleted file mode 100644 index 4737248c..00000000 --- a/src/nxt_vector.c +++ /dev/null @@ -1,156 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#include - - -nxt_vector_t * -nxt_vector_create(nxt_uint_t items, size_t item_size, - const nxt_mem_proto_t *proto, void *pool) -{ - nxt_vector_t *vector; - - vector = proto->alloc(pool, sizeof(nxt_vector_t) + items * item_size); - - if (nxt_fast_path(vector != NULL)) { - vector->start = nxt_pointer_to(vector, sizeof(nxt_vector_t)); - vector->items = 0; - vector->item_size = item_size; - vector->avalaible = items; - vector->type = NXT_VECTOR_EMBEDDED; - } - - return vector; -} - - -void * -nxt_vector_init(nxt_vector_t *vector, nxt_uint_t items, size_t item_size, - const nxt_mem_proto_t *proto, void *pool) -{ - vector->start = proto->alloc(pool, items * item_size); - - if (nxt_fast_path(vector->start != NULL)) { - vector->items = 0; - vector->item_size = item_size; - vector->avalaible = items; - vector->type = NXT_VECTOR_INITED; - } - - return vector->start; -} - - -void -nxt_vector_destroy(nxt_vector_t *vector, const nxt_mem_proto_t *proto, - void *pool) -{ - switch (vector->type) { - - case NXT_VECTOR_INITED: - proto->free(pool, vector->start); -#if (NXT_DEBUG) - vector->start = NULL; - vector->items = 0; - vector->avalaible = 0; -#endif - break; - - case NXT_VECTOR_DESCRETE: - proto->free(pool, vector->start); - - /* Fall through. */ - - case NXT_VECTOR_EMBEDDED: - proto->free(pool, vector); - break; - } -} - - -void * -nxt_vector_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, void *pool) -{ - void *item, *start, *old; - size_t size; - uint32_t n; - - n = vector->avalaible; - - if (n == vector->items) { - - if (n < 16) { - /* Allocate new vector twice as much as current. */ - n *= 2; - - } else { - /* Allocate new vector half as much as current. */ - n += n / 2; - } - - size = n * vector->item_size; - - start = proto->alloc(pool, size); - if (nxt_slow_path(start == NULL)) { - return NULL; - } - - vector->avalaible = n; - old = vector->start; - vector->start = start; - - nxt_memcpy(start, old, size); - - if (vector->type == NXT_VECTOR_EMBEDDED) { - vector->type = NXT_VECTOR_DESCRETE; - - } else { - proto->free(pool, old); - } - } - - item = nxt_pointer_to(vector->start, vector->item_size * vector->items); - - vector->items++; - - return item; -} - - -void * -nxt_vector_zero_add(nxt_vector_t *vector, const nxt_mem_proto_t *proto, - void *pool) -{ - void *item; - - item = nxt_vector_add(vector, proto, pool); - - if (nxt_fast_path(item != NULL)) { - nxt_memzero(item, vector->item_size); - } - - return item; -} - - -void -nxt_vector_remove(nxt_vector_t *vector, void *item) -{ - u_char *next, *last, *end; - uint32_t item_size; - - item_size = vector->item_size; - end = nxt_pointer_to(vector->start, item_size * vector->items); - last = end - item_size; - - if (item != last) { - next = nxt_pointer_to(item, item_size); - - nxt_memmove(item, next, end - next); - } - - vector->items--; -} diff --git a/src/nxt_vector.h b/src/nxt_vector.h deleted file mode 100644 index dcac53d4..00000000 --- a/src/nxt_vector.h +++ /dev/null @@ -1,65 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#ifndef _NXT_VECTOR_H_INCLUDED_ -#define _NXT_VECTOR_H_INCLUDED_ - - -typedef enum { - NXT_VECTOR_INITED = 0, - NXT_VECTOR_DESCRETE, - NXT_VECTOR_EMBEDDED, -} nxt_vector_type_t; - - -typedef struct { - void *start; - /* - * A vector can hold no more than 65536 items. - * The item size is no more than 64K. - */ - uint16_t items; - uint16_t avalaible; - uint16_t item_size; - nxt_vector_type_t type:8; -} nxt_vector_t; - - -NXT_EXPORT nxt_vector_t *nxt_vector_create(nxt_uint_t items, size_t item_size, - const nxt_mem_proto_t *proto, void *pool); -NXT_EXPORT void *nxt_vector_init(nxt_vector_t *vector, nxt_uint_t items, - size_t item_size, const nxt_mem_proto_t *proto, void *pool); -NXT_EXPORT void nxt_vector_destroy(nxt_vector_t *vector, - const nxt_mem_proto_t *proto, void *pool); -NXT_EXPORT void *nxt_vector_add(nxt_vector_t *vector, - const nxt_mem_proto_t *proto, void *pool); -NXT_EXPORT void *nxt_vector_zero_add(nxt_vector_t *vector, - const nxt_mem_proto_t *proto, void *pool); -NXT_EXPORT void nxt_vector_remove(nxt_vector_t *vector, void *item); - - -#define nxt_vector_last(vector) \ - nxt_pointer_to((vector)->start, \ - (vector)->item_size * ((vector)->items - 1)) - - -#define nxt_vector_reset(vector) \ - (vector)->items = 0; - - -#define nxt_vector_is_empty(vector) \ - ((vector)->items == 0) - - -nxt_inline void * -nxt_vector_remove_last(nxt_vector_t *vector) -{ - vector->items--; - return nxt_pointer_to(vector->start, vector->item_size * vector->items); -} - - -#endif /* _NXT_VECTOR_H_INCLUDED_ */ -- cgit From 353d2d055798f7d1625c549a27062a6ca3a415db Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 23 Feb 2024 00:34:57 +0000 Subject: Var: Remove a dead assignment in nxt_var_interpreter() p is not used again before returning from the function. Found by the clang static analyser. Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_var.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_var.c b/src/nxt_var.c index 2600371b..2328d4ec 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -566,7 +566,7 @@ nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, } if (last != var->length) { - p = nxt_cpymem(p, &src[last], var->length - last); + nxt_cpymem(p, &src[last], var->length - last); } return NXT_OK; -- cgit From c2f7f2964c9394643b69076ab8f0df490b000f45 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 23 Feb 2024 01:05:04 +0000 Subject: Avoid potential NULL pointer dereference in nxt_router_temp_conf() In nxt_router_temp_conf() we have rtcf = nxt_mp_zget(mp, sizeof(nxt_router_conf_t)); if (nxt_slow_path(rtcf == NULL)) { goto fail; } If rtcf is NULL then we do fail: if (rtcf->tstr_state != NULL) { nxt_tstr_state_release(rtcf->tstr_state); } In which case we will dereference the NULL pointer rtcf. This patch re-works the goto labels to make them more specific to their intended purpose and ensures we are freeing things which have been allocated. This was found by the clang static analyser. Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_router.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nxt_router.c b/src/nxt_router.c index 1a1aca2b..e395929e 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1077,14 +1077,14 @@ nxt_router_temp_conf(nxt_task_t *task) rtcf = nxt_mp_zget(mp, sizeof(nxt_router_conf_t)); if (nxt_slow_path(rtcf == NULL)) { - goto fail; + goto out_free_mp; } rtcf->mem_pool = mp; rtcf->tstr_state = nxt_tstr_state_new(mp, 0); if (nxt_slow_path(rtcf->tstr_state == NULL)) { - goto fail; + goto out_free_mp; } #if (NXT_HAVE_NJS) @@ -1093,12 +1093,12 @@ nxt_router_temp_conf(nxt_task_t *task) tmp = nxt_mp_create(1024, 128, 256, 32); if (nxt_slow_path(tmp == NULL)) { - goto fail; + goto out_free_tstr_state; } tmcf = nxt_mp_zget(tmp, sizeof(nxt_router_temp_conf_t)); if (nxt_slow_path(tmcf == NULL)) { - goto temp_fail; + goto out_free; } tmcf->mem_pool = tmp; @@ -1109,7 +1109,7 @@ nxt_router_temp_conf(nxt_task_t *task) tmcf->engines = nxt_array_create(tmcf->mem_pool, 4, sizeof(nxt_router_engine_conf_t)); if (nxt_slow_path(tmcf->engines == NULL)) { - goto temp_fail; + goto out_free; } nxt_queue_init(&creating_sockets); @@ -1131,16 +1131,18 @@ nxt_router_temp_conf(nxt_task_t *task) return tmcf; -temp_fail: +out_free: nxt_mp_destroy(tmp); -fail: +out_free_tstr_state: if (rtcf->tstr_state != NULL) { nxt_tstr_state_release(rtcf->tstr_state); } +out_free_mp: + nxt_mp_destroy(mp); return NULL; -- cgit From f6899af68dcc5629b9a6d9b5ecfdd83a4a830ced Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 6 Mar 2024 16:09:32 +0800 Subject: Var: Fix cacheable issue for njs variable access The variables accessed with JS template literal should not be cacheable. Since it is parsed by njs engine, Unit can't create indexes on these variables for caching purpose. For example: { "format": "`{bodyLength:\"${vars.body_bytes_sent}\",status:\"${vars.status}\"}\n`" } The variables like the above are not cacheable. Closes: https://github.com/nginx/unit/issues/1169 --- src/nxt_var.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_var.c b/src/nxt_var.c index 2328d4ec..94d10cd8 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -147,7 +147,7 @@ nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name, nxt_mp_t *mp) if (decl != NULL) { ref->handler = decl->handler; - ref->cacheable = decl->cacheable; + ref->cacheable = (mp == state->pool) ? decl->cacheable : 0; goto done; } -- cgit From 5511593dacb771490f6d12d78e7485c5ff8a0b38 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 6 Mar 2024 21:00:38 +0000 Subject: Remove support for Microsoft's Visual C++ compiler We don't run on Windows and only really support compiling Unit with GCC and Clang. Cc: Dan Callahan Co-developed-by: Alejandro Colomar Signed-off-by: Alejandro Colomar Signed-off-by: Andrew Clayton --- src/nxt_types.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nxt_types.h b/src/nxt_types.h index 03e9c187..723346d9 100644 --- a/src/nxt_types.h +++ b/src/nxt_types.h @@ -51,7 +51,6 @@ typedef off_t nxt_off_t; * 64-bit on 32-bit NetBSD 6.0; * 32-bit on 64-bit OpenBSD; * 64-bit in Linux x32 ABI; - * 64-bit in 32-bit Visual Studio C++ 2005. */ #if (NXT_QNX) /* -- cgit From e79e463556d6a08432a7008d185c958907fa4f40 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 6 Mar 2024 21:06:34 +0000 Subject: Remove support for IBM's XL C compiler We really only support building Unit with GCC and Clang. Cc: Dan Callahan Reviewed-by: Alejandro Colomar Signed-off-by: Andrew Clayton --- src/nxt_atomic.h | 104 +------------------------------------------------------ 1 file changed, 1 insertion(+), 103 deletions(-) (limited to 'src') diff --git a/src/nxt_atomic.h b/src/nxt_atomic.h index dae999a9..585d0be2 100644 --- a/src/nxt_atomic.h +++ b/src/nxt_atomic.h @@ -161,109 +161,7 @@ typedef volatile nxt_atomic_uint_t nxt_atomic_t; */ -#elif (NXT_HAVE_XLC_ATOMIC) /* XL C/C++ V8.0 for AIX */ - -#if (NXT_64BIT) - -typedef long nxt_atomic_int_t; -typedef unsigned long nxt_atomic_uint_t; -typedef volatile nxt_atomic_int_t nxt_atomic_t; - - -nxt_inline nxt_bool_t -nxt_atomic_cmp_set(nxt_atomic_t *lock, nxt_atomic_int_t cmp, - nxt_atomic_int_t set) -{ - nxt_atomic_int_t old; - - old = cmp; - - return __compare_and_swaplp(lock, &old, set); -} - - -#define nxt_atomic_xchg(lock, set) \ - __fetch_and_swaplp(lock, set) - - -#define nxt_atomic_fetch_add(value, add) \ - __fetch_and_addlp(value, add) - - -#else /* NXT_32BIT */ - -typedef int nxt_atomic_int_t; -typedef unsigned int nxt_atomic_uint_t; -typedef volatile nxt_atomic_int_t nxt_atomic_t; - - -nxt_inline nxt_bool_t -nxt_atomic_cmp_set(nxt_atomic_t *lock, nxt_atomic_int_t cmp, - nxt_atomic_int_t set) -{ - nxt_atomic_int_t old; - - old = cmp; - - return __compare_and_swap(lock, &old, set); -} - - -#define nxt_atomic_xchg(lock, set) \ - __fetch_and_swap(lock, set) - - -#define nxt_atomic_fetch_add(value, add) \ - __fetch_and_add(value, add) - - -#endif /* NXT_32BIT*/ - - -/* - * __lwsync() is a "lwsync" instruction that sets #LoadLoad, #LoadStore, - * and #StoreStore barrier. - * - * __compare_and_swap() is a pair of "ldarx" and "stdcx" instructions. - * A "lwsync" does not set #StoreLoad barrier so it can not be used after - * this pair since a next load inside critical section can be performed - * after the "ldarx" instruction but before the "stdcx" instruction. - * However, this next load instruction will load correct data because - * otherwise the "ldarx/stdcx" pair will fail and this data will be - * discarded. Nevertheless, the "isync" instruction is used for sure. - * - * A full barrier can be set with __sync(), a "sync" instruction, but there - * is also a faster __isync(), an "isync" instruction. This instruction is - * not a memory barrier but an instruction barrier. An "isync" instruction - * causes the processor to complete execution of all previous instructions - * and then to discard instructions (which may have begun execution) following - * the "isync". After the "isync" is executed, the following instructions - * then begin execution. The "isync" is used to ensure that the loads - * following entry into a critical section are not performed (because of - * aggressive out-of-order or speculative execution in the processor) until - * the lock is granted. - */ - -nxt_inline nxt_bool_t -nxt_atomic_try_lock(nxt_atomic_t *lock) -{ - if (nxt_atomic_cmp_set(lock, 0, 1)) { - __isync(); - return 1; - } - - return 0; -} - - -#define nxt_atomic_release(lock) \ - do { __lwsync(); *lock = 0; } while (0) - - -#define nxt_cpu_pause() - - -#endif /* NXT_HAVE_XLC_ATOMIC */ +#endif /* NXT_HAVE_GCC_ATOMIC */ #endif /* _NXT_ATOMIC_H_INCLUDED_ */ -- cgit From 9cd11133f9eaf4f31f7d1c477613d12c22774b09 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 6 Mar 2024 21:08:43 +0000 Subject: Remove support for Sun's Sun Studio/SunPro C compiler We really only support building Unit with GCC and Clang. Cc: Dan Callahan Reviewed-by: Alejandro Colomar Signed-off-by: Andrew Clayton --- src/nxt_atomic.h | 75 -------------------------------------------------------- 1 file changed, 75 deletions(-) (limited to 'src') diff --git a/src/nxt_atomic.h b/src/nxt_atomic.h index 585d0be2..376375c5 100644 --- a/src/nxt_atomic.h +++ b/src/nxt_atomic.h @@ -67,81 +67,6 @@ typedef volatile nxt_atomic_uint_t nxt_atomic_t; #endif -#elif (NXT_HAVE_SOLARIS_ATOMIC) /* Solaris 10 */ - -#include - -typedef long nxt_atomic_int_t; -typedef ulong_t nxt_atomic_uint_t; -typedef volatile nxt_atomic_uint_t nxt_atomic_t; - - -#define nxt_atomic_cmp_set(lock, cmp, set) \ - (atomic_cas_ulong(lock, cmp, set) == (ulong_t) cmp) - - -#define nxt_atomic_xchg(lock, set) \ - atomic_add_swap(lock, set) - - -#define nxt_atomic_fetch_add(value, add) \ - (atomic_add_long_nv(value, add) - add) - - -#define nxt_atomic_or_fetch(ptr, val) \ - atomic_or_ulong_nv(ptr, val) - - -#define nxt_atomic_and_fetch(ptr, val) \ - atomic_and_ulong_nv(ptr, val) - - -/* - * Solaris uses SPARC Total Store Order model. In this model: - * 1) Each atomic load-store instruction behaves as if it were followed by - * #LoadLoad, #LoadStore, and #StoreStore barriers. - * 2) Each load instruction behaves as if it were followed by - * #LoadLoad and #LoadStore barriers. - * 3) Each store instruction behaves as if it were followed by - * #StoreStore barrier. - * - * In X86_64 atomic instructions set a full barrier and usual instructions - * set implicit #LoadLoad, #LoadStore, and #StoreStore barriers. - * - * An acquire barrier requires at least #LoadLoad and #LoadStore barriers - * and they are provided by atomic load-store instruction. - * - * A release barrier requires at least #LoadStore and #StoreStore barriers, - * so a lock release does not require an explicit barrier: all load - * instructions in critical section is followed by implicit #LoadStore - * barrier and all store instructions are followed by implicit #StoreStore - * barrier. - */ - -#define nxt_atomic_try_lock(lock) \ - nxt_atomic_cmp_set(lock, 0, 1) - - -#define nxt_atomic_release(lock) \ - *lock = 0; - - -/* - * The "rep; nop" is used instead of "pause" to omit the "[ PAUSE ]" hardware - * capability added by linker since Solaris ld.so.1 does not know about it: - * - * ld.so.1: ...: fatal: hardware capability unsupported: 0x2000 [ PAUSE ] - */ - -#if (__i386__ || __i386 || __amd64__ || __amd64) -#define nxt_cpu_pause() \ - __asm__ ("rep; nop") - -#else -#define nxt_cpu_pause() -#endif - - /* elif (NXT_HAVE_MACOSX_ATOMIC) */ /* -- cgit From 6b13857142782167a544c55e67e292e5e30230fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:34:16 +0000 Subject: Wasm-wc: Bump the mio crate from 0.8.10 to 0.8.11 Bumps mio from 0.8.10 to 0.8.11. Fixes receiving IOCP events after deregistering a Windows named pipe. Not that that effects Unit... Link: Link: Changelog Link: Commits Signed-off-by: dependabot[bot] Reviewed-by: Andrew Clayton [ Tweaked commit message/subject - Andrew ] Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wasm-wasi-component/Cargo.lock b/src/wasm-wasi-component/Cargo.lock index bc09e96a..f785210e 100644 --- a/src/wasm-wasi-component/Cargo.lock +++ b/src/wasm-wasi-component/Cargo.lock @@ -905,9 +905,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", -- cgit From 0d99744debf75ec4434e10624cc0e59336584a29 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:15:12 +0000 Subject: Router: match when pattern and tested string are both zero length Otherwise, undefined behaviour will be triggered. Can be reproduced by test/test_routing.py::test_routes_match_host_empty with enabled UndefinedBehaviorSanitizer: src/nxt_http_route.c:2141:17: runtime error: applying zero offset to null pointer #0 0x100562588 in nxt_http_route_test_rule nxt_http_route.c:2091 #1 0x100564ed8 in nxt_http_route_handler nxt_http_route.c:1574 #2 0x10055188c in nxt_http_request_action nxt_http_request.c:570 #3 0x10052b1a0 in nxt_h1p_request_body_read nxt_h1proto.c:998 #4 0x100449c38 in nxt_event_engine_start nxt_event_engine.c:542 #5 0x100436828 in nxt_thread_trampoline nxt_thread.c:126 #6 0x18133e030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030) #7 0x181338e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/nxt_http_route.c:2141:17 Reviewed-by: Andrew Clayton --- src/nxt_http_route.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 4a64d5c1..d16d5803 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -2134,6 +2134,10 @@ nxt_http_route_pattern(nxt_http_request_t *r, nxt_http_route_pattern_t *pattern, return 0; } + if (nxt_slow_path(start == NULL)) { + return 1; + } + nxt_assert(pattern->u.pattern_slices != NULL); pattern_slices = pattern->u.pattern_slices; -- cgit From fdc46759eb6fb983b651bcbfccbcd5e6b5658bb6 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:16:34 +0000 Subject: NJS: avoiding arithmetic ops with NULL pointer in r->args Can be reproduced by test/test_rewrite.py::test_rewrite_njs with enabled UndefinedBehaviorSanitizer: src/nxt_http_js.c:169:52: runtime error: applying zero offset to null pointer #0 0x10255b044 in nxt_http_js_ext_get_args nxt_http_js.c:169 #1 0x102598ad0 in njs_value_property njs_value.c:1175 #2 0x10259c2c8 in njs_vm_object_prop njs_vm.c:1398 #3 0x102559d74 in nxt_js_call nxt_js.c:445 #4 0x1023c0da0 in nxt_tstr_query nxt_tstr.c:276 #5 0x102516ec4 in nxt_http_rewrite nxt_http_rewrite.c:56 #6 0x1024fd86c in nxt_http_request_action nxt_http_request.c:565 #7 0x1024d71b0 in nxt_h1p_request_body_read nxt_h1proto.c:998 #8 0x1023f5c48 in nxt_event_engine_start nxt_event_engine.c:542 #9 0x1023e2838 in nxt_thread_trampoline nxt_thread.c:126 #10 0x18133e030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030) #11 0x181338e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/nxt_http_js.c:169:52 Same fix was introduced in NJS: Reviewed-by: Andrew Clayton --- src/nxt_http_js.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nxt_http_js.c b/src/nxt_http_js.c index e3beb8b4..3dbf7970 100644 --- a/src/nxt_http_js.c +++ b/src/nxt_http_js.c @@ -162,6 +162,7 @@ static njs_int_t nxt_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { + u_char *start; njs_int_t ret; njs_value_t *args; njs_opaque_value_t val; @@ -175,8 +176,8 @@ nxt_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop, args = njs_value_arg(&val); - ret = njs_vm_query_string_parse(vm, r->args->start, - r->args->start + r->args->length, args); + start = (r->args->start != NULL) ? r->args->start : (u_char *) ""; + ret = njs_vm_query_string_parse(vm, start, start + r->args->length, args); if (ret == NJS_ERROR) { return NJS_ERROR; -- cgit From 8844d33c0aba5b6232366a1fcfbf2f8f866c2f53 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:19:13 +0000 Subject: Fixed undefined behaviour in left shift of int value Found by UndefinedBehaviorSanitizer: src/nxt_random.c:151:31: runtime error: left shift of 140 by 24 places cannot be represented in type 'int' #0 0x104f78968 in nxt_random nxt_random.c:151 #1 0x104f58a98 in nxt_shm_open nxt_port_memory.c:377 #2 0x10503e24c in nxt_controller_conf_send nxt_controller.c:617 #3 0x105041154 in nxt_controller_process_request nxt_controller.c:1109 #4 0x104fcdc48 in nxt_event_engine_start nxt_event_engine.c:542 #5 0x104f27254 in main nxt_main.c:35 #6 0x180fbd0dc () SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/nxt_random.c:151:31 Reviewed-by: Andrew Clayton --- src/nxt_random.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_random.c b/src/nxt_random.c index 1211896c..8290488c 100644 --- a/src/nxt_random.c +++ b/src/nxt_random.c @@ -148,10 +148,10 @@ nxt_random(nxt_random_t *r) nxt_random_stir(r); } - val = nxt_random_byte(r) << 24; - val |= nxt_random_byte(r) << 16; - val |= nxt_random_byte(r) << 8; - val |= nxt_random_byte(r); + val = (uint32_t) nxt_random_byte(r) << 24; + val |= (uint32_t) nxt_random_byte(r) << 16; + val |= (uint32_t) nxt_random_byte(r) << 8; + val |= (uint32_t) nxt_random_byte(r); return val; } -- cgit From 7dcd6c0ebacab6d78ecc34cbac347ef46f79f479 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:20:33 +0000 Subject: Avoiding arithmetic ops with NULL pointer in nxt_http_arguments_parse Can be reproduced by test/test_variables.py::test_variables_dynamic_arguments with enabled UndefinedBehaviorSanitizer: src/nxt_http_request.c:961:17: runtime error: applying zero offset to null pointer #0 0x1050d95a4 in nxt_http_arguments_parse nxt_http_request.c:961 #1 0x105102bf8 in nxt_http_var_arg nxt_http_variables.c:621 #2 0x104f95d74 in nxt_var_interpreter nxt_var.c:507 #3 0x104f98c98 in nxt_tstr_query nxt_tstr.c:265 #4 0x1050abfd8 in nxt_router_access_log_writer nxt_router_access_log.c:194 #5 0x1050d81f4 in nxt_http_request_close_handler nxt_http_request.c:838 #6 0x104fcdc48 in nxt_event_engine_start nxt_event_engine.c:542 #7 0x104fba838 in nxt_thread_trampoline nxt_thread.c:126 #8 0x18133e030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030) #9 0x181338e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/nxt_http_request.c:961:17 Reviewed-by: Andrew Clayton --- src/nxt_http_request.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index f8d8d887..425a4607 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -946,6 +946,10 @@ nxt_http_arguments_parse(nxt_http_request_t *r) return NULL; } + if (nxt_slow_path(r->args->start == NULL)) { + goto end; + } + hash = NXT_HTTP_FIELD_HASH_INIT; name = NULL; name_length = 0; @@ -1026,6 +1030,8 @@ nxt_http_arguments_parse(nxt_http_request_t *r) } } +end: + r->arguments = args; return args; -- cgit From 264b375506121d3a9268552b4f54c77faf171e6a Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:21:03 +0000 Subject: Avoiding arithmetic ops with NULL pointer in nxt_port_mmap_get Can be reproduced by test/test_settings.py::test_settings_send_timeout with enabled UndefinedBehaviorSanitizer. Reviewed-by: Andrew Clayton --- src/nxt_port_memory.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nxt_port_memory.c b/src/nxt_port_memory.c index 0a4a6c53..be7688e2 100644 --- a/src/nxt_port_memory.c +++ b/src/nxt_port_memory.c @@ -454,6 +454,10 @@ nxt_port_mmap_get(nxt_task_t *task, nxt_port_mmaps_t *mmaps, nxt_chunk_id_t *c, nxt_thread_mutex_lock(&mmaps->mutex); + if (nxt_slow_path(mmaps->elts == NULL)) { + goto end; + } + end_port_mmap = mmaps->elts + mmaps->size; for (port_mmap = mmaps->elts; @@ -500,6 +504,8 @@ nxt_port_mmap_get(nxt_task_t *task, nxt_port_mmaps_t *mmaps, nxt_chunk_id_t *c, /* TODO introduce port_mmap limit and release wait. */ +end: + *c = 0; mmap_handler = nxt_port_new_port_mmap(task, mmaps, tracking, n); -- cgit From c9461a6ba849c69b0aad4dd5791c65d582946b8d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:23:10 +0000 Subject: Initialize port_impl only when it is needed Found by UndefinedBehaviorSanitizer. Reviewed-by: Andrew Clayton --- src/nxt_unit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_unit.c b/src/nxt_unit.c index b6291b2d..1fc9acd8 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -1483,9 +1483,9 @@ nxt_unit_request_check_response_port(nxt_unit_request_info_t *req, pthread_mutex_lock(&lib->mutex); port = nxt_unit_port_hash_find(&lib->ports, port_id, 0); - port_impl = nxt_container_of(port, nxt_unit_port_impl_t, port); if (nxt_fast_path(port != NULL)) { + port_impl = nxt_container_of(port, nxt_unit_port_impl_t, port); req->response_port = port; if (nxt_fast_path(port_impl->ready)) { -- cgit From dd701fb449259c5edbc4302ad8556762f1a30b76 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 31 Jan 2024 15:24:06 +0000 Subject: Avoiding arithmetic ops with NULL pointer in nxt_unit_mmap_get Found by UndefinedBehaviorSanitizer. Reviewed-by: Andrew Clayton --- src/nxt_unit.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 1fc9acd8..576c751d 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -3502,6 +3502,10 @@ nxt_unit_mmap_get(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port, pthread_mutex_lock(&lib->outgoing.mutex); + if (nxt_slow_path(lib->outgoing.elts == NULL)) { + goto skip; + } + retry: outgoing_size = lib->outgoing.size; @@ -3598,6 +3602,8 @@ retry: goto retry; } +skip: + *c = 0; hdr = nxt_unit_new_mmap(ctx, port, *n); -- cgit From 9993814d14fa693dc8641c31bca70223895d2055 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 16 Feb 2024 18:22:35 +0000 Subject: NJS: loader should be registered using njs_vm_set_module_loader() This change makes NJS module incompatible with NJS older than 0.8.3. Therefore, the configuration version check has been adjusted accordingly. This change was introduced in NJS 0.8.3 here: --- src/nxt_js.c | 18 ++++++++---------- src/nxt_script.c | 10 ---------- 2 files changed, 8 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nxt_js.c b/src/nxt_js.c index 6885afb7..1f9a3ceb 100644 --- a/src/nxt_js.c +++ b/src/nxt_js.c @@ -69,14 +69,6 @@ nxt_js_module_loader(njs_vm_t *vm, njs_external_ptr_t external, njs_str_t *name) } -static njs_vm_ops_t nxt_js_ops = { - NULL, - NULL, - nxt_js_module_loader, - NULL, -}; - - njs_int_t nxt_js_proto_id; @@ -127,6 +119,7 @@ nxt_js_vm_create(nxt_js_conf_t *jcf) { u_char *p; size_t size; + njs_vm_t *vm; nxt_uint_t i; njs_vm_opt_t opts; nxt_js_module_t *module, *mod; @@ -146,7 +139,6 @@ nxt_js_vm_create(nxt_js_conf_t *jcf) goto done; } - opts.ops = &nxt_js_ops; opts.external = jcf; size = 0; @@ -203,7 +195,13 @@ nxt_js_vm_create(nxt_js_conf_t *jcf) done: - return njs_vm_create(&opts); + vm = njs_vm_create(&opts); + + if (nxt_fast_path(vm != NULL)) { + njs_vm_set_module_loader(vm, nxt_js_module_loader, jcf); + } + + return vm; } diff --git a/src/nxt_script.c b/src/nxt_script.c index 70045a22..05d9561d 100644 --- a/src/nxt_script.c +++ b/src/nxt_script.c @@ -37,14 +37,6 @@ static void nxt_script_buf_completion(nxt_task_t *task, void *obj, void *data); static nxt_lvlhsh_t nxt_script_info; -static njs_vm_ops_t nxt_js_ops = { - NULL, - NULL, - nxt_js_module_loader, - NULL, -}; - - nxt_script_t * nxt_script_new(nxt_task_t *task, nxt_str_t *name, u_char *data, size_t size, u_char *error) @@ -63,8 +55,6 @@ nxt_script_new(nxt_task_t *task, nxt_str_t *name, u_char *data, size_t size, opts.file.start = (u_char *) "default"; opts.file.length = 7; - opts.ops = &nxt_js_ops; - vm = njs_vm_create(&opts); if (nxt_slow_path(vm == NULL)) { return NULL; -- cgit From e75f8d5db200c77707478b558c3ce5e1586ab3e1 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 7 Mar 2024 16:16:55 +0000 Subject: Wasm-wc: Fix application restarts Liam reported a problem when trying to restart wasm-wasi-component based applications using the /control/applications/APPLICATION_NAME/restart endpoint. The application would become unresponsive. What was happening was the old application process(es) weren't exit(3)ing and so while we were starting new application processes, the old ones were still hanging around in a non-functioning state. When we are terminating an application it must call exit(3). So that's what we do. We use the return value of nxt_unit_run() as the exit status. Due to exit(3)ing we also need to now explicitly handle the return on error case. Reported-by: Liam Crilly Fixes: 20ada4b5c ("Wasm-wc: Core of initial Wasm component model language module support") Closes: https://github.com/nginx/unit/issues/1179 Tested-by: Liam Crilly Tested-by: Danielle De Leo Co-developed-by: Dan Callahan Signed-off-by: Dan Callahan Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/src/lib.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index 3ee40c4f..b0552e81 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -4,6 +4,7 @@ use http_body_util::combinators::BoxBody; use http_body_util::{BodyExt, Full}; use std::ffi::{CStr, CString}; use std::mem::MaybeUninit; +use std::process::exit; use std::ptr; use std::sync::OnceLock; use tokio::sync::mpsc; @@ -101,7 +102,9 @@ unsafe extern "C" fn start( task: *mut bindings::nxt_task_t, data: *mut bindings::nxt_process_data_t, ) -> bindings::nxt_int_t { - handle_result(task, || { + let mut rc: i32 = 0; + + let result = handle_result(task, || { let config = GLOBAL_CONFIG.get().unwrap(); let state = GlobalState::new(&config) .context("failed to create initial state")?; @@ -123,11 +126,17 @@ unsafe extern "C" fn start( bail!("nxt_unit_init() failed"); } - bindings::nxt_unit_run(unit_ctx); + rc = bindings::nxt_unit_run(unit_ctx); bindings::nxt_unit_done(unit_ctx); Ok(()) - }) + }); + + if result != bindings::NXT_OK as bindings::nxt_int_t { + return result; + } + + exit(rc); } unsafe fn handle_result( -- cgit From d494d2ebb71ab45781ec7c8cf8b80e6892ce65a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:08:55 +0000 Subject: Wasm-wc: Bump the h2 crate from 0.4.2 to 0.4.4 Bumps h2 from 0.4.2 to 0.4.4. Limit number of CONTINUATION frames for misbehaving connections. Link: Changelog Link: Commits Signed-off-by: dependabot[bot] Reviewed-by: Andrew Clayton [ Tweaked commit message/subject - Andrew ] Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wasm-wasi-component/Cargo.lock b/src/wasm-wasi-component/Cargo.lock index f785210e..7631b716 100644 --- a/src/wasm-wasi-component/Cargo.lock +++ b/src/wasm-wasi-component/Cargo.lock @@ -574,9 +574,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" dependencies = [ "bytes", "fnv", -- cgit From 2d7a84684312fc1c46043fa10af0ea336e73f11d Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 18 Mar 2024 15:16:17 +0800 Subject: HTTP: Added variable validation to the response_headers option This is to improve error messages for response headers configuration. Take the configuration as an example: { "response_headers": { "a": "$b" } } Previously, when applying it the user would see this error message: failed to apply previous configuration After this change, the user will see this improved error message: the previous configuration is invalid: Unknown variable "b" in the "a" value --- src/nxt_conf_validation.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 2099f887..8f802fb7 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -2572,6 +2572,7 @@ static nxt_int_t nxt_conf_vldt_response_header(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) { + nxt_str_t str; nxt_uint_t type; static nxt_str_t content_length = nxt_string("Content-Length"); @@ -2588,7 +2589,17 @@ nxt_conf_vldt_response_header(nxt_conf_validation_t *vldt, nxt_str_t *name, type = nxt_conf_type(value); - if (type == NXT_CONF_STRING || type == NXT_CONF_NULL) { + if (type == NXT_CONF_NULL) { + return NXT_OK; + } + + if (type == NXT_CONF_STRING) { + nxt_conf_get_string(value, &str); + + if (nxt_is_tstr(&str)) { + return nxt_conf_vldt_var(vldt, name, &str); + } + return NXT_OK; } -- cgit From 64934e59f9c06f62fe99466b320cd397c8609807 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 10 Apr 2024 13:45:34 +0800 Subject: HTTP: Introduce quoted target marker in HTTP parsing The quoted_target field is to indentify URLs containing percent-encoded characters. It can be used in places where you might need to generate new URL, such as in the proxy module. It will be used in the subsequent commit. --- src/nxt_http_parse.c | 15 ++++----------- src/nxt_http_parse.h | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 50cbda2b..48be5bdb 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -286,13 +286,11 @@ continue_target: case NXT_HTTP_TARGET_SPACE: rp->target_end = p; goto space_after_target; -#if 0 + case NXT_HTTP_TARGET_QUOTE_MARK: rp->quoted_target = 1; goto rest_of_target; -#else - case NXT_HTTP_TARGET_QUOTE_MARK: -#endif + case NXT_HTTP_TARGET_HASH: rp->complex_target = 1; goto rest_of_target; @@ -434,12 +432,7 @@ space_after_target: rp->request_line_end = p; - if (rp->complex_target != 0 -#if 0 - || rp->quoted_target != 0 -#endif - ) - { + if (rp->complex_target || rp->quoted_target) { rc = nxt_http_parse_complex_target(rp); if (nxt_slow_path(rc != NXT_OK)) { @@ -1041,7 +1034,7 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) break; case sw_quoted: - //rp->quoted_target = 1; + rp->quoted_target = 1; if (ch >= '0' && ch <= '9') { high = (u_char) (ch - '0'); diff --git a/src/nxt_http_parse.h b/src/nxt_http_parse.h index fa95e842..9e1265d1 100644 --- a/src/nxt_http_parse.h +++ b/src/nxt_http_parse.h @@ -61,9 +61,9 @@ struct nxt_http_request_parse_s { /* target with "/." */ uint8_t complex_target; /* 1 bit */ -#if 0 /* target with "%" */ uint8_t quoted_target; /* 1 bit */ +#if 0 /* target with " " */ uint8_t space_in_target; /* 1 bit */ #endif -- cgit From a4dbee147cc13c9eef1f6cb209b4651a1419d17d Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 10 Apr 2024 14:00:39 +0800 Subject: HTTP: Rewrote url target section in nxt_h1p_peer_header_send() Previously, proxy request was constructed based on the `r->target` field. However, r->target will remain unchanged in the future, even in cases of URL rewriting because of the requirement change for $request_uri that will be changed to constant. To accommodate this, the r->target should be designed to be constant, but Unit needs to pass a changeable URL to the upstream server. Based on the above, the proxy module can't depend on r->target. --- src/nxt_h1proto.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++---- src/nxt_http.h | 2 ++ src/nxt_http_rewrite.c | 3 ++ 3 files changed, 74 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 1dfe4b6e..c3a65679 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -90,6 +90,8 @@ static void nxt_h1p_peer_connect(nxt_task_t *task, nxt_http_peer_t *peer); static void nxt_h1p_peer_connected(nxt_task_t *task, void *obj, void *data); static void nxt_h1p_peer_refused(nxt_task_t *task, void *obj, void *data); static void nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer); +static nxt_int_t nxt_h1p_peer_request_target(nxt_http_request_t *r, + nxt_str_t *target); static void nxt_h1p_peer_header_sent(nxt_task_t *task, void *obj, void *data); static void nxt_h1p_peer_header_read(nxt_task_t *task, nxt_http_peer_t *peer); static ssize_t nxt_h1p_peer_io_read_handler(nxt_task_t *task, nxt_conn_t *c); @@ -654,6 +656,8 @@ nxt_h1p_header_process(nxt_task_t *task, nxt_h1proto_t *h1p, r->target.start = h1p->parser.target_start; r->target.length = h1p->parser.target_end - h1p->parser.target_start; + r->quoted_target = h1p->parser.quoted_target; + if (h1p->parser.version.ui64 != 0) { r->version.start = h1p->parser.version.str; r->version.length = sizeof(h1p->parser.version.str); @@ -2263,6 +2267,8 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer) { u_char *p; size_t size; + nxt_int_t ret; + nxt_str_t target; nxt_buf_t *header, *body; nxt_conn_t *c; nxt_http_field_t *field; @@ -2272,7 +2278,12 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer) r = peer->request; - size = r->method->length + sizeof(" ") + r->target.length + ret = nxt_h1p_peer_request_target(r, &target); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + + size = r->method->length + sizeof(" ") + target.length + sizeof(" HTTP/1.1\r\n") + sizeof("Connection: close\r\n") + sizeof("\r\n"); @@ -2288,8 +2299,7 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer) header = nxt_http_buf_mem(task, r, size); if (nxt_slow_path(header == NULL)) { - r->state->error_handler(task, r, peer); - return; + goto fail; } p = header->mem.free; @@ -2328,8 +2338,7 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer) } if (nxt_slow_path(body == NULL)) { - r->state->error_handler(task, r, peer); - return; + goto fail; } header->next = body; @@ -2353,6 +2362,61 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer) } nxt_conn_write(task->thread->engine, c); + + return; + +fail: + + r->state->error_handler(task, r, peer); +} + + +static nxt_int_t +nxt_h1p_peer_request_target(nxt_http_request_t *r, nxt_str_t *target) +{ + u_char *p; + size_t size, encode; + + if (!r->uri_changed) { + *target = r->target; + return NXT_OK; + } + + if (!r->quoted_target && r->args->length == 0) { + *target = *r->path; + return NXT_OK; + } + + if (r->quoted_target) { + encode = nxt_encode_complex_uri(NULL, r->path->start, + r->path->length); + } else { + encode = 0; + } + + size = r->path->length + encode * 2 + 1 + r->args->length; + + target->start = nxt_mp_nget(r->mem_pool, size); + if (target->start == NULL) { + return NXT_ERROR; + } + + if (r->quoted_target) { + p = (u_char *) nxt_encode_complex_uri(target->start, r->path->start, + r->path->length); + + } else { + p = nxt_cpymem(target->start, r->path->start, r->path->length); + } + + if (r->args->length > 0) { + *p++ = '?'; + p = nxt_cpymem(p, r->args->start, r->args->length); + } + + target->length = p - target->start; + + return NXT_OK; } diff --git a/src/nxt_http.h b/src/nxt_http.h index e812bd0d..23d86b91 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -192,6 +192,8 @@ struct nxt_http_request_s { nxt_http_status_t status:16; uint8_t log_route; /* 1 bit */ + uint8_t quoted_target; /* 1 bit */ + uint8_t uri_changed; /* 1 bit */ uint8_t pass_count; /* 8 bits */ uint8_t app_target; diff --git a/src/nxt_http_rewrite.c b/src/nxt_http_rewrite.c index fb216eeb..ff465ecc 100644 --- a/src/nxt_http_rewrite.c +++ b/src/nxt_http_rewrite.c @@ -103,6 +103,9 @@ nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r) *r->path = rp.path; + r->uri_changed = 1; + r->quoted_target = rp.quoted_target; + if (nxt_slow_path(r->log_route)) { nxt_log(task, NXT_LOG_NOTICE, "URI rewritten to \"%V\"", &r->target); } -- cgit From 678c05686996e0aa6ddf79bf71279425306e9113 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 16 Apr 2024 23:30:15 +0800 Subject: Fixes: 64934e59f ("HTTP: Introduce quoted target marker in HTTP parsing") Reviewed-by: Andrew Clayton --- src/test/nxt_http_parse_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/test/nxt_http_parse_test.c b/src/test/nxt_http_parse_test.c index 5f1a518c..474b3f8d 100644 --- a/src/test/nxt_http_parse_test.c +++ b/src/test/nxt_http_parse_test.c @@ -762,7 +762,7 @@ nxt_http_parse_test_request_line(nxt_http_request_parse_t *rp, return NXT_ERROR; } - if (rp->complex_target != (test->complex_target | test->quoted_target)) { + if (rp->complex_target != test->complex_target) { nxt_log_alert(log, "http parse test case failed:\n" " - request:\n\"%V\"\n" " - complex_target: %d (expected: %d)", @@ -770,7 +770,6 @@ nxt_http_parse_test_request_line(nxt_http_request_parse_t *rp, return NXT_ERROR; } -#if 0 if (rp->quoted_target != test->quoted_target) { nxt_log_alert(log, "http parse test case failed:\n" " - request:\n\"%V\"\n" @@ -779,6 +778,7 @@ nxt_http_parse_test_request_line(nxt_http_request_parse_t *rp, return NXT_ERROR; } +#if 0 if (rp->space_in_target != test->space_in_target) { nxt_log_alert(log, "http parse test case failed:\n" " - request:\n\"%V\"\n" -- cgit From 237a26aafc4f2572668d0063228929f482073691 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:54:12 +0000 Subject: wasm-wc: Bump the rustls crate from 0.21.10 to 0.21.11 Bumps from 0.21.10 to 0.21.11. "This release corrects a denial-of-service condition in rustls::ConnectionCommon::complete_io(), reachable via network input. If a close_notify alert is received during a handshake, complete_io() did not terminate. Callers which do not call complete_io() are not affected." The wasm-wasi-component language module is not effected by this as it doesn't handle client connections, Unit does. Link: Release notes Link: Commits Signed-off-by: dependabot[bot] Reviewed-by: Andrew Clayton [ Tweaked commit message/subject - Andrew ] Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wasm-wasi-component/Cargo.lock b/src/wasm-wasi-component/Cargo.lock index 7631b716..3c6b0410 100644 --- a/src/wasm-wasi-component/Cargo.lock +++ b/src/wasm-wasi-component/Cargo.lock @@ -1160,9 +1160,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", "ring", -- cgit From e5bc299d7a55a66e1ecf54d35dcdd9448c49f3d4 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 16 Apr 2024 19:22:59 +0100 Subject: configuration: Constify numerous pointers Mark numerous function argument pointers as 'const' in the configuration sub-system. This also does the same with a few functions in src/nxt_conf_validation.c that are required to accomplish the below, attacking the rest is an exercise for another day... While this is a worthwhile hardening exercise in its own right, the main impetus for this is to 'constify' some local function variables which are currently defined with 'static' storage class and turn them into 'static const', which will be done in a subsequent patch. Reviewed-by: Zhidao HONG Signed-off-by: Andrew Clayton --- src/nxt_conf.c | 73 ++++++++++++++++++++++++----------------------- src/nxt_conf.h | 59 ++++++++++++++++++++------------------ src/nxt_conf_validation.c | 10 +++---- 3 files changed, 74 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 9ae25172..3e9f9f4a 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -123,12 +123,12 @@ static u_char *nxt_conf_json_parse_number(nxt_mp_t *mp, nxt_conf_value_t *value, static void nxt_conf_json_parse_error(nxt_conf_json_error_t *error, u_char *pos, const char *detail); -static nxt_int_t nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, - nxt_conf_value_t *dst, nxt_conf_value_t *src); -static nxt_int_t nxt_conf_copy_array(nxt_mp_t *mp, nxt_conf_op_t *op, - nxt_conf_value_t *dst, nxt_conf_value_t *src); -static nxt_int_t nxt_conf_copy_object(nxt_mp_t *mp, nxt_conf_op_t *op, - nxt_conf_value_t *dst, nxt_conf_value_t *src); +static nxt_int_t nxt_conf_copy_value(nxt_mp_t *mp, const nxt_conf_op_t *op, + nxt_conf_value_t *dst, const nxt_conf_value_t *src); +static nxt_int_t nxt_conf_copy_array(nxt_mp_t *mp, const nxt_conf_op_t *op, + nxt_conf_value_t *dst, const nxt_conf_value_t *src); +static nxt_int_t nxt_conf_copy_object(nxt_mp_t *mp, const nxt_conf_op_t *op, + nxt_conf_value_t *dst, const nxt_conf_value_t *src); static size_t nxt_conf_json_string_length(nxt_conf_value_t *value); static u_char *nxt_conf_json_print_string(u_char *p, nxt_conf_value_t *value); @@ -186,7 +186,7 @@ nxt_conf_get_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str) void -nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str) +nxt_conf_set_string(nxt_conf_value_t *value, const nxt_str_t *str) { if (str->length > NXT_CONF_MAX_SHORT_STRING) { value->type = NXT_CONF_VALUE_STRING; @@ -245,7 +245,7 @@ nxt_conf_get_boolean(nxt_conf_value_t *value) nxt_uint_t -nxt_conf_object_members_count(nxt_conf_value_t *value) +nxt_conf_object_members_count(const nxt_conf_value_t *value) { return value->u.object->count; } @@ -276,7 +276,7 @@ nxt_conf_create_object(nxt_mp_t *mp, nxt_uint_t count) void -nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name, +nxt_conf_set_member(nxt_conf_value_t *object, const nxt_str_t *name, const nxt_conf_value_t *value, uint32_t index) { nxt_conf_object_member_t *member; @@ -290,8 +290,8 @@ nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name, nxt_int_t -nxt_conf_set_member_dup(nxt_conf_value_t *object, nxt_mp_t *mp, nxt_str_t *name, - nxt_conf_value_t *value, uint32_t index) +nxt_conf_set_member_dup(nxt_conf_value_t *object, nxt_mp_t *mp, + const nxt_str_t *name, const nxt_conf_value_t *value, uint32_t index) { nxt_conf_object_member_t *member; @@ -304,8 +304,8 @@ nxt_conf_set_member_dup(nxt_conf_value_t *object, nxt_mp_t *mp, nxt_str_t *name, void -nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name, - nxt_str_t *value, uint32_t index) +nxt_conf_set_member_string(nxt_conf_value_t *object, const nxt_str_t *name, + const nxt_str_t *value, uint32_t index) { nxt_conf_object_member_t *member; @@ -319,7 +319,7 @@ nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name, nxt_int_t nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp, - nxt_str_t *name, nxt_str_t *value, uint32_t index) + const nxt_str_t *name, const nxt_str_t *value, uint32_t index) { nxt_conf_object_member_t *member; @@ -332,7 +332,7 @@ nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp, void -nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name, +nxt_conf_set_member_integer(nxt_conf_value_t *object, const nxt_str_t *name, int64_t value, uint32_t index) { u_char *p, *end; @@ -353,7 +353,7 @@ nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name, void -nxt_conf_set_member_null(nxt_conf_value_t *object, nxt_str_t *name, +nxt_conf_set_member_null(nxt_conf_value_t *object, const nxt_str_t *name, uint32_t index) { nxt_conf_object_member_t *member; @@ -400,7 +400,7 @@ nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index, nxt_int_t nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp, - nxt_uint_t index, nxt_str_t *value) + nxt_uint_t index, const nxt_str_t *value) { nxt_conf_value_t *element; @@ -411,21 +411,21 @@ nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp, nxt_uint_t -nxt_conf_array_elements_count(nxt_conf_value_t *value) +nxt_conf_array_elements_count(const nxt_conf_value_t *value) { return value->u.array->count; } nxt_uint_t -nxt_conf_array_elements_count_or_1(nxt_conf_value_t *value) +nxt_conf_array_elements_count_or_1(const nxt_conf_value_t *value) { return (value->type == NXT_CONF_VALUE_ARRAY) ? value->u.array->count : 1; } nxt_uint_t -nxt_conf_type(nxt_conf_value_t *value) +nxt_conf_type(const nxt_conf_value_t *value) { switch (value->type) { @@ -459,7 +459,7 @@ nxt_conf_type(nxt_conf_value_t *value) nxt_conf_value_t * -nxt_conf_get_path(nxt_conf_value_t *value, nxt_str_t *path) +nxt_conf_get_path(nxt_conf_value_t *value, const nxt_str_t *path) { nxt_str_t token; nxt_int_t ret, index; @@ -550,7 +550,7 @@ nxt_conf_path_next_token(nxt_conf_path_parse_t *parse, nxt_str_t *token) nxt_conf_value_t * -nxt_conf_get_object_member(nxt_conf_value_t *value, nxt_str_t *name, +nxt_conf_get_object_member(const nxt_conf_value_t *value, const nxt_str_t *name, uint32_t *index) { nxt_str_t str; @@ -584,8 +584,8 @@ nxt_conf_get_object_member(nxt_conf_value_t *value, nxt_str_t *name, nxt_int_t -nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value, nxt_conf_map_t *map, - nxt_uint_t n, void *data) +nxt_conf_map_object(nxt_mp_t *mp, const nxt_conf_value_t *value, + const nxt_conf_map_t *map, nxt_uint_t n, void *data) { double num; nxt_str_t str, *s; @@ -736,7 +736,7 @@ nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value, nxt_conf_map_t *map, nxt_conf_value_t * -nxt_conf_next_object_member(nxt_conf_value_t *value, nxt_str_t *name, +nxt_conf_next_object_member(const nxt_conf_value_t *value, nxt_str_t *name, uint32_t *next) { uint32_t n; @@ -764,7 +764,7 @@ nxt_conf_next_object_member(nxt_conf_value_t *value, nxt_str_t *name, nxt_conf_value_t * -nxt_conf_get_array_element(nxt_conf_value_t *value, uint32_t index) +nxt_conf_get_array_element(const nxt_conf_value_t *value, uint32_t index) { nxt_conf_array_t *array; @@ -802,7 +802,7 @@ nxt_conf_get_array_element_or_itself(nxt_conf_value_t *value, uint32_t index) void -nxt_conf_array_qsort(nxt_conf_value_t *value, +nxt_conf_array_qsort(const nxt_conf_value_t *value, int (*compare)(const void *, const void *)) { nxt_conf_array_t *array; @@ -818,8 +818,9 @@ nxt_conf_array_qsort(nxt_conf_value_t *value, nxt_conf_op_ret_t -nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root, - nxt_str_t *path, nxt_conf_value_t *value, nxt_bool_t add) +nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, + const nxt_conf_value_t *root, const nxt_str_t *path, + nxt_conf_value_t *value, nxt_bool_t add) { nxt_str_t token; nxt_int_t ret, index; @@ -956,7 +957,7 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root, nxt_conf_value_t * -nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *value) +nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op, const nxt_conf_value_t *value) { nxt_int_t rc; nxt_conf_value_t *copy; @@ -977,8 +978,8 @@ nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *value) static nxt_int_t -nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst, - nxt_conf_value_t *src) +nxt_conf_copy_value(nxt_mp_t *mp, const nxt_conf_op_t *op, + nxt_conf_value_t *dst, const nxt_conf_value_t *src) { if (op != NULL && src->type != NXT_CONF_VALUE_ARRAY @@ -1020,8 +1021,8 @@ nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst, static nxt_int_t -nxt_conf_copy_array(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst, - nxt_conf_value_t *src) +nxt_conf_copy_array(nxt_mp_t *mp, const nxt_conf_op_t *op, + nxt_conf_value_t *dst, const nxt_conf_value_t *src) { size_t size; nxt_int_t rc; @@ -1120,8 +1121,8 @@ nxt_conf_copy_array(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst, static nxt_int_t -nxt_conf_copy_object(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst, - nxt_conf_value_t *src) +nxt_conf_copy_object(nxt_mp_t *mp, const nxt_conf_op_t *op, + nxt_conf_value_t *dst, const nxt_conf_value_t *src) { size_t size; nxt_int_t rc; diff --git a/src/nxt_conf.h b/src/nxt_conf.h index 626b6d4d..d1a475e5 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -79,27 +79,28 @@ typedef struct { } nxt_conf_validation_t; -NXT_EXPORT nxt_uint_t nxt_conf_type(nxt_conf_value_t *value); +NXT_EXPORT nxt_uint_t nxt_conf_type(const nxt_conf_value_t *value); NXT_EXPORT nxt_conf_value_t *nxt_conf_get_path(nxt_conf_value_t *value, - nxt_str_t *path); -NXT_EXPORT nxt_conf_value_t *nxt_conf_get_object_member(nxt_conf_value_t *value, - nxt_str_t *name, uint32_t *index); + const nxt_str_t *path); +NXT_EXPORT nxt_conf_value_t *nxt_conf_get_object_member( + const nxt_conf_value_t *value, const nxt_str_t *name, uint32_t *index); NXT_EXPORT nxt_conf_value_t *nxt_conf_next_object_member( - nxt_conf_value_t *value, nxt_str_t *name, uint32_t *next); -NXT_EXPORT nxt_conf_value_t *nxt_conf_get_array_element(nxt_conf_value_t *value, - uint32_t index); + const nxt_conf_value_t *value, nxt_str_t *name, uint32_t *next); +NXT_EXPORT nxt_conf_value_t *nxt_conf_get_array_element( + const nxt_conf_value_t *value, uint32_t index); NXT_EXPORT nxt_conf_value_t *nxt_conf_get_array_element_or_itself( nxt_conf_value_t *value, uint32_t index); -NXT_EXPORT nxt_int_t nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value, - nxt_conf_map_t *map, nxt_uint_t n, void *data); +NXT_EXPORT nxt_int_t nxt_conf_map_object(nxt_mp_t *mp, + const nxt_conf_value_t *value, const nxt_conf_map_t *map, nxt_uint_t n, + void *data); nxt_conf_op_ret_t nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, - nxt_conf_value_t *root, nxt_str_t *path, nxt_conf_value_t *value, + const nxt_conf_value_t *root, const nxt_str_t *path, nxt_conf_value_t *value, nxt_bool_t add); nxt_conf_value_t *nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op, - nxt_conf_value_t *value); + const nxt_conf_value_t *value); nxt_conf_value_t *nxt_conf_json_parse(nxt_mp_t *mp, u_char *start, u_char *end, nxt_conf_json_error_t *error); @@ -119,37 +120,41 @@ nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt); NXT_EXPORT void nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str); NXT_EXPORT nxt_str_t *nxt_conf_get_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str); -NXT_EXPORT void nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str); +NXT_EXPORT void nxt_conf_set_string(nxt_conf_value_t *value, + const nxt_str_t *str); NXT_EXPORT nxt_int_t nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, const nxt_str_t *str); NXT_EXPORT double nxt_conf_get_number(nxt_conf_value_t *value); NXT_EXPORT uint8_t nxt_conf_get_boolean(nxt_conf_value_t *value); // FIXME reimplement and reorder functions below -NXT_EXPORT nxt_uint_t nxt_conf_object_members_count(nxt_conf_value_t *value); +NXT_EXPORT nxt_uint_t nxt_conf_object_members_count( + const nxt_conf_value_t *value); nxt_conf_value_t *nxt_conf_create_object(nxt_mp_t *mp, nxt_uint_t count); -void nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name, +void nxt_conf_set_member(nxt_conf_value_t *object, const nxt_str_t *name, const nxt_conf_value_t *value, uint32_t index); nxt_int_t nxt_conf_set_member_dup(nxt_conf_value_t *object, nxt_mp_t *mp, - nxt_str_t *name, nxt_conf_value_t *value, uint32_t index); -void nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name, - nxt_str_t *value, uint32_t index); -nxt_int_t nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp, - nxt_str_t *name, nxt_str_t *value, uint32_t index); -void nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name, - int64_t value, uint32_t index); -void nxt_conf_set_member_null(nxt_conf_value_t *object, nxt_str_t *name, + const nxt_str_t *name, const nxt_conf_value_t *value, uint32_t index); +void nxt_conf_set_member_string(nxt_conf_value_t *object, + const nxt_str_t *name, const nxt_str_t *value, uint32_t index); +nxt_int_t nxt_conf_set_member_string_dup(nxt_conf_value_t *object, + nxt_mp_t *mp, const nxt_str_t *name, const nxt_str_t *value, + uint32_t index); +void nxt_conf_set_member_integer(nxt_conf_value_t *object, + const nxt_str_t *name, int64_t value, uint32_t index); +void nxt_conf_set_member_null(nxt_conf_value_t *object, const nxt_str_t *name, uint32_t index); nxt_conf_value_t *nxt_conf_create_array(nxt_mp_t *mp, nxt_uint_t count); void nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index, const nxt_conf_value_t *value); -nxt_int_t nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp, - nxt_uint_t index, nxt_str_t *value); -NXT_EXPORT nxt_uint_t nxt_conf_array_elements_count(nxt_conf_value_t *value); +nxt_int_t nxt_conf_set_element_string_dup(nxt_conf_value_t *array, + nxt_mp_t *mp, nxt_uint_t index, const nxt_str_t *value); +NXT_EXPORT nxt_uint_t nxt_conf_array_elements_count( + const nxt_conf_value_t *value); NXT_EXPORT nxt_uint_t nxt_conf_array_elements_count_or_1( - nxt_conf_value_t *value); -void nxt_conf_array_qsort(nxt_conf_value_t *value, + const nxt_conf_value_t *value); +void nxt_conf_array_qsort(const nxt_conf_value_t *value, int (*compare)(const void *, const void *)); diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 8f802fb7..38a918fb 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -73,11 +73,11 @@ struct nxt_conf_vldt_object_s { static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt, - nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type); + const nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type); static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...); -static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, - nxt_str_t *value); +static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, + const nxt_str_t *name, nxt_str_t *value); static nxt_int_t nxt_conf_vldt_if(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt, @@ -1436,7 +1436,7 @@ nxt_conf_validate(nxt_conf_validation_t *vldt) static nxt_int_t -nxt_conf_vldt_type(nxt_conf_validation_t *vldt, nxt_str_t *name, +nxt_conf_vldt_type(nxt_conf_validation_t *vldt, const nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type) { u_char *p; @@ -1548,7 +1548,7 @@ nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, static nxt_int_t -nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, +nxt_conf_vldt_var(nxt_conf_validation_t *vldt, const nxt_str_t *name, nxt_str_t *value) { u_char error[NXT_MAX_ERROR_STR]; -- cgit From 8f861cf4d15e8befca6edcee4b04b5304f082f05 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 16 Apr 2024 20:30:48 +0100 Subject: Constify a bunch of static local variables A common pattern was to declare variables in functions like static nxt_str_t ... Not sure why static, as they were being treated more like string literals (and of course they are _not_ thread safe), let's actually make them constants (qualifier wise). This handles core code conversion. Reviewed-by: Zhidao HONG Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 30 +++++++++++++-------------- src/nxt_controller.c | 20 +++++++++--------- src/nxt_http_route.c | 4 ++-- src/nxt_isolation.c | 24 +++++++++++----------- src/nxt_js.c | 15 +++++++------- src/nxt_router.c | 46 +++++++++++++++++++++++------------------- src/nxt_router_access_log.c | 2 +- src/nxt_unit.c | 6 +++--- src/nxt_upstream.c | 2 +- src/nxt_upstream_round_robin.c | 4 ++-- 10 files changed, 79 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 38a918fb..4aaa1b9a 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1445,7 +1445,7 @@ nxt_conf_vldt_type(nxt_conf_validation_t *vldt, const nxt_str_t *name, nxt_uint_t value_type, n, t; u_char buf[nxt_length(NXT_CONF_VLDT_ANY_TYPE_STR)]; - static nxt_str_t type_name[] = { + static const nxt_str_t type_name[] = { nxt_string("a null"), nxt_string("a boolean"), nxt_string("an integer number"), @@ -1568,7 +1568,7 @@ nxt_conf_vldt_if(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, { nxt_str_t str; - static nxt_str_t if_str = nxt_string("if"); + static const nxt_str_t if_str = nxt_string("if"); if (nxt_conf_type(value) != NXT_CONF_STRING) { return nxt_conf_vldt_error(vldt, "The \"if\" must be a string"); @@ -1731,7 +1731,7 @@ nxt_conf_vldt_action(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, nxt_conf_value_t *action; nxt_conf_vldt_object_t *members; - static struct { + static const struct { nxt_str_t name; nxt_conf_vldt_object_t *members; @@ -1778,7 +1778,7 @@ nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, nxt_int_t ret; nxt_str_t segments[3]; - static nxt_str_t targets_str = nxt_string("targets"); + static const nxt_str_t targets_str = nxt_string("targets"); nxt_conf_get_string(value, &pass); @@ -1932,7 +1932,7 @@ nxt_conf_vldt_share_element(nxt_conf_validation_t *vldt, { nxt_str_t str; - static nxt_str_t share = nxt_string("share"); + static const nxt_str_t share = nxt_string("share"); if (nxt_conf_type(value) != NXT_CONF_STRING) { return nxt_conf_vldt_error(vldt, "The \"share\" array must " @@ -1982,7 +1982,7 @@ nxt_conf_vldt_python(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, { nxt_conf_value_t *targets; - static nxt_str_t targets_str = nxt_string("targets"); + static const nxt_str_t targets_str = nxt_string("targets"); targets = nxt_conf_get_object_member(value, &targets_str, NULL); @@ -2575,7 +2575,7 @@ nxt_conf_vldt_response_header(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_str_t str; nxt_uint_t type; - static nxt_str_t content_length = nxt_string("Content-Length"); + static const nxt_str_t content_length = nxt_string("Content-Length"); if (name->length == 0) { return nxt_conf_vldt_error(vldt, "The response header name " @@ -2615,7 +2615,7 @@ nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, nxt_str_t name; nxt_conf_value_t *apps, *app; - static nxt_str_t apps_str = nxt_string("applications"); + static const nxt_str_t apps_str = nxt_string("applications"); nxt_conf_get_string(value, &name); @@ -2647,8 +2647,8 @@ nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, { nxt_conf_value_t *client_ip, *protocol; - static nxt_str_t client_ip_str = nxt_string("client_ip"); - static nxt_str_t protocol_str = nxt_string("protocol"); + static const nxt_str_t client_ip_str = nxt_string("client_ip"); + static const nxt_str_t protocol_str = nxt_string("protocol"); client_ip = nxt_conf_get_object_member(value, &client_ip_str, NULL); protocol = nxt_conf_get_object_member(value, &protocol_str, NULL); @@ -2673,9 +2673,9 @@ nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *type_value; nxt_app_lang_module_t *lang; - static nxt_str_t type_str = nxt_string("type"); + static const nxt_str_t type_str = nxt_string("type"); - static struct { + static const struct { nxt_conf_vldt_handler_t validator; nxt_conf_vldt_object_t *members; @@ -3188,7 +3188,7 @@ nxt_conf_vldt_php(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, { nxt_conf_value_t *targets; - static nxt_str_t targets_str = nxt_string("targets"); + static const nxt_str_t targets_str = nxt_string("targets"); targets = nxt_conf_get_object_member(value, &targets_str, NULL); @@ -3269,7 +3269,7 @@ nxt_conf_vldt_upstream(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_int_t ret; nxt_conf_value_t *conf; - static nxt_str_t servers = nxt_string("servers"); + static const nxt_str_t servers = nxt_string("servers"); ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_VLDT_OBJECT); @@ -3414,7 +3414,7 @@ nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, nxt_int_t ret; nxt_conf_vldt_access_log_conf_t conf; - static nxt_str_t format_str = nxt_string("format"); + static const nxt_str_t format_str = nxt_string("format"); if (nxt_conf_type(value) == NXT_CONF_STRING) { return NXT_OK; diff --git a/src/nxt_controller.c b/src/nxt_controller.c index eb814321..230a4d5d 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -1912,8 +1912,8 @@ nxt_controller_cert_in_use(nxt_str_t *name) nxt_str_t str; nxt_conf_value_t *listeners, *listener, *value; - static nxt_str_t listeners_path = nxt_string("/listeners"); - static nxt_str_t certificate_path = nxt_string("/tls/certificate"); + static const nxt_str_t listeners_path = nxt_string("/listeners"); + static const nxt_str_t certificate_path = nxt_string("/tls/certificate"); listeners = nxt_conf_get_path(nxt_controller_conf.root, &listeners_path); @@ -2178,7 +2178,7 @@ nxt_controller_script_in_use(nxt_str_t *name) nxt_str_t str; nxt_conf_value_t *js_module, *element; - static nxt_str_t js_module_path = nxt_string("/settings/js_module"); + static const nxt_str_t js_module_path = nxt_string("/settings/js_module"); js_module = nxt_conf_get_path(nxt_controller_conf.root, &js_module_path); @@ -2486,13 +2486,13 @@ nxt_controller_response(nxt_task_t *task, nxt_controller_request_t *req, nxt_conf_value_t *value, *location; nxt_conf_json_pretty_t pretty; - static nxt_str_t success_str = nxt_string("success"); - static nxt_str_t error_str = nxt_string("error"); - static nxt_str_t detail_str = nxt_string("detail"); - static nxt_str_t location_str = nxt_string("location"); - static nxt_str_t offset_str = nxt_string("offset"); - static nxt_str_t line_str = nxt_string("line"); - static nxt_str_t column_str = nxt_string("column"); + static const nxt_str_t success_str = nxt_string("success"); + static const nxt_str_t error_str = nxt_string("error"); + static const nxt_str_t detail_str = nxt_string("detail"); + static const nxt_str_t location_str = nxt_string("location"); + static const nxt_str_t offset_str = nxt_string("offset"); + static const nxt_str_t line_str = nxt_string("line"); + static const nxt_str_t column_str = nxt_string("column"); static nxt_time_string_t date_cache = { (nxt_atomic_uint_t) -1, diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index d16d5803..98ff5404 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -405,8 +405,8 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_route_addr_rule_t *addr_rule; nxt_http_route_match_conf_t mtcf; - static nxt_str_t match_path = nxt_string("/match"); - static nxt_str_t action_path = nxt_string("/action"); + static const nxt_str_t match_path = nxt_string("/match"); + static const nxt_str_t action_path = nxt_string("/action"); match_conf = nxt_conf_get_path(cv, &match_path); diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index ed5e0d76..a2913872 100644 --- a/src/nxt_isolation.c +++ b/src/nxt_isolation.c @@ -224,8 +224,8 @@ nxt_isolation_set_cgroup(nxt_task_t *task, nxt_conf_value_t *isolation, nxt_str_t str; nxt_conf_value_t *obj; - static nxt_str_t cgname = nxt_string("cgroup"); - static nxt_str_t path = nxt_string("path"); + static const nxt_str_t cgname = nxt_string("cgroup"); + static const nxt_str_t path = nxt_string("path"); obj = nxt_conf_get_object_member(isolation, &cgname, NULL); if (obj == NULL) { @@ -260,7 +260,7 @@ nxt_isolation_set_namespaces(nxt_task_t *task, nxt_conf_value_t *isolation, nxt_int_t ret; nxt_conf_value_t *obj; - static nxt_str_t nsname = nxt_string("namespaces"); + static const nxt_str_t nsname = nxt_string("namespaces"); obj = nxt_conf_get_object_member(isolation, &nsname, NULL); if (obj != NULL) { @@ -286,8 +286,8 @@ nxt_isolation_set_creds(nxt_task_t *task, nxt_conf_value_t *isolation, nxt_clone_t *clone; nxt_conf_value_t *array; - static nxt_str_t uidname = nxt_string("uidmap"); - static nxt_str_t gidname = nxt_string("gidmap"); + static const nxt_str_t uidname = nxt_string("uidmap"); + static const nxt_str_t gidname = nxt_string("gidmap"); clone = &process->isolation.clone; @@ -323,7 +323,7 @@ nxt_isolation_credential_map(nxt_task_t *task, nxt_mp_t *mp, nxt_uint_t i; nxt_conf_value_t *obj; - static nxt_conf_map_t nxt_clone_map_entry_conf[] = { + static const nxt_conf_map_t nxt_clone_map_entry_conf[] = { { nxt_string("container"), NXT_CONF_MAP_INT64, @@ -496,7 +496,7 @@ nxt_isolation_set_rootfs(nxt_task_t *task, nxt_conf_value_t *isolation, nxt_str_t str; nxt_conf_value_t *obj; - static nxt_str_t rootfs_name = nxt_string("rootfs"); + static const nxt_str_t rootfs_name = nxt_string("rootfs"); obj = nxt_conf_get_object_member(isolation, &rootfs_name, NULL); if (obj != NULL) { @@ -536,10 +536,10 @@ nxt_isolation_set_automount(nxt_task_t *task, nxt_conf_value_t *isolation, nxt_conf_value_t *conf, *value; nxt_process_automount_t *automount; - static nxt_str_t automount_name = nxt_string("automount"); - static nxt_str_t langdeps_name = nxt_string("language_deps"); - static nxt_str_t tmp_name = nxt_string("tmpfs"); - static nxt_str_t proc_name = nxt_string("procfs"); + static const nxt_str_t automount_name = nxt_string("automount"); + static const nxt_str_t langdeps_name = nxt_string("language_deps"); + static const nxt_str_t tmp_name = nxt_string("tmpfs"); + static const nxt_str_t proc_name = nxt_string("procfs"); automount = &process->isolation.automount; @@ -1110,7 +1110,7 @@ nxt_isolation_set_new_privs(nxt_task_t *task, nxt_conf_value_t *isolation, { nxt_conf_value_t *obj; - static nxt_str_t new_privs_name = nxt_string("new_privs"); + static const nxt_str_t new_privs_name = nxt_string("new_privs"); obj = nxt_conf_get_object_member(isolation, &new_privs_name, NULL); if (obj != NULL) { diff --git a/src/nxt_js.c b/src/nxt_js.c index 1f9a3ceb..d46231bd 100644 --- a/src/nxt_js.c +++ b/src/nxt_js.c @@ -124,9 +124,9 @@ nxt_js_vm_create(nxt_js_conf_t *jcf) njs_vm_opt_t opts; nxt_js_module_t *module, *mod; - static nxt_str_t import_str = nxt_string("import"); - static nxt_str_t from_str = nxt_string("from"); - static nxt_str_t global_str = nxt_string("globalThis"); + static const nxt_str_t import_str = nxt_string("import"); + static const nxt_str_t from_str = nxt_string("from"); + static const nxt_str_t global_str = nxt_string("globalThis"); njs_vm_opt_init(&opts); @@ -237,14 +237,15 @@ nxt_js_add_tpl(nxt_js_conf_t *jcf, nxt_str_t *str, nxt_bool_t strz) nxt_js_t *js; nxt_str_t *func; - static nxt_str_t func_str = nxt_string("function(uri, host, remoteAddr, " - "args, headers, cookies, vars) {" - " return "); + static const nxt_str_t func_str = + nxt_string("function(uri, host, remoteAddr, " + "args, headers, cookies, vars) {" + " return "); /* * Appending a terminating null character if strz is true. */ - static nxt_str_t strz_str = nxt_string(" + '\\x00'"); + static const nxt_str_t strz_str = nxt_string(" + '\\x00'"); size = func_str.length + str->length + 1; diff --git a/src/nxt_router.c b/src/nxt_router.c index e395929e..48870d20 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1634,25 +1634,29 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_router_app_conf_t apcf; nxt_router_listener_conf_t lscf; - static nxt_str_t http_path = nxt_string("/settings/http"); - static nxt_str_t applications_path = nxt_string("/applications"); - static nxt_str_t listeners_path = nxt_string("/listeners"); - static nxt_str_t routes_path = nxt_string("/routes"); - static nxt_str_t access_log_path = nxt_string("/access_log"); + static const nxt_str_t http_path = nxt_string("/settings/http"); + static const nxt_str_t applications_path = nxt_string("/applications"); + static const nxt_str_t listeners_path = nxt_string("/listeners"); + static const nxt_str_t routes_path = nxt_string("/routes"); + static const nxt_str_t access_log_path = nxt_string("/access_log"); #if (NXT_TLS) - static nxt_str_t certificate_path = nxt_string("/tls/certificate"); - static nxt_str_t conf_commands_path = nxt_string("/tls/conf_commands"); - static nxt_str_t conf_cache_path = nxt_string("/tls/session/cache_size"); - static nxt_str_t conf_timeout_path = nxt_string("/tls/session/timeout"); - static nxt_str_t conf_tickets = nxt_string("/tls/session/tickets"); + static const nxt_str_t certificate_path = nxt_string("/tls/certificate"); + static const nxt_str_t conf_commands_path = + nxt_string("/tls/conf_commands"); + static const nxt_str_t conf_cache_path = + nxt_string("/tls/session/cache_size"); + static const nxt_str_t conf_timeout_path = + nxt_string("/tls/session/timeout"); + static const nxt_str_t conf_tickets = nxt_string("/tls/session/tickets"); #endif #if (NXT_HAVE_NJS) - static nxt_str_t js_module_path = nxt_string("/settings/js_module"); + static const nxt_str_t js_module_path = nxt_string("/settings/js_module"); #endif - static nxt_str_t static_path = nxt_string("/settings/http/static"); - static nxt_str_t websocket_path = nxt_string("/settings/http/websocket"); - static nxt_str_t forwarded_path = nxt_string("/forwarded"); - static nxt_str_t client_ip_path = nxt_string("/client_ip"); + static const nxt_str_t static_path = nxt_string("/settings/http/static"); + static const nxt_str_t websocket_path = + nxt_string("/settings/http/websocket"); + static const nxt_str_t forwarded_path = nxt_string("/forwarded"); + static const nxt_str_t client_ip_path = nxt_string("/client_ip"); root = nxt_conf_json_parse(tmcf->mem_pool, start, end, NULL); if (root == NULL) { @@ -2283,7 +2287,7 @@ nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_uint_t exts; nxt_conf_value_t *mtypes_conf, *ext_conf, *value; - static nxt_str_t mtypes_path = nxt_string("/mime_types"); + static const nxt_str_t mtypes_path = nxt_string("/mime_types"); mp = rtcf->mem_pool; @@ -2360,11 +2364,11 @@ nxt_router_conf_forward(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *conf) nxt_http_forward_t *forward; nxt_http_route_addr_rule_t *source; - static nxt_str_t header_path = nxt_string("/header"); - static nxt_str_t client_ip_path = nxt_string("/client_ip"); - static nxt_str_t protocol_path = nxt_string("/protocol"); - static nxt_str_t source_path = nxt_string("/source"); - static nxt_str_t recursive_path = nxt_string("/recursive"); + static const nxt_str_t header_path = nxt_string("/header"); + static const nxt_str_t client_ip_path = nxt_string("/client_ip"); + static const nxt_str_t protocol_path = nxt_string("/protocol"); + static const nxt_str_t source_path = nxt_string("/source"); + static const nxt_str_t recursive_path = nxt_string("/recursive"); header_conf = nxt_conf_get_path(conf, &header_path); diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c index 7fc59972..ff17b0b6 100644 --- a/src/nxt_router_access_log.c +++ b/src/nxt_router_access_log.c @@ -75,7 +75,7 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_router_access_log_t *access_log; nxt_router_access_log_conf_t alcf; - static nxt_str_t log_format_str = nxt_string("$remote_addr - - " + static const nxt_str_t log_format_str = nxt_string("$remote_addr - - " "[$time_local] \"$request_line\" $status $body_bytes_sent " "\"$header_referer\" \"$header_user_agent\""); diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 576c751d..50e156d8 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -1948,9 +1948,9 @@ nxt_unit_request_group_dup_fields(nxt_unit_request_info_t *req) nxt_unit_field_t *fields, f; nxt_unit_request_t *r; - static nxt_str_t content_length = nxt_string("content-length"); - static nxt_str_t content_type = nxt_string("content-type"); - static nxt_str_t cookie = nxt_string("cookie"); + static const nxt_str_t content_length = nxt_string("content-length"); + static const nxt_str_t content_type = nxt_string("content-type"); + static const nxt_str_t cookie = nxt_string("cookie"); nxt_unit_req_debug(req, "group_dup_fields"); diff --git a/src/nxt_upstream.c b/src/nxt_upstream.c index 17593173..c92d4a50 100644 --- a/src/nxt_upstream.c +++ b/src/nxt_upstream.c @@ -25,7 +25,7 @@ nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_upstreams_t *upstreams; nxt_conf_value_t *upstreams_conf, *upcf; - static nxt_str_t upstreams_name = nxt_string("upstreams"); + static const nxt_str_t upstreams_name = nxt_string("upstreams"); upstreams_conf = nxt_conf_get_object_member(conf, &upstreams_name, NULL); diff --git a/src/nxt_upstream_round_robin.c b/src/nxt_upstream_round_robin.c index 31e2f48a..1274f5a9 100644 --- a/src/nxt_upstream_round_robin.c +++ b/src/nxt_upstream_round_robin.c @@ -52,8 +52,8 @@ nxt_upstream_round_robin_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *servers_conf, *srvcf, *wtcf; nxt_upstream_round_robin_t *urr; - static nxt_str_t servers = nxt_string("servers"); - static nxt_str_t weight = nxt_string("weight"); + static const nxt_str_t servers = nxt_string("servers"); + static const nxt_str_t weight = nxt_string("weight"); mp = tmcf->router_conf->mem_pool; -- cgit From 33c978cc24de3110b763354d97a907982f664b23 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 16 Apr 2024 20:40:35 +0100 Subject: php: Constify some local static variables A common pattern was to declare variables in functions like static nxt_str_t ... Not sure why static, as they were being treated more like string literals, let's actually make them constants (qualifier wise). Reviewed-by: Zhidao HONG Signed-off-by: Andrew Clayton --- src/nxt_php_sapi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c index 77117533..da667b66 100644 --- a/src/nxt_php_sapi.c +++ b/src/nxt_php_sapi.c @@ -377,9 +377,9 @@ nxt_php_setup(nxt_task_t *task, nxt_process_t *process, nxt_conf_value_t *value; nxt_php_app_conf_t *c; - static nxt_str_t file_str = nxt_string("file"); - static nxt_str_t user_str = nxt_string("user"); - static nxt_str_t admin_str = nxt_string("admin"); + static const nxt_str_t file_str = nxt_string("file"); + static const nxt_str_t user_str = nxt_string("user"); + static const nxt_str_t admin_str = nxt_string("admin"); c = &conf->u.php; @@ -529,9 +529,9 @@ nxt_php_set_target(nxt_task_t *task, nxt_php_target_t *target, nxt_int_t ret; nxt_conf_value_t *value; - static nxt_str_t root_str = nxt_string("root"); - static nxt_str_t script_str = nxt_string("script"); - static nxt_str_t index_str = nxt_string("index"); + static const nxt_str_t root_str = nxt_string("root"); + static const nxt_str_t script_str = nxt_string("script"); + static const nxt_str_t index_str = nxt_string("index"); value = nxt_conf_get_object_member(conf, &root_str, NULL); -- cgit From 31cec908cd9d431eb8632b53b9bbd96caac56bfd Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 17 Apr 2024 15:50:40 +0100 Subject: configuration: Constify more pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This continues the patch series constifying various pointers in the configuration sub-system. This is done as a separate commit as it involved a _slightly_ more invasive change in nxt_conf_get_string(). While it takes a value parameter that is never modified, simply making it const results in CC build/src/nxt_conf.o src/nxt_conf.c: In function ‘nxt_conf_get_string’: src/nxt_conf.c:170:20: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 170 | str->start = value->u.str.start; | ^ due to the assignment operator. Making value const will allow for numerous other constification and seeing as we are not modifying it, seems worthwhile. We can get around the warning by casting ->u.{str,string}.start Reviewed-by: Zhidao HONG Signed-off-by: Andrew Clayton --- src/nxt_conf.c | 43 +++++++++++++++++++++++-------------------- src/nxt_conf.h | 9 +++++---- 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 3e9f9f4a..bb229c33 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -130,16 +130,17 @@ static nxt_int_t nxt_conf_copy_array(nxt_mp_t *mp, const nxt_conf_op_t *op, static nxt_int_t nxt_conf_copy_object(nxt_mp_t *mp, const nxt_conf_op_t *op, nxt_conf_value_t *dst, const nxt_conf_value_t *src); -static size_t nxt_conf_json_string_length(nxt_conf_value_t *value); -static u_char *nxt_conf_json_print_string(u_char *p, nxt_conf_value_t *value); -static size_t nxt_conf_json_array_length(nxt_conf_value_t *value, +static size_t nxt_conf_json_string_length(const nxt_conf_value_t *value); +static u_char *nxt_conf_json_print_string(u_char *p, + const nxt_conf_value_t *value); +static size_t nxt_conf_json_array_length(const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); -static u_char *nxt_conf_json_print_array(u_char *p, nxt_conf_value_t *value, - nxt_conf_json_pretty_t *pretty); -static size_t nxt_conf_json_object_length(nxt_conf_value_t *value, - nxt_conf_json_pretty_t *pretty); -static u_char *nxt_conf_json_print_object(u_char *p, nxt_conf_value_t *value, +static u_char *nxt_conf_json_print_array(u_char *p, + const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); +static size_t nxt_conf_json_object_length(const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); +static u_char *nxt_conf_json_print_object(u_char *p, + const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); static size_t nxt_conf_json_escape_length(u_char *p, size_t size); static u_char *nxt_conf_json_escape(u_char *dst, u_char *src, size_t size); @@ -162,21 +163,22 @@ nxt_conf_json_indentation(u_char *p, uint32_t level) void -nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str) +nxt_conf_get_string(const nxt_conf_value_t *value, nxt_str_t *str) { if (value->type == NXT_CONF_VALUE_SHORT_STRING) { str->length = value->u.str.length; - str->start = value->u.str.start; + str->start = (u_char *) value->u.str.start; } else { str->length = value->u.string.length; - str->start = value->u.string.start; + str->start = (u_char *) value->u.string.start; } } nxt_str_t * -nxt_conf_get_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str) +nxt_conf_get_string_dup(const nxt_conf_value_t *value, nxt_mp_t *mp, + nxt_str_t *str) { nxt_str_t s; @@ -2233,7 +2235,8 @@ nxt_conf_json_parse_error(nxt_conf_json_error_t *error, u_char *pos, size_t -nxt_conf_json_length(nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) +nxt_conf_json_length(const nxt_conf_value_t *value, + nxt_conf_json_pretty_t *pretty) { switch (value->type) { @@ -2265,7 +2268,7 @@ nxt_conf_json_length(nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) u_char * -nxt_conf_json_print(u_char *p, nxt_conf_value_t *value, +nxt_conf_json_print(u_char *p, const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) { switch (value->type) { @@ -2299,7 +2302,7 @@ nxt_conf_json_print(u_char *p, nxt_conf_value_t *value, static size_t -nxt_conf_json_string_length(nxt_conf_value_t *value) +nxt_conf_json_string_length(const nxt_conf_value_t *value) { nxt_str_t str; @@ -2310,7 +2313,7 @@ nxt_conf_json_string_length(nxt_conf_value_t *value) static u_char * -nxt_conf_json_print_string(u_char *p, nxt_conf_value_t *value) +nxt_conf_json_print_string(u_char *p, const nxt_conf_value_t *value) { nxt_str_t str; @@ -2327,7 +2330,7 @@ nxt_conf_json_print_string(u_char *p, nxt_conf_value_t *value) static size_t -nxt_conf_json_array_length(nxt_conf_value_t *value, +nxt_conf_json_array_length(const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) { size_t len; @@ -2369,7 +2372,7 @@ nxt_conf_json_array_length(nxt_conf_value_t *value, static u_char * -nxt_conf_json_print_array(u_char *p, nxt_conf_value_t *value, +nxt_conf_json_print_array(u_char *p, const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) { nxt_uint_t n; @@ -2421,7 +2424,7 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_value_t *value, static size_t -nxt_conf_json_object_length(nxt_conf_value_t *value, +nxt_conf_json_object_length(const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) { size_t len; @@ -2465,7 +2468,7 @@ nxt_conf_json_object_length(nxt_conf_value_t *value, static u_char * -nxt_conf_json_print_object(u_char *p, nxt_conf_value_t *value, +nxt_conf_json_print_object(u_char *p, const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty) { nxt_uint_t n; diff --git a/src/nxt_conf.h b/src/nxt_conf.h index d1a475e5..493d6480 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -108,17 +108,18 @@ nxt_conf_value_t *nxt_conf_json_parse(nxt_mp_t *mp, u_char *start, u_char *end, #define nxt_conf_json_parse_str(mp, str) \ nxt_conf_json_parse(mp, (str)->start, (str)->start + (str)->length, NULL) -size_t nxt_conf_json_length(nxt_conf_value_t *value, +size_t nxt_conf_json_length(const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); -u_char *nxt_conf_json_print(u_char *p, nxt_conf_value_t *value, +u_char *nxt_conf_json_print(u_char *p, const nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); void nxt_conf_json_position(u_char *start, const u_char *pos, nxt_uint_t *line, nxt_uint_t *column); nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt); -NXT_EXPORT void nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str); -NXT_EXPORT nxt_str_t *nxt_conf_get_string_dup(nxt_conf_value_t *value, +NXT_EXPORT void nxt_conf_get_string(const nxt_conf_value_t *value, + nxt_str_t *str); +NXT_EXPORT nxt_str_t *nxt_conf_get_string_dup(const nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str); NXT_EXPORT void nxt_conf_set_string(nxt_conf_value_t *value, const nxt_str_t *str); -- cgit From b26c119f4e535f617c9ffb10076f15c4ee54414d Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 22 Apr 2024 15:04:29 +0100 Subject: Tighten up some string arrays This is the normal way of declaring such things. Reviewed-by: Zhidao HONG Signed-off-by: Andrew Clayton --- src/nxt_controller.c | 9 +++++---- src/nxt_http.h | 9 +++++---- src/nxt_http_variables.c | 5 +++-- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 230a4d5d..30d5f04e 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -2652,11 +2652,12 @@ static u_char * nxt_controller_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format) { - static const char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", - "Sat" }; + static const char * const week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", + "Fri", "Sat" }; - static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + static const char * const month[] = { "Jan", "Feb", "Mar", "Apr", "May", + "Jun", "Jul", "Aug", "Sep", "Oct", + "Nov", "Dec" }; return nxt_sprintf(buf, buf + size, format, week[tm->tm_wday], tm->tm_mday, diff --git a/src/nxt_http.h b/src/nxt_http.h index 23d86b91..5fab5c67 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -305,11 +305,12 @@ struct nxt_http_forward_s { nxt_inline u_char * nxt_http_date(u_char *buf, struct tm *tm) { - static const char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", - "Sat" }; + static const char * const week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", + "Fri", "Sat" }; - static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + static const char * const month[] = { "Jan", "Feb", "Mar", "Apr", "May", + "Jun", "Jul", "Aug", "Sep", "Oct", + "Nov", "Dec" }; return nxt_sprintf(buf, buf + NXT_HTTP_DATE_LEN, "%s, %02d %s %4d %02d:%02d:%02d GMT", diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 85ae6004..3a1746b3 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -366,8 +366,9 @@ nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, u_char sign; time_t gmtoff; - static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + static const char * const month[] = { "Jan", "Feb", "Mar", "Apr", "May", + "Jun", "Jul", "Aug", "Sep", "Oct", + "Nov", "Dec" }; gmtoff = nxt_timezone(tm) / 60; -- cgit From e2a09c7742d2b74e3896ef99d3941ab1e46d2a15 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 13 Apr 2023 19:42:04 +0100 Subject: Convert 0-sized arrays to true flexible array members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declaring a 0-sized array (e.g 'char arr[0];') as the last member of a structure is a GNU extension that was used to implement flexible array members (FAMs) before they were standardised in C99 as simply '[]'. The GNU extension itself was introduced to work around a hack of declaring 1-sized arrays to mean a variable-length object. The advantage of the 0-sized (and true FAMs) is that they don't count towards the size of the structure. Unit already declares some true FAMs, but it also declared some 0-sized arrays. Converting these 0-sized arrays to true FAMs is not only good for consistency but will also allow better compiler checks now (as in a C99 FAM *must* be the last member of a structure and the compiler will warn otherwise) and in the future as doing this fixes a bunch of warnings (treated as errors in Unit by default) when compiled with -O2 -Warray-bounds -Wstrict-flex-arrays -fstrict-flex-arrays=3 (Note -Warray-bounds is enabled by -Wall and -Wstrict-flex-arrays seems to also be enabled via -Wall -Wextra, the -02 is required to make -fstrict-flex-arrays more effective, =3 is the default on at least GCC 14) such as CC build/src/nxt_upstream.o src/nxt_upstream.c: In function ‘nxt_upstreams_create’: src/nxt_upstream.c:56:18: error: array subscript i is outside array bounds of ‘nxt_upstream_t[0]’ {aka ‘struct nxt_upstream_s[]’} [-Werror=array-bounds=] 56 | string = nxt_str_dup(mp, &upstreams->upstream[i].name, &name); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from src/nxt_upstream.c:9: src/nxt_upstream.h:55:48: note: while referencing ‘upstream’ 55 | nxt_upstream_t upstream[0]; | ^~~~~~~~ Making our flexible array members proper C99 FAMs and ensuring any >0 sized trailing arrays in structures are really normal arrays will allow to enable various compiler options (such as the above and more) that will help keep our array usage safe. Changing 0-sized arrays to FAMs should have no effect on structure layouts/sizes (they both have a size of 0, although doing a sizeof() on a FAM will result in a compiler error). Looking at pahole(1) output for the nxt_http_route_ruleset_t structure for the [0] and [] cases... $ pahole -C nxt_http_route_ruleset_t /tmp/build/src/nxt_http_route.o typedef struct { uint32_t items; /* 0 4 */ /* XXX 4 bytes hole, try to pack */ nxt_http_route_rule_t * rule[]; /* 8 0 */ /* size: 8, cachelines: 1, members: 2 */ /* sum members: 4, holes: 1, sum holes: 4 */ /* last cacheline: 8 bytes */ } nxt_http_route_ruleset_t; $ pahole -C nxt_http_route_ruleset_t build/src/nxt_http_route.o typedef struct { uint32_t items; /* 0 4 */ /* XXX 4 bytes hole, try to pack */ nxt_http_route_rule_t * rule[]; /* 8 0 */ /* size: 8, cachelines: 1, members: 2 */ /* sum members: 4, holes: 1, sum holes: 4 */ /* last cacheline: 8 bytes */ } nxt_http_route_ruleset_t; Also checking with the size(1) command on the effected object files shows no changes to their sizes $ for file in build/src/nxt_upstream.o \ build/src/nxt_upstream_round_robin.o \ build/src/nxt_h1proto.o \ build/src/nxt_http_route.o \ build/src/nxt_http_proxy.o \ build/src/python/*.o; do \ size -G /tmp/${file} $file; echo; done text data bss total filename 640 418 0 1058 /tmp/build/src/nxt_upstream.o 640 418 0 1058 build/src/nxt_upstream.o text data bss total filename 929 351 0 1280 /tmp/build/src/nxt_upstream_round_robin.o 929 351 0 1280 build/src/nxt_upstream_round_robin.o text data bss total filename 11707 8281 16 20004 /tmp/build/src/nxt_h1proto.o 11707 8281 16 20004 build/src/nxt_h1proto.o text data bss total filename 8319 3101 0 11420 /tmp/build/src/nxt_http_route.o 8319 3101 0 11420 build/src/nxt_http_route.o text data bss total filename 1495 1056 0 2551 /tmp/build/src/nxt_http_proxy.o 1495 1056 0 2551 build/src/nxt_http_proxy.o text data bss total filename 4321 2895 0 7216 /tmp/build/src/python/nxt_python_asgi_http-python.o 4321 2895 0 7216 build/src/python/nxt_python_asgi_http-python.o text data bss total filename 4231 2266 0 6497 /tmp/build/src/python/nxt_python_asgi_lifespan-python.o 4231 2266 0 6497 build/src/python/nxt_python_asgi_lifespan-python.o text data bss total filename 12051 6090 8 18149 /tmp/build/src/python/nxt_python_asgi-python.o 12051 6090 8 18149 build/src/python/nxt_python_asgi-python.o text data bss total filename 28 1963 432 2423 /tmp/build/src/python/nxt_python_asgi_str-python.o 28 1963 432 2423 build/src/python/nxt_python_asgi_str-python.o text data bss total filename 5818 3518 0 9336 /tmp/build/src/python/nxt_python_asgi_websocket-python.o 5818 3518 0 9336 build/src/python/nxt_python_asgi_websocket-python.o text data bss total filename 4391 2089 168 6648 /tmp/build/src/python/nxt_python-python.o 4391 2089 168 6648 build/src/python/nxt_python-python.o text data bss total filename 9095 5909 152 15156 /tmp/build/src/python/nxt_python_wsgi-python.o 9095 5909 152 15156 build/src/python/nxt_python_wsgi-python.o Link: Link: Signed-off-by: Andrew Clayton --- src/nxt_http_route.c | 14 +++++++------- src/nxt_upstream.h | 2 +- src/nxt_upstream_round_robin.c | 2 +- src/python/nxt_python.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 98ff5404..852f5739 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -103,13 +103,13 @@ struct nxt_http_route_rule_s { } name; } u; - nxt_http_route_pattern_t pattern[0]; + nxt_http_route_pattern_t pattern[]; }; typedef struct { uint32_t items; - nxt_http_route_rule_t *rule[0]; + nxt_http_route_rule_t *rule[]; } nxt_http_route_ruleset_t; @@ -117,7 +117,7 @@ typedef struct { /* The object must be the first field. */ nxt_http_route_object_t object:8; uint32_t items; - nxt_http_route_ruleset_t *ruleset[0]; + nxt_http_route_ruleset_t *ruleset[]; } nxt_http_route_table_t; @@ -125,7 +125,7 @@ struct nxt_http_route_addr_rule_s { /* The object must be the first field. */ nxt_http_route_object_t object:8; uint32_t items; - nxt_http_route_addr_pattern_t addr_pattern[0]; + nxt_http_route_addr_pattern_t addr_pattern[]; }; @@ -139,20 +139,20 @@ typedef union { typedef struct { uint32_t items; nxt_http_action_t action; - nxt_http_route_test_t test[0]; + nxt_http_route_test_t test[]; } nxt_http_route_match_t; struct nxt_http_route_s { nxt_str_t name; uint32_t items; - nxt_http_route_match_t *match[0]; + nxt_http_route_match_t *match[]; }; struct nxt_http_routes_s { uint32_t items; - nxt_http_route_t *route[0]; + nxt_http_route_t *route[]; }; diff --git a/src/nxt_upstream.h b/src/nxt_upstream.h index afc53774..0c3b4c8b 100644 --- a/src/nxt_upstream.h +++ b/src/nxt_upstream.h @@ -52,7 +52,7 @@ struct nxt_upstream_s { struct nxt_upstreams_s { uint32_t items; - nxt_upstream_t upstream[0]; + nxt_upstream_t upstream[]; }; diff --git a/src/nxt_upstream_round_robin.c b/src/nxt_upstream_round_robin.c index 1274f5a9..96c3e44e 100644 --- a/src/nxt_upstream_round_robin.c +++ b/src/nxt_upstream_round_robin.c @@ -23,7 +23,7 @@ struct nxt_upstream_round_robin_server_s { struct nxt_upstream_round_robin_s { uint32_t items; - nxt_upstream_round_robin_server_t server[0]; + nxt_upstream_round_robin_server_t server[]; }; diff --git a/src/python/nxt_python.h b/src/python/nxt_python.h index 37e6265e..f5154514 100644 --- a/src/python/nxt_python.h +++ b/src/python/nxt_python.h @@ -48,7 +48,7 @@ typedef struct { typedef struct { nxt_int_t count; - nxt_python_target_t target[0]; + nxt_python_target_t target[]; } nxt_python_targets_t; -- cgit From 05a822947444a462bd21bf48ecb8c7328e4e156b Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 30 Apr 2024 14:30:24 +0800 Subject: http: Use consistent target in nxt_h1p_peer_header_send() This change is required for the next commit, after which target and r->target may be different. Before the next patch, target and r->target would be the same. No functional changes. Reviewed-by: Andrew Clayton Signed-off-by: Zhidao HONG --- src/nxt_h1proto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index c3a65679..54fe7776 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -2306,7 +2306,7 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer) p = nxt_cpymem(p, r->method->start, r->method->length); *p++ = ' '; - p = nxt_cpymem(p, r->target.start, r->target.length); + p = nxt_cpymem(p, target.start, target.length); p = nxt_cpymem(p, " HTTP/1.1\r\n", 11); p = nxt_cpymem(p, "Connection: close\r\n", 19); -- cgit From 87077ec4ba9a59f3332c3758a3c39a5c149025e5 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 30 Apr 2024 14:45:18 +0800 Subject: http: Ensure REQUEST_URI immutability Previously, the REQUEST_URI within Unit could be modified, for example, during uri rewriting. We decide to make $request_uri immutable and pass constant REQUEST_URI to applications. Based on the new requirement, we remove `r->target` rewriting in the rewrite module. Closes: https://github.com/nginx/unit/issues/916 Reviewed-by: Andrew Clayton Signed-off-by: Zhidao HONG --- src/nxt_http_rewrite.c | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/nxt_http_rewrite.c b/src/nxt_http_rewrite.c index ff465ecc..661200ef 100644 --- a/src/nxt_http_rewrite.c +++ b/src/nxt_http_rewrite.c @@ -28,9 +28,8 @@ nxt_http_rewrite_init(nxt_router_conf_t *rtcf, nxt_http_action_t *action, nxt_int_t nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r) { - u_char *p; nxt_int_t ret; - nxt_str_t str, encoded_path, target; + nxt_str_t str; nxt_router_conf_t *rtcf; nxt_http_action_t *action; nxt_http_request_parse_t rp; @@ -72,30 +71,6 @@ nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r) return NXT_ERROR; } - p = (rp.args.length > 0) ? rp.args.start - 1 : rp.target_end; - - encoded_path.start = rp.target_start; - encoded_path.length = p - encoded_path.start; - - if (r->args->length == 0) { - r->target = encoded_path; - - } else { - target.length = encoded_path.length + 1 + r->args->length; - - target.start = nxt_mp_alloc(r->mem_pool, target.length); - if (target.start == NULL) { - return NXT_ERROR; - } - - p = nxt_cpymem(target.start, encoded_path.start, encoded_path.length); - *p++ = '?'; - nxt_memcpy(p, r->args->start, r->args->length); - - r->target = target; - r->args->start = p; - } - r->path = nxt_mp_alloc(r->mem_pool, sizeof(nxt_str_t)); if (nxt_slow_path(r->path == NULL)) { return NXT_ERROR; @@ -107,7 +82,7 @@ nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r) r->quoted_target = rp.quoted_target; if (nxt_slow_path(r->log_route)) { - nxt_log(task, NXT_LOG_NOTICE, "URI rewritten to \"%V\"", &r->target); + nxt_log(task, NXT_LOG_NOTICE, "URI rewritten to \"%V\"", r->path); } return NXT_OK; -- cgit From 7b19a06c9aa3e658eea4a87622ac74d67c10173f Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 24 May 2024 15:37:26 +0100 Subject: tstr: Constify the 'str' parameter to nxt_tstr_compile() This allows you to then define strings like static const nxt_str_t my_str = nxt_string("string"); Signed-off-by: Andrew Clayton --- src/nxt_tstr.c | 2 +- src/nxt_tstr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index edf6860a..fde4822d 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -81,7 +81,7 @@ nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test) nxt_tstr_t * -nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str, +nxt_tstr_compile(nxt_tstr_state_t *state, const nxt_str_t *str, nxt_tstr_flags_t flags) { u_char *p; diff --git a/src/nxt_tstr.h b/src/nxt_tstr.h index 3e842f81..a156732d 100644 --- a/src/nxt_tstr.h +++ b/src/nxt_tstr.h @@ -38,7 +38,7 @@ typedef enum { nxt_tstr_state_t *nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test); -nxt_tstr_t *nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str, +nxt_tstr_t *nxt_tstr_compile(nxt_tstr_state_t *state, const nxt_str_t *str, nxt_tstr_flags_t flags); nxt_int_t nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error); nxt_int_t nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error); -- cgit From ea5c41b8056997ed40138020272b5159271f1b87 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 24 May 2024 15:48:45 +0100 Subject: wasm: Add a missing 'const' qualifier in nxt_wasm_setup() Signed-off-by: Andrew Clayton --- src/wasm/nxt_wasm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/wasm/nxt_wasm.c b/src/wasm/nxt_wasm.c index 92ed57ab..db79d6ae 100644 --- a/src/wasm/nxt_wasm.c +++ b/src/wasm/nxt_wasm.c @@ -246,7 +246,7 @@ nxt_wasm_setup(nxt_task_t *task, nxt_process_t *process, nxt_conf_value_t *dirs = NULL; nxt_wasm_app_conf_t *c; nxt_wasm_func_handler_t *fh; - static nxt_str_t filesystem_str = nxt_string("filesystem"); + static const nxt_str_t filesystem_str = nxt_string("filesystem"); c = &conf->u.wasm; -- cgit From 04a24f61e069926a6546917ee049dc17fbaf1d03 Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 29 May 2024 13:13:24 +0530 Subject: http: fix use-of-uninitialized-value bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was found via MSan. In nxt_http_fields_hash() we setup a nxt_lvlhsh_query_t structure and initialise a couple of its members. At some point we call lhq->proto->alloc(lhq->pool, nxt_lvlhsh_bucket_size(lhq->proto)); Which in this case is void * nxt_lvlhsh_alloc(void *data, size_t size) { return nxt_memalign(size, size); } So even though lhq.ppol wasn't previously initialised we don't actually use it in that particular function. However MSan triggers on the fact that we are passing an uninitialised value into that function. Indeed, compilers will generally complain about such things, e.g /* u.c */ struct t { void *p; int len; }; static void test(void *p __attribute__((unused)), int len) { (void)len; } int main(void) { struct t t; t.len = 42; test(t.p, t.len); return 0; } GCC and Clang will produce a -Wuninitialized warning. But they won't catch the following... /* u2.c */ struct t { void *p; int len; }; static void _test(void *p __attribute__((unused)), int len) { (void)len; } static void test(struct t *t) { _test(t->p, t->len); } int main(void) { struct t t; t.len = 42; test(&t); return 0; } Which is why we don't get a compiler warning about lhq.pool. In this case initialising lhg.pool even though we don't use it here seems like the right thing to do and maybe compilers will start being able to catch these in the future. Actually GCC with -fanalyzer does catch the above $ gcc -Wall -Wextra -O0 -fanalyzer u2.c u2.c: In function ‘test’: u2.c:15:9: warning: use of uninitialized value ‘*t.p’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 15 | _test(t->p, t->len); | ^~~~~~~~~~~~~~~~~~~ ‘main’: events 1-3 | | 18 | int main(void) | | ^~~~ | | | | | (1) entry to ‘main’ | 19 | { | 20 | struct t t; | | ~ | | | | | (2) region created on stack here |...... | 23 | test(&t); | | ~~~~~~~~ | | | | | (3) calling ‘test’ from ‘main’ | +--> ‘test’: events 4-5 | | 13 | static void test(struct t *t) | | ^~~~ | | | | | (4) entry to ‘test’ | 14 | { | 15 | _test(t->p, t->len); | | ~~~~~~~~~~~~~~~~~~~ | | | | | (5) use of uninitialized value ‘*t.p’ here | Signed-off-by: Arjun Link: [ Commit message - Andrew ] Signed-off-by: Andrew Clayton --- src/nxt_http_parse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 48be5bdb..dd490e72 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -1182,6 +1182,7 @@ nxt_http_fields_hash(nxt_lvlhsh_t *hash, lhq.replace = 0; lhq.proto = &nxt_http_fields_hash_proto; + lhq.pool = NULL; for (i = 0; i < count; i++) { key = NXT_HTTP_FIELD_HASH_INIT; -- cgit From 3db000a5399fd688ec0d97b38e784778bdd90375 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 24 Apr 2024 15:02:11 +0200 Subject: fs: Rename nxt_fs_mkdir_parent() => nxt_fs_mkdir_dirname() "dirname" is the usual way to refer to the directory part of a path name. See for example dirname(1), or the dirname builtin in several languages. Also, in the context of mkdir(), "parents" is used to refer to mkdir -p, which is too similar to "parent", so it can lead to confusion. Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_controller.c | 2 +- src/nxt_fs.c | 2 +- src/nxt_fs.h | 2 +- src/nxt_runtime.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 30d5f04e..109324b8 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -695,7 +695,7 @@ nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt) if (ls->sockaddr->u.sockaddr.sa_family == AF_UNIX) { const char *path = ls->sockaddr->u.sockaddr_un.sun_path; - nxt_fs_mkdir_parent((const u_char *) path, 0755); + nxt_fs_mkdir_dirname((const u_char *) path, 0755); } #endif diff --git a/src/nxt_fs.c b/src/nxt_fs.c index e10c5bcb..f8d872f5 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -49,7 +49,7 @@ nxt_fs_mkdir_all(const u_char *dir, mode_t mode) nxt_int_t -nxt_fs_mkdir_parent(const u_char *path, mode_t mode) +nxt_fs_mkdir_dirname(const u_char *path, mode_t mode) { char *ptr, *dir; nxt_int_t ret; diff --git a/src/nxt_fs.h b/src/nxt_fs.h index c8868d80..3ee0928c 100644 --- a/src/nxt_fs.h +++ b/src/nxt_fs.h @@ -6,7 +6,7 @@ #define _NXT_FS_H_INCLUDED_ -nxt_int_t nxt_fs_mkdir_parent(const u_char *path, mode_t mode); +nxt_int_t nxt_fs_mkdir_dirname(const u_char *path, mode_t mode); nxt_int_t nxt_fs_mkdir_all(const u_char *dir, mode_t mode); diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index 0e7f879e..b368647e 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -1490,7 +1490,7 @@ nxt_runtime_pid_file_create(nxt_task_t *task, nxt_file_name_t *pid_file) file.name = pid_file; - nxt_fs_mkdir_parent(pid_file, 0755); + nxt_fs_mkdir_dirname(pid_file, 0755); n = nxt_file_open(task, &file, O_WRONLY, O_CREAT | O_TRUNC, NXT_FILE_DEFAULT_ACCESS); -- cgit From 40eaf4e4f711978625ecbbdd359caa33d947ec8d Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 24 Apr 2024 15:04:48 +0200 Subject: fs: Rename nxt_fs_mkdir_all() => nxt_fs_mkdir_p() "all" is too generic of an attribute to be meaningful. In the context of mkdir(), "parents" is used for this meaning, as in mkdir -p, so it should be more straightforward to readers. Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_cgroup.c | 2 +- src/nxt_fs.c | 2 +- src/nxt_fs.h | 2 +- src/nxt_isolation.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_cgroup.c b/src/nxt_cgroup.c index 2c404acc..79e240f1 100644 --- a/src/nxt_cgroup.c +++ b/src/nxt_cgroup.c @@ -34,7 +34,7 @@ nxt_cgroup_proc_add(nxt_task_t *task, nxt_process_t *process) return NXT_ERROR; } - ret = nxt_fs_mkdir_all((const u_char *) cgprocs, 0777); + ret = nxt_fs_mkdir_p((const u_char *) cgprocs, 0777); if (nxt_slow_path(ret == NXT_ERROR)) { return NXT_ERROR; } diff --git a/src/nxt_fs.c b/src/nxt_fs.c index f8d872f5..59e9a766 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -9,7 +9,7 @@ static nxt_int_t nxt_fs_mkdir(const u_char *dir, mode_t mode); nxt_int_t -nxt_fs_mkdir_all(const u_char *dir, mode_t mode) +nxt_fs_mkdir_p(const u_char *dir, mode_t mode) { char *start, *end, *dst; size_t dirlen; diff --git a/src/nxt_fs.h b/src/nxt_fs.h index 3ee0928c..9a256bd2 100644 --- a/src/nxt_fs.h +++ b/src/nxt_fs.h @@ -7,7 +7,7 @@ nxt_int_t nxt_fs_mkdir_dirname(const u_char *path, mode_t mode); -nxt_int_t nxt_fs_mkdir_all(const u_char *dir, mode_t mode); +nxt_int_t nxt_fs_mkdir_p(const u_char *dir, mode_t mode); #endif /* _NXT_FS_H_INCLUDED_ */ diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index a2913872..7f25379f 100644 --- a/src/nxt_isolation.c +++ b/src/nxt_isolation.c @@ -780,7 +780,7 @@ nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process) continue; } - ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO); + ret = nxt_fs_mkdir_p(dst, S_IRWXU | S_IRWXG | S_IRWXO); if (nxt_slow_path(ret != NXT_OK)) { nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno); goto undo; -- cgit From af6a67ffa0c5accb90126972116cb1e8e332f3b7 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Apr 2024 12:41:08 +0200 Subject: fs: Use branchless code in nxt_fs_mkdir_p() That branch was to avoid an infinite loop on the slash. However, we can achieve the same by using a +1 to make sure we advance at least 1 byte in each iteration. Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_fs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 59e9a766..0af84742 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -23,11 +23,7 @@ nxt_fs_mkdir_p(const u_char *dir, mode_t mode) start = (char *) dir; while (*start != '\0') { - if (*start == '/') { - *dst++ = *start++; - } - - end = strchr(start, '/'); + end = strchr(start + 1, '/'); if (end == NULL) { end = ((char *)dir + dirlen); } -- cgit From 2eb2f60b46feda3d39aed2211b82673ecfd7c67d Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Apr 2024 12:47:32 +0200 Subject: fs: Use a temporary variable in nxt_fs_mkdir_p() This avoids breaking a long line. Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_fs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 0af84742..a02c51af 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -11,9 +11,10 @@ static nxt_int_t nxt_fs_mkdir(const u_char *dir, mode_t mode); nxt_int_t nxt_fs_mkdir_p(const u_char *dir, mode_t mode) { - char *start, *end, *dst; - size_t dirlen; - char path[PATH_MAX]; + char *start, *end, *dst; + size_t dirlen; + nxt_int_t ret; + char path[PATH_MAX]; dirlen = nxt_strlen(dir); @@ -31,9 +32,8 @@ nxt_fs_mkdir_p(const u_char *dir, mode_t mode) dst = nxt_cpymem(dst, start, end - start); *dst = '\0'; - if (nxt_slow_path(nxt_fs_mkdir((u_char *) path, mode) != NXT_OK - && nxt_errno != EEXIST)) - { + ret = nxt_fs_mkdir((u_char *) path, mode); + if (nxt_slow_path(ret != NXT_OK && nxt_errno != EEXIST)) { return NXT_ERROR; } -- cgit From c6ce038123e4a2cf1678795cf6d86096be716c21 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Apr 2024 23:25:57 +0200 Subject: fs: Accept relative paths in nxt_fs_mkdir_p() Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_fs.c b/src/nxt_fs.c index a02c51af..3c33837c 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -18,7 +18,7 @@ nxt_fs_mkdir_p(const u_char *dir, mode_t mode) dirlen = nxt_strlen(dir); - nxt_assert(dirlen < PATH_MAX && dirlen > 1 && dir[0] == '/'); + nxt_assert(dirlen < PATH_MAX && dirlen > 1); dst = path; start = (char *) dir; -- cgit From 3873f98f7e43967458a5080a30107cff52f8d935 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Apr 2024 23:27:06 +0200 Subject: fs: Accept path names of length 1 in nxt_fs_mkdir_p() That is, accept "/", or relative path names of a single byte. Fixes: e2b53e16c60b ("Added "rootfs" feature.") Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 3c33837c..0d10f623 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -18,7 +18,7 @@ nxt_fs_mkdir_p(const u_char *dir, mode_t mode) dirlen = nxt_strlen(dir); - nxt_assert(dirlen < PATH_MAX && dirlen > 1); + nxt_assert(dirlen < PATH_MAX && dirlen > 0); dst = path; start = (char *) dir; -- cgit From 7b7b303a729508c4a6a02c2dd46e94c5683ad2a2 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Mon, 22 Apr 2024 21:48:14 +0200 Subject: fs: Invert logic to reduce indentation in nxt_fs_mkdir_dirname() This refactor isn't very appealing alone, but it prepares the code for the following commits. Link: Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Cc: Liam Crilly Cc: Konstantin Pavlov Signed-off-by: Alejandro Colomar --- src/nxt_fs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 0d10f623..6a93c670 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -58,11 +58,14 @@ nxt_fs_mkdir_dirname(const u_char *path, mode_t mode) ret = NXT_OK; ptr = strrchr(dir, '/'); - if (nxt_fast_path(ptr != NULL)) { - *ptr = '\0'; - ret = nxt_fs_mkdir((const u_char *) dir, mode); + if (nxt_slow_path(ptr == NULL)) { + goto out_free; } + *ptr = '\0'; + ret = nxt_fs_mkdir((const u_char *) dir, mode); + +out_free: nxt_free(dir); return ret; -- cgit From a9aed2044c6191b93af0199aa77b26ab39cbbad2 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Mon, 22 Apr 2024 22:40:43 +0200 Subject: fs: Correctly handle "/" in nxt_fs_mkdir_dirname() The previous code attempted to mkdir(""), that is an empty string. Since "/" necessarily exists, just goto out_free. Fixes: 57fc9201cb91 ("Socket: Created control socket & pid file directories.") Link: Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Cc: Liam Crilly Cc: Konstantin Pavlov Signed-off-by: Alejandro Colomar --- src/nxt_fs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 6a93c670..788c3ee2 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -1,5 +1,6 @@ /* * Copyright (C) NGINX, Inc. + * Copyright 2024, Alejandro Colomar */ #include @@ -58,7 +59,7 @@ nxt_fs_mkdir_dirname(const u_char *path, mode_t mode) ret = NXT_OK; ptr = strrchr(dir, '/'); - if (nxt_slow_path(ptr == NULL)) { + if (ptr == dir || nxt_slow_path(ptr == NULL)) { goto out_free; } -- cgit From eca38349cb25ccae89acf3a0dc4dfd9a6ca8770c Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Mon, 22 Apr 2024 22:47:27 +0200 Subject: fs: Make the full directory path for the pid file and the control socket Build systems should not attempt to create $runstatedir (or anything under it). Doing so causes warnings in packaging systems, such as in Alpine Linux, as reported by Andy. But unitd(8) can be configured to be installed under /opt, or other trees, where no directories exist before hand. Expecting that the user creates the entire directory trees that unit will need is a bit unreasonable. Instead, let's just create any directories that we need, with all their parents, at run time. Fixes: 57fc9201cb91 ("Socket: Created control socket & pid file directories.") Link: Reported-by: Andy Postnikov Tested-by: Andy Postnikov Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Acked-by: Konstantin Pavlov Cc: Liam Crilly Signed-off-by: Alejandro Colomar --- src/nxt_controller.c | 2 +- src/nxt_fs.c | 4 ++-- src/nxt_fs.h | 2 +- src/nxt_runtime.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 109324b8..b4ae8d09 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -695,7 +695,7 @@ nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt) if (ls->sockaddr->u.sockaddr.sa_family == AF_UNIX) { const char *path = ls->sockaddr->u.sockaddr_un.sun_path; - nxt_fs_mkdir_dirname((const u_char *) path, 0755); + nxt_fs_mkdir_p_dirname((const u_char *) path, 0755); } #endif diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 788c3ee2..8ea8e186 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -46,7 +46,7 @@ nxt_fs_mkdir_p(const u_char *dir, mode_t mode) nxt_int_t -nxt_fs_mkdir_dirname(const u_char *path, mode_t mode) +nxt_fs_mkdir_p_dirname(const u_char *path, mode_t mode) { char *ptr, *dir; nxt_int_t ret; @@ -64,7 +64,7 @@ nxt_fs_mkdir_dirname(const u_char *path, mode_t mode) } *ptr = '\0'; - ret = nxt_fs_mkdir((const u_char *) dir, mode); + ret = nxt_fs_mkdir_p((const u_char *) dir, mode); out_free: nxt_free(dir); diff --git a/src/nxt_fs.h b/src/nxt_fs.h index 9a256bd2..a06e4d3d 100644 --- a/src/nxt_fs.h +++ b/src/nxt_fs.h @@ -6,7 +6,7 @@ #define _NXT_FS_H_INCLUDED_ -nxt_int_t nxt_fs_mkdir_dirname(const u_char *path, mode_t mode); +nxt_int_t nxt_fs_mkdir_p_dirname(const u_char *path, mode_t mode); nxt_int_t nxt_fs_mkdir_p(const u_char *dir, mode_t mode); diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index b368647e..afe5a0b2 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -1490,7 +1490,7 @@ nxt_runtime_pid_file_create(nxt_task_t *task, nxt_file_name_t *pid_file) file.name = pid_file; - nxt_fs_mkdir_dirname(pid_file, 0755); + nxt_fs_mkdir_p_dirname(pid_file, 0755); n = nxt_file_open(task, &file, O_WRONLY, O_CREAT | O_TRUNC, NXT_FILE_DEFAULT_ACCESS); -- cgit From d96d583328f614c658d42f5bb0d2a0f81621327e Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 24 Apr 2024 23:31:54 +0200 Subject: Use octal instead of mode macros They are more readable. And we had a mix of both styles; there wasn't really a consistent style. Tested-by: Andrew Clayton Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_isolation.c | 2 +- src/nxt_listen_socket.c | 2 +- src/nxt_main_process.c | 4 +--- src/nxt_port_memory.c | 6 ++---- src/nxt_runtime.c | 6 ++---- src/nxt_unit.c | 4 ++-- 6 files changed, 9 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index 7f25379f..909a43f4 100644 --- a/src/nxt_isolation.c +++ b/src/nxt_isolation.c @@ -780,7 +780,7 @@ nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process) continue; } - ret = nxt_fs_mkdir_p(dst, S_IRWXU | S_IRWXG | S_IRWXO); + ret = nxt_fs_mkdir_p(dst, 0777); if (nxt_slow_path(ret != NXT_OK)) { nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno); goto undo; diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index 047c1ef9..4fe3e20b 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -132,7 +132,7 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, nxt_runtime_t *rt = thr->runtime; name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; - access = rt->control_mode > 0 ? rt->control_mode : S_IRUSR | S_IWUSR; + access = rt->control_mode > 0 ? rt->control_mode : 0600; if (nxt_file_set_access(name, access) != NXT_OK) { goto listen_fail; diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 060ead41..c302cb02 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -1275,13 +1275,11 @@ nxt_main_listening_socket(nxt_sockaddr_t *sa, nxt_listening_socket_t *ls) && sa->u.sockaddr_un.sun_path[0] != '\0') { char *filename; - mode_t access; nxt_thread_t *thr; filename = sa->u.sockaddr_un.sun_path; - access = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - if (chmod(filename, access) != 0) { + if (chmod(filename, 0666) != 0) { ls->end = nxt_sprintf(ls->start, ls->end, "chmod(\\\"%s\\\") failed %E", filename, nxt_errno); diff --git a/src/nxt_port_memory.c b/src/nxt_port_memory.c index be7688e2..ad6e97ad 100644 --- a/src/nxt_port_memory.c +++ b/src/nxt_port_memory.c @@ -393,8 +393,7 @@ nxt_shm_open(nxt_task_t *task, size_t size) #elif (NXT_HAVE_SHM_OPEN_ANON) - fd = shm_open(SHM_ANON, O_RDWR, S_IRUSR | S_IWUSR); - + fd = shm_open(SHM_ANON, O_RDWR, 0600); if (nxt_slow_path(fd == -1)) { nxt_alert(task, "shm_open(SHM_ANON) failed %E", nxt_errno); @@ -408,8 +407,7 @@ nxt_shm_open(nxt_task_t *task, size_t size) /* Just in case. */ shm_unlink((char *) name); - fd = shm_open((char *) name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); - + fd = shm_open((char *) name, O_CREAT | O_EXCL | O_RDWR, 0600); if (nxt_slow_path(fd == -1)) { nxt_alert(task, "shm_open(%s) failed %E", name, nxt_errno); diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index afe5a0b2..de76f19e 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -895,8 +895,7 @@ nxt_runtime_conf_init(nxt_task_t *task, nxt_runtime_t *rt) return NXT_ERROR; } - ret = mkdir((char *) file_name.start, S_IRWXU); - + ret = mkdir((char *) file_name.start, 0700); if (nxt_fast_path(ret == 0 || nxt_errno == EEXIST)) { rt->certs.length = file_name.len; rt->certs.start = file_name.start; @@ -912,8 +911,7 @@ nxt_runtime_conf_init(nxt_task_t *task, nxt_runtime_t *rt) return NXT_ERROR; } - ret = mkdir((char *) file_name.start, S_IRWXU); - + ret = mkdir((char *) file_name.start, 0700); if (nxt_fast_path(ret == 0 || nxt_errno == EEXIST)) { rt->scripts.length = file_name.len; rt->scripts.start = file_name.start; diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 50e156d8..966a6c0f 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -3857,7 +3857,7 @@ nxt_unit_shm_open(nxt_unit_ctx_t *ctx, size_t size) #elif (NXT_HAVE_SHM_OPEN_ANON) - fd = shm_open(SHM_ANON, O_RDWR, S_IRUSR | S_IWUSR); + fd = shm_open(SHM_ANON, O_RDWR, 0600); if (nxt_slow_path(fd == -1)) { nxt_unit_alert(ctx, "shm_open(SHM_ANON) failed: %s (%d)", strerror(errno), errno); @@ -3870,7 +3870,7 @@ nxt_unit_shm_open(nxt_unit_ctx_t *ctx, size_t size) /* Just in case. */ shm_unlink(name); - fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); + fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600); if (nxt_slow_path(fd == -1)) { nxt_unit_alert(ctx, "shm_open(%s) failed: %s (%d)", name, strerror(errno), errno); -- cgit From 999d274837273e354efc05075c0b012b81902ef1 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 11 Jun 2024 10:18:44 +0800 Subject: http: Move chunked buffer pos pointer while parsing Previously, Unit didn't move the buffer pointer when parsing chunked data because the buffer was not used after sent. It's used for upstream response. With the new requirement to support request chunked body, the buffer might be used for pipeline request, so it's necessary to move the pos pointer while parsing. Reviewed-by: Andrew Clayton --- src/nxt_http_chunk_parse.c | 10 ++++------ src/nxt_http_parse.h | 3 --- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nxt_http_chunk_parse.c b/src/nxt_http_chunk_parse.c index b60bc801..a43ce75b 100644 --- a/src/nxt_http_chunk_parse.c +++ b/src/nxt_http_chunk_parse.c @@ -48,9 +48,7 @@ nxt_http_chunk_parse(nxt_task_t *task, nxt_http_chunk_parse_t *hcp, for (b = in; b != NULL; b = next) { - hcp->pos = b->mem.pos; - - while (hcp->pos < b->mem.free) { + while (b->mem.pos < b->mem.free) { /* * The sw_chunk state is tested outside the switch * to preserve hcp->pos and to not touch memory. @@ -76,7 +74,7 @@ nxt_http_chunk_parse(nxt_task_t *task, nxt_http_chunk_parse_t *hcp, /* ret == NXT_HTTP_CHUNK_END */ } - ch = *hcp->pos++; + ch = *b->mem.pos++; switch (state) { @@ -203,7 +201,7 @@ nxt_http_chunk_buffer(nxt_http_chunk_parse_t *hcp, nxt_buf_t ***tail, size_t size; nxt_buf_t *b; - p = hcp->pos; + p = in->mem.pos; size = in->mem.free - p; b = nxt_buf_mem_alloc(hcp->mem_pool, 0, 0); @@ -224,7 +222,7 @@ nxt_http_chunk_buffer(nxt_http_chunk_parse_t *hcp, nxt_buf_t ***tail, if (hcp->chunk_size < size) { p += hcp->chunk_size; - hcp->pos = p; + in->mem.pos = p; b->mem.free = p; b->mem.end = p; diff --git a/src/nxt_http_parse.h b/src/nxt_http_parse.h index 9e1265d1..9e2f6fab 100644 --- a/src/nxt_http_parse.h +++ b/src/nxt_http_parse.h @@ -96,11 +96,8 @@ struct nxt_http_field_s { typedef struct { - u_char *pos; nxt_mp_t *mem_pool; - uint64_t chunk_size; - uint8_t state; uint8_t last; /* 1 bit */ uint8_t chunk_error; /* 1 bit */ -- cgit From f80a36a60d61ecd5621d33af37aed35fd074f982 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 11 Jun 2024 10:32:34 +0800 Subject: http: Refactored nxt_h1p_request_body_read() It's prepared for the subsequent patch. Reviewed-by: Andrew Clayton --- src/nxt_h1proto.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 54fe7776..fd184eb5 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -856,7 +856,6 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) { size_t size, body_length, body_buffer_size, body_rest; ssize_t res; - nxt_str_t *tmp_path, tmp_name; nxt_buf_t *in, *b; nxt_conn_t *c; nxt_h1proto_t *h1p; @@ -894,6 +893,8 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) body_length); if (body_length > body_buffer_size) { + nxt_str_t *tmp_path, tmp_name; + tmp_path = &r->conf->socket_conf->body_temp_path; tmp_name.length = tmp_path->length + tmp_name_pattern.length; @@ -901,23 +902,11 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) b = nxt_buf_file_alloc(r->mem_pool, body_buffer_size + sizeof(nxt_file_t) + tmp_name.length + 1, 0); + if (nxt_slow_path(b == NULL)) { + status = NXT_HTTP_INTERNAL_SERVER_ERROR; + goto error; + } - } else { - /* This initialization required for CentOS 6, gcc 4.4.7. */ - tmp_path = NULL; - tmp_name.length = 0; - - b = nxt_buf_mem_alloc(r->mem_pool, body_buffer_size, 0); - } - - if (nxt_slow_path(b == NULL)) { - status = NXT_HTTP_INTERNAL_SERVER_ERROR; - goto error; - } - - r->body = b; - - if (body_length > body_buffer_size) { tmp_name.start = nxt_pointer_to(b->mem.start, sizeof(nxt_file_t)); memcpy(tmp_name.start, tmp_path->start, tmp_path->length); @@ -946,8 +935,17 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) &tmp_name, b->file->fd); unlink((char *) tmp_name.start); + + } else { + b = nxt_buf_mem_alloc(r->mem_pool, body_buffer_size, 0); + if (nxt_slow_path(b == NULL)) { + status = NXT_HTTP_INTERNAL_SERVER_ERROR; + goto error; + } } + r->body = b; + body_rest = body_length; in = h1p->conn->read; -- cgit From 64f4c78bf441fa9e021d905a03d374d0a9e05e8d Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 11 Jun 2024 17:59:00 +0800 Subject: 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 --- src/nxt_conf_validation.c | 3 + src/nxt_h1proto.c | 173 ++++++++++++++++++++++++++++++++++++---------- src/nxt_http.h | 2 + src/nxt_http_request.c | 43 ++++++++++++ src/nxt_router.c | 7 ++ src/nxt_router.h | 1 + 6 files changed, 191 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 4aaa1b9a..f91fc887 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -368,6 +368,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = { }, { .name = nxt_string("server_version"), .type = NXT_CONF_VLDT_BOOLEAN, + }, { + .name = nxt_string("chunked_transform"), + .type = NXT_CONF_VLDT_BOOLEAN, }, NXT_CONF_VLDT_END diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index fd184eb5..5d1ed790 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -839,7 +839,12 @@ nxt_h1p_transfer_encoding(void *ctx, nxt_http_field_t *field, uintptr_t data) if (field->value_length == 7 && memcmp(field->value, "chunked", 7) == 0) { + if (r->chunked_field != NULL) { + return NXT_HTTP_BAD_REQUEST; + } + te = NXT_HTTP_TE_CHUNKED; + r->chunked_field = field; } else { te = NXT_HTTP_TE_UNSUPPORTED; @@ -856,14 +861,16 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) { size_t size, body_length, body_buffer_size, body_rest; ssize_t res; - nxt_buf_t *in, *b; + nxt_buf_t *in, *b, *out, *chunk; nxt_conn_t *c; nxt_h1proto_t *h1p; + nxt_socket_conf_t *skcf; nxt_http_status_t status; static const nxt_str_t tmp_name_pattern = nxt_string("/req-XXXXXXXX"); h1p = r->proto.h1; + skcf = r->conf->socket_conf; nxt_debug(task, "h1p request body read %O te:%d", r->content_length_n, h1p->transfer_encoding); @@ -871,8 +878,19 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) switch (h1p->transfer_encoding) { case NXT_HTTP_TE_CHUNKED: - status = NXT_HTTP_LENGTH_REQUIRED; - goto error; + if (!skcf->chunked_transform) { + status = NXT_HTTP_LENGTH_REQUIRED; + goto error; + } + + if (r->content_length != NULL || !nxt_h1p_is_http11(h1p)) { + status = NXT_HTTP_BAD_REQUEST; + goto error; + } + + r->chunked = 1; + h1p->chunked_parse.mem_pool = r->mem_pool; + break; case NXT_HTTP_TE_UNSUPPORTED: status = NXT_HTTP_NOT_IMPLEMENTED; @@ -883,19 +901,20 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) break; } - if (r->content_length_n == -1 || r->content_length_n == 0) { + if (!r->chunked && + (r->content_length_n == -1 || r->content_length_n == 0)) + { goto ready; } body_length = (size_t) r->content_length_n; - body_buffer_size = nxt_min(r->conf->socket_conf->body_buffer_size, - body_length); + body_buffer_size = nxt_min(skcf->body_buffer_size, body_length); if (body_length > body_buffer_size) { nxt_str_t *tmp_path, tmp_name; - tmp_path = &r->conf->socket_conf->body_temp_path; + tmp_path = &skcf->body_temp_path; tmp_name.length = tmp_path->length + tmp_name_pattern.length; @@ -946,31 +965,69 @@ nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r) r->body = b; - body_rest = body_length; + body_rest = r->chunked ? 1 : body_length; in = h1p->conn->read; size = nxt_buf_mem_used_size(&in->mem); if (size != 0) { - size = nxt_min(size, body_length); - if (nxt_buf_is_file(b)) { - res = nxt_fd_write(b->file->fd, in->mem.pos, size); - if (nxt_slow_path(res < (ssize_t) size)) { - status = NXT_HTTP_INTERNAL_SERVER_ERROR; - goto error; - } + if (r->chunked) { + out = nxt_http_chunk_parse(task, &h1p->chunked_parse, in); - b->file_end += size; + if (h1p->chunked_parse.error) { + status = NXT_HTTP_INTERNAL_SERVER_ERROR; + goto error; + } + + if (h1p->chunked_parse.chunk_error) { + status = NXT_HTTP_BAD_REQUEST; + goto error; + } + + for (chunk = out; chunk != NULL; chunk = chunk->next) { + size = nxt_buf_mem_used_size(&chunk->mem); + + res = nxt_fd_write(b->file->fd, chunk->mem.pos, size); + if (nxt_slow_path(res < (ssize_t) size)) { + status = NXT_HTTP_INTERNAL_SERVER_ERROR; + goto error; + } + + b->file_end += size; + + if ((size_t) b->file_end > skcf->max_body_size) { + status = NXT_HTTP_PAYLOAD_TOO_LARGE; + goto error; + } + } + + if (h1p->chunked_parse.last) { + body_rest = 0; + } + + } else { + size = nxt_min(size, body_length); + res = nxt_fd_write(b->file->fd, in->mem.pos, size); + if (nxt_slow_path(res < (ssize_t) size)) { + status = NXT_HTTP_INTERNAL_SERVER_ERROR; + goto error; + } + + b->file_end += size; + + in->mem.pos += size; + body_rest -= size; + } } else { size = nxt_min(body_buffer_size, size); b->mem.free = nxt_cpymem(b->mem.free, in->mem.pos, size); - } - in->mem.pos += size; - body_rest -= size; + in->mem.pos += size; + body_rest -= size; + } } nxt_debug(task, "h1p body rest: %uz", body_rest); @@ -1028,9 +1085,10 @@ nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, void *data) { size_t size, body_rest; ssize_t res; - nxt_buf_t *b; + nxt_buf_t *b, *out, *chunk; nxt_conn_t *c; nxt_h1proto_t *h1p; + nxt_socket_conf_t *skcf; nxt_http_request_t *r; nxt_event_engine_t *engine; @@ -1040,38 +1098,77 @@ nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "h1p conn request body read"); r = h1p->request; + skcf = r->conf->socket_conf; engine = task->thread->engine; b = c->read; if (nxt_buf_is_file(b)) { - body_rest = b->file->size - b->file_end; - size = nxt_buf_mem_used_size(&b->mem); - size = nxt_min(size, body_rest); + if (r->chunked) { + body_rest = 1; - res = nxt_fd_write(b->file->fd, b->mem.pos, size); - if (nxt_slow_path(res < (ssize_t) size)) { - nxt_h1p_request_error(task, h1p, r); - return; - } + out = nxt_http_chunk_parse(task, &h1p->chunked_parse, b); - b->file_end += size; - body_rest -= res; + if (h1p->chunked_parse.error) { + nxt_h1p_request_error(task, h1p, r); + return; + } - b->mem.pos += size; + if (h1p->chunked_parse.chunk_error) { + nxt_http_request_error(task, r, NXT_HTTP_BAD_REQUEST); + return; + } - if (b->mem.pos == b->mem.free) { - if (body_rest >= (size_t) nxt_buf_mem_size(&b->mem)) { - b->mem.free = b->mem.start; + for (chunk = out; chunk != NULL; chunk = chunk->next) { + size = nxt_buf_mem_used_size(&chunk->mem); + res = nxt_fd_write(b->file->fd, chunk->mem.pos, size); + if (nxt_slow_path(res < (ssize_t) size)) { + nxt_h1p_request_error(task, h1p, r); + return; + } - } else { - /* This required to avoid reading next request. */ - b->mem.free = b->mem.end - body_rest; + b->file_end += size; + + if ((size_t) b->file_end > skcf->max_body_size) { + nxt_h1p_request_error(task, h1p, r); + return; + } } - b->mem.pos = b->mem.free; + if (h1p->chunked_parse.last) { + body_rest = 0; + } + + } else { + body_rest = b->file->size - b->file_end; + + size = nxt_buf_mem_used_size(&b->mem); + size = nxt_min(size, body_rest); + + res = nxt_fd_write(b->file->fd, b->mem.pos, size); + if (nxt_slow_path(res < (ssize_t) size)) { + nxt_h1p_request_error(task, h1p, r); + return; + } + + b->file_end += size; + body_rest -= res; + + b->mem.pos += size; + + if (b->mem.pos == b->mem.free) { + if (body_rest >= (size_t) nxt_buf_mem_size(&b->mem)) { + b->mem.free = b->mem.start; + + } else { + /* This required to avoid reading next request. */ + b->mem.free = b->mem.end - body_rest; + } + + b->mem.pos = b->mem.free; + } } } else { diff --git a/src/nxt_http.h b/src/nxt_http.h index 5fab5c67..fe5e72a8 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -157,6 +157,7 @@ struct nxt_http_request_s { nxt_list_t *fields; nxt_http_field_t *content_type; nxt_http_field_t *content_length; + nxt_http_field_t *chunked_field; nxt_http_field_t *cookie; nxt_http_field_t *referer; nxt_http_field_t *user_agent; @@ -204,6 +205,7 @@ struct nxt_http_request_s { uint8_t inconsistent; /* 1 bit */ uint8_t error; /* 1 bit */ uint8_t websocket_handshake; /* 1 bit */ + uint8_t chunked; /* 1 bit */ }; 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); } diff --git a/src/nxt_router.c b/src/nxt_router.c index 48870d20..43209451 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1575,6 +1575,12 @@ static nxt_conf_map_t nxt_router_http_conf[] = { NXT_CONF_MAP_INT8, offsetof(nxt_socket_conf_t, server_version), }, + + { + nxt_string("chunked_transform"), + NXT_CONF_MAP_INT8, + offsetof(nxt_socket_conf_t, chunked_transform), + }, }; @@ -1994,6 +2000,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, skcf->proxy_read_timeout = 30 * 1000; skcf->server_version = 1; + skcf->chunked_transform = 0; skcf->websocket_conf.max_frame_size = 1024 * 1024; skcf->websocket_conf.read_timeout = 60 * 1000; diff --git a/src/nxt_router.h b/src/nxt_router.h index 3e523001..cfc7258c 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -208,6 +208,7 @@ typedef struct { uint8_t discard_unsafe_fields; /* 1 bit */ uint8_t server_version; /* 1 bit */ + uint8_t chunked_transform; /* 1 bit */ nxt_http_forward_t *forwarded; nxt_http_forward_t *client_ip; -- cgit From 5c4911a35e289d1813daeab61bf7e347d7bea3f3 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 21 Jun 2024 23:56:20 +0100 Subject: perl: Constify some local static variables These somehow got missed in my previous constification patches... Signed-off-by: Andrew Clayton --- src/perl/nxt_perl_psgi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/perl/nxt_perl_psgi.c b/src/perl/nxt_perl_psgi.c index 807d1741..271494ac 100644 --- a/src/perl/nxt_perl_psgi.c +++ b/src/perl/nxt_perl_psgi.c @@ -407,7 +407,7 @@ nxt_perl_psgi_module_create(const char *script) char *buf, *p; size_t length; - static nxt_str_t prefix = nxt_string( + static const nxt_str_t prefix = nxt_string( "package NGINX::Unit::Sandbox;" "sub new {" " return bless {}, $_[0];" @@ -415,7 +415,7 @@ nxt_perl_psgi_module_create(const char *script) "{my $app = do \"" ); - static nxt_str_t suffix = nxt_string_zero( + static const nxt_str_t suffix = nxt_string_zero( "\";" "unless ($app) {" " if($@ || $1) {die $@ || $1}" -- cgit From ab1b3f9da8cd6d4816f916244a728243e514a544 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 21 Jun 2024 23:57:44 +0100 Subject: test/clone: Constify some local static variables These somehow got missed in my previous constification patches... Signed-off-by: Andrew Clayton --- src/test/nxt_clone_test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/test/nxt_clone_test.c b/src/test/nxt_clone_test.c index 64b9ddea..1a864f0e 100644 --- a/src/test/nxt_clone_test.c +++ b/src/test/nxt_clone_test.c @@ -560,9 +560,9 @@ nxt_clone_test_parse_map(nxt_task_t *task, nxt_str_t *map_str, nxt_runtime_t *rt; nxt_conf_value_t *array, *obj, *value; - static nxt_str_t host_name = nxt_string("host"); - static nxt_str_t cont_name = nxt_string("container"); - static nxt_str_t size_name = nxt_string("size"); + static const nxt_str_t host_name = nxt_string("host"); + static const nxt_str_t cont_name = nxt_string("container"); + static const nxt_str_t size_name = nxt_string("size"); rt = task->thread->runtime; -- cgit From 8e254a4d6762da22bc1967140ef85cf8fedfa02d Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 25 Jun 2024 14:51:30 +0530 Subject: tstr, conf: Ensure error strings are nul-terminated This issue was found with oss-fuzz. ==18420==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x55dd798a5797 in nxt_vsprintf unit/src/nxt_sprintf.c:163:31 #1 0x55dd798d5bdb in nxt_conf_vldt_error unit/src/nxt_conf_validation.c:1525:11 #2 0x55dd798dd4cd in nxt_conf_vldt_var unit/src/nxt_conf_validation.c:1560:16 #3 0x55dd798dd4cd in nxt_conf_vldt_if unit/src/nxt_conf_validation.c:1592:16 #4 0x55dd798d55f4 in nxt_conf_vldt_object unit/src/nxt_conf_validation.c:2815:23 #5 0x55dd798d6f84 in nxt_conf_vldt_access_log unit/src/nxt_conf_validation.c:3426:11 #6 0x55dd798d55f4 in nxt_conf_vldt_object unit/src/nxt_conf_validation.c:2815:23 #7 0x55dd798d47bd in nxt_conf_validate unit/src/nxt_conf_validation.c:1421:11 #8 0x55dd79871c82 in LLVMFuzzerTestOneInput unit/fuzzing/nxt_json_fuzz.c:67:5 #9 0x55dd79770620 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13 #10 0x55dd7975adb4 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6 #11 0x55dd7976084a in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9 #12 0x55dd7978cc42 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 #13 0x7e8192213082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/libc-start.c:308:16 #14 0x55dd7975188d in _start Uninitialized value was created by an allocation of 'error.i' in the stack frame #0 0x55dd798dd42b in nxt_conf_vldt_var unit/src/nxt_conf_validation.c:1557:5 #1 0x55dd798dd42b in nxt_conf_vldt_if unit/src/nxt_conf_validation.c:1592:16 The issue was in nxt_tstr_test() where we create an error message with nxt_sprintf(), where this error message is then later used with the '%s' format specifier which expects a nul-terminated string, but by default nxt_sprintf() doesn't nul-terminate, you must use the '%Z' specifier to signify a '\0' at the end of the string. Signed-off-by: Arjun Co-developed-by: Zhidao HONG Signed-off-by: Zhidao HONG Link: Reviewed-by: Andrew Clayton [ Commit message/subject - Andrew ] Signed-off-by: Andrew Clayton --- src/nxt_tstr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index fde4822d..6f39cff2 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -159,7 +159,7 @@ nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) #else nxt_sprintf(error, error + NXT_MAX_ERROR_STR, "Unit is built without support of njs: " - "\"--njs\" ./configure option is missing."); + "\"--njs\" ./configure option is missing.%Z"); return NXT_ERROR; #endif -- cgit From d62a5e2c3749a927e1f5283c1ad2178d665cd399 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 27 May 2024 16:41:55 +0100 Subject: contrib: updated njs to 0.8.5 njs changed strings API so now instead of njs_vm_value_string_set() used njs_vm_value_string_create() as a drop-in replacement. Link: --- src/nxt_http_js.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nxt_http_js.c b/src/nxt_http_js.c index 3dbf7970..34689fba 100644 --- a/src/nxt_http_js.c +++ b/src/nxt_http_js.c @@ -120,7 +120,8 @@ nxt_http_js_ext_uri(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return njs_vm_value_string_set(vm, retval, r->path->start, r->path->length); + return njs_vm_value_string_create(vm, retval, r->path->start, + r->path->length); } @@ -136,7 +137,8 @@ nxt_http_js_ext_host(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return njs_vm_value_string_set(vm, retval, r->host.start, r->host.length); + return njs_vm_value_string_create(vm, retval, r->host.start, + r->host.length); } @@ -152,9 +154,9 @@ nxt_http_js_ext_remote_addr(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return njs_vm_value_string_set(vm, retval, - nxt_sockaddr_address(r->remote), - r->remote->address_length); + return njs_vm_value_string_create(vm, retval, + nxt_sockaddr_address(r->remote), + r->remote->address_length); } @@ -215,8 +217,8 @@ nxt_http_js_ext_get_header(njs_vm_t *vm, njs_object_prop_t *prop, if (key.length == f->name_length && memcmp(key.start, f->name, f->name_length) == 0) { - return njs_vm_value_string_set(vm, retval, f->value, - f->value_length); + return njs_vm_value_string_create(vm, retval, f->value, + f->value_length); } } nxt_list_loop; @@ -251,7 +253,7 @@ nxt_http_js_ext_keys_header(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) return NJS_ERROR; } - rc = njs_vm_value_string_set(vm, value, f->name, f->name_length); + rc = njs_vm_value_string_create(vm, value, f->name, f->name_length); if (rc != NJS_OK) { return NJS_ERROR; } @@ -297,8 +299,8 @@ nxt_http_js_ext_get_cookie(njs_vm_t *vm, njs_object_prop_t *prop, if (key.length == nv->name_length && memcmp(key.start, nv->name, nv->name_length) == 0) { - return njs_vm_value_string_set(vm, retval, nv->value, - nv->value_length); + return njs_vm_value_string_create(vm, retval, nv->value, + nv->value_length); } } @@ -341,7 +343,7 @@ nxt_http_js_ext_keys_cookie(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) return NJS_ERROR; } - rc = njs_vm_value_string_set(vm, value, nv->name, nv->name_length); + rc = njs_vm_value_string_create(vm, value, nv->name, nv->name_length); if (rc != NJS_OK) { return NJS_ERROR; } @@ -381,7 +383,7 @@ nxt_http_js_ext_get_var(njs_vm_t *vm, njs_object_prop_t *prop, vv = nxt_var_get(&r->task, rtcf->tstr_state, &r->tstr_cache.var, &name, r); if (vv != NULL) { - return njs_vm_value_string_set(vm, retval, vv->start, vv->length); + return njs_vm_value_string_create(vm, retval, vv->start, vv->length); } njs_value_undefined_set(retval); -- cgit From a9aa9e76db2766a681350c09947df848898531f6 Mon Sep 17 00:00:00 2001 From: Gourav Date: Wed, 26 Jun 2024 11:14:50 +0530 Subject: python: Support application factories Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: https://github.com/nginx/unit/issues/1106 Link: [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 11 +++++++++++ src/python/nxt_python.c | 27 ++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index f91fc887..04091745 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -841,6 +841,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { .type = NXT_CONF_VLDT_STRING, .validator = nxt_conf_vldt_targets_exclusive, .u.string = "callable", + }, { + .name = nxt_string("factory"), + .type = NXT_CONF_VLDT_BOOLEAN, + .validator = nxt_conf_vldt_targets_exclusive, + .u.string = "factory", }, { .name = nxt_string("prefix"), .type = NXT_CONF_VLDT_STRING, @@ -865,6 +870,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_target_members[] = { }, { .name = nxt_string("callable"), .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("factory"), + .type = NXT_CONF_VLDT_BOOLEAN, }, { .name = nxt_string("prefix"), .type = NXT_CONF_VLDT_STRING, @@ -883,6 +891,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_notargets_members[] = { }, { .name = nxt_string("callable"), .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("factory"), + .type = NXT_CONF_VLDT_BOOLEAN, }, { .name = nxt_string("prefix"), .type = NXT_CONF_VLDT_STRING, diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c index 7c059649..aa0f65b1 100644 --- a/src/python/nxt_python.c +++ b/src/python/nxt_python.c @@ -403,11 +403,13 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target, char *callable, *module_name; PyObject *module, *obj; nxt_str_t str; + nxt_bool_t is_factory = 0; nxt_conf_value_t *value; static nxt_str_t module_str = nxt_string("module"); static nxt_str_t callable_str = nxt_string("callable"); static nxt_str_t prefix_str = nxt_string("prefix"); + static nxt_str_t factory_flag_str = nxt_string("factory"); module = obj = NULL; @@ -449,7 +451,30 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target, goto fail; } - if (nxt_slow_path(PyCallable_Check(obj) == 0)) { + value = nxt_conf_get_object_member(conf, &factory_flag_str, NULL); + if (value != NULL) { + is_factory = nxt_conf_get_boolean(value); + } + + if (is_factory) { + if (nxt_slow_path(PyCallable_Check(obj) == 0)) { + nxt_alert(task, + "factory \"%s\" in module \"%s\" " + "can not be called to fetch callable", + callable, module_name); + goto fail; + } + + obj = PyObject_CallObject(obj, NULL); + if (nxt_slow_path(PyCallable_Check(obj) == 0)) { + nxt_alert(task, + "factory \"%s\" in module \"%s\" " + "did not return callable object", + callable, module_name); + goto fail; + } + + } else if (nxt_slow_path(PyCallable_Check(obj) == 0)) { nxt_alert(task, "\"%s\" in module \"%s\" is not a callable object", callable, module_name); goto fail; -- cgit From 3621352278aa6a3ef760c2fdfbbec0c1310ec1e6 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 1 Jul 2024 12:36:39 +0800 Subject: Fix certificate deletion for array type certificates Previously, the certificate deletion only handled string type certificates, causing issues when certificates were specified as an array in the configuration. Reviewed-by: Andrew Clayton --- src/nxt_controller.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nxt_controller.c b/src/nxt_controller.c index b4ae8d09..1ffcf815 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -1908,9 +1908,9 @@ nxt_controller_process_cert_save(nxt_task_t *task, nxt_port_recv_msg_t *msg, static nxt_bool_t nxt_controller_cert_in_use(nxt_str_t *name) { - uint32_t next; + uint32_t i, n, next; nxt_str_t str; - nxt_conf_value_t *listeners, *listener, *value; + nxt_conf_value_t *listeners, *listener, *value, *element; static const nxt_str_t listeners_path = nxt_string("/listeners"); static const nxt_str_t certificate_path = nxt_string("/tls/certificate"); @@ -1931,10 +1931,27 @@ nxt_controller_cert_in_use(nxt_str_t *name) continue; } - nxt_conf_get_string(value, &str); + if (nxt_conf_type(value) == NXT_CONF_ARRAY) { + n = nxt_conf_array_elements_count(value); - if (nxt_strstr_eq(&str, name)) { - return 1; + for (i = 0; i < n; i++) { + element = nxt_conf_get_array_element(value, i); + + nxt_conf_get_string(element, &str); + + if (nxt_strstr_eq(&str, name)) { + return 1; + } + } + + } else { + /* NXT_CONF_STRING */ + + nxt_conf_get_string(value, &str); + + if (nxt_strstr_eq(&str, name)) { + return 1; + } } } } -- cgit From ff6d504530ad2c126fc264744faa9e62bcc43fb9 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Sat, 22 Jun 2024 00:20:00 +0100 Subject: python: Constify some local static variables These somehow got missed in my previous constification patches... Signed-off-by: Andrew Clayton --- src/python/nxt_python.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c index aa0f65b1..7bbf3d49 100644 --- a/src/python/nxt_python.c +++ b/src/python/nxt_python.c @@ -406,10 +406,10 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target, nxt_bool_t is_factory = 0; nxt_conf_value_t *value; - static nxt_str_t module_str = nxt_string("module"); - static nxt_str_t callable_str = nxt_string("callable"); - static nxt_str_t prefix_str = nxt_string("prefix"); - static nxt_str_t factory_flag_str = nxt_string("factory"); + static const nxt_str_t module_str = nxt_string("module"); + static const nxt_str_t callable_str = nxt_string("callable"); + static const nxt_str_t prefix_str = nxt_string("prefix"); + static const nxt_str_t factory_flag_str = nxt_string("factory"); module = obj = NULL; -- cgit From 081e51151efc7976f578692ee9fc23df14b35a6e Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 26 Jun 2024 18:15:55 +0100 Subject: status: Constify a bunch of local variables This is yet more missed constification, due in this case to me searching for 'static nxt_str_t ' but these only having a single space after the type... Anyway no problem, this can be a preparatory patch for adding further /status information... Signed-off-by: Andrew Clayton --- src/nxt_status.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nxt_status.c b/src/nxt_status.c index f8002e86..0635f0b2 100644 --- a/src/nxt_status.c +++ b/src/nxt_status.c @@ -17,17 +17,17 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) nxt_status_app_t *app; nxt_conf_value_t *status, *obj, *apps, *app_obj; - static nxt_str_t conns_str = nxt_string("connections"); - static nxt_str_t acc_str = nxt_string("accepted"); - static nxt_str_t active_str = nxt_string("active"); - static nxt_str_t idle_str = nxt_string("idle"); - static nxt_str_t closed_str = nxt_string("closed"); - static nxt_str_t reqs_str = nxt_string("requests"); - static nxt_str_t total_str = nxt_string("total"); - static nxt_str_t apps_str = nxt_string("applications"); - static nxt_str_t procs_str = nxt_string("processes"); - static nxt_str_t run_str = nxt_string("running"); - static nxt_str_t start_str = nxt_string("starting"); + static const nxt_str_t conns_str = nxt_string("connections"); + static const nxt_str_t acc_str = nxt_string("accepted"); + static const nxt_str_t active_str = nxt_string("active"); + static const nxt_str_t idle_str = nxt_string("idle"); + static const nxt_str_t closed_str = nxt_string("closed"); + static const nxt_str_t reqs_str = nxt_string("requests"); + static const nxt_str_t total_str = nxt_string("total"); + static const nxt_str_t apps_str = nxt_string("applications"); + static const nxt_str_t procs_str = nxt_string("processes"); + static const nxt_str_t run_str = nxt_string("running"); + static const nxt_str_t start_str = nxt_string("starting"); status = nxt_conf_create_object(mp, 3); if (nxt_slow_path(status == NULL)) { -- cgit From c8d70c3ff28bcf18dfbcfa1332ce0f0d869c0d5f Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 26 Jun 2024 23:52:43 +0100 Subject: status: Use a variable to represent the status member index In nxt_status_get() call nxt_conf_set_member() multiple times to set the main /status json sections. Previously this used hard coded values, 0, 1, 2 etc, if you wanted to change the order or insert new sections it could mean renumbering all these. Instead use a variable to track this index which starts at 0 and is simply incremented in each call of nxt_conf_set_member(). Currently this is only for the main outer sections, but can be replicated for inner sections if required. This is a preparatory patch for adding a new "modules" section at the top. Signed-off-by: Andrew Clayton --- src/nxt_status.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nxt_status.c b/src/nxt_status.c index 0635f0b2..957bc34e 100644 --- a/src/nxt_status.c +++ b/src/nxt_status.c @@ -12,6 +12,7 @@ nxt_conf_value_t * nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) { size_t i; + uint32_t idx = 0; nxt_str_t name; nxt_int_t ret; nxt_status_app_t *app; @@ -39,7 +40,7 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) return NULL; } - nxt_conf_set_member(status, &conns_str, obj, 0); + nxt_conf_set_member(status, &conns_str, obj, idx++); nxt_conf_set_member_integer(obj, &acc_str, report->accepted_conns, 0); nxt_conf_set_member_integer(obj, &active_str, report->accepted_conns @@ -53,7 +54,7 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) return NULL; } - nxt_conf_set_member(status, &reqs_str, obj, 1); + nxt_conf_set_member(status, &reqs_str, obj, idx++); nxt_conf_set_member_integer(obj, &total_str, report->requests, 0); @@ -62,7 +63,7 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) return NULL; } - nxt_conf_set_member(status, &apps_str, apps, 2); + nxt_conf_set_member(status, &apps_str, apps, idx++); for (i = 0; i < report->apps_count; i++) { app = &report->apps[i]; -- cgit From 55041ef9607c073bc5e1b431ec271e9c23200cb1 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 4 Jul 2024 15:52:56 +0100 Subject: Flow the language module name into nxt_app_lang_module_t The nxt_app_lang_module_t structure contains various bits of information as obtained from the nxt_app_module_t structure that language modules define. One bit of information that is in the nxt_app_module_t but not in the nxt_app_lang_module_t is the language module name. Having this name flowed through will be useful for displaying the loaded language modules in the /status endpoint. Signed-off-by: Andrew Clayton --- src/nxt_application.c | 15 ++++++++++++--- src/nxt_application.h | 1 + src/nxt_main_process.c | 6 ++++++ 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nxt_application.c b/src/nxt_application.c index e0247bf0..629aa11c 100644 --- a/src/nxt_application.c +++ b/src/nxt_application.c @@ -32,6 +32,7 @@ typedef struct { nxt_app_type_t type; + nxt_str_t name; nxt_str_t version; nxt_str_t file; nxt_array_t *mounts; @@ -257,12 +258,14 @@ nxt_discovery_modules(nxt_task_t *task, const char *path) module[i].type, &module[i].version, &module[i].file); size += nxt_length("{\"type\": ,"); + size += nxt_length(" \"name\": \"\","); size += nxt_length(" \"version\": \"\","); size += nxt_length(" \"file\": \"\","); size += nxt_length(" \"mounts\": []},"); size += NXT_INT_T_LEN + module[i].version.length + + module[i].name.length + module[i].file.length; mounts = module[i].mounts; @@ -294,9 +297,10 @@ nxt_discovery_modules(nxt_task_t *task, const char *path) for (i = 0; i < n; i++) { mounts = module[i].mounts; - p = nxt_sprintf(p, end, "{\"type\": %d, \"version\": \"%V\", " - "\"file\": \"%V\", \"mounts\": [", - module[i].type, &module[i].version, &module[i].file); + p = nxt_sprintf(p, end, "{\"type\": %d, \"name\": \"%V\", " + "\"version\": \"%V\", \"file\": \"%V\", \"mounts\": [", + module[i].type, &module[i].name, &module[i].version, + &module[i].file); mnt = mounts->elts; for (j = 0; j < mounts->nelts; j++) { @@ -412,6 +416,11 @@ nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp, nxt_array_t *modules, goto fail; } + nxt_str_dup(mp, &module->name, &app->type); + if (module->name.start == NULL) { + goto fail; + } + module->file.length = nxt_strlen(name); module->file.start = nxt_mp_alloc(mp, module->file.length); diff --git a/src/nxt_application.h b/src/nxt_application.h index f5d7a9df..a3b4230a 100644 --- a/src/nxt_application.h +++ b/src/nxt_application.h @@ -35,6 +35,7 @@ typedef nxt_int_t (*nxt_application_setup_t)(nxt_task_t *task, typedef struct { nxt_app_type_t type; + char *name; u_char *version; char *file; nxt_app_module_t *module; diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index c302cb02..00318226 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -1354,6 +1354,12 @@ static nxt_conf_map_t nxt_app_lang_module_map[] = { offsetof(nxt_app_lang_module_t, type), }, + { + nxt_string("name"), + NXT_CONF_MAP_CSTRZ, + offsetof(nxt_app_lang_module_t, name), + }, + { nxt_string("version"), NXT_CONF_MAP_CSTRZ, -- cgit From 707f4ef821f82eb772728f687e41afc9d6945f98 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 28 Jun 2024 21:09:37 +0100 Subject: status: Show list of loaded language modules When querying the '/status' node in the control API, display the list of currently loaded modules. So we now get something like { "modules": { "python": [ { "version": "3.12.3", "lib": "/opt/unit/modules/python.unit.so" }, { "version": "3.12.1", "lib": "/opt/unit/modules/python-3.12.1.unit.so" } ], "wasm": { "version": "0.1", "lib": "/opt/unit/modules/wasm.unit.so" }, "wasm-wasi-component": { "version": "0.1", "lib": "/opt/unit/modules/wasm_wasi_component.unit.so" } }, ... } This can be useful for debugging to show exactly what modules Unit has loaded _and_ from where. Closes: https://github.com/nginx/unit/issues/1343 Signed-off-by: Andrew Clayton --- src/nxt_status.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nxt_status.c b/src/nxt_status.c index 957bc34e..b48ec743 100644 --- a/src/nxt_status.c +++ b/src/nxt_status.c @@ -6,18 +6,27 @@ #include #include #include +#include nxt_conf_value_t * nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) { - size_t i; - uint32_t idx = 0; - nxt_str_t name; - nxt_int_t ret; - nxt_status_app_t *app; - nxt_conf_value_t *status, *obj, *apps, *app_obj; - + size_t i, nr_langs; + uint16_t lang_cnts[NXT_APP_UNKNOWN] = { 1 }; + uint32_t idx = 0; + nxt_str_t name; + nxt_int_t ret; + nxt_array_t *langs; + nxt_thread_t *thr; + nxt_app_type_t type, prev_type; + nxt_status_app_t *app; + nxt_conf_value_t *status, *obj, *mods, *apps, *app_obj, *mod_obj; + nxt_app_lang_module_t *modules; + + static const nxt_str_t modules_str = nxt_string("modules"); + static const nxt_str_t version_str = nxt_string("version"); + static const nxt_str_t lib_str = nxt_string("lib"); static const nxt_str_t conns_str = nxt_string("connections"); static const nxt_str_t acc_str = nxt_string("accepted"); static const nxt_str_t active_str = nxt_string("active"); @@ -30,11 +39,88 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) static const nxt_str_t run_str = nxt_string("running"); static const nxt_str_t start_str = nxt_string("starting"); - status = nxt_conf_create_object(mp, 3); + status = nxt_conf_create_object(mp, 4); if (nxt_slow_path(status == NULL)) { return NULL; } + thr = nxt_thread(); + langs = thr->runtime->languages; + + modules = langs->elts; + /* + * We need to count the number of unique languages to correctly + * allocate the below mods object. + * + * We also need to count how many of each language. + * + * Start by skipping past NXT_APP_EXTERNAL which is always the + * first entry. + */ + for (i = 1, nr_langs = 0, prev_type = NXT_APP_UNKNOWN; i < langs->nelts; + i++) + { + type = modules[i].type; + + lang_cnts[type]++; + + if (type == prev_type) { + continue; + } + + nr_langs++; + prev_type = type; + } + + mods = nxt_conf_create_object(mp, nr_langs); + if (nxt_slow_path(mods == NULL)) { + return NULL; + } + + nxt_conf_set_member(status, &modules_str, mods, idx++); + + i = 1; + obj = mod_obj = NULL; + prev_type = NXT_APP_UNKNOWN; + for (size_t l = 0, a = 0; i < langs->nelts; i++) { + nxt_str_t item, mod_name; + + type = modules[i].type; + if (type != prev_type) { + a = 0; + + if (lang_cnts[type] == 1) { + mod_obj = nxt_conf_create_object(mp, 2); + obj = mod_obj; + } else { + mod_obj = nxt_conf_create_array(mp, lang_cnts[type]); + } + + if (nxt_slow_path(mod_obj == NULL)) { + return NULL; + } + + mod_name.start = (u_char *)modules[i].name; + mod_name.length = strlen(modules[i].name); + nxt_conf_set_member(mods, &mod_name, mod_obj, l++); + } + + if (lang_cnts[type] > 1) { + obj = nxt_conf_create_object(mp, 2); + nxt_conf_set_element(mod_obj, a++, obj); + } + + item.start = modules[i].version; + item.length = nxt_strlen(modules[i].version); + nxt_conf_set_member_string(obj, &version_str, &item, 0); + + item.start = (u_char *)modules[i].file; + item.length = strlen(modules[i].file); + nxt_conf_set_member_string(obj, &lib_str, &item, 1); + + prev_type = type; + } + obj = nxt_conf_create_object(mp, 4); if (nxt_slow_path(obj == NULL)) { return NULL; -- cgit From ebb10b0ad3fc120b5ad219f9155c80311693f5af Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 12 Jul 2024 00:49:28 +0100 Subject: Fix a comment typo for 'Memory-only buffers' in src/nxt_buf.h As the comment for 'Memory-only buffers' says "... it is equal to offsetof(nxt_buf_t, file.pos)" and "... that is it is nxt_buf_t without file and mmap part" Those are at odds with each other, 'file.pos' comes _after_ 'file' in the nxt_buf_t structure. Fix the 'offset()' bit of the comment to reflect that and to match the relevant macro #define NXT_BUF_MEM_SIZE offsetof(nxt_buf_t, file) Signed-off-by: Andrew Clayton --- src/nxt_buf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_buf.h b/src/nxt_buf.h index f1e2879f..a561ef4e 100644 --- a/src/nxt_buf.h +++ b/src/nxt_buf.h @@ -13,7 +13,7 @@ * should be allocated by appropriate nxt_buf_XXX_alloc() function. * * 1) Memory-only buffers, their size is less than nxt_buf_t size, it - * is equal to offsetof(nxt_buf_t, file_pos), that is it is nxt_buf_t + * is equal to offsetof(nxt_buf_t, file), that is it is nxt_buf_t * without file and mmap part. The buffers are frequently used, so * the reduction allows to save 20-32 bytes depending on platform. * -- cgit From 1c607662eb952ecafad08e9774c87aa8676eb836 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Sat, 13 Jul 2024 06:17:51 +0100 Subject: status: Add a missing check for potential NULL Fixes: 707f4ef8 ("status: Show list of loaded language modules") Signed-off-by: Andrew Clayton --- src/nxt_status.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/nxt_status.c b/src/nxt_status.c index b48ec743..92cbf2e6 100644 --- a/src/nxt_status.c +++ b/src/nxt_status.c @@ -107,6 +107,10 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) if (lang_cnts[type] > 1) { obj = nxt_conf_create_object(mp, 2); + if (nxt_slow_path(obj == NULL)) { + return NULL; + } + nxt_conf_set_element(mod_obj, a++, obj); } -- cgit From 2444d45ec969a539c6e1f4484783dd9e9ce21626 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Sun, 11 Aug 2024 16:54:13 +0100 Subject: lib: Better available cpu count determination on Linux At startup, the unit router process creates a number of threads, it tries to create the same number of threads (not incl the main thread) as there are 'cpus' in the system. On Linux the number of available cpus is determined via a call to sysconf(_SC_NPROCESSORS_ONLN); in a lot of cases this produces the right result, i.e. on a four cpu system this will return 4. However this can break down if unit has been restricted in the cpus it's allowed to run on via something like cpuset()'s and/or sched_setaffinity(2). For example, on a four 'cpu' system, starting unit will create an extra 4 router threads $ /opt/unit/sbin/unitd $ ps -efL | grep router andrew 234102 234099 234102 0 5 17:00 pts/10 00:00:00 unit: router andrew 234102 234099 234103 0 5 17:00 pts/10 00:00:00 unit: router andrew 234102 234099 234104 0 5 17:00 pts/10 00:00:00 unit: router andrew 234102 234099 234105 0 5 17:00 pts/10 00:00:00 unit: router andrew 234102 234099 234106 0 5 17:00 pts/10 00:00:00 unit: router Say we want to limit unit to two cpus, i.e. $ taskset -a -c 2-3 /opt/unit/sbin/unitd $ ps -efL | grep router andrew 235772 235769 235772 0 5 17:08 pts/10 00:00:00 unit: router andrew 235772 235769 235773 0 5 17:08 pts/10 00:00:00 unit: router andrew 235772 235769 235774 0 5 17:08 pts/10 00:00:00 unit: router andrew 235772 235769 235775 0 5 17:08 pts/10 00:00:00 unit: router andrew 235772 235769 235776 0 5 17:08 pts/10 00:00:00 unit: router So despite limiting unit to two cpus $ grep Cpus_allowed_list /proc/235772/status Cpus_allowed_list: 2-3 It still created 4 threads, probably not such an issue in this case, but if we had a 64 'cpu' system and wanted to limit unit two cpus, then we'd have 64 threads vying to run on two cpus and with our spinlock implementation this can cause a lot of thread scheduling and congestion overhead. Besides, our intention is currently to create nr router threads == nr cpus. To resolve this, on Linux at least, this patch makes use of sched_getaffinity(2) to determine what cpus unit is actually allowed to run on. We still use the result of sysconf(_SC_NPROCESSORS_ONLN); as a fallback, we also use its result to allocate the required cpuset size (where sched_getaffinity() will store its result) as the standard cpu_set_t only has space to store 1023 cpus. So with this patch if we try to limit unit to two cpus we now get $ taskset -a -c 2-3 /opt/unit/sbin/unitd $ ps -efL | grep router andrew 236887 236884 236887 0 3 17:20 pts/10 00:00:00 unit: router andrew 236887 236884 236888 0 3 17:20 pts/10 00:00:00 unit: router andrew 236887 236884 236889 0 3 17:20 pts/10 00:00:00 unit: router This also applies to the likes of docker, if you run docker with the --cpuset-cpus="" option, unit will now create a number of router threads that matches the cpu count specified. Perhaps useful if you are running a number of unit docker instances on a high cpu count machine. Link: Signed-off-by: Andrew Clayton --- src/nxt_lib.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_lib.c b/src/nxt_lib.c index aba07dda..de23ce0a 100644 --- a/src/nxt_lib.c +++ b/src/nxt_lib.c @@ -32,7 +32,7 @@ const char *malloc_conf = "junk:true"; nxt_int_t nxt_lib_start(const char *app, char **argv, char ***envp) { - int n; + int n = 0; nxt_int_t flags; nxt_bool_t update; nxt_thread_t *thread; @@ -87,13 +87,32 @@ nxt_lib_start(const char *app, char **argv, char ***envp) #ifdef _SC_NPROCESSORS_ONLN /* Linux, FreeBSD, Solaris, MacOSX. */ n = sysconf(_SC_NPROCESSORS_ONLN); +#endif + +#if (NXT_HAVE_LINUX_SCHED_GETAFFINITY) + if (n > 0) { + int err; + size_t size; + cpu_set_t *set; + + set = CPU_ALLOC(n); + if (set == NULL) { + return NXT_ERROR; + } + + size = CPU_ALLOC_SIZE(n); + + err = sched_getaffinity(0, size, set); + if (err == 0) { + n = CPU_COUNT_S(size, set); + } + + CPU_FREE(set); + } #elif (NXT_HPUX) n = mpctl(MPC_GETNUMSPUS, NULL, NULL); -#else - n = 0; - #endif nxt_debug(&nxt_main_task, "ncpu: %d", n); -- cgit From 57c88fd4086d47bf866e3fe7e4c03d0262d413ae Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 12 Aug 2024 22:56:16 +0100 Subject: router: Make the number of router threads configurable Unit generally creates an extra number of router threads (to handle client connections, not incl the main thread) to match the number of available CPUs. There are cases when this can go wrong, e.g on a high CPU count machine and Unit is being effectively limited to a few CPUs via the cgroups cpu controller. So Unit may create a large number of router threads when they are only going to effectively run on a couple of CPUs or so. There may be other cases where you would like to tweak the number of router threads, depending on your workload. As it turns out it looks like it was intended to be made configurable but was just never hooked up to the config system. This adds a new '/settings/listen_threads' config option which can be set like { "listen": { ... }, "settings": { "listen_threads": 2, ... }, ... } Before this patch (on a four cpu system) $ ps -efL | grep router andrew 419832 419829 419832 0 5 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419833 0 5 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419834 0 5 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 445145 0 5 03:31 pts/10 00:00:00 unit: router andrew 419832 419829 445146 0 5 03:31 pts/10 00:00:00 unit: router After, with a threads setting of 2 $ ps -efL | grep router andrew 419832 419829 419832 0 3 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419833 0 3 Aug12 pts/10 00:00:00 unit: router andrew 419832 419829 419834 0 3 Aug12 pts/10 00:00:00 unit: router Closes: https://github.com/nginx/unit/issues/1042 Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 27 +++++++++++++++++++++++++++ src/nxt_router.c | 18 +++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 04091745..c9c51ac1 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -134,6 +134,8 @@ static nxt_int_t nxt_conf_vldt_python_protocol(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_python_prefix(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_listen_threads(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_threads(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_thread_stack_size(nxt_conf_validation_t *vldt, @@ -305,6 +307,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = { static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[] = { { + .name = nxt_string("listen_threads"), + .type = NXT_CONF_VLDT_INTEGER, + .validator = nxt_conf_vldt_listen_threads, + }, { .name = nxt_string("http"), .type = NXT_CONF_VLDT_OBJECT, .validator = nxt_conf_vldt_object, @@ -2078,6 +2084,27 @@ nxt_conf_vldt_python_prefix(nxt_conf_validation_t *vldt, return NXT_OK; } +static nxt_int_t +nxt_conf_vldt_listen_threads(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + int64_t threads; + + threads = nxt_conf_get_number(value); + + if (threads < 1) { + return nxt_conf_vldt_error(vldt, "The \"listen_threads\" number must " + "be equal to or greater than 1."); + } + + if (threads > NXT_INT32_T_MAX) { + return nxt_conf_vldt_error(vldt, "The \"listen_threads\" number must " + "not exceed %d.", NXT_INT32_T_MAX); + } + + return NXT_OK; +} + static nxt_int_t nxt_conf_vldt_threads(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, diff --git a/src/nxt_router.c b/src/nxt_router.c index 43209451..c8ba4744 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1412,7 +1412,7 @@ nxt_router_conf_send(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, static nxt_conf_map_t nxt_router_conf[] = { { - nxt_string("listeners_threads"), + nxt_string("listen_threads"), NXT_CONF_MAP_INT32, offsetof(nxt_router_conf_t, threads), }, @@ -1630,7 +1630,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *js_module; #endif nxt_conf_value_t *root, *conf, *http, *value, *websocket; - nxt_conf_value_t *applications, *application; + nxt_conf_value_t *applications, *application, *settings; nxt_conf_value_t *listeners, *listener; nxt_socket_conf_t *skcf; nxt_router_conf_t *rtcf; @@ -1640,6 +1640,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_router_app_conf_t apcf; nxt_router_listener_conf_t lscf; + static const nxt_str_t settings_path = nxt_string("/settings"); static const nxt_str_t http_path = nxt_string("/settings/http"); static const nxt_str_t applications_path = nxt_string("/applications"); static const nxt_str_t listeners_path = nxt_string("/listeners"); @@ -1673,11 +1674,14 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, rtcf = tmcf->router_conf; mp = rtcf->mem_pool; - ret = nxt_conf_map_object(mp, root, nxt_router_conf, - nxt_nitems(nxt_router_conf), rtcf); - if (ret != NXT_OK) { - nxt_alert(task, "root map error"); - return NXT_ERROR; + settings = nxt_conf_get_path(root, &settings_path); + if (settings != NULL) { + ret = nxt_conf_map_object(mp, settings, nxt_router_conf, + nxt_nitems(nxt_router_conf), rtcf); + if (ret != NXT_OK) { + nxt_alert(task, "router_conf map error"); + return NXT_ERROR; + } } if (rtcf->threads == 0) { -- cgit From 97c15fa38fba641aef4b3adbc4226221c680a206 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 14 Aug 2024 16:15:46 +0100 Subject: socket: Use a default listen backlog of -1 on Linux On FreeBSD, OpenBSD & macOS we use a default listen(2) backlog of -1 which means use the OS's default value. On Linux (and others) we used a hard coded value of 511, presumably due to this comment /* Linux, Solaris, and NetBSD treat negative value as 0. */ On Linux (at least since 2.4), this is wrong, Linux treats -1 (and so on) as use the OS's default (net.core.somaxconn). See this code in net/socket.c::__sys_listen() if ((unsigned int)backlog > somaxconn) backlog = somaxconn; On Linux prior to 5.4 somaxconn defaulted to 128, since 5.4 it defaults to 4096. We've had complaints that a listen backlog of 511 is too small. This would help in those cases. Unless they are on an old Kernel, in which case it's worse, but then the plan is to also make this configurable. This would effect RHEL 8, which is based on 4.10, however they seem to set somaxconn to 2048, so that's fine. Another advantage of using -1 is that we will automatically keep up to date with the kernels default value. Before this change $ ss -tunxlp | grep unit Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process u_str LISTEN 0 511 /opt/unit/control.unit.sock.tmp 4302333 * 0 users:(("unitd",pid=18290,fd=6),("unitd",pid=18289,fd=6),("unitd",pid=18287,fd=6)) tcp LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("unitd",pid=18290,fd=12)) tcp LISTEN 0 511 [::1]:8080 [::]:* users:(("unitd",pid=18290,fd=11)) After $ ss -tunxlp | grep unit Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process u_str LISTEN 0 4096 /opt/unit/control.unit.sock.tmp 5408464 * 0 users:(("unitd",pid=132442,fd=6),("unitd",pid=132441,fd=6),("unitd",pid=132439,fd=6)) tcp LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("unitd",pid=132442,fd=12)) tcp LISTEN 0 4096 [::1]:8080 [::]:* users:(("unitd",pid=132442,fd=11)) Link: Link: Signed-off-by: Andrew Clayton --- src/nxt_listen_socket.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_listen_socket.h b/src/nxt_listen_socket.h index e2435b76..8bf320bc 100644 --- a/src/nxt_listen_socket.h +++ b/src/nxt_listen_socket.h @@ -35,16 +35,16 @@ typedef struct { } nxt_listen_socket_t; -#if (NXT_FREEBSD || NXT_MACOSX || NXT_OPENBSD) +#if (NXT_LINUX || NXT_FREEBSD || NXT_MACOSX || NXT_OPENBSD) /* - * A backlog is limited by system-wide sysctl kern.ipc.somaxconn. - * This is supported by FreeBSD 2.2, OpenBSD 2.0, and MacOSX. + * A backlog is limited by system-wide sysctl {net.core,kern.ipc}.somaxconn. + * This is supported by Linux, FreeBSD 2.2, OpenBSD 2.0, and MacOSX. */ #define NXT_LISTEN_BACKLOG -1 #else /* - * Linux, Solaris, and NetBSD treat negative value as 0. + * Solaris and NetBSD treat negative value as 0. * 511 is a safe default. */ #define NXT_LISTEN_BACKLOG 511 -- cgit From 76489fb7e0ab9142651b91ee8072c6cda270dd09 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 14 Aug 2024 00:33:13 +0100 Subject: conf, router: Make the listen(2) backlog configurable @oopsoop2 on GitHub reported a performance issue related to the default listen(2) backlog size of 511 on nginx. They found that increasing it helped, nginx has a config option to configure this. They would like to be able to do the same on Unit (which also defaults to 511 on some systems). This seems reasonable. NOTE: On Linux before commit 97c15fa38 ("socket: Use a default listen backlog of -1 on Linux") we defaulted to 511. Since that commit we default to the Kernels default, which before 5.4 is 128 and after is 4096. This adds a new per-listener 'backlog' config option, e.g { "listeners": { "[::1]:8080": { "pass": "routes", "backlog": 1024 }, } ... } This doesn't effect the control socket. Closes: https://github.com/nginx/unit/issues/1384 Reported-by: Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 32 ++++++++++++++++++++++++++++++++ src/nxt_router.c | 27 ++++++++++++++++++--------- 2 files changed, 50 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index c9c51ac1..8f31bd18 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -178,6 +178,8 @@ static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_listen_backlog(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt, @@ -430,6 +432,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { .type = NXT_CONF_VLDT_OBJECT, .validator = nxt_conf_vldt_object, .u.members = nxt_conf_vldt_client_ip_members + }, { + .name = nxt_string("backlog"), + .type = NXT_CONF_VLDT_NUMBER, + .validator = nxt_conf_vldt_listen_backlog, }, #if (NXT_TLS) @@ -2704,6 +2710,32 @@ nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, } +static nxt_int_t +nxt_conf_vldt_listen_backlog(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + int64_t backlog; + + backlog = nxt_conf_get_number(value); + + /* + * POSIX allows this to be 0 and some systems use -1 to + * indicate to use the OS's default value. + */ + if (backlog < -1) { + return nxt_conf_vldt_error(vldt, "The \"backlog\" number must be " + "equal to or greater than -1."); + } + + if (backlog > NXT_INT32_T_MAX) { + return nxt_conf_vldt_error(vldt, "The \"backlog\" number must " + "not exceed %d.", NXT_INT32_T_MAX); + } + + return NXT_OK; +} + + static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) diff --git a/src/nxt_router.c b/src/nxt_router.c index c8ba4744..076cd134 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -40,6 +40,7 @@ typedef struct { typedef struct { nxt_str_t pass; nxt_str_t application; + int backlog; } nxt_router_listener_conf_t; @@ -166,7 +167,7 @@ static void nxt_router_app_prefork_ready(nxt_task_t *task, static void nxt_router_app_prefork_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf, nxt_str_t *name); + nxt_router_temp_conf_t *tmcf, nxt_str_t *name, int backlog); static nxt_int_t nxt_router_listen_socket_find(nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *nskcf, nxt_sockaddr_t *sa); @@ -1494,6 +1495,12 @@ static nxt_conf_map_t nxt_router_listener_conf[] = { NXT_CONF_MAP_STR_COPY, offsetof(nxt_router_listener_conf_t, application), }, + + { + nxt_string("backlog"), + NXT_CONF_MAP_INT32, + offsetof(nxt_router_listener_conf_t, backlog), + }, }; @@ -1968,13 +1975,10 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, break; } - skcf = nxt_router_socket_conf(task, tmcf, &name); - if (skcf == NULL) { - goto fail; - } - nxt_memzero(&lscf, sizeof(lscf)); + lscf.backlog = -1; + ret = nxt_conf_map_object(mp, listener, nxt_router_listener_conf, nxt_nitems(nxt_router_listener_conf), &lscf); @@ -1985,6 +1989,11 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_debug(task, "application: %V", &lscf.application); + skcf = nxt_router_socket_conf(task, tmcf, &name, lscf.backlog); + if (skcf == NULL) { + goto fail; + } + // STUB, default values if http block is not defined. skcf->header_buffer_size = 2048; skcf->large_header_buffer_size = 8192; @@ -2688,7 +2697,7 @@ nxt_router_application_init(nxt_router_conf_t *rtcf, nxt_str_t *name, static nxt_socket_conf_t * nxt_router_socket_conf(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, - nxt_str_t *name) + nxt_str_t *name, int backlog) { size_t size; nxt_int_t ret; @@ -2732,7 +2741,7 @@ nxt_router_socket_conf(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_listen_socket_remote_size(ls); ls->socket = -1; - ls->backlog = NXT_LISTEN_BACKLOG; + ls->backlog = backlog > -1 ? backlog : NXT_LISTEN_BACKLOG; ls->flags = NXT_NONBLOCK; ls->read_after_accept = 1; } @@ -2879,7 +2888,7 @@ nxt_router_listen_socket_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, nxt_socket_defer_accept(task, s, rpc->socket_conf->listen->sockaddr); - ret = nxt_listen_socket(task, s, NXT_LISTEN_BACKLOG); + ret = nxt_listen_socket(task, s, rpc->socket_conf->listen->backlog); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } -- cgit From 2eecee7520558a8f72e98e839a77330712a946b4 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 18 Apr 2024 18:16:01 +0800 Subject: var: Restrict nxt_tstr_query() to only support synchronous operation Initially, variable query was designed to accomodate both synchronous and asynchronous operations. However, upon consideration of actual requirements, we recognized that asynchronous support was not needed. The refactoring ensures that the success or failure of the variable query operation is now directly indicated by its return value. This change streamlines the function's usage and enhances code clarity, as it facilitates immediate error handling without the need for asynchronous callbacks or additional error checking functions. Note the patch only works for Unit native variables but not njs variables. --- src/nxt_http_request.c | 5 ++--- src/nxt_http_rewrite.c | 5 ++--- src/nxt_http_set_headers.c | 5 ++--- src/nxt_tstr.c | 12 +++++++----- src/nxt_tstr.h | 4 ++-- 5 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 54d1bd27..ccd2b141 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -936,9 +936,8 @@ nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, return NXT_DECLINED; } - nxt_tstr_query(task, r->tstr_query, rtcf->log_expr, &str); - - if (nxt_slow_path(nxt_tstr_query_failed(r->tstr_query))) { + ret = nxt_tstr_query(task, r->tstr_query, rtcf->log_expr, &str); + if (nxt_slow_path(ret != NXT_OK)) { return NXT_DECLINED; } } diff --git a/src/nxt_http_rewrite.c b/src/nxt_http_rewrite.c index 661200ef..5de15ed7 100644 --- a/src/nxt_http_rewrite.c +++ b/src/nxt_http_rewrite.c @@ -52,9 +52,8 @@ nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r) return NXT_ERROR; } - nxt_tstr_query(task, r->tstr_query, action->rewrite, &str); - - if (nxt_slow_path(nxt_tstr_query_failed(r->tstr_query))) { + ret = nxt_tstr_query(task, r->tstr_query, action->rewrite, &str); + if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } } diff --git a/src/nxt_http_set_headers.c b/src/nxt_http_set_headers.c index 25dd7478..7fd6aba5 100644 --- a/src/nxt_http_set_headers.c +++ b/src/nxt_http_set_headers.c @@ -139,9 +139,8 @@ nxt_http_set_headers(nxt_http_request_t *r) return NXT_ERROR; } - nxt_tstr_query(&r->task, r->tstr_query, hv->value, &value[i]); - - if (nxt_slow_path(nxt_tstr_query_failed(r->tstr_query))) { + ret = nxt_tstr_query(&r->task, r->tstr_query, hv->value, &value[i]); + if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } } diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index 6f39cff2..a72d7ddc 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -246,7 +246,7 @@ nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_tstr_state_t *state, } -void +nxt_int_t nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, nxt_str_t *val) { @@ -254,11 +254,11 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, if (nxt_tstr_is_const(tstr)) { nxt_tstr_str(tstr, val); - return; + return NXT_OK; } if (nxt_slow_path(query->failed)) { - return; + return NXT_ERROR; } if (tstr->type == NXT_TSTR_VAR) { @@ -268,7 +268,7 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, if (nxt_slow_path(ret != NXT_OK)) { query->failed = 1; - return; + return NXT_ERROR; } } else { @@ -278,7 +278,7 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, if (nxt_slow_path(ret != NXT_OK)) { query->failed = 1; - return; + return NXT_ERROR; } #endif } @@ -294,6 +294,8 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, nxt_debug(task, "tstr query: \"%V\", result: \"%V\"", &str, val); #endif + + return NXT_OK; } diff --git a/src/nxt_tstr.h b/src/nxt_tstr.h index a156732d..574b4281 100644 --- a/src/nxt_tstr.h +++ b/src/nxt_tstr.h @@ -50,8 +50,8 @@ void nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str); nxt_int_t nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_tstr_state_t *state, nxt_tstr_cache_t *cache, void *ctx, nxt_mp_t *mp); -void nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, - nxt_str_t *val); +nxt_int_t nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, + nxt_tstr_t *tstr, nxt_str_t *val); nxt_bool_t nxt_tstr_query_failed(nxt_tstr_query_t *query); void nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query, void *data, nxt_work_handler_t ready, nxt_work_handler_t error); -- cgit From 76a255b27ec2351ce580baaf54d28ee4b59680ad Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 18 Apr 2024 18:20:53 +0800 Subject: http: Refactor return action --- src/nxt_http_return.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index b50e4ad0..a3551683 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -24,8 +24,8 @@ static nxt_http_action_t *nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); static nxt_int_t nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded, const nxt_str_t *location); -static void nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data); -static void nxt_http_return_send_error(nxt_task_t *task, void *obj, void *data); +static void nxt_http_return_send(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_return_ctx_t *ctx); static const nxt_http_request_state_t nxt_http_return_send_state; @@ -120,8 +120,6 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, ctx->encoded = conf->encoded; } - nxt_http_return_send_ready(task, r, ctx); - } else { rtcf = r->conf->socket_conf->router_conf; @@ -131,13 +129,15 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, goto fail; } - nxt_tstr_query(task, r->tstr_query, conf->location, &ctx->location); - - nxt_tstr_query_resolve(task, r->tstr_query, ctx, - nxt_http_return_send_ready, - nxt_http_return_send_error); + ret = nxt_tstr_query(task, r->tstr_query, conf->location, + &ctx->location); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } } + nxt_http_return_send(task, r, ctx); + return NULL; fail: @@ -174,15 +174,11 @@ nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded, static void -nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) +nxt_http_return_send(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_return_ctx_t *ctx) { - nxt_int_t ret; - nxt_http_field_t *field; - nxt_http_request_t *r; - nxt_http_return_ctx_t *ctx; - - r = obj; - ctx = data; + nxt_int_t ret; + nxt_http_field_t *field; if (ctx != NULL) { if (ctx->location.length > 0) { @@ -216,17 +212,6 @@ fail: } -static void -nxt_http_return_send_error(nxt_task_t *task, void *obj, void *data) -{ - nxt_http_request_t *r; - - r = obj; - - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); -} - - static const nxt_http_request_state_t nxt_http_return_send_state nxt_aligned(64) = { -- cgit From 08a23272a7b8618400a4de725bccd1d016329c9a Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 18 Apr 2024 18:23:59 +0800 Subject: http: Refactor route pass query --- src/nxt_http_route.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 852f5739..a82518a4 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -193,8 +193,8 @@ static nxt_int_t nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action); static nxt_http_action_t *nxt_http_pass_var(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); -static void nxt_http_pass_query_ready(nxt_task_t *task, void *obj, void *data); -static void nxt_http_pass_query_error(nxt_task_t *task, void *obj, void *data); +static void nxt_http_pass_query(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_action_t *action); static nxt_int_t nxt_http_pass_find(nxt_mp_t *mp, nxt_router_conf_t *rtcf, nxt_str_t *pass, nxt_http_action_t *action); static nxt_int_t nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name, @@ -1344,10 +1344,13 @@ nxt_http_pass_var(nxt_task_t *task, nxt_http_request_t *r, action->u.pass = nxt_pointer_to(action, sizeof(nxt_http_action_t)); - nxt_tstr_query(task, r->tstr_query, tstr, action->u.pass); - nxt_tstr_query_resolve(task, r->tstr_query, action, - nxt_http_pass_query_ready, - nxt_http_pass_query_error); + ret = nxt_tstr_query(task, r->tstr_query, tstr, action->u.pass); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + + nxt_http_pass_query(task, r, action); + return NULL; fail: @@ -1358,16 +1361,13 @@ fail: static void -nxt_http_pass_query_ready(nxt_task_t *task, void *obj, void *data) +nxt_http_pass_query(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_action_t *action) { - nxt_int_t ret; - nxt_router_conf_t *rtcf; - nxt_http_action_t *action; - nxt_http_status_t status; - nxt_http_request_t *r; - - r = obj; - action = data; + nxt_int_t ret; + nxt_router_conf_t *rtcf; + nxt_http_status_t status; + rtcf = r->conf->socket_conf->router_conf; nxt_debug(task, "http pass lookup: %V", action->u.pass); @@ -1386,17 +1386,6 @@ nxt_http_pass_query_ready(nxt_task_t *task, void *obj, void *data) } -static void -nxt_http_pass_query_error(nxt_task_t *task, void *obj, void *data) -{ - nxt_http_request_t *r; - - r = obj; - - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); -} - - static nxt_int_t nxt_http_pass_find(nxt_mp_t *mp, nxt_router_conf_t *rtcf, nxt_str_t *pass, nxt_http_action_t *action) -- cgit From 9d19e7e0ff5cfd75644df9fcf91c37db25aa7109 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 18 Apr 2024 18:29:15 +0800 Subject: http: Refactor static action --- src/nxt_http_static.c | 50 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index ee25015e..67591595 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -47,8 +47,8 @@ static nxt_http_action_t *nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); static void nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, nxt_http_static_ctx_t *ctx); -static void nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data); -static void nxt_http_static_send_error(nxt_task_t *task, void *obj, void *data); +static void nxt_http_static_send(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_static_ctx_t *ctx); static void nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r, nxt_http_static_ctx_t *ctx, nxt_http_status_t status); #if (NXT_HAVE_OPENAT2) @@ -271,35 +271,44 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, } #endif - nxt_http_static_send_ready(task, r, ctx); - } else { rtcf = r->conf->socket_conf->router_conf; ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, &r->tstr_cache, r, r->mem_pool); if (nxt_slow_path(ret != NXT_OK)) { - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); - return; + goto fail; } - nxt_tstr_query(task, r->tstr_query, share->tstr, &ctx->share); + ret = nxt_tstr_query(task, r->tstr_query, share->tstr, &ctx->share); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } #if (NXT_HAVE_OPENAT2) if (conf->chroot != NULL && ctx->share_idx == 0) { - nxt_tstr_query(task, r->tstr_query, conf->chroot, &ctx->chroot); + ret = nxt_tstr_query(task, r->tstr_query, conf->chroot, + &ctx->chroot); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } } #endif + } + + nxt_http_static_send(task, r, ctx); + + return; + +fail: - nxt_tstr_query_resolve(task, r->tstr_query, ctx, - nxt_http_static_send_ready, - nxt_http_static_send_error); - } + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); } static void -nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) +nxt_http_static_send(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_static_ctx_t *ctx) { size_t length, encode; u_char *p, *fname; @@ -314,13 +323,9 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) nxt_http_status_t status; nxt_router_conf_t *rtcf; nxt_http_action_t *action; - nxt_http_request_t *r; nxt_work_handler_t body_handler; - nxt_http_static_ctx_t *ctx; nxt_http_static_conf_t *conf; - r = obj; - ctx = data; action = ctx->action; conf = action->u.conf; rtcf = r->conf->socket_conf->router_conf; @@ -662,17 +667,6 @@ fail: } -static void -nxt_http_static_send_error(nxt_task_t *task, void *obj, void *data) -{ - nxt_http_request_t *r; - - r = obj; - - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); -} - - static void nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r, nxt_http_static_ctx_t *ctx, nxt_http_status_t status) -- cgit From ecb3f86c8528a26d770e93bd5296b780981e20ff Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 18 Apr 2024 18:31:04 +0800 Subject: http: Refactor access log write --- src/nxt_router_access_log.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c index ff17b0b6..cc8d5e4f 100644 --- a/src/nxt_router_access_log.c +++ b/src/nxt_router_access_log.c @@ -26,10 +26,8 @@ typedef struct { static void nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, nxt_router_access_log_t *access_log, nxt_tstr_t *format); -static void nxt_router_access_log_write_ready(nxt_task_t *task, void *obj, - void *data); -static void nxt_router_access_log_write_error(nxt_task_t *task, void *obj, - void *data); +static void nxt_router_access_log_write(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_access_log_ctx_t *ctx); static void nxt_router_access_log_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); static void nxt_router_access_log_error(nxt_task_t *task, @@ -180,8 +178,6 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, if (nxt_tstr_is_const(format)) { nxt_tstr_str(format, &ctx->text); - nxt_router_access_log_write_ready(task, r, ctx); - } else { rtcf = r->conf->socket_conf->router_conf; @@ -191,36 +187,26 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, return; } - nxt_tstr_query(task, r->tstr_query, format, &ctx->text); - nxt_tstr_query_resolve(task, r->tstr_query, ctx, - nxt_router_access_log_write_ready, - nxt_router_access_log_write_error); - } + ret = nxt_tstr_query(task, r->tstr_query, format, &ctx->text); + if (nxt_slow_path(ret != NXT_OK)) { + return; + } + } + + nxt_router_access_log_write(task, r, ctx); } static void -nxt_router_access_log_write_ready(nxt_task_t *task, void *obj, void *data) +nxt_router_access_log_write(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_access_log_ctx_t *ctx) { - nxt_http_request_t *r; - nxt_router_access_log_ctx_t *ctx; - - r = obj; - ctx = data; - nxt_fd_write(ctx->access_log->fd, ctx->text.start, ctx->text.length); nxt_http_request_close_handler(task, r, r->proto.any); } -static void -nxt_router_access_log_write_error(nxt_task_t *task, void *obj, void *data) -{ - -} - - void nxt_router_access_log_open(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) { -- cgit From 5f6ae1a189b1736eb7cc35f1ff8018fd8606db9b Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 18 Apr 2024 18:34:07 +0800 Subject: var: Remove unused functions and structure fields --- src/nxt_tstr.c | 49 ------------------------------------------------- src/nxt_tstr.h | 5 ----- src/nxt_var.c | 6 ------ 3 files changed, 60 deletions(-) (limited to 'src') diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index a72d7ddc..a6d2e7ad 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -36,14 +36,8 @@ struct nxt_tstr_query_s { nxt_tstr_state_t *state; nxt_tstr_cache_t *cache; - nxt_uint_t waiting; - nxt_uint_t failed; /* 1 bit */ - void *ctx; void *data; - - nxt_work_handler_t ready; - nxt_work_handler_t error; }; @@ -257,17 +251,12 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, return NXT_OK; } - if (nxt_slow_path(query->failed)) { - return NXT_ERROR; - } - if (tstr->type == NXT_TSTR_VAR) { ret = nxt_var_interpreter(task, query->state, &query->cache->var, tstr->u.var, val, query->ctx, tstr->flags & NXT_TSTR_LOGGING); if (nxt_slow_path(ret != NXT_OK)) { - query->failed = 1; return NXT_ERROR; } @@ -277,7 +266,6 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, tstr->u.js, val, query->ctx); if (nxt_slow_path(ret != NXT_OK)) { - query->failed = 1; return NXT_ERROR; } #endif @@ -299,43 +287,6 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, } -nxt_bool_t -nxt_tstr_query_failed(nxt_tstr_query_t *query) -{ - return query->failed; -} - - -void -nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query, void *data, - nxt_work_handler_t ready, nxt_work_handler_t error) -{ - query->data = data; - query->ready = ready; - query->error = error; - - if (query->waiting == 0) { - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - query->failed ? query->error : query->ready, - task, query->ctx, query->data); - } -} - - -void -nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query, - nxt_bool_t failed) -{ - query->failed |= failed; - - if (--query->waiting == 0) { - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - query->failed ? query->error : query->ready, - task, query->ctx, query->data); - } -} - - void nxt_tstr_query_release(nxt_tstr_query_t *query) { diff --git a/src/nxt_tstr.h b/src/nxt_tstr.h index 574b4281..2aa905df 100644 --- a/src/nxt_tstr.h +++ b/src/nxt_tstr.h @@ -52,11 +52,6 @@ nxt_int_t nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_mp_t *mp); nxt_int_t nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, nxt_str_t *val); -nxt_bool_t nxt_tstr_query_failed(nxt_tstr_query_t *query); -void nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query, - void *data, nxt_work_handler_t ready, nxt_work_handler_t error); -void nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query, - nxt_bool_t failed); void nxt_tstr_query_release(nxt_tstr_query_t *query); diff --git a/src/nxt_var.c b/src/nxt_var.c index 94d10cd8..16aa1c7e 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -30,14 +30,8 @@ struct nxt_var_query_s { nxt_var_cache_t cache; - nxt_uint_t waiting; - nxt_uint_t failed; /* 1 bit */ - void *ctx; void *data; - - nxt_work_handler_t ready; - nxt_work_handler_t error; }; -- cgit From 82e168fe01306cf03f8eaba284f31f7285347424 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 16 Aug 2024 00:06:45 +0800 Subject: http: Refactor out nxt_tstr_cond_t from the access log module This nxt_tstr_cond_t will be reused for the feature of adding "if" option to the "match" object. The two "if" options have the same usage. --- src/nxt_http.h | 3 ++ src/nxt_http_request.c | 80 ++++++++++++++++++++++++++------------------- src/nxt_router.h | 3 +- src/nxt_router_access_log.c | 11 ++----- src/nxt_tstr.c | 20 ++++++++++++ src/nxt_tstr.h | 8 +++++ 6 files changed, 80 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/nxt_http.h b/src/nxt_http.h index fe5e72a8..5369c8e1 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -441,6 +441,9 @@ void nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_bool_t all); nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data); +int nxt_http_cond_value(nxt_task_t *task, nxt_http_request_t *r, + nxt_tstr_cond_t *cond); + extern const nxt_conn_state_t nxt_h1p_idle_close_state; #endif /* _NXT_HTTP_H_INCLUDED_ */ diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index ccd2b141..a65163d0 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -915,44 +915,11 @@ static nxt_int_t nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, nxt_router_conf_t *rtcf) { - nxt_int_t ret; - nxt_str_t str; - nxt_bool_t expr; nxt_router_access_log_t *access_log; access_log = rtcf->access_log; - expr = 1; - - if (rtcf->log_expr != NULL) { - - if (nxt_tstr_is_const(rtcf->log_expr)) { - nxt_tstr_str(rtcf->log_expr, &str); - - } else { - ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, - &r->tstr_cache, r, r->mem_pool); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_DECLINED; - } - - ret = nxt_tstr_query(task, r->tstr_query, rtcf->log_expr, &str); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_DECLINED; - } - } - - if (str.length == 0 - || nxt_str_eq(&str, "0", 1) - || nxt_str_eq(&str, "false", 5) - || nxt_str_eq(&str, "null", 4) - || nxt_str_eq(&str, "undefined", 9)) - { - expr = 0; - } - } - - if (rtcf->log_negate ^ expr) { + if (nxt_http_cond_value(task, r, &rtcf->log_cond)) { access_log->handler(task, r, access_log, rtcf->log_format); return NXT_OK; } @@ -1364,3 +1331,48 @@ nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name) { return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_NONE); } + + +int +nxt_http_cond_value(nxt_task_t *task, nxt_http_request_t *r, + nxt_tstr_cond_t *cond) +{ + nxt_int_t ret; + nxt_str_t str; + nxt_bool_t expr; + nxt_router_conf_t *rtcf; + + rtcf = r->conf->socket_conf->router_conf; + + expr = 1; + + if (cond->expr != NULL) { + + if (nxt_tstr_is_const(cond->expr)) { + nxt_tstr_str(cond->expr, &str); + + } else { + ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, + &r->tstr_cache, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + return -1; + } + + ret = nxt_tstr_query(task, r->tstr_query, cond->expr, &str); + if (nxt_slow_path(ret != NXT_OK)) { + return -1; + } + } + + if (str.length == 0 + || nxt_str_eq(&str, "0", 1) + || nxt_str_eq(&str, "false", 5) + || nxt_str_eq(&str, "null", 4) + || nxt_str_eq(&str, "undefined", 9)) + { + expr = 0; + } + } + + return cond->negate ^ expr; +} diff --git a/src/nxt_router.h b/src/nxt_router.h index cfc7258c..06c6bb32 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -54,8 +54,7 @@ typedef struct { nxt_router_access_log_t *access_log; nxt_tstr_t *log_format; - nxt_tstr_t *log_expr; - uint8_t log_negate; /* 1 bit */ + nxt_tstr_cond_t log_cond; } nxt_router_conf_t; diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c index cc8d5e4f..afecd0b1 100644 --- a/src/nxt_router_access_log.c +++ b/src/nxt_router_access_log.c @@ -143,15 +143,8 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf, if (alcf.expr != NULL) { nxt_conf_get_string(alcf.expr, &str); - if (str.length > 0 && str.start[0] == '!') { - rtcf->log_negate = 1; - - str.start++; - str.length--; - } - - rtcf->log_expr = nxt_tstr_compile(rtcf->tstr_state, &str, 0); - if (nxt_slow_path(rtcf->log_expr == NULL)) { + ret = nxt_tstr_cond_compile(rtcf->tstr_state, &str, &rtcf->log_cond); + if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } } diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index a6d2e7ad..50df4c47 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -196,6 +196,26 @@ nxt_tstr_state_release(nxt_tstr_state_t *state) } +nxt_int_t +nxt_tstr_cond_compile(nxt_tstr_state_t *state, nxt_str_t *str, + nxt_tstr_cond_t *cond) +{ + if (str->length > 0 && str->start[0] == '!') { + cond->negate = 1; + + str->start++; + str->length--; + } + + cond->expr = nxt_tstr_compile(state, str, 0); + if (nxt_slow_path(cond->expr == NULL)) { + return NXT_ERROR; + } + + return NXT_OK; +} + + nxt_bool_t nxt_tstr_is_const(nxt_tstr_t *tstr) { diff --git a/src/nxt_tstr.h b/src/nxt_tstr.h index 2aa905df..aca74e20 100644 --- a/src/nxt_tstr.h +++ b/src/nxt_tstr.h @@ -37,12 +37,20 @@ typedef enum { } nxt_tstr_flags_t; +typedef struct { + nxt_tstr_t *expr; + uint8_t negate; /* 1 bit */ +} nxt_tstr_cond_t; + + nxt_tstr_state_t *nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test); nxt_tstr_t *nxt_tstr_compile(nxt_tstr_state_t *state, const nxt_str_t *str, nxt_tstr_flags_t flags); nxt_int_t nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error); nxt_int_t nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error); void nxt_tstr_state_release(nxt_tstr_state_t *state); +nxt_int_t nxt_tstr_cond_compile(nxt_tstr_state_t *state, nxt_str_t *str, + nxt_tstr_cond_t *cond); nxt_bool_t nxt_tstr_is_const(nxt_tstr_t *tstr); void nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str); -- cgit From 57f939569d3c3db11d8bbc7dd0b45693cbe3344e Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 16 Aug 2024 00:09:22 +0800 Subject: http: Get rid of nxt_http_request_access_log() --- src/nxt_http_request.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index a65163d0..a7e9ff69 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -24,8 +24,6 @@ static void nxt_http_request_proto_info(nxt_task_t *task, static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data); -static nxt_int_t nxt_http_request_access_log(nxt_task_t *task, - nxt_http_request_t *r, nxt_router_conf_t *rtcf); static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); @@ -861,12 +859,12 @@ nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data) void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) { - nxt_int_t ret; nxt_http_proto_t proto; nxt_router_conf_t *rtcf; nxt_http_request_t *r; nxt_http_protocol_t protocol; nxt_socket_conf_joint_t *conf; + nxt_router_access_log_t *access_log; r = obj; proto.any = data; @@ -878,8 +876,10 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) r->logged = 1; if (rtcf->access_log != NULL) { - ret = nxt_http_request_access_log(task, r, rtcf); - if (ret == NXT_OK) { + access_log = rtcf->access_log; + + if (nxt_http_cond_value(task, r, &rtcf->log_cond)) { + access_log->handler(task, r, access_log, rtcf->log_format); return; } } @@ -911,23 +911,6 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) } -static nxt_int_t -nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, - nxt_router_conf_t *rtcf) -{ - nxt_router_access_log_t *access_log; - - access_log = rtcf->access_log; - - if (nxt_http_cond_value(task, r, &rtcf->log_cond)) { - access_log->handler(task, r, access_log, rtcf->log_format); - return NXT_OK; - } - - return NXT_DECLINED; -} - - static u_char * nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format) -- cgit From debd61c3a4f7e5817bf842c2166217929ef80c88 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 16 Aug 2024 00:29:16 +0800 Subject: http: Add "if" option to the "match" object This feature allows users to specify conditions to check if one route is matched. It is used the same way as the "if" option in the access log. Example: { "match": { "if": "`${headers['User-Agent'].split('/')[0] == 'curl'}`" }, "action": { "return": 204 } } --- src/nxt_conf_validation.c | 4 ++++ src/nxt_http_route.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 8f31bd18..5d7f7c52 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -696,6 +696,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_match_members[] = { .type = NXT_CONF_VLDT_OBJECT | NXT_CONF_VLDT_ARRAY, .validator = nxt_conf_vldt_match_patterns_sets, .u.string = "cookies" + }, { + .name = nxt_string("if"), + .type = NXT_CONF_VLDT_STRING, + .validator = nxt_conf_vldt_if, }, NXT_CONF_VLDT_END diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index a82518a4..bd0646f3 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -51,6 +51,7 @@ typedef struct { nxt_conf_value_t *query; nxt_conf_value_t *source; nxt_conf_value_t *destination; + nxt_conf_value_t *condition; } nxt_http_route_match_conf_t; @@ -138,6 +139,7 @@ typedef union { typedef struct { uint32_t items; + nxt_tstr_cond_t condition; nxt_http_action_t action; nxt_http_route_test_t test[]; } nxt_http_route_match_t; @@ -350,6 +352,12 @@ static nxt_conf_map_t nxt_http_route_match_conf[] = { NXT_CONF_MAP_PTR, offsetof(nxt_http_route_match_conf_t, destination), }, + + { + nxt_string("if"), + NXT_CONF_MAP_PTR, + offsetof(nxt_http_route_match_conf_t, condition), + }, }; @@ -397,7 +405,9 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, uint32_t n; nxt_mp_t *mp; nxt_int_t ret; - nxt_conf_value_t *match_conf, *action_conf; + nxt_str_t str; + nxt_conf_value_t *match_conf, *action_conf, *condition; + nxt_router_conf_t *rtcf; nxt_http_route_test_t *test; nxt_http_route_rule_t *rule; nxt_http_route_table_t *table; @@ -405,6 +415,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_route_addr_rule_t *addr_rule; nxt_http_route_match_conf_t mtcf; + static const nxt_str_t if_path = nxt_string("/if"); static const nxt_str_t match_path = nxt_string("/match"); static const nxt_str_t action_path = nxt_string("/action"); @@ -413,9 +424,21 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, n = (match_conf != NULL) ? nxt_conf_object_members_count(match_conf) : 0; size = sizeof(nxt_http_route_match_t) + n * sizeof(nxt_http_route_test_t *); - mp = tmcf->router_conf->mem_pool; + rtcf = tmcf->router_conf; + mp = rtcf->mem_pool; + + condition = NULL; + + if (match_conf != NULL) { + condition = nxt_conf_get_path(match_conf, &if_path); + + if (condition != NULL) { + n--; + size -= sizeof(nxt_http_route_test_t *); + } + } - match = nxt_mp_alloc(mp, size); + match = nxt_mp_zalloc(mp, size); if (nxt_slow_path(match == NULL)) { return NULL; } @@ -432,7 +455,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, return NULL; } - if (n == 0) { + if (n == 0 && condition == NULL) { return match; } @@ -445,6 +468,15 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, return NULL; } + if (condition != NULL) { + nxt_conf_get_string(condition, &str); + + ret = nxt_tstr_cond_compile(rtcf->tstr_state, &str, &match->condition); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; + } + } + test = &match->test[0]; if (mtcf.scheme != NULL) { @@ -1596,6 +1628,12 @@ nxt_http_route_match(nxt_task_t *task, nxt_http_request_t *r, nxt_int_t ret; nxt_http_route_test_t *test, *end; + ret = nxt_http_cond_value(task, r, &match->condition); + if (ret <= 0) { + /* 0 => NULL, -1 => NXT_HTTP_ACTION_ERROR. */ + return (nxt_http_action_t *) (intptr_t) ret; + } + test = &match->test[0]; end = test + match->items; -- cgit From 932b914618791b6c9648b1066e0cfe4ee6d25cff Mon Sep 17 00:00:00 2001 From: Arjun Date: Fri, 23 Aug 2024 09:15:18 +0530 Subject: socket: Prevent buffer under-read in nxt_inet_addr() This was found via ASan. Given a listener address like ":" (or any address where the first character is a colon) we can end up under-reading the addr->start buffer here if (nxt_slow_path(*(buf + length - 1) == '.')) { due to length (essentially the position of the ":" in the string) being 0. Seeing as any address that starts with a ":" is invalid Unit config wise, we should simply reject the address if length == 0 in nxt_sockaddr_inet_parse(). Link: Signed-off-by: Arjun [ Commit message - Andrew ] Signed-off-by: Andrew Clayton --- src/nxt_sockaddr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/nxt_sockaddr.c b/src/nxt_sockaddr.c index 32941893..4d1e723b 100644 --- a/src/nxt_sockaddr.c +++ b/src/nxt_sockaddr.c @@ -732,6 +732,11 @@ nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr) length = p - addr->start; } + if (length == 0) { + nxt_thread_log_error(NXT_LOG_ERR, "invalid address \"%V\"", addr); + return NULL; + } + inaddr = INADDR_ANY; if (length != 1 || addr->start[0] != '*') { -- cgit From 011071aaa1809f63abdc4287c80843c8d6e7e179 Mon Sep 17 00:00:00 2001 From: Ava Hahn Date: Wed, 28 Aug 2024 12:50:45 -0700 Subject: wasm-wc: bump wasmtime to v24 Signed-off-by: Ava Hahn --- src/wasm-wasi-component/Cargo.lock | 563 ++++++++++++++++++++----------------- src/wasm-wasi-component/Cargo.toml | 9 +- src/wasm-wasi-component/src/lib.rs | 61 ++-- 3 files changed, 334 insertions(+), 299 deletions(-) (limited to 'src') diff --git a/src/wasm-wasi-component/Cargo.lock b/src/wasm-wasi-component/Cargo.lock index 3c6b0410..6b8c7cba 100644 --- a/src/wasm-wasi-component/Cargo.lock +++ b/src/wasm-wasi-component/Cargo.lock @@ -8,7 +8,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli", + "gimli 0.28.1", ] [[package]] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -93,19 +93,10 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.32.2", "rustc-demangle", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bindgen" version = "0.68.1" @@ -155,9 +146,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cap-fs-ext" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e341d15ac1029aadce600be764a1a1edafe40e03cde23285bc1d261b3a4866" +checksum = "eb23061fc1c4ead4e45ca713080fe768e6234e959f5a5c399c39eb41aa34e56e" dependencies = [ "cap-primitives", "cap-std", @@ -167,9 +158,9 @@ dependencies = [ [[package]] name = "cap-net-ext" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434168fe6533055f0f4204039abe3ff6d7db338ef46872a5fa39e9d5ad5ab7a9" +checksum = "f83ae11f116bcbafc5327c6af250341db96b5930046732e1905f7dc65887e0e1" dependencies = [ "cap-primitives", "cap-std", @@ -179,9 +170,9 @@ dependencies = [ [[package]] name = "cap-primitives" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe16767ed8eee6d3f1f00d6a7576b81c226ab917eb54b96e5f77a5216ef67abb" +checksum = "6d00bd8d26c4270d950eaaa837387964a2089a1c3c349a690a1fa03221d29531" dependencies = [ "ambient-authority", "fs-set-times", @@ -196,9 +187,9 @@ dependencies = [ [[package]] name = "cap-rand" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e5695565f0cd7106bc3c7170323597540e772bb73e0be2cd2c662a0f8fa4ca" +checksum = "dbcb16a619d8b8211ed61f42bd290d2a1ac71277a69cf8417ec0996fa92f5211" dependencies = [ "ambient-authority", "rand", @@ -206,9 +197,9 @@ dependencies = [ [[package]] name = "cap-std" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "593db20e4c51f62d3284bae7ee718849c3214f93a3b94ea1899ad85ba119d330" +checksum = "19eb8e3d71996828751c1ed3908a439639752ac6bdc874e41469ef7fc15fbd7f" dependencies = [ "cap-primitives", "io-extras", @@ -218,9 +209,9 @@ dependencies = [ [[package]] name = "cap-time-ext" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03261630f291f425430a36f38c847828265bc928f517cdd2004c56f4b02f002b" +checksum = "61142dc51e25b7acc970ca578ce2c3695eac22bbba46c1073f5f583e78957725" dependencies = [ "ambient-authority", "cap-primitives", @@ -265,6 +256,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -273,73 +270,86 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cranelift-bforest" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d819feeda4c420a18f1e28236ca0ce1177b22bf7c8a44ddee92dfe40de15bcf0" +checksum = "b80c3a50b9c4c7e5b5f73c0ed746687774fc9e36ef652b110da8daebf0c6e0e6" dependencies = [ "cranelift-entity", ] +[[package]] +name = "cranelift-bitset" +version = "0.111.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38778758c2ca918b05acb2199134e0c561fb577c50574259b26190b6c2d95ded" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "cranelift-codegen" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b8d03d5bdbca7e5f72b0e0a0f69933ed1f09e24be6c075aa6fe3f802b0cc0c" +checksum = "58258667ad10e468bfc13a8d620f50dfcd4bb35d668123e97defa2549b9ad397" dependencies = [ "bumpalo", "cranelift-bforest", + "cranelift-bitset", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-control", "cranelift-entity", "cranelift-isle", - "gimli", + "gimli 0.29.0", "hashbrown 0.14.3", "log", "regalloc2", + "rustc-hash", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3fd3664e38e51649b17dc30cfdd561273fe2f590dcd013fb75d9eabc6272dfb" +checksum = "043f0b702e529dcb07ff92bd7d40e7d5317b5493595172c5eb0983343751ee06" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b031ec5e605828975952622b5a77d49126f20ffe88d33719a0af66b23a0fc36" +checksum = "7763578888ab53eca5ce7da141953f828e82c2bfadcffc106d10d1866094ffbb" [[package]] name = "cranelift-control" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fada054d017cf2ed8f7ed2336e0517fc1b19e6825be1790de9eb00c94788362b" +checksum = "32db15f08c05df570f11e8ab33cb1ec449a64b37c8a3498377b77650bef33d8b" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177b6f94ae8de6348eb45bf977c79ab9e3c40fc3ac8cb7ed8109560ea39bee7d" +checksum = "5289cdb399381a27e7bbfa1b42185916007c3d49aeef70b1d01cb4caa8010130" dependencies = [ + "cranelift-bitset", "serde", "serde_derive", ] [[package]] name = "cranelift-frontend" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebebd23a69a23e3ddea78e98ff3a2de222e88c8e045d81ef4a72f042e0d79dbd" +checksum = "31ba8ab24eb9470477e98ddfa3c799a649ac5a0d9a2042868c4c952133c234e8" dependencies = [ "cranelift-codegen", "log", @@ -349,15 +359,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1571bfc14df8966d12c6121b5325026591a4b4009e22fea0fe3765ab7cd33b96" +checksum = "2b72a3c5c166a70426dcb209bdd0bb71a787c1ea76023dc0974fbabca770e8f9" [[package]] name = "cranelift-native" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a69c37e0c10b46fe5527f2397ac821046efbf5f7ec112c8b84df25712f465b" +checksum = "46a42424c956bbc31fc5c2706073df896156c5420ae8fa2a5d48dbc7b295d71b" dependencies = [ "cranelift-codegen", "libc", @@ -366,9 +376,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.104.0" +version = "0.111.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3fef8bbceb8cb56d3f1778b0418d75c5cf12ec571a35fc01eb41abb0227a25" +checksum = "49778df4289933d735b93c30a345513e030cf83101de0036e19b760f8aa09f68" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -376,7 +386,7 @@ dependencies = [ "itertools", "log", "smallvec", - "wasmparser 0.118.1", + "wasmparser", "wasmtime-types", ] @@ -415,6 +425,18 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -491,6 +513,7 @@ checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", + "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -513,12 +536,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -537,11 +582,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -560,6 +610,12 @@ name = "gimli" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" dependencies = [ "fallible-iterator", "indexmap", @@ -607,6 +663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", + "serde", ] [[package]] @@ -678,9 +735,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.1.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -692,6 +749,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "smallvec", "tokio", "want", ] @@ -770,9 +828,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itertools" -version = "0.10.5" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -826,6 +884,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.0.1" @@ -850,10 +914,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "mach" -version = "0.3.2" +name = "mach2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ "libc", ] @@ -879,15 +943,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -939,6 +994,15 @@ name = "object" version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "object" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "crc32fast", "hashbrown 0.14.3", @@ -982,6 +1046,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1145,9 +1221,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.4.2", "errno", @@ -1160,23 +1236,32 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.11" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] +[[package]] +name = "rustls-pki-types" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] @@ -1186,21 +1271,14 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "semver" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -1268,6 +1346,9 @@ name = "smallvec" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -1297,6 +1378,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.48" @@ -1310,9 +1397,9 @@ dependencies = [ [[package]] name = "system-interface" -version = "0.26.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0682e006dd35771e392a6623ac180999a9a854b1d4a6c12fb2e804941c2b1f58" +checksum = "b858526d22750088a9b3cf2e3c2aacebd5377f13adeec02860c30d09113010a6" dependencies = [ "bitflags 2.4.2", "cap-fs-ext", @@ -1326,9 +1413,18 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.13" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] [[package]] name = "thiserror" @@ -1383,11 +1479,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls", + "rustls-pki-types", "tokio", ] @@ -1509,13 +1606,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasi-cap-std-sync" -version = "17.0.0" +name = "wasi-common" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db014d2ced91f17d1f1a8f2b76d6ea8d731bc1dbc8c2bbaec689d6a242568e5d" +checksum = "7336747832c6fe1086c81ef38b63dfeaeec48fc1b7c33a88fd16115cc940d178" dependencies = [ "anyhow", - "async-trait", + "bitflags 2.4.2", "cap-fs-ext", "cap-rand", "cap-std", @@ -1523,27 +1620,10 @@ dependencies = [ "fs-set-times", "io-extras", "io-lifetimes", + "log", "once_cell", "rustix", "system-interface", - "tracing", - "wasi-common", - "windows-sys 0.52.0", -] - -[[package]] -name = "wasi-common" -version = "17.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449d17849e3c83a931374442fe2deee4d6bd1ebf469719ef44192e9e82e19c89" -dependencies = [ - "anyhow", - "bitflags 2.4.2", - "cap-rand", - "cap-std", - "io-extras", - "log", - "rustix", "thiserror", "tracing", "wasmtime", @@ -1607,9 +1687,9 @@ checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-encoder" -version = "0.38.1" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" +checksum = "4fb56df3e06b8e6b77e37d2969a50ba51281029a9aeb3855e76b7f49b6418847" dependencies = [ "leb128", ] @@ -1622,11 +1702,14 @@ dependencies = [ "bindgen", "bytes", "cc", + "futures", "futures-util", "http", "http-body", "http-body-util", + "hyper", "tokio", + "wasi-common", "wasmtime", "wasmtime-wasi", "wasmtime-wasi-http", @@ -1634,83 +1717,89 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.118.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" -dependencies = [ - "indexmap", - "semver", -] - -[[package]] -name = "wasmparser" -version = "0.121.0" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953cf6a7606ab31382cb1caa5ae403e77ba70c7f8e12eeda167e7040d42bfda8" +checksum = "53fbde0881f24199b81cf49b6ff8f9c145ac8eb1b7fc439adb5c099734f7d90e" dependencies = [ + "ahash", "bitflags 2.4.2", + "hashbrown 0.14.3", "indexmap", "semver", + "serde", ] [[package]] name = "wasmprinter" -version = "0.2.78" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e32c13c59fdc64d3f6998a1d52eb1d362b6904a88b754190ccb85661ad577a" +checksum = "d8e9a325d85053408209b3d2ce5eaddd0dd6864d1cff7a007147ba073157defc" dependencies = [ "anyhow", - "wasmparser 0.121.0", + "termcolor", + "wasmparser", ] [[package]] name = "wasmtime" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "910fabce77e660f0e0e41cfd5f69fc8bf020a025f059718846e918db7177f469" +checksum = "9a5883d64dfc8423c56e3d8df27cffc44db25336aa468e8e0724fddf30a333d7" dependencies = [ "anyhow", "async-trait", - "bincode", + "bitflags 2.4.2", "bumpalo", + "cc", "cfg-if", "encoding_rs", + "hashbrown 0.14.3", "indexmap", "libc", + "libm", "log", - "object", + "mach2", + "memfd", + "object 0.36.3", "once_cell", "paste", + "postcard", + "psm", + "rustix", + "semver", "serde", "serde_derive", - "serde_json", + "smallvec", + "sptr", "target-lexicon", - "wasmparser 0.118.1", + "wasmparser", + "wasmtime-asm-macros", "wasmtime-component-macro", "wasmtime-component-util", "wasmtime-cranelift", "wasmtime-environ", "wasmtime-fiber", - "wasmtime-jit", - "wasmtime-runtime", + "wasmtime-jit-icache-coherence", + "wasmtime-slab", + "wasmtime-versioned-export-macros", "wasmtime-winch", "windows-sys 0.52.0", ] [[package]] name = "wasmtime-asm-macros" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37288142e9b4a61655a3bcbdc7316c2e4bb9e776b10ce3dd758f8186b4469572" +checksum = "1c4dc7e2a379c0dd6be5b55857d14c4b277f43a9c429a9e14403eb61776ae3be" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-component-macro" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad63de18eb42e586386b6091f787c82707cbd5ac5e9343216dba1976190cd03a" +checksum = "4b07773d1c3dab5f014ec61316ee317aa424033e17e70a63abdf7c3a47e58fcf" dependencies = [ "anyhow", "proc-macro2", @@ -1723,15 +1812,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0a160c0c44369aa4bee6d311a8e4366943bab1651040cc8b0fcec2c9eb8906" +checksum = "e38d735320f4e83478369ce649ad8fe87c6b893220902e798547a225fc0c5874" [[package]] name = "wasmtime-cranelift" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3734cc01b7cd37bc62fdbcd9529ca9547440052d4b3886cfdec3b8081a5d3647" +checksum = "e570d831d0785d93d7d8c722b1eb9a34e0d0c1534317666f65892818358a2da9" dependencies = [ "anyhow", "cfg-if", @@ -1741,51 +1830,36 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli", + "gimli 0.29.0", "log", - "object", + "object 0.36.3", "target-lexicon", "thiserror", - "wasmparser 0.118.1", - "wasmtime-cranelift-shared", + "wasmparser", "wasmtime-environ", "wasmtime-versioned-export-macros", ] -[[package]] -name = "wasmtime-cranelift-shared" -version = "17.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0eb33cd30c47844aa228d4d0030587e65c1108343f311fe9f7248b5bd9cb65c" -dependencies = [ - "anyhow", - "cranelift-codegen", - "cranelift-control", - "cranelift-native", - "gimli", - "object", - "target-lexicon", - "wasmtime-environ", -] - [[package]] name = "wasmtime-environ" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a056b041fdea604f0972e2fae97958e7748d629a55180228348baefdfc217" +checksum = "c5fe80dfbd81687431a7d4f25929fae1ae96894786d5c96b14ae41164ee97377" dependencies = [ "anyhow", + "cranelift-bitset", "cranelift-entity", - "gimli", + "gimli 0.29.0", "indexmap", "log", - "object", + "object 0.36.3", + "postcard", + "semver", "serde", "serde_derive", "target-lexicon", - "thiserror", "wasm-encoder", - "wasmparser 0.118.1", + "wasmparser", "wasmprinter", "wasmtime-component-util", "wasmtime-types", @@ -1793,9 +1867,9 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43987d0977c07f15c3608c2f255870c127ffd19e35eeedb1ac1dccedf9932a42" +checksum = "0f39043d13c7b58db69dc9a0feb191a961e75a9ec2402aebf42de183c022bb8a" dependencies = [ "anyhow", "cc", @@ -1806,86 +1880,43 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "wasmtime-jit" -version = "17.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3e48395ac672b386ed588d97a9612aa13a345008f26466f0dfb2a91628aa9f" -dependencies = [ - "anyhow", - "bincode", - "cfg-if", - "gimli", - "log", - "object", - "rustix", - "serde", - "serde_derive", - "target-lexicon", - "wasmtime-environ", - "wasmtime-jit-icache-coherence", - "wasmtime-runtime", - "windows-sys 0.52.0", -] - [[package]] name = "wasmtime-jit-icache-coherence" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdc26415bb89e9ccd3bdc498fef63aabf665c4c0dd710c107691deb9694955da" +checksum = "d15de8429db996f0d17a4163a35eccc3f874cbfb50f29c379951ea1bbb39452e" dependencies = [ + "anyhow", "cfg-if", "libc", "windows-sys 0.52.0", ] [[package]] -name = "wasmtime-runtime" -version = "17.0.0" +name = "wasmtime-slab" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abddaf17912aabaf39be0802d5eba9a002e956e902d1ebd438a2fe1c88769a2" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "encoding_rs", - "indexmap", - "libc", - "log", - "mach", - "memfd", - "memoffset", - "paste", - "psm", - "rustix", - "sptr", - "wasm-encoder", - "wasmtime-asm-macros", - "wasmtime-environ", - "wasmtime-fiber", - "wasmtime-versioned-export-macros", - "wasmtime-wmemcheck", - "windows-sys 0.52.0", -] +checksum = "1f68d38fa6b30c5e1fc7d608263062997306f79e577ebd197ddcd6b0f55d87d1" [[package]] name = "wasmtime-types" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35a95cdc1433729085beab42c0a5c742b431f25b17c40d7718e46df63d5ffc7" +checksum = "6634e7079d9c5cfc81af8610ed59b488cc5b7f9777a2f4c1667a2565c2e45249" dependencies = [ + "anyhow", "cranelift-entity", "serde", "serde_derive", - "thiserror", - "wasmparser 0.118.1", + "smallvec", + "wasmparser", ] [[package]] name = "wasmtime-versioned-export-macros" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad322733fe67e45743784d8b1df452bcb54f581572a4f1a646a4332deecbcc2" +checksum = "3850e3511d6c7f11a72d571890b0ed5f6204681f7f050b9de2690e7f13123fed" dependencies = [ "proc-macro2", "quote", @@ -1894,9 +1925,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902cc299b73655c36679b77efdfce4bb5971992f1a4a8a436dd3809a6848ff0e" +checksum = "545ae8298ffce025604f7480f9c7d6948c985bef7ce9aee249ef79307813e83c" dependencies = [ "anyhow", "async-trait", @@ -1911,8 +1942,6 @@ dependencies = [ "futures", "io-extras", "io-lifetimes", - "libc", - "log", "once_cell", "rustix", "system-interface", @@ -1920,8 +1949,6 @@ dependencies = [ "tokio", "tracing", "url", - "wasi-cap-std-sync", - "wasi-common", "wasmtime", "wiggle", "windows-sys 0.52.0", @@ -1929,9 +1956,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi-http" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "151fc711fad35034b8a6df00a5bcd5a7b1acb89ca12c2407f564a36ebd382e26" +checksum = "f5b50208c61fed1ac138b6bf84b8b44c921ba16ac79b1a511804ecd95c98fd73" dependencies = [ "anyhow", "async-trait", @@ -1952,26 +1979,26 @@ dependencies = [ [[package]] name = "wasmtime-winch" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e63aeca929f84560eec52c5af43bf5d623b92683b0195d9fb06da8ed860e092" +checksum = "2a25199625effa4c13dd790d64bd56884b014c69829431bfe43991c740bd5bc1" dependencies = [ "anyhow", "cranelift-codegen", - "gimli", - "object", + "gimli 0.29.0", + "object 0.36.3", "target-lexicon", - "wasmparser 0.118.1", - "wasmtime-cranelift-shared", + "wasmparser", + "wasmtime-cranelift", "wasmtime-environ", "winch-codegen", ] [[package]] name = "wasmtime-wit-bindgen" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e5675998fdc74495afdd90ad2bd221206a258075b23048af0535a969b07893" +checksum = "3cb331ac7ed1d5ba49cddcdb6b11973752a857148858bb308777d2fc5584121f" dependencies = [ "anyhow", "heck", @@ -1979,12 +2006,6 @@ dependencies = [ "wit-parser", ] -[[package]] -name = "wasmtime-wmemcheck" -version = "17.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b20a19e10d8cb50b45412fb21192982b7ce85c0122dc33bb71f1813e25dc6e52" - [[package]] name = "wast" version = "35.0.2" @@ -1996,9 +2017,12 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "which" @@ -2014,9 +2038,9 @@ dependencies = [ [[package]] name = "wiggle" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "737728db69a7657a5f6a7bac445c02d8564d603d62c46c95edf928554e67d072" +checksum = "cc850ca3c02c5835934d23f28cec4c5a3fb66fe0b4ecd968bbb35609dda5ddc0" dependencies = [ "anyhow", "async-trait", @@ -2029,9 +2053,9 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2460c7163b79ffefd9a564eaeab0a5b0e84bb91afdfeeb84d36f304ddbe08982" +checksum = "634b8804a67200bcb43ea8af5f7c53e862439a086b68b16fd333454bc74d5aab" dependencies = [ "anyhow", "heck", @@ -2044,9 +2068,9 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "17.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8d8412375ba8325d61fbae56dead51dabfaec85d620ce36427922fb9cece83" +checksum = "474b7cbdb942c74031e619d66c600bba7f73867c5800fc2c2306cf307649be2f" dependencies = [ "proc-macro2", "quote", @@ -2070,6 +2094,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2078,17 +2111,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "0.15.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2b346bad5397b219b4ff0a8fa7230936061ff07c61f05d589d8d81e06fb7b2" +checksum = "073efe897d9ead7fc609874f94580afc831114af5149b6a90ee0a3a39b497fe0" dependencies = [ "anyhow", "cranelift-codegen", - "gimli", + "gimli 0.29.0", "regalloc2", "smallvec", "target-lexicon", - "wasmparser 0.118.1", + "wasmparser", + "wasmtime-cranelift", "wasmtime-environ", ] @@ -2245,9 +2279,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.13.1" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df4913a2219096373fd6512adead1fb77ecdaa59d7fc517972a7d30b12f625be" +checksum = "935a97eaffd57c3b413aa510f8f0b550a4a9fe7d59e79cd8b89a83dcb860321f" dependencies = [ "anyhow", "id-arena", @@ -2258,6 +2292,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", + "wasmparser", ] [[package]] @@ -2291,3 +2326,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/src/wasm-wasi-component/Cargo.toml b/src/wasm-wasi-component/Cargo.toml index feb7f53c..bc325826 100644 --- a/src/wasm-wasi-component/Cargo.toml +++ b/src/wasm-wasi-component/Cargo.toml @@ -10,14 +10,17 @@ crate-type = ["cdylib"] [dependencies] anyhow = "1.0.75" bytes = "1.5.0" +futures = "0.3.30" futures-util = { version = "0.3.29", default-features = false } http = "1.0.0" http-body = { version = "1.0.0", default-features = false } http-body-util = "0.1.0" +hyper = "1.4.1" tokio = { version = "1.33.0", default-features = false } -wasmtime = { version = "17.0.0", default-features = false, features = ['component-model', 'cranelift'] } -wasmtime-wasi = "17.0.0" -wasmtime-wasi-http = "17.0.0" +wasi-common = "24.0.0" +wasmtime = { version = "24.0.0", default-features = false, features = ['component-model', 'cranelift'] } +wasmtime-wasi = "24.0.0" +wasmtime-wasi-http = "24.0.0" [build-dependencies] bindgen = "0.68.1" diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index b0552e81..facbe2a0 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -2,19 +2,18 @@ use anyhow::{bail, Context, Result}; use bytes::{Bytes, BytesMut}; use http_body_util::combinators::BoxBody; use http_body_util::{BodyExt, Full}; +use hyper::Error; use std::ffi::{CStr, CString}; use std::mem::MaybeUninit; use std::process::exit; use std::ptr; use std::sync::OnceLock; use tokio::sync::mpsc; -use wasmtime::component::{Component, InstancePre, Linker, ResourceTable}; +use wasmtime::component::{Component, Linker, ResourceTable}; use wasmtime::{Config, Engine, Store}; -use wasmtime_wasi::preview2::{ - DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView, -}; -use wasmtime_wasi::{ambient_authority, Dir}; -use wasmtime_wasi_http::bindings::http::types::ErrorCode; +use wasmtime_wasi::{DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView}; +use wasmtime_wasi_http::bindings::http::types::{ErrorCode, Scheme}; +use wasmtime_wasi_http::bindings::ProxyPre; use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; #[allow( @@ -180,7 +179,7 @@ struct GlobalConfig { struct GlobalState { engine: Engine, - component: InstancePre, + component: ProxyPre, global_config: &'static GlobalConfig, sender: mpsc::Sender, } @@ -209,11 +208,15 @@ impl GlobalState { let component = Component::from_file(&engine, &global_config.component) .context("failed to compile component")?; let mut linker = Linker::::new(&engine); - wasmtime_wasi::preview2::command::add_to_linker(&mut linker)?; - wasmtime_wasi_http::proxy::add_only_http_to_linker(&mut linker)?; + wasmtime_wasi::add_to_linker_async(&mut linker) + .context("failed to add wasi to linker")?; + wasmtime_wasi_http::add_only_http_to_linker_sync(&mut linker) + .context("failed to add wasi:http to linker")?; let component = linker .instantiate_pre(&component) .context("failed to pre-instantiate the provided component")?; + let proxy = + ProxyPre::new(component).context("failed to conform to proxy")?; // Spin up the Tokio async runtime in a separate thread with a // communication channel into it. This thread will send requests to @@ -223,7 +226,7 @@ impl GlobalState { Ok(GlobalState { engine, - component, + component: proxy, sender, global_config, }) @@ -257,21 +260,17 @@ impl GlobalState { cx.inherit_stdout(); cx.inherit_stderr(); for dir in self.global_config.dirs.iter() { - let fd = Dir::open_ambient_dir(dir, ambient_authority()) - .with_context(|| { - format!("failed to open directory '{dir}'") - })?; cx.preopened_dir( - fd, + dir, + dir, DirPerms::all(), FilePerms::all(), - dir, - ); + )?; } cx.build() }, table: ResourceTable::default(), - http: WasiHttpCtx, + http: WasiHttpCtx::new(), }; let mut store = Store::new(&self.engine, data); @@ -292,15 +291,13 @@ impl GlobalState { // generate headers, write those below, and then compute the body // afterwards. let task = tokio::spawn(async move { - let (proxy, _) = wasmtime_wasi_http::proxy::Proxy::instantiate_pre( - &mut store, - &self.component, - ) - .await - .context("failed to instantiate")?; - let req = store.data_mut().new_incoming_request(request)?; + let req = store + .data_mut() + .new_incoming_request(Scheme::Http, request)?; let out = store.data_mut().new_response_outparam(sender)?; - proxy + self.component + .instantiate_async(&mut store) + .await? .wasi_http_incoming_handler() .call_handle(&mut store, req, out) .await @@ -376,7 +373,7 @@ impl GlobalState { fn to_request_body( &self, info: &mut NxtRequestInfo, - ) -> BoxBody { + ) -> BoxBody { // TODO: should convert the body into a form of `Stream` to become an // async stream of frames. The return value can represent that here // but for now this slurps up the entire body into memory and puts it @@ -594,16 +591,10 @@ struct StoreState { } impl WasiView for StoreState { - fn table(&self) -> &ResourceTable { - &self.table - } - fn table_mut(&mut self) -> &mut ResourceTable { + fn table(&mut self) -> &mut ResourceTable { &mut self.table } - fn ctx(&self) -> &WasiCtx { - &self.ctx - } - fn ctx_mut(&mut self) -> &mut WasiCtx { + fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx } } -- cgit From 56c237b347fd0ff3fa182663cbc965e05b158e39 Mon Sep 17 00:00:00 2001 From: Robbie McKinstry Date: Wed, 28 Aug 2024 03:00:43 +0100 Subject: wasm-wc: Enable environment inheritance While the C based wasm language module inherits the process environment the Rust based wasm-wasi-component language module did not. One upshot of this is that with wasm-wasi-component you don't get access to any environment variables specified in the Unit configuration. wasm-wasi-component was based on wasmtime 17.0.0. This capability wasn't added to the wasmtime-crate until version 20.0.0. Now that wasm-wasi-component has been updated to a newer wasmtime-crate we can enable this functionality. Closes: https://github.com/nginx/unit/issues/1312 [ Commit message - Andrew ] Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/src/lib.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index facbe2a0..93c26214 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -259,6 +259,7 @@ impl GlobalState { // shouldn't get raw access to stdout/stderr. cx.inherit_stdout(); cx.inherit_stderr(); + cx.inherit_env(); for dir in self.global_config.dirs.iter() { cx.preopened_dir( dir, -- cgit From 5fde2ff79c92e2bb2ff67e4537640af7d06e73b6 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 9 Sep 2024 23:15:29 +0800 Subject: http: Fix router process crash whilst using proxy When the client closes the connection before the upstream, the proxy's error handler was calling cleanup operation like peer close and request close twice, this fix ensures the cleanup is performed only once, improving proxy stability. Closes: https://github.com/nginx/unit/issues/828 --- src/nxt_h1proto.c | 5 +++++ src/nxt_http_proxy.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 5d1ed790..48c2697b 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -2869,6 +2869,11 @@ nxt_h1p_peer_body_process(nxt_task_t *task, nxt_http_peer_t *peer, } else if (h1p->remainder > 0) { length = nxt_buf_chain_length(out); h1p->remainder -= length; + + if (h1p->remainder == 0) { + nxt_buf_chain_add(&out, nxt_http_buf_last(peer->request)); + peer->closed = 1; + } } peer->body = out; diff --git a/src/nxt_http_proxy.c b/src/nxt_http_proxy.c index 6aa3aabb..7f6ad686 100644 --- a/src/nxt_http_proxy.c +++ b/src/nxt_http_proxy.c @@ -381,9 +381,10 @@ nxt_http_proxy_error(nxt_task_t *task, void *obj, void *data) r = obj; peer = r->peer; - nxt_http_proto[peer->protocol].peer_close(task, peer); - - nxt_mp_release(r->mem_pool); + if (!peer->closed) { + nxt_http_proto[peer->protocol].peer_close(task, peer); + nxt_mp_release(r->mem_pool); + } nxt_http_request_error(&r->task, r, peer->status); } -- cgit From 50b1aca3b8318c58f7073fe11911f1f0d52c651d Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 12 Sep 2024 16:48:10 +0100 Subject: python: Don't decrement a reference to a borrowed object On some Python 3.11 systems, 3.11.9 & 3.11.10, we were seeing a crash triggered by Py_Finalize() in nxt_python_atexit() when running one of our pytests, namely test/test_python_factory.py::test_python_factory_invalid_callable_value 2024/09/12 15:07:29 [alert] 5452#5452 factory "wsgi_invalid_callable" in module "wsgi" can not be called to fetch callable Fatal Python error: none_dealloc: deallocating None: bug likely caused by a refcount error in a C extension Python runtime state: finalizing (tstate=0x00007f560b88a718) Current thread 0x00007f560bde7ad0 (most recent call first): 2024/09/12 15:07:29 [alert] 5451#5451 app process 5452 exited on signal 6 (core dumped) This was due to obj = PyDict_GetItemString(PyModule_GetDict(module), callable); in nxt_python_set_target() which returns a *borrowed* reference, then due to the test meaning this is a `None` object we `goto fail` and call Py_DECREF(obj); which then causes `Py_Finalize()` to blow up. The simple fix is to just increment its reference count before the `goto fail`. Note: This problem only showed up under (the various versions of Python we test on); 3.11.9 & 3.11.10. It doesn't show up under; 3.6, 3.7, 3.9, 3.10, 3.12 Cc: Konstantin Pavlov Closes: https://github.com/nginx/unit/issues/1413 Fixes: a9aa9e76d ("python: Support application factories") Signed-off-by: Andrew Clayton --- src/python/nxt_python.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c index 7bbf3d49..143d8d5d 100644 --- a/src/python/nxt_python.c +++ b/src/python/nxt_python.c @@ -462,6 +462,7 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target, "factory \"%s\" in module \"%s\" " "can not be called to fetch callable", callable, module_name); + Py_INCREF(obj); /* borrowed reference */ goto fail; } -- cgit