diff options
Diffstat (limited to 'src')
61 files changed, 1488 insertions, 1414 deletions
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_atomic.h b/src/nxt_atomic.h index dae999a9..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 <atomic.h> - -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) */ /* @@ -161,109 +86,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_ */ 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. * 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_conf.c b/src/nxt_conf.c index 008cb968..bb229c33 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -123,23 +123,24 @@ 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 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 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(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; @@ -186,7 +188,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 +247,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 +278,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 +292,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 +306,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 +321,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 +334,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 +355,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 +402,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 +413,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 +461,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 +552,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 +586,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 +738,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 +766,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 +804,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 +820,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 +959,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 +980,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 +1023,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 +1123,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; @@ -1441,7 +1444,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)) { @@ -2232,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) { @@ -2264,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) { @@ -2298,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; @@ -2309,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; @@ -2326,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; @@ -2368,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; @@ -2420,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; @@ -2464,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 626b6d4d..493d6480 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); @@ -107,49 +108,54 @@ 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, 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 2099f887..5d7f7c52 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, @@ -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, @@ -176,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, @@ -305,6 +309,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, @@ -368,6 +376,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 @@ -421,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) @@ -681,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 @@ -839,6 +858,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { .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, .validator = nxt_conf_vldt_targets_exclusive, @@ -863,6 +887,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, .validator = nxt_conf_vldt_python_prefix, @@ -881,6 +908,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, .validator = nxt_conf_vldt_python_prefix, @@ -1436,7 +1466,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; @@ -1445,7 +1475,7 @@ nxt_conf_vldt_type(nxt_conf_validation_t *vldt, 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"), @@ -1548,7 +1578,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]; @@ -1568,7 +1598,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 +1761,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 +1808,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 +1962,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 +2012,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); @@ -2064,6 +2094,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, @@ -2572,9 +2623,10 @@ 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"); + 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 " @@ -2588,7 +2640,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; } @@ -2604,7 +2666,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); @@ -2636,8 +2698,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); @@ -2653,6 +2715,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) { @@ -2662,9 +2750,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; @@ -3177,7 +3265,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); @@ -3258,7 +3346,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); @@ -3403,7 +3491,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..1ffcf815 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_p_dirname((const u_char *) path, 0755); } #endif @@ -1908,12 +1908,12 @@ 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 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); @@ -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; + } } } } @@ -2178,7 +2195,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 +2503,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, @@ -2652,11 +2669,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_fs.c b/src/nxt_fs.c index e10c5bcb..8ea8e186 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -1,5 +1,6 @@ /* * Copyright (C) NGINX, Inc. + * Copyright 2024, Alejandro Colomar <alx@kernel.org> */ #include <nxt_main.h> @@ -9,25 +10,22 @@ 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; - char path[PATH_MAX]; + char *start, *end, *dst; + size_t dirlen; + nxt_int_t ret; + char path[PATH_MAX]; dirlen = nxt_strlen(dir); - nxt_assert(dirlen < PATH_MAX && dirlen > 1 && dir[0] == '/'); + nxt_assert(dirlen < PATH_MAX && dirlen > 0); dst = path; start = (char *) dir; while (*start != '\0') { - if (*start == '/') { - *dst++ = *start++; - } - - end = strchr(start, '/'); + end = strchr(start + 1, '/'); if (end == NULL) { end = ((char *)dir + dirlen); } @@ -35,9 +33,8 @@ nxt_fs_mkdir_all(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; } @@ -49,7 +46,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_p_dirname(const u_char *path, mode_t mode) { char *ptr, *dir; nxt_int_t ret; @@ -62,11 +59,14 @@ nxt_fs_mkdir_parent(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 (ptr == dir || nxt_slow_path(ptr == NULL)) { + goto out_free; } + *ptr = '\0'; + ret = nxt_fs_mkdir_p((const u_char *) dir, mode); + +out_free: nxt_free(dir); return ret; diff --git a/src/nxt_fs.h b/src/nxt_fs.h index c8868d80..a06e4d3d 100644 --- a/src/nxt_fs.h +++ b/src/nxt_fs.h @@ -6,8 +6,8 @@ #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_all(const u_char *dir, 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); #endif /* _NXT_FS_H_INCLUDED_ */ diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 1dfe4b6e..48c2697b 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); @@ -835,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; @@ -852,15 +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_str_t *tmp_path, tmp_name; - 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); @@ -868,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; @@ -880,40 +901,31 @@ 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) { - tmp_path = &r->conf->socket_conf->body_temp_path; + nxt_str_t *tmp_path, tmp_name; + + tmp_path = &skcf->body_temp_path; tmp_name.length = tmp_path->length + tmp_name_pattern.length; 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); @@ -942,33 +954,80 @@ 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; + } } - body_rest = body_length; + r->body = b; + + 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); @@ -1026,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; @@ -1038,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; + } + } + + if (h1p->chunked_parse.last) { + body_rest = 0; } - b->mem.pos = b->mem.free; + } 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 { @@ -2263,6 +2362,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 +2373,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,15 +2394,14 @@ 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; 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); @@ -2328,8 +2433,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 +2457,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; } @@ -2710,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.h b/src/nxt_http.h index e812bd0d..5369c8e1 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; @@ -192,6 +193,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; @@ -202,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 */ }; @@ -303,11 +307,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", @@ -436,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_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_js.c b/src/nxt_http_js.c index e3beb8b4..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); } @@ -162,6 +164,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 +178,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; @@ -214,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; @@ -250,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; } @@ -296,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); } } @@ -340,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; } @@ -380,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); diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 50cbda2b..dd490e72 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'); @@ -1189,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; diff --git a/src/nxt_http_parse.h b/src/nxt_http_parse.h index fa95e842..9e2f6fab 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 @@ -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 */ 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); } diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index f8d8d887..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); @@ -540,15 +538,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); } @@ -818,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; @@ -835,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; } } @@ -868,57 +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_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; - } - - nxt_tstr_query(task, r->tstr_query, rtcf->log_expr, &str); - - if (nxt_slow_path(nxt_tstr_query_failed(r->tstr_query))) { - 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) { - 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) @@ -946,6 +938,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 +1022,8 @@ nxt_http_arguments_parse(nxt_http_request_t *r) } } +end: + r->arguments = args; return args; @@ -1316,3 +1314,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_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) = { diff --git a/src/nxt_http_rewrite.c b/src/nxt_http_rewrite.c index fb216eeb..5de15ed7 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; @@ -53,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; } } @@ -72,30 +70,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; @@ -103,8 +77,11 @@ 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); + nxt_log(task, NXT_LOG_NOTICE, "URI rewritten to \"%V\"", r->path); } return NXT_OK; diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 4a64d5c1..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; @@ -103,13 +104,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 +118,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 +126,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[]; }; @@ -138,21 +139,22 @@ typedef union { typedef struct { uint32_t items; + nxt_tstr_cond_t condition; 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[]; }; @@ -193,8 +195,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, @@ -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,17 +415,30 @@ 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 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"); match_conf = nxt_conf_get_path(cv, &match_path); 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) { @@ -1344,10 +1376,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 +1393,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 +1418,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) @@ -1607,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; @@ -2134,6 +2161,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; 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_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; @@ -663,17 +668,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) { 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; diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index ed5e0d76..909a43f4 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; @@ -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, 0777); if (nxt_slow_path(ret != NXT_OK)) { nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno); goto undo; @@ -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 6885afb7..d46231bd 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,13 +119,14 @@ 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; - 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); @@ -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; } @@ -239,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_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); 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_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 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 <nxt_hash.h> #include <nxt_sort.h> -#include <nxt_vector.h> #include <nxt_list.h> #include <nxt_service.h> diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 060ead41..00318226 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); @@ -1357,6 +1355,12 @@ static nxt_conf_map_t nxt_app_lang_module_map[] = { }, { + nxt_string("name"), + NXT_CONF_MAP_CSTRZ, + offsetof(nxt_app_lang_module_t, name), + }, + + { nxt_string("version"), NXT_CONF_MAP_CSTRZ, offsetof(nxt_app_lang_module_t, version), 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); diff --git a/src/nxt_port_memory.c b/src/nxt_port_memory.c index 0a4a6c53..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); @@ -454,6 +452,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 +502,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); 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; } diff --git a/src/nxt_router.c b/src/nxt_router.c index 1a1aca2b..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); @@ -1077,14 +1078,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 +1094,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 +1110,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 +1132,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; @@ -1410,7 +1413,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), }, @@ -1492,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), + }, }; @@ -1573,6 +1582,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), + }, }; @@ -1622,7 +1637,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; @@ -1632,25 +1647,30 @@ 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 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"); + 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) { @@ -1661,11 +1681,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) { @@ -1952,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); @@ -1969,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; @@ -1988,6 +2013,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; @@ -2281,7 +2307,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; @@ -2358,11 +2384,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); @@ -2671,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; @@ -2715,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; } @@ -2862,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; } diff --git a/src/nxt_router.h b/src/nxt_router.h index 3e523001..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; @@ -208,6 +207,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; diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c index 7fc59972..afecd0b1 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, @@ -75,7 +73,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\""); @@ -145,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; } } @@ -180,8 +171,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 +180,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) { diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index 0e7f879e..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; @@ -1490,7 +1488,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_p_dirname(pid_file, 0755); n = nxt_file_open(task, &file, O_WRONLY, O_CREAT | O_TRUNC, NXT_FILE_DEFAULT_ACCESS); 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; 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] != '*') { diff --git a/src/nxt_status.c b/src/nxt_status.c index f8002e86..92cbf2e6 100644 --- a/src/nxt_status.c +++ b/src/nxt_status.c @@ -6,40 +6,131 @@ #include <nxt_main.h> #include <nxt_conf.h> #include <nxt_status.h> +#include <nxt_application.h> nxt_conf_value_t * nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) { - size_t i; - nxt_str_t name; - nxt_int_t ret; - 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"); - - status = nxt_conf_create_object(mp, 3); + 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"); + 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, 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); + if (nxt_slow_path(obj == NULL)) { + return NULL; + } + + 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; } - 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 +144,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 +153,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]; diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index edf6860a..50df4c47 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; }; @@ -81,7 +75,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; @@ -159,7 +153,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 @@ -202,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) { @@ -246,7 +260,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 +268,7 @@ 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; - } - - if (nxt_slow_path(query->failed)) { - return; + return NXT_OK; } if (tstr->type == NXT_TSTR_VAR) { @@ -267,8 +277,7 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, tstr->flags & NXT_TSTR_LOGGING); if (nxt_slow_path(ret != NXT_OK)) { - query->failed = 1; - return; + return NXT_ERROR; } } else { @@ -277,8 +286,7 @@ 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; + return NXT_ERROR; } #endif } @@ -294,43 +302,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 -} - - -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); - } + return NXT_OK; } diff --git a/src/nxt_tstr.h b/src/nxt_tstr.h index 3e842f81..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, 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); 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); @@ -50,13 +58,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_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); +nxt_int_t nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, + nxt_tstr_t *tstr, nxt_str_t *val); void nxt_tstr_query_release(nxt_tstr_query_t *query); 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) /* diff --git a/src/nxt_unit.c b/src/nxt_unit.c index b6291b2d..966a6c0f 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)) { @@ -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"); @@ -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); @@ -3851,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); @@ -3864,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); 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.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 31e2f48a..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[]; }; @@ -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; diff --git a/src/nxt_var.c b/src/nxt_var.c index 57110f66..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; }; @@ -566,7 +560,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; 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_main.h> - - -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_ */ 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}" diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c index 7c059649..143d8d5d 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 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; @@ -449,7 +451,31 @@ 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); + Py_INCREF(obj); /* borrowed reference */ + 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; 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; 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; 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" diff --git a/src/wasm-wasi-component/Cargo.lock b/src/wasm-wasi-component/Cargo.lock index bc09e96a..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,20 +93,11 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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", @@ -266,6 +257,12 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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", ] @@ -416,6 +426,18 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -491,6 +513,7 @@ checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", + "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -514,12 +537,34 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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", @@ -574,9 +630,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", @@ -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", ] @@ -827,6 +885,12 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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", ] @@ -880,15 +944,6 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -905,9 +960,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", @@ -940,6 +995,15 @@ 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", "indexmap", @@ -983,6 +1047,18 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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.10" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +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", ] @@ -1187,20 +1272,13 @@ 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" @@ -1298,6 +1379,12 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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", @@ -1807,85 +1881,42 @@ dependencies = [ ] [[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", @@ -1980,12 +2007,6 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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", @@ -2071,6 +2095,15 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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..93c26214 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<StoreState>, + component: ProxyPre<StoreState>, global_config: &'static GlobalConfig, sender: mpsc::Sender<NxtRequestInfo>, } @@ -209,11 +208,15 @@ impl GlobalState { let component = Component::from_file(&engine, &global_config.component) .context("failed to compile component")?; let mut linker = Linker::<StoreState>::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, }) @@ -256,22 +259,19 @@ 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() { - 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 +292,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 +374,7 @@ impl GlobalState { fn to_request_body( &self, info: &mut NxtRequestInfo, - ) -> BoxBody<Bytes, ErrorCode> { + ) -> BoxBody<Bytes, Error> { // 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 +592,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 } } 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; |