From ef1ebf96f300d9a2f487656ac827a9c166f57197 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Tue, 23 Nov 2021 15:36:24 +0300 Subject: Fixed possible access to an uninitialized field. The "recv_msg.incoming_buf" is checked after jumping to the "done" label if nxt_socket_msg_oob_get_fds() returns an error. Also moved initialization of "port_msg" near to its first usage. Found by Coverity (CID 373899). --- src/nxt_unit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 06ad1636..135c06ed 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -937,9 +937,9 @@ nxt_unit_process_msg(nxt_unit_ctx_t *ctx, nxt_unit_read_buf_t *rbuf, lib = nxt_container_of(ctx->unit, nxt_unit_impl_t, unit); + recv_msg.incoming_buf = NULL; recv_msg.fd[0] = -1; recv_msg.fd[1] = -1; - port_msg = (nxt_port_msg_t *) rbuf->buf; rc = nxt_socket_msg_oob_get_fds(&rbuf->oob, recv_msg.fd); if (nxt_slow_path(rc != NXT_OK)) { @@ -948,8 +948,6 @@ nxt_unit_process_msg(nxt_unit_ctx_t *ctx, nxt_unit_read_buf_t *rbuf, goto done; } - recv_msg.incoming_buf = NULL; - if (nxt_slow_path(rbuf->size < (ssize_t) sizeof(nxt_port_msg_t))) { if (nxt_slow_path(rbuf->size == 0)) { nxt_unit_debug(ctx, "read port closed"); @@ -965,6 +963,8 @@ nxt_unit_process_msg(nxt_unit_ctx_t *ctx, nxt_unit_read_buf_t *rbuf, goto done; } + port_msg = (nxt_port_msg_t *) rbuf->buf; + nxt_unit_debug(ctx, "#%"PRIu32": process message %d fd[0] %d fd[1] %d", port_msg->stream, (int) port_msg->type, recv_msg.fd[0], recv_msg.fd[1]); -- cgit From 2c636a03f35c1807fa0744b53d19f364b131dc1d Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 24 Nov 2021 13:11:47 +0300 Subject: Sending shared port to application prototype. Application process started with shared port (and queue) already configured. But still waits for PORT_ACK message from router to start request processing (so-called "ready state"). Waiting for router confirmation is necessary. Otherwise, the application may produce response and send it to router before the router have the information about the application process. This is a subject of further optimizations. --- src/nxt_application.c | 3 ++ src/nxt_application.h | 3 ++ src/nxt_external.c | 12 ++++++++ src/nxt_main_process.c | 30 ++++++++++++++++--- src/nxt_port.c | 5 ++-- src/nxt_router.c | 61 ++++++++++++-------------------------- src/nxt_unit.c | 79 +++++++++++++++++++++++++++----------------------- src/nxt_unit.h | 2 ++ 8 files changed, 110 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/nxt_application.c b/src/nxt_application.c index 589821fb..d1ff9ee7 100644 --- a/src/nxt_application.c +++ b/src/nxt_application.c @@ -1052,6 +1052,9 @@ nxt_unit_default_init(nxt_task_t *task, nxt_unit_init_t *init, init->read_port.in_fd = my_port->pair[0]; init->read_port.out_fd = my_port->pair[1]; + init->shared_port_fd = conf->shared_port_fd; + init->shared_queue_fd = conf->shared_queue_fd; + init->log_fd = 2; init->shm_limit = conf->shm_limit; diff --git a/src/nxt_application.h b/src/nxt_application.h index 4612f072..30a1a12f 100644 --- a/src/nxt_application.h +++ b/src/nxt_application.h @@ -103,6 +103,9 @@ struct nxt_common_app_conf_s { size_t shm_limit; uint32_t request_limit; + nxt_fd_t shared_port_fd; + nxt_fd_t shared_queue_fd; + union { nxt_external_app_conf_t external; nxt_python_app_conf_t python; diff --git a/src/nxt_external.c b/src/nxt_external.c index b41ca51b..c724b9bd 100644 --- a/src/nxt_external.c +++ b/src/nxt_external.c @@ -106,6 +106,16 @@ nxt_external_start(nxt_task_t *task, nxt_process_data_t *data) return NXT_ERROR; } + rc = nxt_external_fd_no_cloexec(task, conf->shared_port_fd); + if (nxt_slow_path(rc != NXT_OK)) { + return NXT_ERROR; + } + + rc = nxt_external_fd_no_cloexec(task, conf->shared_queue_fd); + if (nxt_slow_path(rc != NXT_OK)) { + return NXT_ERROR; + } + end = buf + sizeof(buf); p = nxt_sprintf(buf, end, @@ -113,12 +123,14 @@ nxt_external_start(nxt_task_t *task, nxt_process_data_t *data) "%PI,%ud,%d;" "%PI,%ud,%d;" "%PI,%ud,%d,%d;" + "%d,%d;" "%d,%z,%uD,%Z", NXT_VERSION, my_port->process->stream, proto_port->pid, proto_port->id, proto_port->pair[1], router_port->pid, router_port->id, router_port->pair[1], my_port->pid, my_port->id, my_port->pair[0], my_port->pair[1], + conf->shared_port_fd, conf->shared_queue_fd, 2, conf->shm_limit, conf->request_limit); if (nxt_slow_path(p == end)) { diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index a5a20d3d..3914c041 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -382,25 +382,25 @@ nxt_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) port = rt->port_by_type[NXT_PROCESS_ROUTER]; if (nxt_slow_path(port == NULL)) { nxt_alert(task, "router port not found"); - return; + goto close_fds; } if (nxt_slow_path(port->pid != nxt_recv_msg_cmsg_pid(msg))) { nxt_alert(task, "process %PI cannot start processes", nxt_recv_msg_cmsg_pid(msg)); - return; + goto close_fds; } process = nxt_process_new(rt); if (nxt_slow_path(process == NULL)) { - return; + goto close_fds; } process->mem_pool = nxt_mp_create(1024, 128, 256, 32); if (process->mem_pool == NULL) { nxt_process_use(task, process, -1); - return; + goto close_fds; } process->parent_port = rt->port_by_type[NXT_PROCESS_MAIN]; @@ -422,6 +422,9 @@ nxt_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) goto failed; } + app_conf->shared_port_fd = msg->fd[0]; + app_conf->shared_queue_fd = msg->fd[1]; + start = b->mem.pos; app_conf->name.start = start; @@ -509,6 +512,17 @@ nxt_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) ret = nxt_process_start(task, process); if (nxt_fast_path(ret == NXT_OK || ret == NXT_AGAIN)) { + + /* Close shared port fds only in main process. */ + if (ret == NXT_OK) { + nxt_fd_close(app_conf->shared_port_fd); + nxt_fd_close(app_conf->shared_queue_fd); + } + + /* Avoid fds close in caller. */ + msg->fd[0] = -1; + msg->fd[1] = -1; + return; } @@ -523,6 +537,14 @@ failed: nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR, -1, msg->port_msg.stream, 0, NULL); } + +close_fds: + + nxt_fd_close(msg->fd[0]); + msg->fd[0] = -1; + + nxt_fd_close(msg->fd[1]); + msg->fd[1] = -1; } diff --git a/src/nxt_port.c b/src/nxt_port.c index 1e8fa28a..88d645af 100644 --- a/src/nxt_port.c +++ b/src/nxt_port.c @@ -176,8 +176,9 @@ nxt_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) if (nxt_fast_path(msg->port_msg.type < NXT_PORT_MSG_MAX)) { - nxt_debug(task, "port %d: message type:%uD", - msg->port->socket.fd, msg->port_msg.type); + nxt_debug(task, "port %d: message type:%uD fds:%d,%d", + msg->port->socket.fd, msg->port_msg.type, + msg->fd[0], msg->fd[1]); handlers = msg->port->data; handlers[msg->port_msg.type](task, msg); diff --git a/src/nxt_router.c b/src/nxt_router.c index 7623ccbb..f718bb6e 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -221,8 +221,6 @@ static void nxt_router_access_log_reopen_error(nxt_task_t *task, static void nxt_router_app_port_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); -static nxt_int_t nxt_router_app_shared_port_send(nxt_task_t *task, - nxt_port_t *app_port); static void nxt_router_app_port_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); @@ -394,6 +392,7 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, { size_t size; uint32_t stream; + nxt_fd_t port_fd, queue_fd; nxt_int_t ret; nxt_app_t *app; nxt_buf_t *b; @@ -413,6 +412,8 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, nxt_debug(task, "app '%V' %p start process", &app->name, app); b = NULL; + port_fd = -1; + queue_fd = -1; } else { if (app->proto_port_requests > 0) { @@ -439,6 +440,9 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, nxt_buf_cpystr(b, &app->name); *b->mem.free++ = '\0'; nxt_buf_cpystr(b, &app->conf); + + port_fd = app->shared_port->pair[0]; + queue_fd = app->shared_port->queue_fd; } app_joint_rpc = nxt_port_rpc_register_handler_ex(task, port, @@ -451,8 +455,8 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, stream = nxt_port_rpc_ex_stream(app_joint_rpc); - ret = nxt_port_socket_write(task, dport, NXT_PORT_MSG_START_PROCESS, - -1, stream, port->id, b); + ret = nxt_port_socket_write2(task, dport, NXT_PORT_MSG_START_PROCESS, + port_fd, queue_fd, stream, port->id, b); if (nxt_slow_path(ret != NXT_OK)) { nxt_port_rpc_cancel(task, port, stream); @@ -2773,6 +2777,7 @@ nxt_router_app_rpc_create(nxt_task_t *task, { size_t size; uint32_t stream; + nxt_fd_t port_fd, queue_fd; nxt_int_t ret; nxt_buf_t *b; nxt_port_t *router_port, *dport; @@ -2801,10 +2806,15 @@ nxt_router_app_rpc_create(nxt_task_t *task, dport = rt->port_by_type[NXT_PROCESS_MAIN]; + port_fd = app->shared_port->pair[0]; + queue_fd = app->shared_port->queue_fd; + } else { nxt_debug(task, "app '%V' prefork", &app->name); b = NULL; + port_fd = -1; + queue_fd = -1; } router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; @@ -2823,9 +2833,8 @@ nxt_router_app_rpc_create(nxt_task_t *task, stream = nxt_port_rpc_ex_stream(rpc); - ret = nxt_port_socket_write(task, dport, - NXT_PORT_MSG_START_PROCESS, - -1, stream, router_port->id, b); + ret = nxt_port_socket_write2(task, dport, NXT_PORT_MSG_START_PROCESS, + port_fd, queue_fd, stream, router_port->id, b); if (nxt_slow_path(ret != NXT_OK)) { nxt_port_rpc_cancel(task, router_port, stream); goto fail; @@ -2900,7 +2909,7 @@ nxt_router_app_prefork_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, nxt_port_inc_use(port); - nxt_router_app_shared_port_send(task, port); + nxt_port_socket_write(task, port, NXT_PORT_MSG_PORT_ACK, -1, 0, 0, NULL); nxt_work_queue_add(&engine->fast_work_queue, nxt_router_conf_apply, task, rpc->temp_conf, NULL); @@ -4596,46 +4605,12 @@ nxt_router_app_port_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, nxt_debug(task, "app '%V' new port ready, pid %PI, %d/%d", &app->name, port->pid, app->processes, app->pending_processes); - nxt_router_app_shared_port_send(task, port); + nxt_port_socket_write(task, port, NXT_PORT_MSG_PORT_ACK, -1, 0, 0, NULL); nxt_router_app_port_release(task, app, port, NXT_APR_NEW_PORT); } -static nxt_int_t -nxt_router_app_shared_port_send(nxt_task_t *task, nxt_port_t *app_port) -{ - nxt_buf_t *b; - nxt_port_t *port; - nxt_port_msg_new_port_t *msg; - - b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, - sizeof(nxt_port_data_t)); - if (nxt_slow_path(b == NULL)) { - return NXT_ERROR; - } - - port = app_port->app->shared_port; - - nxt_debug(task, "send port %FD to process %PI", - port->pair[0], app_port->pid); - - b->mem.free += sizeof(nxt_port_msg_new_port_t); - msg = (nxt_port_msg_new_port_t *) b->mem.pos; - - msg->id = port->id; - msg->pid = port->pid; - msg->max_size = port->max_size; - msg->max_share = port->max_share; - msg->type = port->type; - - return nxt_port_socket_write2(task, app_port, - NXT_PORT_MSG_NEW_PORT, - port->pair[0], port->queue_fd, - 0, 0, b); -} - - static void nxt_router_app_port_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data) diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 135c06ed..57b89617 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -55,6 +55,7 @@ nxt_inline void nxt_unit_mmap_buf_insert_tail(nxt_unit_mmap_buf_t **prev, nxt_inline void nxt_unit_mmap_buf_unlink(nxt_unit_mmap_buf_t *mmap_buf); static int nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port, nxt_unit_port_t *read_port, + int *shared_port_fd, int *shared_queue_fd, int *log_fd, uint32_t *stream, uint32_t *shm_limit, uint32_t *request_limit); static int nxt_unit_ready(nxt_unit_ctx_t *ctx, int ready_fd, uint32_t stream, @@ -424,12 +425,12 @@ static pid_t nxt_unit_pid; nxt_unit_ctx_t * nxt_unit_init(nxt_unit_init_t *init) { - int rc, queue_fd; + int rc, queue_fd, shared_queue_fd; void *mem; uint32_t ready_stream, shm_limit, request_limit; nxt_unit_ctx_t *ctx; nxt_unit_impl_t *lib; - nxt_unit_port_t ready_port, router_port, read_port; + nxt_unit_port_t ready_port, router_port, read_port, shared_port; nxt_unit_pid = getpid(); @@ -440,6 +441,7 @@ nxt_unit_init(nxt_unit_init_t *init) queue_fd = -1; mem = MAP_FAILED; + shared_port.out_fd = -1; if (init->ready_port.id.pid != 0 && init->ready_stream != 0 @@ -458,8 +460,12 @@ nxt_unit_init(nxt_unit_init_t *init) nxt_unit_port_id_init(&read_port.id, read_port.id.pid, read_port.id.id); + shared_port.in_fd = init->shared_port_fd; + shared_queue_fd = init->shared_queue_fd; + } else { rc = nxt_unit_read_env(&ready_port, &router_port, &read_port, + &shared_port.in_fd, &shared_queue_fd, &lib->log_fd, &ready_stream, &shm_limit, &request_limit); if (nxt_slow_path(rc != NXT_UNIT_OK)) { @@ -525,6 +531,27 @@ nxt_unit_init(nxt_unit_init_t *init) goto fail; } + nxt_unit_port_id_init(&shared_port.id, read_port.id.pid, + NXT_UNIT_SHARED_PORT_ID); + + mem = mmap(NULL, sizeof(nxt_app_queue_t), PROT_READ | PROT_WRITE, + MAP_SHARED, shared_queue_fd, 0); + if (nxt_slow_path(mem == MAP_FAILED)) { + nxt_unit_alert(ctx, "mmap(%d) failed: %s (%d)", shared_queue_fd, + strerror(errno), errno); + + goto fail; + } + + nxt_unit_close(shared_queue_fd); + + lib->shared_port = nxt_unit_add_port(ctx, &shared_port, mem); + if (nxt_slow_path(lib->shared_port == NULL)) { + nxt_unit_alert(NULL, "failed to add shared_port"); + + goto fail; + } + rc = nxt_unit_ready(ctx, ready_port.out_fd, ready_stream, queue_fd); if (nxt_slow_path(rc != NXT_UNIT_OK)) { nxt_unit_alert(NULL, "failed to send READY message"); @@ -799,7 +826,8 @@ nxt_unit_mmap_buf_unlink(nxt_unit_mmap_buf_t *mmap_buf) static int nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port, - nxt_unit_port_t *read_port, int *log_fd, uint32_t *stream, + nxt_unit_port_t *read_port, int *shared_port_fd, int *shared_queue_fd, + int *log_fd, uint32_t *stream, uint32_t *shm_limit, uint32_t *request_limit) { int rc; @@ -845,11 +873,13 @@ nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port, "%"PRId64",%"PRIu32",%d;" "%"PRId64",%"PRIu32",%d;" "%"PRId64",%"PRIu32",%d,%d;" + "%d,%d;" "%d,%"PRIu32",%"PRIu32, &ready_stream, &ready_pid, &ready_id, &ready_fd, &router_pid, &router_id, &router_fd, &read_pid, &read_id, &read_in_fd, &read_out_fd, + shared_port_fd, shared_queue_fd, log_fd, shm_limit, request_limit); if (nxt_slow_path(rc == EOF)) { @@ -859,9 +889,9 @@ nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port, return NXT_UNIT_ERROR; } - if (nxt_slow_path(rc != 14)) { + if (nxt_slow_path(rc != 16)) { nxt_unit_alert(NULL, "invalid number of variables in %s env: " - "found %d of %d in %s", NXT_UNIT_INIT_ENV, rc, 14, vars); + "found %d of %d in %s", NXT_UNIT_INIT_ENV, rc, 16, vars); return NXT_UNIT_ERROR; } @@ -1137,7 +1167,6 @@ static int nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg) { void *mem; - nxt_unit_impl_t *lib; nxt_unit_port_t new_port, *port; nxt_port_msg_new_port_t *new_port_msg; @@ -1162,33 +1191,17 @@ nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg) recv_msg->stream, (int) new_port_msg->pid, (int) new_port_msg->id, recv_msg->fd[0], recv_msg->fd[1]); - lib = nxt_container_of(ctx->unit, nxt_unit_impl_t, unit); - - if (new_port_msg->id == NXT_UNIT_SHARED_PORT_ID) { - nxt_unit_port_id_init(&new_port.id, lib->pid, new_port_msg->id); - - new_port.in_fd = recv_msg->fd[0]; - new_port.out_fd = -1; - - mem = mmap(NULL, sizeof(nxt_app_queue_t), PROT_READ | PROT_WRITE, - MAP_SHARED, recv_msg->fd[1], 0); - - } else { - if (nxt_slow_path(nxt_unit_fd_blocking(recv_msg->fd[0]) - != NXT_UNIT_OK)) - { - return NXT_UNIT_ERROR; - } + if (nxt_slow_path(nxt_unit_fd_blocking(recv_msg->fd[0]) != NXT_UNIT_OK)) { + return NXT_UNIT_ERROR; + } - nxt_unit_port_id_init(&new_port.id, new_port_msg->pid, - new_port_msg->id); + nxt_unit_port_id_init(&new_port.id, new_port_msg->pid, new_port_msg->id); - new_port.in_fd = -1; - new_port.out_fd = recv_msg->fd[0]; + new_port.in_fd = -1; + new_port.out_fd = recv_msg->fd[0]; - mem = mmap(NULL, sizeof(nxt_port_queue_t), PROT_READ | PROT_WRITE, - MAP_SHARED, recv_msg->fd[1], 0); - } + mem = mmap(NULL, sizeof(nxt_port_queue_t), PROT_READ | PROT_WRITE, + MAP_SHARED, recv_msg->fd[1], 0); if (nxt_slow_path(mem == MAP_FAILED)) { nxt_unit_alert(ctx, "mmap(%d) failed: %s (%d)", recv_msg->fd[1], @@ -1206,12 +1219,6 @@ nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg) return NXT_UNIT_ERROR; } - if (new_port_msg->id == NXT_UNIT_SHARED_PORT_ID) { - lib->shared_port = port; - - return nxt_unit_ctx_ready(ctx); - } - nxt_unit_port_release(port); return NXT_UNIT_OK; diff --git a/src/nxt_unit.h b/src/nxt_unit.h index 1b5280af..35f9fa55 100644 --- a/src/nxt_unit.h +++ b/src/nxt_unit.h @@ -176,6 +176,8 @@ struct nxt_unit_init_s { uint32_t ready_stream; nxt_unit_port_t router_port; nxt_unit_port_t read_port; + int shared_port_fd; + int shared_queue_fd; int log_fd; }; -- cgit From 9e2e69dd58f01005e088b55466e67c0eafc2a414 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 24 Nov 2021 13:11:48 +0300 Subject: Fixing alerts on router restart. Splitting the process type connectivity matrix to 'keep ports' and 'send ports'; the 'keep ports' matrix is used to clean up unnecessary ports after forking a new process, and the 'send ports' matrix determines which process types expect to get created process ports. Unfortunately, the original single connectivity matrix no longer works because of an application stop delay caused by prototypes. Existing applications should not get the new router port at the moment. --- src/nxt_port.c | 2 +- src/nxt_process.c | 15 ++++++++++++--- src/nxt_process.h | 6 +++--- 3 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nxt_port.c b/src/nxt_port.c index 88d645af..ed7050f3 100644 --- a/src/nxt_port.c +++ b/src/nxt_port.c @@ -217,7 +217,7 @@ nxt_port_send_new_port(nxt_task_t *task, nxt_runtime_t *rt, port = nxt_process_port_first(process); - if (nxt_proc_conn_matrix[port->type][new_port->type]) { + if (nxt_proc_send_matrix[port->type][new_port->type]) { (void) nxt_port_send_port(task, port, new_port, stream); } diff --git a/src/nxt_process.c b/src/nxt_process.c index fca197eb..82e66a99 100644 --- a/src/nxt_process.c +++ b/src/nxt_process.c @@ -58,7 +58,7 @@ nxt_uid_t nxt_euid; /* A cached process effective gid */ nxt_gid_t nxt_egid; -nxt_bool_t nxt_proc_conn_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = { +uint8_t nxt_proc_keep_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = { { 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 0 }, { 1, 0, 0, 1, 0, 0 }, @@ -67,7 +67,16 @@ nxt_bool_t nxt_proc_conn_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = { { 1, 0, 0, 1, 0, 0 }, }; -nxt_bool_t nxt_proc_remove_notify_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = { +uint8_t nxt_proc_send_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = { + { 1, 1, 1, 1, 1, 1 }, + { 1, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 1, 0, 0 }, + { 1, 0, 1, 1, 1, 1 }, + { 1, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0 }, +}; + +uint8_t nxt_proc_remove_notify_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, 0, 0 }, @@ -265,7 +274,7 @@ nxt_process_child_fixup(nxt_task_t *task, nxt_process_t *process) /* Remove not ready processes. */ nxt_runtime_process_each(rt, p) { - if (nxt_proc_conn_matrix[ptype][nxt_process_type(p)] == 0 + if (nxt_proc_keep_matrix[ptype][nxt_process_type(p)] == 0 && p->pid != nxt_ppid) /* Always keep parent's port. */ { nxt_debug(task, "remove not required process %PI", p->pid); diff --git a/src/nxt_process.h b/src/nxt_process.h index c92eebd8..694f457e 100644 --- a/src/nxt_process.h +++ b/src/nxt_process.h @@ -151,9 +151,9 @@ typedef struct { } nxt_process_init_t; -extern nxt_bool_t nxt_proc_conn_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX]; -extern nxt_bool_t - nxt_proc_remove_notify_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX]; +extern uint8_t nxt_proc_keep_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX]; +extern uint8_t nxt_proc_send_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX]; +extern uint8_t nxt_proc_remove_notify_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX]; NXT_EXPORT nxt_pid_t nxt_process_execute(nxt_task_t *task, char *name, char **argv, char **envp); -- cgit From 2bc95990571f82ddfc685fadff4847abff4362e3 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 24 Nov 2021 13:11:50 +0300 Subject: Fixing zombie process appearance and hang up on shutdown. After the c8790d2a89bb commit, the SIGCHLD handler may return before processing all awaiting PIDs. To avoid zombie processes and ensure successful main process termination, waitpid() must be called until an error is returned. This closes #600 issue on GitHub. --- src/nxt_main_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 3914c041..9883f04c 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -972,9 +972,11 @@ nxt_main_process_sigchld_handler(nxt_task_t *task, void *obj, void *data) if (rt->nprocesses <= 1) { nxt_runtime_quit(task, 0); + + return; } - return; + continue; } nxt_port_remove_notify_others(task, process); -- cgit From 0af5f6ddb495902914880f540b44d8c828d945f1 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Thu, 25 Nov 2021 16:58:43 +0300 Subject: Fixing access_log structure reference counting. The reference to the access_log structure is stored in the current nxt_router_conf_t and the global nxt_router_t. When the reference is copied, the reference counter should be adjusted accordingly. This closes #593 issue on GitHub. --- src/nxt_router.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nxt_router.c b/src/nxt_router.c index f718bb6e..52ea0f37 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -210,6 +210,8 @@ 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, nxt_port_recv_msg_t *msg, void *data); +static void nxt_router_access_log_use(nxt_thread_spinlock_t *lock, + nxt_router_access_log_t *access_log); static void nxt_router_access_log_release(nxt_task_t *task, nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log); static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, @@ -1153,7 +1155,13 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) nxt_queue_add(&router->sockets, &updating_sockets); nxt_queue_add(&router->sockets, &creating_sockets); - router->access_log = rtcf->access_log; + if (router->access_log != rtcf->access_log) { + nxt_router_access_log_use(&router->lock, rtcf->access_log); + + nxt_router_access_log_release(task, &router->lock, router->access_log); + + router->access_log = rtcf->access_log; + } nxt_router_conf_ready(task, tmcf); @@ -1975,9 +1983,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, access_log = router->access_log; if (access_log != NULL && nxt_strstr_eq(&path, &access_log->path)) { - nxt_thread_spin_lock(&router->lock); - access_log->count++; - nxt_thread_spin_unlock(&router->lock); + nxt_router_access_log_use(&router->lock, access_log); } else { access_log = nxt_malloc(sizeof(nxt_router_access_log_t) @@ -3931,6 +3937,22 @@ nxt_router_access_log_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, } +static void +nxt_router_access_log_use(nxt_thread_spinlock_t *lock, + nxt_router_access_log_t *access_log) +{ + if (access_log == NULL) { + return; + } + + nxt_thread_spin_lock(lock); + + access_log->count++; + + nxt_thread_spin_unlock(lock); +} + + static void nxt_router_access_log_release(nxt_task_t *task, nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log) -- cgit From f8237911d723ed1c8db0e4e5b75e1126b94f798a Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Thu, 25 Nov 2021 19:58:54 +0300 Subject: PHP: fixed crash when calling module functions in OPcache preload. In PHP, custom fastcgi_finish_request() and overloaded chdir() functions can be invoked by an OPcache preloading script (it runs when php_module_startup() is called in the app process setup handler). In this case, there was no runtime context set so trying to access it caused a segmentation fault. This closes #602 issue on GitHub. --- src/nxt_php_sapi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c index ea5f5581..68ef07eb 100644 --- a/src/nxt_php_sapi.c +++ b/src/nxt_php_sapi.c @@ -204,7 +204,10 @@ ZEND_NAMED_FUNCTION(nxt_php_chdir) nxt_php_run_ctx_t *ctx; ctx = SG(server_context); - ctx->chdir = 1; + + if (nxt_fast_path(ctx != NULL)) { + ctx->chdir = 1; + } nxt_php_chdir_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); } @@ -225,7 +228,7 @@ PHP_FUNCTION(fastcgi_finish_request) ctx = SG(server_context); - if (nxt_slow_path(ctx->req == NULL)) { + if (nxt_slow_path(ctx == NULL || ctx->req == NULL)) { RETURN_FALSE; } -- cgit From 8c9228d19f76f3668bf00725413960d5e7cc6173 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Wed, 1 Dec 2021 17:09:02 +0300 Subject: Logging of the daemon version on startup. --- src/nxt_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_main.c b/src/nxt_main.c index 03403991..26bee873 100644 --- a/src/nxt_main.c +++ b/src/nxt_main.c @@ -30,7 +30,7 @@ main(int argc, char **argv) return 1; } - nxt_log(&nxt_main_task, NXT_LOG_INFO, "unit started"); + nxt_log(&nxt_main_task, NXT_LOG_INFO, "unit " NXT_VERSION " started"); nxt_event_engine_start(nxt_main_task.thread->engine); -- cgit From 8fb9f7f049474e4d9c80c0b25ad152bb937c2f86 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 1 Dec 2021 18:05:16 +0300 Subject: Fixing uninitialized structure field. Port's "data" field may be used by application and thus need to be set to NULL. The issue was introduced in the f8a0992944df commit. Found by Coverity (CID 374352). --- src/nxt_unit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 57b89617..dac612b8 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -442,6 +442,7 @@ nxt_unit_init(nxt_unit_init_t *init) queue_fd = -1; mem = MAP_FAILED; shared_port.out_fd = -1; + shared_port.data = NULL; if (init->ready_port.id.pid != 0 && init->ready_stream != 0 -- cgit From 64db3ef1bbf32457aefb002b9fecabb6c07923f9 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 1 Dec 2021 18:05:50 +0300 Subject: Fixing prototype process crash. A prototype stores linked application processes structures. When an application process terminates, it's removed from the list. To avoid double removal, the pointer to the next element should be set to NULL. The issue was introduced in c8790d2a89bb. --- src/nxt_application.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nxt_application.c b/src/nxt_application.c index d1ff9ee7..594574b1 100644 --- a/src/nxt_application.c +++ b/src/nxt_application.c @@ -1150,6 +1150,8 @@ nxt_proto_process_remove(nxt_task_t *task, nxt_pid_t pid) process = lhq.value; nxt_queue_remove(&process->link); + process->link.next = NULL; + break; default: -- cgit From a6a884ebdbad54e2443e5281d53111c92f3ec837 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 3 Dec 2021 12:08:54 +0800 Subject: Fixed debug message broken in 45b25ffb2e8c. --- src/nxt_var.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_var.c b/src/nxt_var.c index 60650ef4..0a722d17 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -627,7 +627,8 @@ nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query) nxt_array_reset(&query->parts); - nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, val[i].value); + nxt_debug(task, "var: \"%*s\" -> \"%V\"", var->length, src, + val[i].value); } done: -- cgit From f8452838207d56892fb80b5976b37aab1efcaa1e Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Mon, 27 Dec 2021 16:37:35 +0300 Subject: Perl: creating input and error streams if closed. Application handler can do anything with a stream object (including close it). Once the stream is closed, Unit creates a new stream. This closes #616 issue on GitHub. --- src/perl/nxt_perl_psgi.c | 188 ++++++++++++++++++----------------------- src/perl/nxt_perl_psgi_layer.c | 64 ++++---------- src/perl/nxt_perl_psgi_layer.h | 28 +++--- 3 files changed, 113 insertions(+), 167 deletions(-) (limited to 'src') diff --git a/src/perl/nxt_perl_psgi.c b/src/perl/nxt_perl_psgi.c index 02555c96..749ebd80 100644 --- a/src/perl/nxt_perl_psgi.c +++ b/src/perl/nxt_perl_psgi.c @@ -28,19 +28,15 @@ typedef struct { } nxt_perl_psgi_ctx_t; -static long nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl, +static SSize_t nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length); -static long nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl, +static SSize_t nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length); -static long nxt_perl_psgi_io_input_flush(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg); -static long nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl, +static SSize_t nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length); -static long nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl, +static SSize_t nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length); -static long nxt_perl_psgi_io_error_flush(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg); /* static void nxt_perl_psgi_xs_core_global_changes(PerlInterpreter *my_perl, @@ -57,10 +53,8 @@ static SV *nxt_perl_psgi_call_method(PerlInterpreter *my_perl, SV *obj, /* For currect load XS modules */ EXTERN_C void boot_DynaLoader(pTHX_ CV *cv); -static nxt_int_t nxt_perl_psgi_io_input_init(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg); -static nxt_int_t nxt_perl_psgi_io_error_init(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg); +static int nxt_perl_psgi_io_init(PerlInterpreter *my_perl, + nxt_perl_psgi_io_arg_t *arg, const char *mode, void *req); static int nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx); @@ -125,20 +119,26 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = { nxt_perl_psgi_start, }; +const nxt_perl_psgi_io_tab_t nxt_perl_psgi_io_tab_input = { + .read = nxt_perl_psgi_io_input_read, + .write = nxt_perl_psgi_io_input_write, +}; + +const nxt_perl_psgi_io_tab_t nxt_perl_psgi_io_tab_error = { + .read = nxt_perl_psgi_io_error_read, + .write = nxt_perl_psgi_io_error_write, +}; -static long + +static SSize_t nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length) { - nxt_perl_psgi_ctx_t *pctx; - - pctx = arg->pctx; - - return nxt_unit_request_read(pctx->req, vbuf, length); + return nxt_unit_request_read(arg->req, vbuf, length); } -static long +static SSize_t nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length) { @@ -146,15 +146,7 @@ nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl, } -static long -nxt_perl_psgi_io_input_flush(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg) -{ - return 0; -} - - -static long +static SSize_t nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length) { @@ -162,25 +154,13 @@ nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl, } -static long +static SSize_t nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length) { - nxt_perl_psgi_ctx_t *pctx; - - pctx = arg->pctx; - - nxt_unit_req_error(pctx->req, "Perl: %s", (const char*) vbuf); - - return (long) length; -} - + nxt_unit_req_error(arg->req, "Perl: %s", (const char*) vbuf); -static long -nxt_perl_psgi_io_error_flush(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg) -{ - return 0; + return (SSize_t) length; } @@ -461,70 +441,49 @@ nxt_perl_psgi_module_create(const char *script) } -static nxt_int_t -nxt_perl_psgi_io_input_init(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg) +static int +nxt_perl_psgi_io_init(PerlInterpreter *my_perl, + nxt_perl_psgi_io_arg_t *arg, const char *mode, void *req) { SV *io; PerlIO *fp; - fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg, "r"); - - if (nxt_slow_path(fp == NULL)) { - return NXT_ERROR; - } + if (arg->io == NULL) { + fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg->rv, mode); + if (nxt_slow_path(fp == NULL)) { + return NXT_UNIT_ERROR; + } - io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp); + io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp); + if (nxt_slow_path(io == NULL)) { + nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp); + return NXT_UNIT_ERROR; + } - if (nxt_slow_path(io == NULL)) { - nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp); - return NXT_ERROR; + arg->io = io; + arg->fp = fp; } - arg->io = io; - arg->fp = fp; - arg->flush = nxt_perl_psgi_io_input_flush; - arg->read = nxt_perl_psgi_io_input_read; - arg->write = nxt_perl_psgi_io_input_write; + arg->req = req; - return NXT_OK; + return NXT_UNIT_OK; } -static nxt_int_t -nxt_perl_psgi_io_error_init(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg) +static void +nxt_perl_psgi_io_release(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg) { - SV *io; - PerlIO *fp; - - fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg, "w"); - - if (nxt_slow_path(fp == NULL)) { - return NXT_ERROR; + if (arg->io != NULL) { + SvREFCNT_dec(arg->io); + arg->io = NULL; } - - io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp); - - if (nxt_slow_path(io == NULL)) { - nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp); - return NXT_ERROR; - } - - arg->io = io; - arg->fp = fp; - arg->flush = nxt_perl_psgi_io_error_flush; - arg->read = nxt_perl_psgi_io_error_read; - arg->write = nxt_perl_psgi_io_error_write; - - return NXT_OK; } static int nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx) { - int status; + int status, res; char *run_module; PerlInterpreter *my_perl; @@ -577,19 +536,27 @@ nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx) goto fail; } - pctx->arg_input.pctx = pctx; + pctx->arg_input.rv = newSV_type(SVt_RV); + sv_setptrref(pctx->arg_input.rv, &pctx->arg_input); + SvSETMAGIC(pctx->arg_input.rv); - status = nxt_perl_psgi_io_input_init(my_perl, &pctx->arg_input); - if (nxt_slow_path(status != NXT_OK)) { + pctx->arg_input.io_tab = &nxt_perl_psgi_io_tab_input; + + res = nxt_perl_psgi_io_init(my_perl, &pctx->arg_input, "r", NULL); + if (nxt_slow_path(res != NXT_UNIT_OK)) { nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.input"); goto fail; } - pctx->arg_error.pctx = pctx; + pctx->arg_error.rv = newSV_type(SVt_RV); + sv_setptrref(pctx->arg_error.rv, &pctx->arg_error); + SvSETMAGIC(pctx->arg_error.rv); + + pctx->arg_error.io_tab = &nxt_perl_psgi_io_tab_error; - status = nxt_perl_psgi_io_error_init(my_perl, &pctx->arg_error); - if (nxt_slow_path(status != NXT_OK)) { - nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.errors"); + res = nxt_perl_psgi_io_init(my_perl, &pctx->arg_error, "w", NULL); + if (nxt_slow_path(res != NXT_UNIT_OK)) { + nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.error"); goto fail; } @@ -607,6 +574,9 @@ nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx) fail: + nxt_perl_psgi_io_release(my_perl, &pctx->arg_input); + nxt_perl_psgi_io_release(my_perl, &pctx->arg_error); + if (run_module != NULL) { nxt_unit_free(NULL, run_module); } @@ -614,6 +584,8 @@ fail: perl_destruct(my_perl); perl_free(my_perl); + pctx->my_perl = NULL; + return NXT_UNIT_ERROR; } @@ -672,21 +644,25 @@ nxt_perl_psgi_env_create(PerlInterpreter *my_perl, r->tls ? newSVpv("https", 5) : newSVpv("http", 4))); + RC(nxt_perl_psgi_io_init(my_perl, &pctx->arg_input, "r", req)); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.input"), - SvREFCNT_inc(pctx->arg_input.io))); + SvREFCNT_inc(pctx->arg_input.io))); + + RC(nxt_perl_psgi_io_init(my_perl, &pctx->arg_error, "w", req)); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.errors"), - SvREFCNT_inc(pctx->arg_error.io))); + SvREFCNT_inc(pctx->arg_error.io))); + RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.multithread"), - nxt_perl_psgi_ctxs != NULL - ? &PL_sv_yes : &PL_sv_no)); + nxt_perl_psgi_ctxs != NULL + ? &PL_sv_yes : &PL_sv_no)); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.multiprocess"), - &PL_sv_yes)); + &PL_sv_yes)); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.run_once"), - &PL_sv_no)); + &PL_sv_no)); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.nonblocking"), - &PL_sv_no)); + &PL_sv_no)); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.streaming"), - &PL_sv_yes)); + &PL_sv_yes)); RC(nxt_perl_psgi_add_sptr(my_perl, hash_env, NL("QUERY_STRING"), &r->query, r->query_length)); @@ -1447,11 +1423,11 @@ nxt_perl_psgi_ctx_free(nxt_perl_psgi_ctx_t *pctx) PERL_SET_CONTEXT(my_perl); - nxt_perl_psgi_layer_stream_io_destroy(aTHX_ pctx->arg_input.io); - nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ pctx->arg_input.fp); + SvREFCNT_dec(pctx->arg_input.rv); + SvREFCNT_dec(pctx->arg_error.rv); - nxt_perl_psgi_layer_stream_io_destroy(aTHX_ pctx->arg_error.io); - nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ pctx->arg_error.fp); + nxt_perl_psgi_io_release(my_perl, &pctx->arg_input); + nxt_perl_psgi_io_release(my_perl, &pctx->arg_error); perl_destruct(my_perl); perl_free(my_perl); diff --git a/src/perl/nxt_perl_psgi_layer.c b/src/perl/nxt_perl_psgi_layer.c index f77453e9..303e5f27 100644 --- a/src/perl/nxt_perl_psgi_layer.c +++ b/src/perl/nxt_perl_psgi_layer.c @@ -93,11 +93,9 @@ nxt_perl_psgi_layer_stream_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t); if (arg != NULL && SvOK(arg)) { - unit_stream->var = arg; + unit_stream->var = SvREFCNT_inc(arg); } - SvSETMAGIC(unit_stream->var); - return PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab); } @@ -105,11 +103,17 @@ nxt_perl_psgi_layer_stream_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, static IV nxt_perl_psgi_layer_stream_popped(pTHX_ PerlIO *f) { + nxt_perl_psgi_io_arg_t *arg; nxt_perl_psgi_layer_stream_t *unit_stream; unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t); if (unit_stream->var != NULL) { + arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var)); + + arg->io = NULL; + arg->fp = NULL; + SvREFCNT_dec(unit_stream->var); unit_stream->var = Nullsv; } @@ -181,9 +185,6 @@ nxt_perl_psgi_layer_stream_read(pTHX_ PerlIO *f, void *vbuf, Size_t count) return 0; } - unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t); - arg = (nxt_perl_psgi_io_arg_t *) (intptr_t) SvIV(SvRV(unit_stream->var)); - if ((PerlIOBase(f)->flags & PERLIO_F_CANREAD) == 0) { PerlIOBase(f)->flags |= PERLIO_F_ERROR; @@ -192,7 +193,10 @@ nxt_perl_psgi_layer_stream_read(pTHX_ PerlIO *f, void *vbuf, Size_t count) return 0; } - return (SSize_t) arg->read(PERL_GET_CONTEXT, arg, vbuf, count); + unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t); + arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var)); + + return arg->io_tab->read(PERL_GET_CONTEXT, arg, vbuf, count); } @@ -204,13 +208,10 @@ nxt_perl_psgi_layer_stream_write(pTHX_ PerlIO *f, nxt_perl_psgi_layer_stream_t *unit_stream; if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) { - unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t); + arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var)); - arg = (nxt_perl_psgi_io_arg_t *) - (intptr_t) SvIV(SvRV(unit_stream->var)); - - return (SSize_t) arg->write(PERL_GET_CONTEXT, arg, vbuf, count); + return arg->io_tab->write(PERL_GET_CONTEXT, arg, vbuf, count); } return 0; @@ -244,13 +245,7 @@ nxt_perl_psgi_layer_stream_fill(pTHX_ PerlIO *f) static IV nxt_perl_psgi_layer_stream_flush(pTHX_ PerlIO *f) { - nxt_perl_psgi_io_arg_t *arg; - nxt_perl_psgi_layer_stream_t *unit_stream; - - unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t); - arg = (nxt_perl_psgi_io_arg_t *) (intptr_t) SvIV(SvRV(unit_stream->var)); - - return (IV) arg->flush(PERL_GET_CONTEXT, arg); + return 0; } @@ -346,29 +341,11 @@ nxt_perl_psgi_layer_stream_init(pTHX) PerlIO * -nxt_perl_psgi_layer_stream_fp_create(pTHX_ nxt_perl_psgi_io_arg_t *arg, +nxt_perl_psgi_layer_stream_fp_create(pTHX_ SV *arg_rv, const char *mode) { - SV *arg_rv; - PerlIO *fp; - - arg_rv = newSV_type(SVt_RV); - - if (arg_rv == NULL) { - return NULL; - } - - sv_setptrref(arg_rv, arg); - - fp = PerlIO_openn(aTHX_ "NGINX_Unit_PSGI_Layer_Stream", - mode, 0, 0, 0, NULL, 1, &arg_rv); - - if (fp == NULL) { - SvREFCNT_dec(arg_rv); - return NULL; - } - - return fp; + return PerlIO_openn(aTHX_ "NGINX_Unit_PSGI_Layer_Stream", + mode, 0, 0, 0, NULL, 1, &arg_rv); } @@ -403,10 +380,3 @@ nxt_perl_psgi_layer_stream_io_create(pTHX_ PerlIO *fp) return rvio; } - - -void -nxt_perl_psgi_layer_stream_io_destroy(pTHX_ SV *rvio) -{ - SvREFCNT_dec(rvio); -} diff --git a/src/perl/nxt_perl_psgi_layer.h b/src/perl/nxt_perl_psgi_layer.h index af18ad0d..0972d66f 100644 --- a/src/perl/nxt_perl_psgi_layer.h +++ b/src/perl/nxt_perl_psgi_layer.h @@ -14,35 +14,35 @@ #include +typedef struct nxt_perl_psgi_io_tab_s nxt_perl_psgi_io_tab_t; typedef struct nxt_perl_psgi_io_arg_s nxt_perl_psgi_io_arg_t; -typedef long (*nxt_perl_psgi_io_read_f)(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length); -typedef long (*nxt_perl_psgi_io_write_f)(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length); -typedef long (*nxt_perl_psgi_io_arg_f)(PerlInterpreter *my_perl, - nxt_perl_psgi_io_arg_t *arg); + +struct nxt_perl_psgi_io_tab_s { + SSize_t (*read)(PerlInterpreter *my_perl, + nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length); + SSize_t (*write)(PerlInterpreter *my_perl, + nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length); +}; struct nxt_perl_psgi_io_arg_s { - SV *io; - PerlIO *fp; + SV *rv; + SV *io; + PerlIO *fp; - nxt_perl_psgi_io_arg_f flush; - nxt_perl_psgi_io_read_f read; - nxt_perl_psgi_io_write_f write; + const nxt_perl_psgi_io_tab_t *io_tab; - void *pctx; + void *req; }; void nxt_perl_psgi_layer_stream_init(pTHX); -PerlIO *nxt_perl_psgi_layer_stream_fp_create(pTHX_ nxt_perl_psgi_io_arg_t *arg, +PerlIO *nxt_perl_psgi_layer_stream_fp_create(pTHX_ SV *arg_rv, const char *mode); void nxt_perl_psgi_layer_stream_fp_destroy(pTHX_ PerlIO *io); SV *nxt_perl_psgi_layer_stream_io_create(pTHX_ PerlIO *fp); -void nxt_perl_psgi_layer_stream_io_destroy(pTHX_ SV *rvio); #endif /* _NXT_PERL_PSGI_LAYER_H_INCLUDED_ */ -- cgit From 818a78d82cd9aeb6c7429ef97cd1f39f9053b909 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Mon, 27 Dec 2021 16:37:36 +0300 Subject: Java: fixing multiple SCI initializations. - Ignoring Tomcat WebSocket container initialization. - Renaming application class loader to UnitClassLoader to avoid development environment enablement in Spring Boot. This closes #609 issue on GitHub. --- src/java/nginx/unit/Context.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/java/nginx/unit/Context.java b/src/java/nginx/unit/Context.java index 0197858b..e1245e1f 100644 --- a/src/java/nginx/unit/Context.java +++ b/src/java/nginx/unit/Context.java @@ -422,7 +422,7 @@ public class Context implements ServletContext, InitParams processWebXml(root); - loader_ = new AppClassLoader(urls, + loader_ = new UnitClassLoader(urls, Context.class.getClassLoader().getParent()); Class wsSession_class = WsSession.class; @@ -531,7 +531,7 @@ public class Context implements ServletContext, InitParams } } - private static class AppClassLoader extends URLClassLoader + private static class UnitClassLoader extends URLClassLoader { static { ClassLoader.registerAsParallelCapable(); @@ -547,7 +547,7 @@ public class Context implements ServletContext, InitParams private ClassLoader system_loader; - public AppClassLoader(URL[] urls, ClassLoader parent) + public UnitClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); @@ -1514,6 +1514,18 @@ public class Context implements ServletContext, InitParams { trace("loadInitializer: initializer: " + sci.getClass().getName()); + /* + Unit WebSocket container is a copy of Tomcat WsSci with own + transport implementation. Tomcat implementation will not work in + Unit and should be ignored here. + */ + if (sci.getClass().getName() + .equals("org.apache.tomcat.websocket.server.WsSci")) + { + trace("loadInitializer: ignore"); + return; + } + HandlesTypes ann = sci.getClass().getAnnotation(HandlesTypes.class); if (ann == null) { trace("loadInitializer: no HandlesTypes annotation"); @@ -1558,7 +1570,6 @@ public class Context implements ServletContext, InitParams try { sci.onStartup(handles_classes, this); - metadata_complete_ = true; } catch(Exception e) { System.err.println("loadInitializer: exception caught: " + e.toString()); } -- cgit From 2b5941df74806d344c59ec0ca126b81cc7bbffe1 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Tue, 8 Feb 2022 12:04:41 +0300 Subject: Python: fixing incorrect function object dereference. The __call__ method can be native and not be a PyFunction type. A type check is thus required before accessing op_code and other fields. Reproduced on Ubuntu 21.04, Python 3.9.4 and Falcon framework: here, the App.__call__ method is compiled with Cython, so accessing op_code->co_flags is invalid; accidentally, the COROUTINE bit is set which forces the Python module into the ASGI mode. The workaround is explicit protocol specification. Note: it is impossible to specify the legacy mode for ASGI. --- src/python/nxt_python_asgi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/python/nxt_python_asgi.c b/src/python/nxt_python_asgi.c index 354e3a81..2d3efc7d 100644 --- a/src/python/nxt_python_asgi.c +++ b/src/python/nxt_python_asgi.c @@ -117,15 +117,20 @@ nxt_python_asgi_get_func(PyObject *obj) if (PyMethod_Check(call)) { obj = PyMethod_GET_FUNCTION(call); - Py_INCREF(obj); - Py_DECREF(call); + if (PyFunction_Check(obj)) { + Py_INCREF(obj); - return obj; + } else { + obj = NULL; + } + + } else { + obj = NULL; } Py_DECREF(call); - return NULL; + return obj; } @@ -161,8 +166,9 @@ nxt_python_asgi_init(nxt_unit_init_t *init, nxt_python_proto_t *proto) for (i = 0; i < nxt_py_targets->count; i++) { func = nxt_python_asgi_get_func(nxt_py_targets->target[i].application); if (nxt_slow_path(func == NULL)) { - nxt_unit_alert(NULL, "Python cannot find function for callable"); - return NXT_UNIT_ERROR; + nxt_unit_debug(NULL, "asgi: cannot find function for callable, " + "unable to check for legacy mode (#%d)", i); + continue; } code = (PyCodeObject *) PyFunction_GET_CODE(func); -- cgit From bf6282b16ca192ace20b35711ed9b8a8014e63d4 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 9 Feb 2022 10:37:51 +0300 Subject: Python: fixing debug message field type. Introduced in the 78864c9d5ba8 commit. Sorry about that. --- src/python/nxt_python_asgi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/nxt_python_asgi.c b/src/python/nxt_python_asgi.c index 2d3efc7d..91af8f4b 100644 --- a/src/python/nxt_python_asgi.c +++ b/src/python/nxt_python_asgi.c @@ -167,7 +167,8 @@ nxt_python_asgi_init(nxt_unit_init_t *init, nxt_python_proto_t *proto) func = nxt_python_asgi_get_func(nxt_py_targets->target[i].application); if (nxt_slow_path(func == NULL)) { nxt_unit_debug(NULL, "asgi: cannot find function for callable, " - "unable to check for legacy mode (#%d)", i); + "unable to check for legacy mode (#%d)", + (int) i); continue; } -- cgit From 4fcfb9d5fb2b1bfbb3bd87a8617d293cbf2f4ddf Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 14 Feb 2022 20:14:03 +0800 Subject: Certificates: fixed crash when reallocating chain. --- src/nxt_cert.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nxt_cert.c b/src/nxt_cert.c index 01d413e0..4a1f1496 100644 --- a/src/nxt_cert.c +++ b/src/nxt_cert.c @@ -241,7 +241,6 @@ nxt_cert_bio(nxt_task_t *task, BIO *bio) goto fail; } - nxt_free(cert); cert = new_cert; } -- cgit From aeed86c6829c62359e79f239b849766efb8857a7 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 22 Feb 2022 19:18:18 +0800 Subject: Workaround for the warning in nxt_realloc() on GCC 12. This closes #639 issue on Github. --- src/nxt_malloc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nxt_malloc.c b/src/nxt_malloc.c index fed58e96..5ea7322f 100644 --- a/src/nxt_malloc.c +++ b/src/nxt_malloc.c @@ -64,17 +64,24 @@ nxt_zalloc(size_t size) void * nxt_realloc(void *p, size_t size) { - void *n; + void *n; + uintptr_t ptr; + + /* + * Workaround for a warning on GCC 12 about using "p" pointer in debug log + * after realloc(). + */ + ptr = (uintptr_t) p; n = realloc(p, size); if (nxt_fast_path(n != NULL)) { - nxt_log_debug(nxt_malloc_log(), "realloc(%p, %uz): %p", p, size, n); + nxt_log_debug(nxt_malloc_log(), "realloc(%p, %uz): %p", ptr, size, n); } else { nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(), "realloc(%p, %uz) failed %E", - p, size, nxt_errno); + ptr, size, nxt_errno); } return n; -- cgit From 940d695f827eaffd19723429732c07e2dc7fb467 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 19 Dec 2021 01:53:27 +0100 Subject: Added 'const' for read-only function parameter. That parameter is not being modified in the function. Make it 'const' to allow passing 'static const' variables. --- src/nxt_conf.c | 3 ++- src/nxt_conf.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 1aca0a7e..8546e2b7 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -192,7 +192,8 @@ nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str) nxt_int_t -nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str) +nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, + const nxt_str_t *str) { nxt_str_t tmp, *ptr; diff --git a/src/nxt_conf.h b/src/nxt_conf.h index 8b3565fd..09f21756 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -115,7 +115,7 @@ 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 void nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str); NXT_EXPORT nxt_int_t nxt_conf_set_string_dup(nxt_conf_value_t *value, - nxt_mp_t *mp, nxt_str_t *str); + 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); -- cgit From e525605d057fd923aa2728babe5b49e95d86d22b Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 18 Dec 2021 21:39:01 +0100 Subject: Added new array APIs that also work with non-arrays. Similar to how C pointers to variables can always be considered as pointers to the first element of an array of size 1 (see the following code for an example of how they are equivalent), treating non-NXT_CONF_VALUE_ARRAY as if they were NXT_CONF_VALUE_ARRAYs of size 1 allows for simpler and more generic code. void foo(ptrdiff_t sz, int arr[sz]) { for (ptrdiff_t i = 0; i < sz; i++) arr[i] = 0; } void bar(void) { int x; int y[1]; foo(1, &x); foo(1, y); } nxt_conf_array_elements_count_or_1(): Similar to nxt_conf_array_elements_count(). Return a size of 1 when input is non-array, instead of causing undefined behavior. That value (1) makes sense because it will be used as the limiter of a loop that loops over the array and calls nxt_conf_get_array_element_or_itself(), which will return a correct element for such loops. nxt_conf_get_array_element_or_itself(): Similar to nxt_conf_get_array_element(). Return the input pointer unmodified (i.e., a pointer to the unique element of a hypothetical array), instead of returning NULL, which wasn't very useful. nxt_conf_array_qsort(): Since it's a no-op for non-arrays, this API can be reused. --- src/nxt_conf.c | 26 ++++++++++++++++++++++++++ src/nxt_conf.h | 4 ++++ 2 files changed, 30 insertions(+) (limited to 'src') diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 8546e2b7..79e776a0 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -392,6 +392,13 @@ nxt_conf_array_elements_count(nxt_conf_value_t *value) } +nxt_uint_t +nxt_conf_array_elements_count_or_1(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) { @@ -750,6 +757,25 @@ nxt_conf_get_array_element(nxt_conf_value_t *value, uint32_t index) } +nxt_conf_value_t * +nxt_conf_get_array_element_or_itself(nxt_conf_value_t *value, uint32_t index) +{ + nxt_conf_array_t *array; + + if (value->type != NXT_CONF_VALUE_ARRAY) { + return (index == 0) ? value : NULL; + } + + array = value->u.array; + + if (index >= array->count) { + return NULL; + } + + return &array->elements[index]; +} + + void nxt_conf_array_qsort(nxt_conf_value_t *value, int (*compare)(const void *, const void *)) diff --git a/src/nxt_conf.h b/src/nxt_conf.h index 09f21756..cfbc5991 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -87,6 +87,8 @@ 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); +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); @@ -139,6 +141,8 @@ void 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_EXPORT nxt_uint_t nxt_conf_array_elements_count(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, int (*compare)(const void *, const void *)); -- cgit From bce0f432c402ad18718aecab227b663160682ea4 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 18 Dec 2021 22:58:27 +0100 Subject: Removed special cases for non-NXT_CONF_VALUE_ARRAY. The previous commit added more generic APIs for handling NXT_CONF_VALUE_ARRAY and non-NXT_CONF_VALUE_ARRAY together. Modify calling code to remove special cases for arrays and non-arrays, taking special care that the path for non arrays is logically equivalent to the previous special cased code. Use the now-generic array code only. --- src/nxt_http_route.c | 51 ++++++------------------------------------------- src/nxt_http_static.c | 28 ++++++--------------------- src/nxt_openssl.c | 24 ++++++----------------- src/nxt_router.c | 24 +++++++---------------- src/python/nxt_python.c | 13 ++----------- 5 files changed, 27 insertions(+), 113 deletions(-) (limited to 'src') diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 606bf266..9add051b 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -718,13 +718,11 @@ nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp, { size_t size; uint32_t i, n; - nxt_bool_t array; nxt_conf_value_t *ruleset_cv; nxt_http_route_table_t *table; nxt_http_route_ruleset_t *ruleset; - array = (nxt_conf_type(table_cv) == NXT_CONF_ARRAY); - n = array ? nxt_conf_array_elements_count(table_cv) : 1; + n = nxt_conf_array_elements_count_or_1(table_cv); size = sizeof(nxt_http_route_table_t) + n * sizeof(nxt_http_route_ruleset_t *); @@ -736,20 +734,8 @@ nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp, table->items = n; table->object = NXT_HTTP_ROUTE_TABLE; - if (!array) { - ruleset = nxt_http_route_ruleset_create(task, mp, table_cv, object, - case_sensitive, encoding); - if (nxt_slow_path(ruleset == NULL)) { - return NULL; - } - - table->ruleset[0] = ruleset; - - return table; - } - for (i = 0; i < n; i++) { - ruleset_cv = nxt_conf_get_array_element(table_cv, i); + ruleset_cv = nxt_conf_get_array_element_or_itself(table_cv, i); ruleset = nxt_http_route_ruleset_create(task, mp, ruleset_cv, object, case_sensitive, encoding); @@ -911,13 +897,11 @@ nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp, size_t size; uint32_t i, n; nxt_int_t ret; - nxt_bool_t string; nxt_conf_value_t *value; nxt_http_route_rule_t *rule; nxt_http_route_pattern_t *pattern; - string = (nxt_conf_type(cv) != NXT_CONF_ARRAY); - n = string ? 1 : nxt_conf_array_elements_count(cv); + n = nxt_conf_array_elements_count_or_1(cv); size = sizeof(nxt_http_route_rule_t) + n * sizeof(nxt_http_route_pattern_t); rule = nxt_mp_alloc(mp, size); @@ -929,22 +913,11 @@ nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp, pattern = &rule->pattern[0]; - if (string) { - pattern[0].case_sensitive = case_sensitive; - ret = nxt_http_route_pattern_create(task, mp, cv, &pattern[0], - pattern_case, encoding); - if (nxt_slow_path(ret != NXT_OK)) { - return NULL; - } - - return rule; - } - nxt_conf_array_qsort(cv, nxt_http_pattern_compare); for (i = 0; i < n; i++) { pattern[i].case_sensitive = case_sensitive; - value = nxt_conf_get_array_element(cv, i); + value = nxt_conf_get_array_element_or_itself(cv, i); ret = nxt_http_route_pattern_create(task, mp, value, &pattern[i], pattern_case, encoding); @@ -963,13 +936,11 @@ nxt_http_route_addr_rule_create(nxt_task_t *task, nxt_mp_t *mp, { size_t size; uint32_t i, n; - nxt_bool_t array; nxt_conf_value_t *value; nxt_http_route_addr_rule_t *addr_rule; nxt_http_route_addr_pattern_t *pattern; - array = (nxt_conf_type(cv) == NXT_CONF_ARRAY); - n = array ? nxt_conf_array_elements_count(cv) : 1; + n = nxt_conf_array_elements_count_or_1(cv); size = sizeof(nxt_http_route_addr_rule_t) + n * sizeof(nxt_http_route_addr_pattern_t); @@ -981,19 +952,9 @@ nxt_http_route_addr_rule_create(nxt_task_t *task, nxt_mp_t *mp, addr_rule->items = n; - if (!array) { - pattern = &addr_rule->addr_pattern[0]; - - if (nxt_http_route_addr_pattern_parse(mp, pattern, cv) != NXT_OK) { - return NULL; - } - - return addr_rule; - } - for (i = 0; i < n; i++) { pattern = &addr_rule->addr_pattern[i]; - value = nxt_conf_get_array_element(cv, i); + value = nxt_conf_get_array_element_or_itself(cv, i); if (nxt_http_route_addr_pattern_parse(mp, pattern, value) != NXT_OK) { return NULL; diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 36c1ebc9..5231f98e 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -77,7 +77,6 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_mp_t *mp; nxt_str_t str; nxt_var_t *var; - nxt_bool_t array; nxt_conf_value_t *cv; nxt_http_static_conf_t *conf; @@ -91,39 +90,24 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, action->handler = nxt_http_static; action->u.conf = conf; - array = (nxt_conf_type(acf->share) == NXT_CONF_ARRAY); - conf->nshares = array ? nxt_conf_array_elements_count(acf->share) : 1; - + conf->nshares = nxt_conf_array_elements_count_or_1(acf->share); conf->shares = nxt_mp_zget(mp, sizeof(nxt_http_static_share_t) * conf->nshares); if (nxt_slow_path(conf->shares == NULL)) { return NXT_ERROR; } - if (array) { - for (i = 0; i < conf->nshares; i++) { - cv = nxt_conf_get_array_element(acf->share, i); - nxt_conf_get_string(cv, &str); - - var = nxt_var_compile(&str, mp, 1); - if (nxt_slow_path(var == NULL)) { - return NXT_ERROR; - } - - conf->shares[i].var = var; - conf->shares[i].is_const = nxt_var_is_const(var); - } - - } else { - nxt_conf_get_string(acf->share, &str); + for (i = 0; i < conf->nshares; i++) { + cv = nxt_conf_get_array_element_or_itself(acf->share, i); + nxt_conf_get_string(cv, &str); var = nxt_var_compile(&str, mp, 1); if (nxt_slow_path(var == NULL)) { return NXT_ERROR; } - conf->shares[0].var = var; - conf->shares[0].is_const = nxt_var_is_const(var); + conf->shares[i].var = var; + conf->shares[i].is_const = nxt_var_is_const(var); } #if (NXT_HAVE_OPENAT2) diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index 1e08015e..59c58b2b 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -644,16 +644,10 @@ nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init, return NXT_OK; } - if (nxt_conf_type(tickets_conf) == NXT_CONF_ARRAY) { - count = nxt_conf_array_elements_count(tickets_conf); + count = nxt_conf_array_elements_count_or_1(tickets_conf); - if (count == 0) { - goto no_ticket; - } - - } else { - /* nxt_conf_type(tickets_conf) == NXT_CONF_STRING */ - count = 1; + if (count == 0) { + goto no_ticket; } #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB @@ -673,15 +667,9 @@ nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init, i++; - if (nxt_conf_type(tickets_conf) == NXT_CONF_ARRAY) { - member = nxt_conf_get_array_element(tickets_conf, count - i); - if (member == NULL) { - break; - } - - } else { - /* nxt_conf_type(tickets_conf) == NXT_CONF_STRING */ - member = tickets_conf; + member = nxt_conf_get_array_element_or_itself(tickets_conf, count - i); + if (member == NULL) { + break; } nxt_conf_get_string(member, &value); diff --git a/src/nxt_router.c b/src/nxt_router.c index 52ea0f37..3a32a363 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1924,25 +1924,15 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, tls_init->tickets_conf = nxt_conf_get_path(listener, &conf_tickets); - if (nxt_conf_type(certificate) == NXT_CONF_ARRAY) { - n = nxt_conf_array_elements_count(certificate); + n = nxt_conf_array_elements_count_or_1(certificate); - for (i = 0; i < n; i++) { - value = nxt_conf_get_array_element(certificate, i); - - nxt_assert(value != NULL); - - ret = nxt_router_conf_tls_insert(tmcf, value, skcf, - tls_init, i == 0); - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } - } + for (i = 0; i < n; i++) { + value = nxt_conf_get_array_element_or_itself(certificate, + i); + nxt_assert(value != NULL); - } else { - /* NXT_CONF_STRING */ - ret = nxt_router_conf_tls_insert(tmcf, certificate, skcf, - tls_init, 1); + ret = nxt_router_conf_tls_insert(tmcf, value, skcf, + tls_init, i == 0); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c index 8687c869..188c4920 100644 --- a/src/python/nxt_python.c +++ b/src/python/nxt_python.c @@ -411,15 +411,8 @@ nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value) /* sys is a Borrowed reference. */ - if (nxt_conf_type(value) == NXT_CONF_STRING) { - n = 0; - goto value_is_string; - } - - /* NXT_CONF_ARRAY */ array = value; - - n = nxt_conf_array_elements_count(array); + n = nxt_conf_array_elements_count_or_1(array); while (n != 0) { n--; @@ -430,9 +423,7 @@ nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value) * specified in the "path" option. */ - value = nxt_conf_get_array_element(array, n); - - value_is_string: + value = nxt_conf_get_array_element_or_itself(array, n); nxt_conf_get_string(value, &str); -- cgit From a3d19f71a205d31ce141dcfd8880f7ed13bd65e5 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 19 Dec 2021 00:58:18 +0100 Subject: Fixed indentation. Some lines (incorrectly) had an indentation of 3 or 5, or 7 or 9, or 11 or 13, or 15 or 17 spaces instead of 4, 8, 12, or 16. Fix them. Found with: $ find src -type f | xargs grep -n '^ [^ ]'; $ find src -type f | xargs grep -n '^ [^ *]'; $ find src -type f | xargs grep -n '^ [^ ]'; $ find src -type f | xargs grep -n '^ [^ *]'; $ find src -type f | xargs grep -n '^ [^ +]'; $ find src -type f | xargs grep -n '^ [^ *+]'; $ find src -type f | xargs grep -n '^ [^ +]'; $ find src -type f | xargs grep -n '^ [^ *+]'; --- .../nginx/unit/websocket/WsRemoteEndpointImplBase.java | 2 +- src/nxt_clone.c | 2 +- src/nxt_conf_validation.c | 6 +++--- src/nxt_gnutls.c | 4 ++-- src/nxt_h1proto.c | 10 +++++----- src/nxt_http.h | 14 +++++++------- src/nxt_http_route.c | 4 ++-- src/nxt_main_process.c | 2 +- src/nxt_mp.c | 16 ++++++++-------- src/nxt_time_parse.c | 6 +++--- src/nxt_unit.c | 4 ++-- src/nxt_work_queue.h | 4 ++-- src/perl/nxt_perl_psgi.c | 2 +- 13 files changed, 38 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java b/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java index 776124fd..d451db7d 100644 --- a/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java +++ b/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java @@ -1175,7 +1175,7 @@ public abstract class WsRemoteEndpointImplBase implements RemoteEndpoint { } else if (state == State.WRITER_WRITING) { // NO-OP. Leave state as is. } else if (state == State.STREAM_WRITING) { - // NO-OP. Leave state as is. + // NO-OP. Leave state as is. } else { // Should never happen // The if ... else ... blocks above should cover all states diff --git a/src/nxt_clone.c b/src/nxt_clone.c index 9ee3c012..aa952a54 100644 --- a/src/nxt_clone.c +++ b/src/nxt_clone.c @@ -384,7 +384,7 @@ nxt_clone_vldt_credential_gidmap(nxt_task_t *task, } return NXT_OK; - } + } base_ok = 0; gids_ok = 0; diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 3f068bbb..4dd46dd8 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -114,7 +114,7 @@ static nxt_int_t nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, static nxt_int_t nxt_conf_vldt_return(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_share(nxt_conf_validation_t *vldt, - nxt_conf_value_t *value, void *data); + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_share_element(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt, @@ -194,7 +194,7 @@ static nxt_int_t nxt_conf_vldt_java_classpath(nxt_conf_validation_t *vldt, static nxt_int_t nxt_conf_vldt_java_option(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_upstream(nxt_conf_validation_t *vldt, - nxt_str_t *name, nxt_conf_value_t *value); + nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_server(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_server_weight(nxt_conf_validation_t *vldt, @@ -2448,7 +2448,7 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, break; } - } + } ret = nxt_conf_vldt_type(vldt, &name, member, vals->type); if (ret != NXT_OK) { diff --git a/src/nxt_gnutls.c b/src/nxt_gnutls.c index 4618dce9..aab4699c 100644 --- a/src/nxt_gnutls.c +++ b/src/nxt_gnutls.c @@ -708,11 +708,11 @@ nxt_gnutls_log_error_level(nxt_event_conn_t *c, ssize_t err) case GNUTLS_E_UNKNOWN_CIPHER_SUITE: /* -21 */ - /* Disable gnutls_bye(), because it returns GNUTLS_E_INTERNAL_ERROR. */ + /* Disable gnutls_bye(), because it returns GNUTLS_E_INTERNAL_ERROR. */ ssltls = c->u.ssltls; ssltls->no_shutdown = 1; - /* Fall through. */ + /* Fall through. */ case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: /* -9 */ c->socket.error = 1000; /* Nonexistent errno code. */ diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index b683cb22..d3340774 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -1881,11 +1881,11 @@ nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data) #define NXT_H1P_IDLE_TIMEOUT \ - "HTTP/1.1 408 Request Timeout\r\n" \ - "Server: " NXT_SERVER "\r\n" \ - "Connection: close\r\n" \ - "Content-Length: 0\r\n" \ - "Date: " + "HTTP/1.1 408 Request Timeout\r\n" \ + "Server: " NXT_SERVER "\r\n" \ + "Connection: close\r\n" \ + "Content-Length: 0\r\n" \ + "Date: " static void diff --git a/src/nxt_http.h b/src/nxt_http.h index 02d66f58..7cef1345 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -90,17 +90,17 @@ typedef union { #define nxt_http_field_name_set(_field, _name) \ do { \ - (_field)->name_length = nxt_length(_name); \ - (_field)->name = (u_char *) _name; \ + (_field)->name_length = nxt_length(_name); \ + (_field)->name = (u_char *) _name; \ } while (0) #define nxt_http_field_set(_field, _name, _value) \ do { \ - (_field)->name_length = nxt_length(_name); \ - (_field)->value_length = nxt_length(_value); \ - (_field)->name = (u_char *) _name; \ - (_field)->value = (u_char *) _value; \ + (_field)->name_length = nxt_length(_name); \ + (_field)->value_length = nxt_length(_value); \ + (_field)->name = (u_char *) _name; \ + (_field)->value = (u_char *) _value; \ } while (0) @@ -238,7 +238,7 @@ typedef struct { void (*body_read)(nxt_task_t *task, nxt_http_request_t *r); void (*local_addr)(nxt_task_t *task, nxt_http_request_t *r); void (*header_send)(nxt_task_t *task, nxt_http_request_t *r, - nxt_work_handler_t body_handler, void *data); + nxt_work_handler_t body_handler, void *data); void (*send)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out); nxt_off_t (*body_bytes_sent)(nxt_task_t *task, nxt_http_proto_t proto); void (*discard)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *last); diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 9add051b..c2321906 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -932,7 +932,7 @@ nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp, nxt_http_route_addr_rule_t * nxt_http_route_addr_rule_create(nxt_task_t *task, nxt_mp_t *mp, - nxt_conf_value_t *cv) + nxt_conf_value_t *cv) { size_t size; uint32_t i, n; @@ -2294,7 +2294,7 @@ nxt_http_route_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end) name = NULL; start = p + 1; - } + } } if (name != NULL) { diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 9883f04c..03761a10 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -579,7 +579,7 @@ nxt_main_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) -1, msg->port_msg.stream, 0, NULL); return; } - } + } #endif diff --git a/src/nxt_mp.c b/src/nxt_mp.c index 4eaa16d0..d0de2c0e 100644 --- a/src/nxt_mp.c +++ b/src/nxt_mp.c @@ -939,12 +939,12 @@ nxt_mp_chunk_free(nxt_mp_t *mp, nxt_mp_block_t *cluster, u_char *p) page = cluster->pages; do { - if (page->size != 0) { - return NULL; - } + if (page->size != 0) { + return NULL; + } - page++; - n--; + page++; + n--; } while (n != 0); /* Free cluster. */ @@ -953,9 +953,9 @@ nxt_mp_chunk_free(nxt_mp_t *mp, nxt_mp_block_t *cluster, u_char *p) page = cluster->pages; do { - nxt_queue_remove(&page->link); - page++; - n--; + nxt_queue_remove(&page->link); + page++; + n--; } while (n != 0); nxt_rbtree_delete(&mp->blocks, &cluster->node); diff --git a/src/nxt_time_parse.c b/src/nxt_time_parse.c index 5a32b213..94c43289 100644 --- a/src/nxt_time_parse.c +++ b/src/nxt_time_parse.c @@ -282,9 +282,9 @@ nxt_time_parse(const u_char *p, size_t len) days = days - 719527 + 31 + 28; s = (uint64_t) days * 86400 - + (nxt_uint_t) hour * 3600 - + (nxt_uint_t) min * 60 - + (nxt_uint_t) sec; + + (nxt_uint_t) hour * 3600 + + (nxt_uint_t) min * 60 + + (nxt_uint_t) sec; #if (NXT_TIME_T_SIZE <= 4) diff --git a/src/nxt_unit.c b/src/nxt_unit.c index dac612b8..32bb07ab 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -5114,9 +5114,9 @@ nxt_unit_ctx_alloc(nxt_unit_ctx_t *ctx, void *data) rc = nxt_unit_ctx_init(lib, new_ctx, data); if (nxt_slow_path(rc != NXT_UNIT_OK)) { - nxt_unit_free(ctx, new_ctx); + nxt_unit_free(ctx, new_ctx); - return NULL; + return NULL; } queue_fd = -1; diff --git a/src/nxt_work_queue.h b/src/nxt_work_queue.h index 6c2d6c23..ffa21d27 100644 --- a/src/nxt_work_queue.h +++ b/src/nxt_work_queue.h @@ -16,12 +16,12 @@ struct nxt_task_s { uint32_t ident; nxt_work_t *next_work; - /* TODO: exception_handler, prev/next task, subtasks. */ + /* TODO: exception_handler, prev/next task, subtasks. */ }; #define nxt_task_next_ident() \ - ((uint32_t) nxt_atomic_fetch_add(&nxt_task_ident, 1) & 0x3FFFFFFF) + ((uint32_t) nxt_atomic_fetch_add(&nxt_task_ident, 1) & 0x3FFFFFFF) /* diff --git a/src/perl/nxt_perl_psgi.c b/src/perl/nxt_perl_psgi.c index 749ebd80..08a6f29e 100644 --- a/src/perl/nxt_perl_psgi.c +++ b/src/perl/nxt_perl_psgi.c @@ -612,7 +612,7 @@ nxt_perl_psgi_env_create(PerlInterpreter *my_perl, do { \ if (nxt_slow_path((FNS) != NXT_UNIT_OK)) \ goto fail; \ - } while (0) + } while (0) #define NL(S) (S), sizeof(S)-1 -- cgit From 0b79735b503cc0a35062799a8ac45f169f0af0f7 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 11 Mar 2022 01:59:24 +0100 Subject: Added NXT_MAYBE_UNUSED for __attribute__((__unused__)). When testing some configurations of compilers and OSes, I noticed that clang(1) 13 on Debian caused a function to be compiled but unused, and the compiler triggered a compile error. To avoid that error, use __attribute__((__unused__)). Let's call our wrapper NXT_MAYBE_UNUSED, since it describes itself more precisely than the GCC attribute name. It's also the name that C2x (likely C23) has given to the standard attribute, which is [[maybe_unused]], so it's also likely to be more readable because of that name being in ISO C. --- src/nxt_clang.h | 11 +++++++++++ src/nxt_conf_validation.c | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_clang.h b/src/nxt_clang.h index a10de08a..26afba7a 100644 --- a/src/nxt_clang.h +++ b/src/nxt_clang.h @@ -132,6 +132,17 @@ nxt_prefetch(a) #endif +#if (NXT_HAVE_GCC_ATTRIBUTE_UNUSED) + +#define NXT_MAYBE_UNUSED __attribute__((__unused__)) + +#else + +#define NXT_MAYBE_UNUSED + +#endif + + #if (NXT_HAVE_BUILTIN_POPCOUNT) #define nxt_popcount __builtin_popcount diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 4dd46dd8..876c5bbc 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -77,7 +77,8 @@ static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt, static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_str_t *value); nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt, - nxt_conf_value_t *value, void *data); + nxt_conf_value_t *value, void *data) + NXT_MAYBE_UNUSED; static nxt_int_t nxt_conf_vldt_mtypes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); -- cgit From 6fb7777ce73ba529327d307ca0722e66a7cb9262 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 5 Apr 2022 11:47:56 +0200 Subject: Supporting variables in "location". ............ Description: ............ Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations: - "location" contains no variables: In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time. - "location" contains variables: In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string. In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding. ........... Usefulness: ........... An example of why this feature may be useful is redirecting HTTP to HTTPS with something like: "action": { "return": 301, "location": "https://${host}${uri}" } ..... Bugs: ..... This feature conflicts with the relevant RFCs in the following: '$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'. ...... Notes: ...... An empty string is handled as if "location" wasn't specified at all, so no Location header is sent. This is incorrect, and the code is slightly misleading. The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2]. [1]: [2]: Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly. I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string. ................. Testing (manual): ................. { "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } } $ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0 $ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0 $ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0 $ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0 $ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0 $ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0 $ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0 $ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0 $ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0 $ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0 --- src/nxt_conf_validation.c | 1 + src/nxt_http_return.c | 183 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 147 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 876c5bbc..1b97bd0a 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -635,6 +635,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_return_action_members[] = { }, { .name = nxt_string("location"), .type = NXT_CONF_VLDT_STRING, + .flags = NXT_CONF_VLDT_VAR, }, NXT_CONF_VLDT_END diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index 18fd490d..92dfa465 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -8,13 +8,26 @@ typedef struct { - nxt_http_status_t status; - nxt_str_t location; + nxt_http_status_t status; + nxt_var_t *location; + nxt_str_t encoded; + uint8_t loc_is_const; } nxt_http_return_conf_t; +typedef struct { + nxt_http_action_t *action; + nxt_str_t location; + nxt_str_t encoded; +} nxt_http_return_ctx_t; + + 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_var_error(nxt_task_t *task, void *obj, void *data); static const nxt_http_request_state_t nxt_http_return_send_state; @@ -24,8 +37,8 @@ nxt_int_t nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, nxt_http_action_conf_t *acf) { - nxt_str_t *loc; - nxt_uint_t encode; + nxt_str_t str; + nxt_var_t *var; nxt_http_return_conf_t *conf; conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t)); @@ -38,30 +51,22 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, conf->status = nxt_conf_get_number(acf->ret); - if (acf->location.length > 0) { - if (nxt_is_complex_uri_encoded(acf->location.start, - acf->location.length)) - { - loc = nxt_str_dup(mp, &conf->location, &acf->location); - if (nxt_slow_path(loc == NULL)) { - return NXT_ERROR; - } - - } else { - loc = &conf->location; - - encode = nxt_encode_complex_uri(NULL, acf->location.start, - acf->location.length); - loc->length = acf->location.length + encode * 2; - - loc->start = nxt_mp_nget(mp, loc->length); - if (nxt_slow_path(loc->start == NULL)) { - return NXT_ERROR; - } - - nxt_encode_complex_uri(loc->start, acf->location.start, - acf->location.length); - } + if (acf->location.length == 0) { + conf->loc_is_const = 1; + return NXT_OK; + } + + var = nxt_var_compile(&acf->location, mp, 0); + if (nxt_slow_path(var == NULL)) { + return NXT_ERROR; + } + + conf->location = var; + conf->loc_is_const = nxt_var_is_const(var); + + if (conf->loc_is_const) { + nxt_var_raw(conf->location, &str); + return nxt_http_return_encode(mp, &conf->encoded, &str); } return NXT_OK; @@ -72,13 +77,21 @@ nxt_http_action_t * nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action) { - nxt_http_field_t *field; + nxt_int_t ret; + nxt_str_t loc; + nxt_http_return_ctx_t *ctx; nxt_http_return_conf_t *conf; conf = action->u.conf; - nxt_debug(task, "http return: %d (loc: \"%V\")", - conf->status, &conf->location); + if (conf->location == NULL) { + nxt_str_null(&loc); + + } else { + nxt_var_raw(conf->location, &loc); + } + + nxt_debug(task, "http return: %d (loc: \"%V\")", conf->status, &loc); if (conf->status >= NXT_HTTP_BAD_REQUEST && conf->status <= NXT_HTTP_SERVER_ERROR_MAX) @@ -87,27 +100,123 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, return NULL; } + ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_return_ctx_t)); + if (nxt_slow_path(ctx == NULL)) { + goto fail; + } + + ctx->action = action; r->status = conf->status; r->resp.content_length_n = 0; - if (conf->location.length > 0) { + if (conf->loc_is_const) { + ctx->encoded = conf->encoded; + + nxt_http_return_send_ready(task, r, ctx); + + } else { + ret = nxt_var_query_init(&r->var_query, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + + nxt_var_query(task, r->var_query, conf->location, &ctx->location); + + nxt_var_query_resolve(task, r->var_query, ctx, + nxt_http_return_send_ready, + nxt_http_return_var_error); + } + + return NULL; + +fail: + + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + return NULL; +} + + +static nxt_int_t +nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded, + const nxt_str_t *location) +{ + nxt_uint_t encode; + + if (nxt_is_complex_uri_encoded(location->start, location->length)) { + *encoded = *location; + + return NXT_OK; + } + + encode = nxt_encode_complex_uri(NULL, location->start, location->length); + encoded->length = location->length + encode * 2; + + encoded->start = nxt_mp_nget(mp, encoded->length); + if (nxt_slow_path(encoded->start == NULL)) { + return NXT_ERROR; + } + + nxt_encode_complex_uri(encoded->start, location->start, location->length); + + return NXT_OK; +} + + +static void +nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) +{ + nxt_int_t ret; + nxt_http_field_t *field; + nxt_http_action_t *action; + nxt_http_request_t *r; + nxt_http_return_ctx_t *ctx; + nxt_http_return_conf_t *conf; + + r = obj; + ctx = data; + action = ctx->action; + conf = action->u.conf; + + if (!conf->loc_is_const) { + ret = nxt_http_return_encode(r->mem_pool, &ctx->encoded, + &ctx->location); + if (nxt_slow_path(ret == NXT_ERROR)) { + goto fail; + } + } + + if (ctx->encoded.length > 0) { field = nxt_list_zero_add(r->resp.fields); if (nxt_slow_path(field == NULL)) { - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); - return NULL; + goto fail; } nxt_http_field_name_set(field, "Location"); - field->value = conf->location.start; - field->value_length = conf->location.length; + field->value = ctx->encoded.start; + field->value_length = ctx->encoded.length; } r->state = &nxt_http_return_send_state; nxt_http_request_header_send(task, r, NULL, NULL); - return NULL; + return; + +fail: + + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); +} + + +static void +nxt_http_return_var_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); } -- cgit From 952bcc50bfc5bd651a56fd97aa6f1f3c3e214071 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 30 Apr 2022 19:20:23 +0200 Subject: Fixed #define style. We had a mix of styles for declaring function-like macros: Style A: #define \ foo() \ do { \ ... \ } while (0) Style B: #define foo() \ do { \ ... \ } while (0) We had a similar number of occurences of each style: $ grep -rnI '^\w*(.*\\' | wc -l 244 $ grep -rn 'define.*(.*)' | wc -l 239 (Those regexes aren't perfect, but a very decent approximation.) Real examples: $ find src -type f | xargs sed -n '/^nxt_double_is_zero/,/^$/p' nxt_double_is_zero(f) \ (fabs(f) <= FLT_EPSILON) $ find src -type f | xargs sed -n '/define nxt_http_field_set/,/^$/p' #define nxt_http_field_set(_field, _name, _value) \ do { \ (_field)->name_length = nxt_length(_name); \ (_field)->value_length = nxt_length(_value); \ (_field)->name = (u_char *) _name; \ (_field)->value = (u_char *) _value; \ } while (0) I'd like to standardize on a single style for them, and IMO, having the identifier in the same line as #define is a better option for the following reasons: - Programmers are used to `#define foo() ...` (readability). - One less line of code. - The program for finding them is really simple (see below). function grep_ngx_func() { if (($# != 1)); then >&2 echo "Usage: ${FUNCNAME[0]} "; return 1; fi; find src -type f \ | grep '\.[ch]$' \ | xargs grep -l "$1" \ | sort \ | xargs pcregrep -Mn "(?s)^\$[\w\s*]+?^$1\(.*?^}"; find src -type f \ | grep '\.[ch]$' \ | xargs grep -l "$1" \ | sort \ | xargs pcregrep -Mn "(?s)define $1\(.*?^$" \ | sed -E '1s/^[^:]+:[0-9]+:/&\n\n/'; } $ grep_ngx_func Usage: grep_ngx_func $ grep_ngx_func nxt_http_field_set src/nxt_http.h:98: #define nxt_http_field_set(_field, _name, _value) \ do { \ (_field)->name_length = nxt_length(_name); \ (_field)->value_length = nxt_length(_value); \ (_field)->name = (u_char *) _name; \ (_field)->value = (u_char *) _value; \ } while (0) $ grep_ngx_func nxt_sprintf src/nxt_sprintf.c:56: u_char * nxt_cdecl nxt_sprintf(u_char *buf, u_char *end, const char *fmt, ...) { u_char *p; va_list args; va_start(args, fmt); p = nxt_vsprintf(buf, end, fmt, args); va_end(args); return p; } ................ Scripted change: ................ $ find src -type f \ | grep '\.[ch]$' \ | xargs sed -i '/define *\\$/{N;s/ *\\\n/ /;s/ //}' --- src/nxt_array.h | 9 ++--- src/nxt_atomic.h | 60 +++++++++++--------------------- src/nxt_buf.h | 84 +++++++++++++++------------------------------ src/nxt_buf_pool.h | 15 +++----- src/nxt_cache.c | 3 +- src/nxt_clang.h | 66 ++++++++++++----------------------- src/nxt_djb_hash.h | 3 +- src/nxt_dyld.h | 3 +- src/nxt_errno.h | 12 +++---- src/nxt_event_engine.h | 36 +++++++------------ src/nxt_fastcgi_source.c | 3 +- src/nxt_fd_event.h | 6 ++-- src/nxt_fiber.c | 3 +- src/nxt_file.h | 39 +++++++-------------- src/nxt_http_chunk_parse.c | 3 +- src/nxt_http_parse.c | 3 +- src/nxt_job.h | 9 ++--- src/nxt_list.h | 12 +++---- src/nxt_log.h | 21 ++++-------- src/nxt_log_moderation.h | 6 ++-- src/nxt_lvlhsh.c | 69 +++++++++++++------------------------ src/nxt_lvlhsh.h | 6 ++-- src/nxt_malloc.h | 27 +++++---------- src/nxt_mem_map.h | 9 ++--- src/nxt_mem_zone.c | 27 +++++---------- src/nxt_mem_zone.h | 3 +- src/nxt_queue.h | 60 +++++++++++--------------------- src/nxt_service.h | 3 +- src/nxt_signal.h | 6 ++-- src/nxt_socket.h | 6 ++-- src/nxt_source.h | 3 +- src/nxt_sprintf.c | 3 +- src/nxt_string.h | 69 +++++++++++++------------------------ src/nxt_thread.h | 33 ++++++------------ src/nxt_thread_id.h | 6 ++-- src/nxt_thread_time.h | 9 ++--- src/nxt_time.h | 12 +++---- src/nxt_unix.h | 12 +++---- src/nxt_vector.h | 9 ++--- src/nxt_work_queue.h | 3 +- src/test/nxt_rbtree1_test.c | 6 ++-- 41 files changed, 259 insertions(+), 518 deletions(-) (limited to 'src') diff --git a/src/nxt_array.h b/src/nxt_array.h index 8318fccd..f06ff14c 100644 --- a/src/nxt_array.h +++ b/src/nxt_array.h @@ -35,18 +35,15 @@ NXT_EXPORT void nxt_array_remove(nxt_array_t *array, void *elt); NXT_EXPORT nxt_array_t *nxt_array_copy(nxt_mp_t *mp, nxt_array_t *dst, nxt_array_t *src); -#define \ -nxt_array_last(array) \ +#define nxt_array_last(array) \ nxt_pointer_to((array)->elts, (array)->size * ((array)->nelts - 1)) -#define \ -nxt_array_reset(array) \ +#define nxt_array_reset(array) \ (array)->nelts = 0; -#define \ -nxt_array_is_empty(array) \ +#define nxt_array_is_empty(array) \ ((array)->nelts == 0) diff --git a/src/nxt_atomic.h b/src/nxt_atomic.h index 9e2e5ec1..cd2e7253 100644 --- a/src/nxt_atomic.h +++ b/src/nxt_atomic.h @@ -26,28 +26,23 @@ typedef volatile nxt_atomic_uint_t nxt_atomic_t; * __sync_lock_release() is a release barrier. */ -#define \ -nxt_atomic_cmp_set(lock, cmp, set) \ +#define nxt_atomic_cmp_set(lock, cmp, set) \ __sync_bool_compare_and_swap(lock, cmp, set) -#define \ -nxt_atomic_xchg(lock, set) \ +#define nxt_atomic_xchg(lock, set) \ __sync_lock_test_and_set(lock, set) -#define \ -nxt_atomic_fetch_add(value, add) \ +#define nxt_atomic_fetch_add(value, add) \ __sync_fetch_and_add(value, add) -#define \ -nxt_atomic_try_lock(lock) \ +#define nxt_atomic_try_lock(lock) \ nxt_atomic_cmp_set(lock, 0, 1) -#define \ -nxt_atomic_release(lock) \ +#define nxt_atomic_release(lock) \ __sync_lock_release(lock) @@ -60,13 +55,11 @@ nxt_atomic_release(lock) \ #if (__i386__ || __i386 || __amd64__ || __amd64) -#define \ -nxt_cpu_pause() \ +#define nxt_cpu_pause() \ __asm__ ("pause") #else -#define \ -nxt_cpu_pause() +#define nxt_cpu_pause() #endif @@ -79,18 +72,15 @@ typedef ulong_t nxt_atomic_uint_t; typedef volatile nxt_atomic_uint_t nxt_atomic_t; -#define \ -nxt_atomic_cmp_set(lock, cmp, set) \ +#define nxt_atomic_cmp_set(lock, cmp, set) \ (atomic_cas_ulong(lock, cmp, set) == (ulong_t) cmp) -#define \ -nxt_atomic_xchg(lock, set) \ +#define nxt_atomic_xchg(lock, set) \ atomic_add_swap(lock, set) -#define \ -nxt_atomic_fetch_add(value, add) \ +#define nxt_atomic_fetch_add(value, add) \ (atomic_add_long_nv(value, add) - add) @@ -124,13 +114,11 @@ nxt_atomic_fetch_add(value, add) \ * barrier. */ -#define \ -nxt_atomic_try_lock(lock) \ +#define nxt_atomic_try_lock(lock) \ nxt_atomic_cmp_set(lock, 0, 1) -#define \ -nxt_atomic_release(lock) \ +#define nxt_atomic_release(lock) \ *lock = 0; @@ -142,13 +130,11 @@ nxt_atomic_release(lock) \ */ #if (__i386__ || __i386 || __amd64__ || __amd64) -#define \ -nxt_cpu_pause() \ +#define nxt_cpu_pause() \ __asm__ ("rep; nop") #else -#define \ -nxt_cpu_pause() +#define nxt_cpu_pause() #endif @@ -192,13 +178,11 @@ nxt_atomic_cmp_set(nxt_atomic_t *lock, nxt_atomic_int_t cmp, } -#define \ -nxt_atomic_xchg(lock, set) \ +#define nxt_atomic_xchg(lock, set) \ __fetch_and_swaplp(lock, set) -#define \ -nxt_atomic_fetch_add(value, add) \ +#define nxt_atomic_fetch_add(value, add) \ __fetch_and_addlp(value, add) @@ -221,13 +205,11 @@ nxt_atomic_cmp_set(nxt_atomic_t *lock, nxt_atomic_int_t cmp, } -#define \ -nxt_atomic_xchg(lock, set) \ +#define nxt_atomic_xchg(lock, set) \ __fetch_and_swap(lock, set) -#define \ -nxt_atomic_fetch_add(value, add) \ +#define nxt_atomic_fetch_add(value, add) \ __fetch_and_add(value, add) @@ -270,13 +252,11 @@ nxt_atomic_try_lock(nxt_atomic_t *lock) } -#define \ -nxt_atomic_release(lock) \ +#define nxt_atomic_release(lock) \ do { __lwsync(); *lock = 0; } while (0) -#define \ -nxt_cpu_pause() +#define nxt_cpu_pause() #endif /* NXT_HAVE_XLC_ATOMIC */ diff --git a/src/nxt_buf.h b/src/nxt_buf.h index 5121d659..f1e2879f 100644 --- a/src/nxt_buf.h +++ b/src/nxt_buf.h @@ -113,127 +113,100 @@ struct nxt_buf_s { #define NXT_BUF_SYNC_LAST 4 -#define \ -nxt_buf_is_mem(b) \ +#define nxt_buf_is_mem(b) \ ((b)->mem.pos != NULL) -#define \ -nxt_buf_is_file(b) \ +#define nxt_buf_is_file(b) \ ((b)->is_file) -#define \ -nxt_buf_set_file(b) \ +#define nxt_buf_set_file(b) \ (b)->is_file = 1 -#define \ -nxt_buf_clear_file(b) \ +#define nxt_buf_clear_file(b) \ (b)->is_file = 0 -#define \ -nxt_buf_is_mmap(b) \ +#define nxt_buf_is_mmap(b) \ ((b)->is_mmap) -#define \ -nxt_buf_set_mmap(b) \ +#define nxt_buf_set_mmap(b) \ (b)->is_mmap = 1 -#define \ -nxt_buf_clear_mmap(b) \ +#define nxt_buf_clear_mmap(b) \ (b)->is_mmap = 0 -#define \ -nxt_buf_is_port_mmap(b) \ +#define nxt_buf_is_port_mmap(b) \ ((b)->is_port_mmap) -#define \ -nxt_buf_set_port_mmap(b) \ +#define nxt_buf_set_port_mmap(b) \ (b)->is_port_mmap = 1 -#define \ -nxt_buf_clear_port_mmap(b) \ +#define nxt_buf_clear_port_mmap(b) \ (b)->is_port_mmap = 0 -#define \ -nxt_buf_is_sync(b) \ +#define nxt_buf_is_sync(b) \ ((b)->is_sync) -#define \ -nxt_buf_set_sync(b) \ +#define nxt_buf_set_sync(b) \ (b)->is_sync = 1 -#define \ -nxt_buf_clear_sync(b) \ +#define nxt_buf_clear_sync(b) \ (b)->is_sync = 0 -#define \ -nxt_buf_is_nobuf(b) \ +#define nxt_buf_is_nobuf(b) \ ((b)->is_nobuf) -#define \ -nxt_buf_set_nobuf(b) \ +#define nxt_buf_set_nobuf(b) \ (b)->is_nobuf = 1 -#define \ -nxt_buf_clear_nobuf(b) \ +#define nxt_buf_clear_nobuf(b) \ (b)->is_nobuf = 0 -#define \ -nxt_buf_is_flush(b) \ +#define nxt_buf_is_flush(b) \ ((b)->is_flush) -#define \ -nxt_buf_set_flush(b) \ +#define nxt_buf_set_flush(b) \ (b)->is_flush = 1 -#define \ -nxt_buf_clear_flush(b) \ +#define nxt_buf_clear_flush(b) \ (b)->is_flush = 0 -#define \ -nxt_buf_is_last(b) \ +#define nxt_buf_is_last(b) \ ((b)->is_last) -#define \ -nxt_buf_set_last(b) \ +#define nxt_buf_set_last(b) \ (b)->is_last = 1 -#define \ -nxt_buf_clear_last(b) \ +#define nxt_buf_clear_last(b) \ (b)->is_last = 0 -#define \ -nxt_buf_mem_set_size(bm, size) \ +#define nxt_buf_mem_set_size(bm, size) \ do { \ (bm)->start = 0; \ (bm)->end = (void *) size; \ } while (0) -#define \ -nxt_buf_mem_size(bm) \ +#define nxt_buf_mem_size(bm) \ ((bm)->end - (bm)->start) -#define \ -nxt_buf_mem_used_size(bm) \ +#define nxt_buf_mem_used_size(bm) \ ((bm)->free - (bm)->pos) -#define \ -nxt_buf_mem_free_size(bm) \ +#define nxt_buf_mem_free_size(bm) \ ((bm)->end - (bm)->free) -#define \ -nxt_buf_used_size(b) \ +#define nxt_buf_used_size(b) \ (nxt_buf_is_file(b) ? (b)->file_end - (b)->file_pos: \ nxt_buf_mem_used_size(&(b)->mem)) @@ -264,8 +237,7 @@ nxt_buf_chk_make_plain(nxt_mp_t *mp, nxt_buf_t *src, size_t size) return src; } -#define \ -nxt_buf_free(mp, b) \ +#define nxt_buf_free(mp, b) \ nxt_mp_free((mp), (b)) diff --git a/src/nxt_buf_pool.h b/src/nxt_buf_pool.h index 6a04fd7e..3d22d7fa 100644 --- a/src/nxt_buf_pool.h +++ b/src/nxt_buf_pool.h @@ -42,8 +42,7 @@ NXT_EXPORT void nxt_buf_pool_destroy(nxt_buf_pool_t *bp); /* There is ready free buffer. */ -#define \ -nxt_buf_pool_ready(bp) \ +#define nxt_buf_pool_ready(bp) \ ((bp)->free != NULL \ || ((bp)->current != NULL \ && (bp)->current->mem.free < (bp)->current->mem.end)) @@ -51,29 +50,25 @@ nxt_buf_pool_ready(bp) \ /* A free buffer is allowed to be allocated. */ -#define \ -nxt_buf_pool_obtainable(bp) \ +#define nxt_buf_pool_obtainable(bp) \ ((bp)->num < (bp)->max) /* There is ready free buffer or it is allowed to be allocated. */ -#define \ -nxt_buf_pool_available(bp) \ +#define nxt_buf_pool_available(bp) \ (nxt_buf_pool_obtainable(bp) || nxt_buf_pool_ready(bp)) /* Reserve allocation of "n" free buffers as they were allocated. */ -#define \ -nxt_buf_pool_reserve(bp, n) \ +#define nxt_buf_pool_reserve(bp, n) \ (bp)->num += (n) /* Release a reservation. */ -#define \ -nxt_buf_pool_release(bp, n) \ +#define nxt_buf_pool_release(bp, n) \ (bp)->num -= (n) diff --git a/src/nxt_cache.c b/src/nxt_cache.c index 409ba301..e81d63dc 100644 --- a/src/nxt_cache.c +++ b/src/nxt_cache.c @@ -8,8 +8,7 @@ /* A cache time resolution is 10ms. */ -#define \ -nxt_cache_time(thr) \ +#define nxt_cache_time(thr) \ (uint64_t) (nxt_thread_time(thr) * 100) diff --git a/src/nxt_clang.h b/src/nxt_clang.h index 26afba7a..94638346 100644 --- a/src/nxt_clang.h +++ b/src/nxt_clang.h @@ -16,45 +16,37 @@ #if (NXT_CLANG) /* Any __asm__ directive disables loop vectorization in GCC and Clang. */ -#define \ -nxt_pragma_loop_disable_vectorization \ +#define nxt_pragma_loop_disable_vectorization \ __asm__("") #else -#define \ -nxt_pragma_loop_disable_vectorization +#define nxt_pragma_loop_disable_vectorization #endif #if (NXT_HAVE_BUILTIN_EXPECT) -#define \ -nxt_expect(c, x) \ +#define nxt_expect(c, x) \ __builtin_expect((long) (x), (c)) -#define \ -nxt_fast_path(x) \ +#define nxt_fast_path(x) \ nxt_expect(1, x) -#define \ -nxt_slow_path(x) \ +#define nxt_slow_path(x) \ nxt_expect(0, x) #else -#define \ -nxt_expect(c, x) \ +#define nxt_expect(c, x) \ (x) -#define \ -nxt_fast_path(x) \ +#define nxt_fast_path(x) \ (x) -#define \ -nxt_slow_path(x) \ +#define nxt_slow_path(x) \ (x) #endif @@ -62,28 +54,24 @@ nxt_slow_path(x) \ #if (NXT_HAVE_BUILTIN_UNREACHABLE) -#define \ -nxt_unreachable() \ +#define nxt_unreachable() \ __builtin_unreachable() #else -#define \ -nxt_unreachable() +#define nxt_unreachable() #endif #if (NXT_HAVE_BUILTIN_PREFETCH) -#define \ -nxt_prefetch(a) \ +#define nxt_prefetch(a) \ __builtin_prefetch(a) #else -#define \ -nxt_prefetch(a) +#define nxt_prefetch(a) #endif @@ -206,13 +194,11 @@ nxt_popcount(unsigned int x) #endif -#define \ -nxt_alloca(size) \ +#define nxt_alloca(size) \ alloca(size) -#define \ -nxt_container_of(p, type, field) \ +#define nxt_container_of(p, type, field) \ (type *) ((u_char *) (p) - offsetof(type, field)) @@ -224,30 +210,25 @@ nxt_container_of(p, type, field) \ *(type *) ((u_char *) p + offset) -#define \ -nxt_nitems(x) \ +#define nxt_nitems(x) \ (sizeof(x) / sizeof((x)[0])) /* GCC and Clang use __builtin_abs() instead of libc abs(). */ -#define \ -nxt_abs(val) \ +#define nxt_abs(val) \ abs(val) -#define \ -nxt_max(val1, val2) \ +#define nxt_max(val1, val2) \ ((val1 < val2) ? (val2) : (val1)) -#define \ -nxt_min(val1, val2) \ +#define nxt_min(val1, val2) \ ((val1 > val2) ? (val2) : (val1)) -#define \ -nxt_bswap32(val) \ +#define nxt_bswap32(val) \ ( ((val) >> 24) \ | (((val) & 0x00FF0000) >> 8) \ | (((val) & 0x0000FF00) << 8) \ @@ -258,18 +239,15 @@ nxt_bswap32(val) \ ((((value) - 1) & (value)) == 0) -#define \ -nxt_align_size(d, a) \ +#define nxt_align_size(d, a) \ (((d) + ((size_t) (a) - 1)) & ~((size_t) (a) - 1)) -#define \ -nxt_align_ptr(p, a) \ +#define nxt_align_ptr(p, a) \ (u_char *) (((uintptr_t) (p) + ((uintptr_t) (a) - 1)) \ & ~((uintptr_t) (a) - 1)) -#define \ -nxt_trunc_ptr(p, a) \ +#define nxt_trunc_ptr(p, a) \ (u_char *) ((uintptr_t) (p) & ~((uintptr_t) (a) - 1)) diff --git a/src/nxt_djb_hash.h b/src/nxt_djb_hash.h index c7ba6fdb..43395e6a 100644 --- a/src/nxt_djb_hash.h +++ b/src/nxt_djb_hash.h @@ -18,8 +18,7 @@ NXT_EXPORT uint32_t nxt_djb_hash_lowcase(const void *data, size_t len); #define NXT_DJB_HASH_INIT 5381 -#define \ -nxt_djb_hash_add(hash, val) \ +#define nxt_djb_hash_add(hash, val) \ ((uint32_t) ((((hash) << 5) + (hash)) ^ (uint32_t) (val))) diff --git a/src/nxt_dyld.h b/src/nxt_dyld.h index a0cbeda3..65ce1874 100644 --- a/src/nxt_dyld.h +++ b/src/nxt_dyld.h @@ -17,8 +17,7 @@ typedef struct { #define NXT_DYLD_ANY RTLD_DEFAULT -#define \ -nxt_dyld_is_valid(dyld) \ +#define nxt_dyld_is_valid(dyld) \ ((dyld)->handle != NULL) diff --git a/src/nxt_errno.h b/src/nxt_errno.h index ec700537..f19d50ba 100644 --- a/src/nxt_errno.h +++ b/src/nxt_errno.h @@ -65,20 +65,16 @@ typedef int nxt_err_t; #define NXT_DONE (-4) -#define \ -nxt_errno \ +#define nxt_errno \ errno -#define \ -nxt_socket_errno \ +#define nxt_socket_errno \ errno -#define \ -nxt_set_errno(err) \ +#define nxt_set_errno(err) \ errno = err -#define \ -nxt_set_socket_errno(err) \ +#define nxt_set_socket_errno(err) \ errno = err diff --git a/src/nxt_event_engine.h b/src/nxt_event_engine.h index 6b05d510..91cfc0aa 100644 --- a/src/nxt_event_engine.h +++ b/src/nxt_event_engine.h @@ -351,43 +351,35 @@ void nxt_fd_event_hash_delete(nxt_task_t *task, nxt_lvlhsh_t *lvlhsh, void nxt_fd_event_hash_destroy(nxt_lvlhsh_t *lvlhsh); -#define \ -nxt_fd_event_disable(engine, ev) \ +#define nxt_fd_event_disable(engine, ev) \ (engine)->event.disable(engine, ev) -#define \ -nxt_fd_event_delete(engine, ev) \ +#define nxt_fd_event_delete(engine, ev) \ (engine)->event.delete(engine, ev) -#define \ -nxt_fd_event_close(engine, ev) \ +#define nxt_fd_event_close(engine, ev) \ (engine)->event.close(engine, ev) -#define \ -nxt_fd_event_enable_read(engine, ev) \ +#define nxt_fd_event_enable_read(engine, ev) \ (engine)->event.enable_read(engine, ev) -#define \ -nxt_fd_event_enable_write(engine, ev) \ +#define nxt_fd_event_enable_write(engine, ev) \ (engine)->event.enable_write(engine, ev) -#define \ -nxt_fd_event_disable_read(engine, ev) \ +#define nxt_fd_event_disable_read(engine, ev) \ (engine)->event.disable_read(engine, ev) -#define \ -nxt_fd_event_disable_write(engine, ev) \ +#define nxt_fd_event_disable_write(engine, ev) \ (engine)->event.disable_write(engine, ev) -#define \ -nxt_fd_event_block_read(engine, ev) \ +#define nxt_fd_event_block_read(engine, ev) \ do { \ if (nxt_fd_event_is_active((ev)->read)) { \ (engine)->event.block_read(engine, ev); \ @@ -395,8 +387,7 @@ nxt_fd_event_block_read(engine, ev) \ } while (0) -#define \ -nxt_fd_event_block_write(engine, ev) \ +#define nxt_fd_event_block_write(engine, ev) \ do { \ if (nxt_fd_event_is_active((ev)->write)) { \ (engine)->event.block_write(engine, ev); \ @@ -404,18 +395,15 @@ nxt_fd_event_block_write(engine, ev) \ } while (0) -#define \ -nxt_fd_event_oneshot_read(engine, ev) \ +#define nxt_fd_event_oneshot_read(engine, ev) \ (engine)->event.oneshot_read(engine, ev) -#define \ -nxt_fd_event_oneshot_write(engine, ev) \ +#define nxt_fd_event_oneshot_write(engine, ev) \ (engine)->event.oneshot_write(engine, ev) -#define \ -nxt_fd_event_enable_accept(engine, ev) \ +#define nxt_fd_event_enable_accept(engine, ev) \ (engine)->event.enable_accept(engine, ev) diff --git a/src/nxt_fastcgi_source.c b/src/nxt_fastcgi_source.c index b1be3303..b2424292 100644 --- a/src/nxt_fastcgi_source.c +++ b/src/nxt_fastcgi_source.c @@ -18,8 +18,7 @@ typedef struct { } nxt_fastcgi_param_t; -#define \ -nxt_fastcgi_set_record_length(p, length) \ +#define nxt_fastcgi_set_record_length(p, length) \ do { \ uint32_t len = length; \ \ diff --git a/src/nxt_fd_event.h b/src/nxt_fd_event.h index 762fdf25..3a8d9460 100644 --- a/src/nxt_fd_event.h +++ b/src/nxt_fd_event.h @@ -44,13 +44,11 @@ typedef enum { } nxt_fd_event_state_t; -#define \ -nxt_fd_event_is_disabled(state) \ +#define nxt_fd_event_is_disabled(state) \ ((state) < NXT_EVENT_ONESHOT) -#define \ -nxt_fd_event_is_active(state) \ +#define nxt_fd_event_is_active(state) \ ((state) >= NXT_EVENT_ONESHOT) diff --git a/src/nxt_fiber.c b/src/nxt_fiber.c index 2312c855..d6cac893 100644 --- a/src/nxt_fiber.c +++ b/src/nxt_fiber.c @@ -14,8 +14,7 @@ static void nxt_fiber_switch(nxt_task_t *task, nxt_fiber_t *fib); static void nxt_fiber_timer_handler(nxt_task_t *task, void *obj, void *data); -#define \ -nxt_fiber_enqueue(thr, task, fib) \ +#define nxt_fiber_enqueue(thr, task, fib) \ nxt_work_queue_add(&(thr)->engine->fast_work_queue, \ nxt_fiber_switch_handler, task, fib, NULL) diff --git a/src/nxt_file.h b/src/nxt_file.h index 4846305b..07c7a22b 100644 --- a/src/nxt_file.h +++ b/src/nxt_file.h @@ -27,23 +27,19 @@ typedef struct { } nxt_file_name_str_t; -#define \ -nxt_file_name_str_set(file_name, mem_pool, name) \ +#define nxt_file_name_str_set(file_name, mem_pool, name) \ ((file_name) = (nxt_file_name_t *) (name), NXT_OK) -#define \ -nxt_file_name_alloc(mem_pool, len) \ +#define nxt_file_name_alloc(mem_pool, len) \ nxt_mp_nget(mem_pool, len) -#define \ -nxt_file_name_copy(dst, src, len) \ +#define nxt_file_name_copy(dst, src, len) \ nxt_cpymem(dst, src, len) -#define \ -nxt_file_name_add(dst, src, len) \ +#define nxt_file_name_add(dst, src, len) \ nxt_cpymem(dst, src, len) @@ -51,21 +47,18 @@ nxt_file_name_add(dst, src, len) \ /* MacOSX, Cygwin. */ -#define \ -nxt_file_name_eq(fn1, fn2) \ +#define nxt_file_name_eq(fn1, fn2) \ (nxt_strcasecmp(fn1, fn2) == 0) #else -#define \ -nxt_file_name_eq(fn1, fn2) \ +#define nxt_file_name_eq(fn1, fn2) \ (nxt_strcmp(fn1, fn2) == 0) #endif -#define \ -nxt_file_name_is_absolute(name) \ +#define nxt_file_name_is_absolute(name) \ (name[0] == '/') @@ -168,20 +161,16 @@ NXT_EXPORT void nxt_file_read_ahead(nxt_file_t *file, nxt_off_t offset, NXT_EXPORT nxt_int_t nxt_file_info(nxt_file_t *file, nxt_file_info_t *fi); -#define \ -nxt_is_dir(fi) \ +#define nxt_is_dir(fi) \ (S_ISDIR((fi)->st_mode)) -#define \ -nxt_is_file(fi) \ +#define nxt_is_file(fi) \ (S_ISREG((fi)->st_mode)) -#define \ -nxt_file_size(fi) \ +#define nxt_file_size(fi) \ (fi)->st_size -#define \ -nxt_file_mtime(fi) \ +#define nxt_file_mtime(fi) \ (fi)->st_mtime @@ -206,12 +195,10 @@ NXT_EXPORT nxt_int_t nxt_stderr_start(void); #define nxt_stderr STDERR_FILENO -#define \ -nxt_write_console(fd, buf, size) \ +#define nxt_write_console(fd, buf, size) \ write(fd, buf, size) -#define \ -nxt_write_syslog(priority, message) \ +#define nxt_write_syslog(priority, message) \ syslog(priority, "%s", message) diff --git a/src/nxt_http_chunk_parse.c b/src/nxt_http_chunk_parse.c index deab116d..b60bc801 100644 --- a/src/nxt_http_chunk_parse.c +++ b/src/nxt_http_chunk_parse.c @@ -12,8 +12,7 @@ #define NXT_HTTP_CHUNK_END 2 -#define \ -nxt_size_is_sufficient(cs) \ +#define nxt_size_is_sufficient(cs) \ (cs < ((__typeof__(cs)) 1 << (sizeof(cs) * 8 - 4))) diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 338b0a90..1ab6cc90 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -827,8 +827,7 @@ nxt_http_parse_field_end(nxt_http_request_parse_t *rp, u_char **pos, } -#define \ -nxt_http_is_normal(c) \ +#define nxt_http_is_normal(c) \ (nxt_fast_path((nxt_http_normal[c / 8] & (1 << (c & 7))) != 0)) diff --git a/src/nxt_job.h b/src/nxt_job.h index d308c35d..0495c484 100644 --- a/src/nxt_job.h +++ b/src/nxt_job.h @@ -67,21 +67,18 @@ NXT_EXPORT void nxt_job_return(nxt_task_t *task, nxt_job_t *job, nxt_work_handler_t handler); -#define \ -nxt_job_cancel(job) \ +#define nxt_job_cancel(job) \ (job)->cancel = 1 #if (NXT_DEBUG) -#define \ -nxt_job_set_name(job, text) \ +#define nxt_job_set_name(job, text) \ (job)->name = text #else -#define \ -nxt_job_set_name(job, text) +#define nxt_job_set_name(job, text) #endif diff --git a/src/nxt_list.h b/src/nxt_list.h index ecbb67a9..dc948e03 100644 --- a/src/nxt_list.h +++ b/src/nxt_list.h @@ -37,18 +37,15 @@ typedef struct { } nxt_list_next_t; -#define \ -nxt_list_part(list) \ +#define nxt_list_part(list) \ (&(list)->part) -#define \ -nxt_list_data(part) \ +#define nxt_list_data(part) \ ((void *) part->data) -#define \ -nxt_list_first(list) \ +#define nxt_list_first(list) \ nxt_list_data(nxt_list_part(list)) @@ -102,8 +99,7 @@ NXT_EXPORT void *nxt_list_zero_add(nxt_list_t *list); NXT_EXPORT void *nxt_list_next(nxt_list_t *list, nxt_list_next_t *next); -#define \ -nxt_list_next_value(list, next) \ +#define nxt_list_next_value(list, next) \ (nxt_pointer_to(nxt_list_data((next)->part), (next)->elt * (list)->size)) diff --git a/src/nxt_log.h b/src/nxt_log.h index 0cf10b5c..aa2fe673 100644 --- a/src/nxt_log.h +++ b/src/nxt_log.h @@ -41,8 +41,7 @@ NXT_EXPORT void nxt_cdecl nxt_log_handler(nxt_uint_t level, nxt_log_t *log, const char *fmt, ...); -#define \ -nxt_log_level_enough(log, level) \ +#define nxt_log_level_enough(log, level) \ ((log)->level >= (level)) @@ -83,8 +82,7 @@ nxt_log_level_enough(log, level) \ } while (0) -#define \ -nxt_log_error(_level, _log, ...) \ +#define nxt_log_error(_level, _log, ...) \ do { \ nxt_log_t *_log_ = (_log); \ nxt_uint_t _level_ = (_level); \ @@ -107,8 +105,7 @@ nxt_log_error(_level, _log, ...) \ } while (0) -#define \ -nxt_log_debug(_log, ...) \ +#define nxt_log_debug(_log, ...) \ do { \ nxt_log_t *_log_ = (_log); \ \ @@ -131,8 +128,7 @@ nxt_log_debug(_log, ...) \ #define nxt_debug(...) -#define \ -nxt_log_debug(...) +#define nxt_log_debug(...) #define nxt_assert(c) @@ -151,18 +147,15 @@ nxt_log_debug(...) #endif -#define \ -nxt_main_log_alert(...) \ +#define nxt_main_log_alert(...) \ nxt_log_alert(&nxt_main_log, __VA_ARGS__) -#define \ -nxt_main_log_error(level, ...) \ +#define nxt_main_log_error(level, ...) \ nxt_log_error(level, &nxt_main_log, __VA_ARGS__) -#define \ -nxt_main_log_debug(...) \ +#define nxt_main_log_debug(...) \ nxt_log_debug(&nxt_main_log, __VA_ARGS__) diff --git a/src/nxt_log_moderation.h b/src/nxt_log_moderation.h index 0a53594d..c6033201 100644 --- a/src/nxt_log_moderation.h +++ b/src/nxt_log_moderation.h @@ -23,8 +23,7 @@ typedef struct { #define NXT_LOG_MODERATION 0, -1, 0, 0, NXT_TIMER -#define \ -nxt_log_alert_moderate(_mod, _log, ...) \ +#define nxt_log_alert_moderate(_mod, _log, ...) \ do { \ nxt_log_t *_log_ = _log; \ \ @@ -34,8 +33,7 @@ nxt_log_alert_moderate(_mod, _log, ...) \ } while (0) -#define \ -nxt_log_moderate(_mod, _level, _log, ...) \ +#define nxt_log_moderate(_mod, _level, _log, ...) \ do { \ nxt_log_t *_log_ = _log; \ \ diff --git a/src/nxt_lvlhsh.c b/src/nxt_lvlhsh.c index d10dbc58..7a8b3dda 100644 --- a/src/nxt_lvlhsh.c +++ b/src/nxt_lvlhsh.c @@ -43,121 +43,98 @@ * several levels. */ -#define \ -nxt_lvlhsh_is_bucket(p) \ +#define nxt_lvlhsh_is_bucket(p) \ ((uintptr_t) (p) & 1) -#define \ -nxt_lvlhsh_count_inc(n) \ +#define nxt_lvlhsh_count_inc(n) \ n = (void *) ((uintptr_t) (n) + 2) -#define \ -nxt_lvlhsh_count_dec(n) \ +#define nxt_lvlhsh_count_dec(n) \ n = (void *) ((uintptr_t) (n) - 2) -#define \ -nxt_lvlhsh_level_size(proto, nlvl) \ +#define nxt_lvlhsh_level_size(proto, nlvl) \ ((uintptr_t) 1 << proto->shift[nlvl]) -#define \ -nxt_lvlhsh_level(lvl, mask) \ +#define nxt_lvlhsh_level(lvl, mask) \ (void **) ((uintptr_t) lvl & (~mask << 2)) -#define \ -nxt_lvlhsh_level_entries(lvl, mask) \ +#define nxt_lvlhsh_level_entries(lvl, mask) \ ((uintptr_t) lvl & (mask << 1)) -#define \ -nxt_lvlhsh_store_bucket(slot, bkt) \ +#define nxt_lvlhsh_store_bucket(slot, bkt) \ slot = (void **) ((uintptr_t) bkt | 2 | 1) -#define \ -nxt_lvlhsh_bucket_size(proto) \ +#define nxt_lvlhsh_bucket_size(proto) \ proto->bucket_size -#define \ -nxt_lvlhsh_bucket(proto, bkt) \ +#define nxt_lvlhsh_bucket(proto, bkt) \ (uint32_t *) ((uintptr_t) bkt & ~(uintptr_t) proto->bucket_mask) -#define \ -nxt_lvlhsh_bucket_entries(proto, bkt) \ +#define nxt_lvlhsh_bucket_entries(proto, bkt) \ (((uintptr_t) bkt & (uintptr_t) proto->bucket_mask) >> 1) -#define \ -nxt_lvlhsh_bucket_end(proto, bkt) \ +#define nxt_lvlhsh_bucket_end(proto, bkt) \ &bkt[proto->bucket_end] -#define \ -nxt_lvlhsh_free_entry(e) \ +#define nxt_lvlhsh_free_entry(e) \ (!(nxt_lvlhsh_valid_entry(e))) -#define \ -nxt_lvlhsh_next_bucket(proto, bkt) \ +#define nxt_lvlhsh_next_bucket(proto, bkt) \ ((void **) &bkt[proto->bucket_end]) #if (NXT_64BIT) -#define \ -nxt_lvlhsh_valid_entry(e) \ +#define nxt_lvlhsh_valid_entry(e) \ (((e)[0] | (e)[1]) != 0) -#define \ -nxt_lvlhsh_entry_value(e) \ +#define nxt_lvlhsh_entry_value(e) \ (void *) (((uintptr_t) (e)[1] << 32) + (e)[0]) -#define \ -nxt_lvlhsh_set_entry_value(e, n) \ +#define nxt_lvlhsh_set_entry_value(e, n) \ (e)[0] = (uint32_t) (uintptr_t) n; \ (e)[1] = (uint32_t) ((uintptr_t) n >> 32) -#define \ -nxt_lvlhsh_entry_key(e) \ +#define nxt_lvlhsh_entry_key(e) \ (e)[2] -#define \ -nxt_lvlhsh_set_entry_key(e, n) \ +#define nxt_lvlhsh_set_entry_key(e, n) \ (e)[2] = n #else -#define \ -nxt_lvlhsh_valid_entry(e) \ +#define nxt_lvlhsh_valid_entry(e) \ ((e)[0] != 0) -#define \ -nxt_lvlhsh_entry_value(e) \ +#define nxt_lvlhsh_entry_value(e) \ (void *) (e)[0] -#define \ -nxt_lvlhsh_set_entry_value(e, n) \ +#define nxt_lvlhsh_set_entry_value(e, n) \ (e)[0] = (uint32_t) n -#define \ -nxt_lvlhsh_entry_key(e) \ +#define nxt_lvlhsh_entry_key(e) \ (e)[1] -#define \ -nxt_lvlhsh_set_entry_key(e, n) \ +#define nxt_lvlhsh_set_entry_key(e, n) \ (e)[1] = n #endif diff --git a/src/nxt_lvlhsh.h b/src/nxt_lvlhsh.h index 7127c0d0..c051081c 100644 --- a/src/nxt_lvlhsh.h +++ b/src/nxt_lvlhsh.h @@ -114,13 +114,11 @@ typedef struct { } nxt_lvlhsh_each_t; -#define \ -nxt_lvlhsh_is_empty(lh) \ +#define nxt_lvlhsh_is_empty(lh) \ ((lh)->slot == NULL) -#define \ -nxt_lvlhsh_init(lh) \ +#define nxt_lvlhsh_init(lh) \ (lh)->slot = NULL /* diff --git a/src/nxt_malloc.h b/src/nxt_malloc.h index ccc3e1ef..fd5493a5 100644 --- a/src/nxt_malloc.h +++ b/src/nxt_malloc.h @@ -24,8 +24,7 @@ NXT_EXPORT void nxt_free(void *p); #else -#define \ -nxt_free(p) \ +#define nxt_free(p) \ free(p) #endif @@ -54,12 +53,10 @@ nxt_free(p) \ * Glibc malloc_usable_size() is fast operation. */ -#define \ -nxt_malloc_usable_size(p, size) \ +#define nxt_malloc_usable_size(p, size) \ size = malloc_usable_size(p) -#define \ -nxt_malloc_cutback(cutback, size) \ +#define nxt_malloc_cutback(cutback, size) \ size = ((cutback) && size > 127 * 1024) ? size - 32 : size #elif (NXT_FREEBSD) @@ -81,12 +78,10 @@ nxt_malloc_cutback(cutback, size) \ * are lesser than 1M. Larger allocations require mutex acquiring. */ -#define \ -nxt_malloc_usable_size(p, size) \ +#define nxt_malloc_usable_size(p, size) \ size = malloc_usable_size(p) -#define \ -nxt_malloc_cutback(cutback, size) +#define nxt_malloc_cutback(cutback, size) #endif @@ -103,20 +98,16 @@ nxt_malloc_cutback(cutback, size) * malloc_good_size() is faster than malloc_size() */ -#define \ -nxt_malloc_usable_size(p, size) \ +#define nxt_malloc_usable_size(p, size) \ size = malloc_good_size(size) -#define \ -nxt_malloc_cutback(cutback, size) +#define nxt_malloc_cutback(cutback, size) #else -#define \ -nxt_malloc_usable_size(p, size) +#define nxt_malloc_usable_size(p, size) -#define \ -nxt_malloc_cutback(cutback, size) +#define nxt_malloc_cutback(cutback, size) #endif diff --git a/src/nxt_mem_map.h b/src/nxt_mem_map.h index a4a10cc4..e529aff8 100644 --- a/src/nxt_mem_map.h +++ b/src/nxt_mem_map.h @@ -43,17 +43,14 @@ #define NXT_MEM_MAP_FILE (MAP_SHARED | NXT_MEM_MAP_PREFAULT) -#define \ - nxt_mem_map_file_ctx_t(ctx) +#define nxt_mem_map_file_ctx_t(ctx) -#define \ -nxt_mem_map(addr, ctx, len, protection, flags, fd, offset) \ +#define nxt_mem_map(addr, ctx, len, protection, flags, fd, offset) \ nxt_mem_mmap(addr, len, protection, flags, fd, offset) -#define \ -nxt_mem_unmap(addr, ctx, len) \ +#define nxt_mem_unmap(addr, ctx, len) \ nxt_mem_munmap(addr, len) diff --git a/src/nxt_mem_zone.c b/src/nxt_mem_zone.c index 67c6d746..f8ab09d9 100644 --- a/src/nxt_mem_zone.c +++ b/src/nxt_mem_zone.c @@ -87,48 +87,39 @@ struct nxt_mem_zone_s { }; -#define \ -nxt_mem_zone_page_addr(zone, page) \ +#define nxt_mem_zone_page_addr(zone, page) \ (void *) (zone->start + ((page - zone->pages) << zone->page_size_shift)) -#define \ -nxt_mem_zone_addr_page(zone, addr) \ +#define nxt_mem_zone_addr_page(zone, addr) \ &zone->pages[((u_char *) addr - zone->start) >> zone->page_size_shift] -#define \ -nxt_mem_zone_page_is_free(page) \ +#define nxt_mem_zone_page_is_free(page) \ (page->size < NXT_MEM_ZONE_PAGE_USED) -#define \ -nxt_mem_zone_page_is_chunked(page) \ +#define nxt_mem_zone_page_is_chunked(page) \ (page->size >= 16) -#define \ -nxt_mem_zone_page_bitmap(zone, slot) \ +#define nxt_mem_zone_page_bitmap(zone, slot) \ (slot->size < zone->small_bitmap_min_size) -#define \ -nxt_mem_zone_set_chunk_free(map, chunk) \ +#define nxt_mem_zone_set_chunk_free(map, chunk) \ map[chunk / 8] &= ~(0x80 >> (chunk & 7)) -#define \ -nxt_mem_zone_chunk_is_free(map, chunk) \ +#define nxt_mem_zone_chunk_is_free(map, chunk) \ ((map[chunk / 8] & (0x80 >> (chunk & 7))) == 0) -#define \ -nxt_mem_zone_fresh_junk(p, size) \ +#define nxt_mem_zone_fresh_junk(p, size) \ nxt_memset((p), 0xA5, size) -#define \ -nxt_mem_zone_free_junk(p, size) \ +#define nxt_mem_zone_free_junk(p, size) \ nxt_memset((p), 0x5A, size) diff --git a/src/nxt_mem_zone.h b/src/nxt_mem_zone.h index 3f078c2d..89d73ca2 100644 --- a/src/nxt_mem_zone.h +++ b/src/nxt_mem_zone.h @@ -14,8 +14,7 @@ typedef struct nxt_mem_zone_s nxt_mem_zone_t; NXT_EXPORT nxt_mem_zone_t *nxt_mem_zone_init(u_char *start, size_t zone_size, nxt_uint_t page_size); -#define \ -nxt_mem_zone_alloc(zone, size) \ +#define nxt_mem_zone_alloc(zone, size) \ nxt_mem_zone_align((zone), 1, (size)) NXT_EXPORT void *nxt_mem_zone_align(nxt_mem_zone_t *zone, size_t alignment, diff --git a/src/nxt_queue.h b/src/nxt_queue.h index 44e9ad61..6b7f5d57 100644 --- a/src/nxt_queue.h +++ b/src/nxt_queue.h @@ -21,16 +21,14 @@ typedef struct { } nxt_queue_t; -#define \ -nxt_queue_init(queue) \ +#define nxt_queue_init(queue) \ do { \ (queue)->head.prev = &(queue)->head; \ (queue)->head.next = &(queue)->head; \ } while (0) -#define \ -nxt_queue_sentinel(link) \ +#define nxt_queue_sentinel(link) \ do { \ (link)->prev = (link); \ (link)->next = (link); \ @@ -42,13 +40,11 @@ nxt_queue_sentinel(link) \ * using nxt_queue_remove(). */ -#define \ -nxt_queue_self(link) \ +#define nxt_queue_self(link) \ nxt_queue_sentinel(link) -#define \ -nxt_queue_is_empty(queue) \ +#define nxt_queue_is_empty(queue) \ (&(queue)->head == (queue)->head.prev) /* @@ -73,38 +69,31 @@ nxt_queue_is_empty(queue) \ * tp = nxt_queue_link_data(lnk, nxt_type_t, link); */ -#define \ -nxt_queue_first(queue) \ +#define nxt_queue_first(queue) \ (queue)->head.next -#define \ -nxt_queue_last(queue) \ +#define nxt_queue_last(queue) \ (queue)->head.prev -#define \ -nxt_queue_head(queue) \ +#define nxt_queue_head(queue) \ (&(queue)->head) -#define \ -nxt_queue_tail(queue) \ +#define nxt_queue_tail(queue) \ (&(queue)->head) -#define \ -nxt_queue_next(link) \ +#define nxt_queue_next(link) \ (link)->next -#define \ -nxt_queue_prev(link) \ +#define nxt_queue_prev(link) \ (link)->prev -#define \ -nxt_queue_insert_head(queue, link) \ +#define nxt_queue_insert_head(queue, link) \ do { \ (link)->next = (queue)->head.next; \ (link)->next->prev = (link); \ @@ -113,8 +102,7 @@ nxt_queue_insert_head(queue, link) \ } while (0) -#define \ -nxt_queue_insert_tail(queue, link) \ +#define nxt_queue_insert_tail(queue, link) \ do { \ (link)->prev = (queue)->head.prev; \ (link)->prev->next = (link); \ @@ -123,8 +111,7 @@ nxt_queue_insert_tail(queue, link) \ } while (0) -#define \ -nxt_queue_insert_after(target, link) \ +#define nxt_queue_insert_after(target, link) \ do { \ (link)->next = (target)->next; \ (link)->next->prev = (link); \ @@ -133,8 +120,7 @@ nxt_queue_insert_after(target, link) \ } while (0) -#define \ -nxt_queue_insert_before(target, link) \ +#define nxt_queue_insert_before(target, link) \ do { \ (link)->next = (target); \ (link)->prev = (target)->prev; \ @@ -145,8 +131,7 @@ nxt_queue_insert_before(target, link) \ #if (NXT_DEBUG) -#define \ -nxt_queue_remove(link) \ +#define nxt_queue_remove(link) \ do { \ (link)->next->prev = (link)->prev; \ (link)->prev->next = (link)->next; \ @@ -156,8 +141,7 @@ nxt_queue_remove(link) \ #else -#define \ -nxt_queue_remove(link) \ +#define nxt_queue_remove(link) \ do { \ (link)->next->prev = (link)->prev; \ (link)->prev->next = (link)->next; \ @@ -171,8 +155,7 @@ nxt_queue_remove(link) \ * the "tail" is the new tail queue. */ -#define \ -nxt_queue_split(queue, link, tail) \ +#define nxt_queue_split(queue, link, tail) \ do { \ (tail)->head.prev = (queue)->head.prev; \ (tail)->head.prev->next = &(tail)->head; \ @@ -185,8 +168,7 @@ nxt_queue_split(queue, link, tail) \ /* Truncate the queue "queue" starting at element "link". */ -#define \ -nxt_queue_truncate(queue, link) \ +#define nxt_queue_truncate(queue, link) \ do { \ (queue)->head.prev = (link)->prev; \ (queue)->head.prev->next = &(queue)->head; \ @@ -199,8 +181,7 @@ nxt_queue_truncate(queue, link) \ * it must be initiated with nxt_queue_init(tail). */ -#define \ -nxt_queue_add(queue, tail) \ +#define nxt_queue_add(queue, tail) \ do { \ (queue)->head.prev->next = (tail)->head.next; \ (tail)->head.next->prev = (queue)->head.prev; \ @@ -209,8 +190,7 @@ nxt_queue_add(queue, tail) \ } while (0) -#define \ -nxt_queue_link_data(lnk, type, link) \ +#define nxt_queue_link_data(lnk, type, link) \ nxt_container_of(lnk, type, link) diff --git a/src/nxt_service.h b/src/nxt_service.h index 55d98351..c43d5394 100644 --- a/src/nxt_service.h +++ b/src/nxt_service.h @@ -15,8 +15,7 @@ typedef struct { } nxt_service_t; -#define \ -nxt_service_is_module(s) \ +#define nxt_service_is_module(s) \ ((s)->type == NULL) diff --git a/src/nxt_signal.h b/src/nxt_signal.h index 900a9e16..bc61eb2f 100644 --- a/src/nxt_signal.h +++ b/src/nxt_signal.h @@ -36,12 +36,10 @@ typedef struct { nxt_event_signals_t *nxt_event_engine_signals(const nxt_sig_event_t *sigev); -#define \ -nxt_event_engine_signals_start(engine) \ +#define nxt_event_engine_signals_start(engine) \ nxt_signal_thread_start(engine) -#define \ -nxt_event_engine_signals_stop(engine) \ +#define nxt_event_engine_signals_stop(engine) \ nxt_signal_thread_stop(engine) diff --git a/src/nxt_socket.h b/src/nxt_socket.h index ec21d779..69b09039 100644 --- a/src/nxt_socket.h +++ b/src/nxt_socket.h @@ -118,12 +118,10 @@ NXT_EXPORT ssize_t nxt_socketpair_recv(nxt_fd_event_t *ev, nxt_iobuf_t *iob, nxt_uint_t niob, void *oob); -#define \ -nxt_socket_nonblocking(task, fd) \ +#define nxt_socket_nonblocking(task, fd) \ nxt_fd_nonblocking(task, fd) -#define \ -nxt_socket_blocking(task, fd) \ +#define nxt_socket_blocking(task, fd) \ nxt_fd_blocking(task, fd) diff --git a/src/nxt_source.h b/src/nxt_source.h index 976cc8f9..0b4658dd 100644 --- a/src/nxt_source.h +++ b/src/nxt_source.h @@ -22,8 +22,7 @@ typedef void (*nxt_source_handler_t)(void *source_context, nxt_source_hook_t *query); -#define \ -nxt_source_filter(thr, wq, task, next, out) \ +#define nxt_source_filter(thr, wq, task, next, out) \ do { \ if (thr->engine->batch != 0) { \ nxt_thread_work_queue_add(thr, wq, nxt_source_filter_handler, \ diff --git a/src/nxt_sprintf.c b/src/nxt_sprintf.c index 9557b327..50705ede 100644 --- a/src/nxt_sprintf.c +++ b/src/nxt_sprintf.c @@ -90,8 +90,7 @@ static u_char *nxt_number(nxt_sprintf_t *spf, u_char *buf, double n); /* A right way of "f == 0.0". */ -#define \ -nxt_double_is_zero(f) \ +#define nxt_double_is_zero(f) \ (fabs(f) <= FLT_EPSILON) diff --git a/src/nxt_string.h b/src/nxt_string.h index 4d565e87..80cdbb59 100644 --- a/src/nxt_string.h +++ b/src/nxt_string.h @@ -8,50 +8,40 @@ #define _NXT_STRING_H_INCLUDED_ -#define \ -nxt_lowcase(c) \ +#define nxt_lowcase(c) \ (u_char) ((c >= 'A' && c <= 'Z') ? c | 0x20 : c) -#define \ -nxt_upcase(c) \ +#define nxt_upcase(c) \ (u_char) ((c >= 'a' && c <= 'z') ? c & ~0x20 : c) -#define \ -nxt_isdigit(c) \ +#define nxt_isdigit(c) \ ((u_char) ((c) - '0') <= 9) -#define \ -nxt_strtod(s, endptr) \ +#define nxt_strtod(s, endptr) \ strtod((char *) s, (char **) endptr) -#define \ -nxt_strlen(s) \ +#define nxt_strlen(s) \ strlen((char *) s) -#define \ -nxt_strdup(s) \ +#define nxt_strdup(s) \ strdup((char *) s) -#define \ -nxt_strchr(buf, delim) \ +#define nxt_strchr(buf, delim) \ (u_char *) strchr((char *) buf, delim) -#define \ -nxt_memzero(buf, length) \ +#define nxt_memzero(buf, length) \ (void) memset(buf, 0, length) -#define \ -nxt_memset(buf, c, length) \ +#define nxt_memset(buf, c, length) \ (void) memset(buf, c, length) -#define \ -nxt_memcpy(dst, src, length) \ +#define nxt_memcpy(dst, src, length) \ (void) memcpy(dst, src, length) @@ -72,28 +62,23 @@ nxt_cpymem(void *dst, const void *src, size_t length) } -#define \ -nxt_memmove(dst, src, length) \ +#define nxt_memmove(dst, src, length) \ (void) memmove(dst, src, length) -#define \ -nxt_memcmp(s1, s2, length) \ +#define nxt_memcmp(s1, s2, length) \ memcmp((char *) s1, (char *) s2, length) -#define \ -nxt_memchr(s, c, length) \ +#define nxt_memchr(s, c, length) \ memchr((char *) s, c, length) -#define \ -nxt_strcmp(s1, s2) \ +#define nxt_strcmp(s1, s2) \ strcmp((char *) s1, (char *) s2) -#define \ -nxt_strncmp(s1, s2, length) \ +#define nxt_strncmp(s1, s2, length) \ strncmp((char *) s1, (char *) s2, length) @@ -125,16 +110,14 @@ typedef struct { #define nxt_null_string { 0, NULL } -#define \ -nxt_str_set(str, text) \ +#define nxt_str_set(str, text) \ do { \ (str)->length = nxt_length(text); \ (str)->start = (u_char *) text; \ } while (0) -#define \ -nxt_str_null(str) \ +#define nxt_str_null(str) \ do { \ (str)->length = 0; \ (str)->start = NULL; \ @@ -147,35 +130,29 @@ NXT_EXPORT nxt_str_t *nxt_str_dup(nxt_mp_t *mp, nxt_str_t *dst, NXT_EXPORT char *nxt_str_cstrz(nxt_mp_t *mp, const nxt_str_t *src); -#define \ -nxt_strstr_eq(s1, s2) \ +#define nxt_strstr_eq(s1, s2) \ (((s1)->length == (s2)->length) \ && (nxt_memcmp((s1)->start, (s2)->start, (s1)->length) == 0)) -#define \ -nxt_strcasestr_eq(s1, s2) \ +#define nxt_strcasestr_eq(s1, s2) \ (((s1)->length == (s2)->length) \ && (nxt_memcasecmp((s1)->start, (s2)->start, (s1)->length) == 0)) -#define \ -nxt_str_eq(s, p, _length) \ +#define nxt_str_eq(s, p, _length) \ (((s)->length == _length) && (nxt_memcmp((s)->start, p, _length) == 0)) -#define \ -nxt_str_start(s, p, _length) \ +#define nxt_str_start(s, p, _length) \ (((s)->length >= _length) && (nxt_memcmp((s)->start, p, _length) == 0)) -#define \ -nxt_strchr_eq(s, c) \ +#define nxt_strchr_eq(s, c) \ (((s)->length == 1) && ((s)->start[0] == c)) -#define \ -nxt_strchr_start(s, c) \ +#define nxt_strchr_start(s, c) \ (((s)->length != 0) && ((s)->start[0] == c)) diff --git a/src/nxt_thread.h b/src/nxt_thread.h index 2ebc331d..53b2d8c0 100644 --- a/src/nxt_thread.h +++ b/src/nxt_thread.h @@ -30,19 +30,15 @@ #if (NXT_HAVE_THREAD_STORAGE_CLASS) -#define \ -nxt_thread_extern_data(type, tsd) \ +#define nxt_thread_extern_data(type, tsd) \ NXT_EXPORT extern __thread type tsd -#define \ -nxt_thread_declare_data(type, tsd) \ +#define nxt_thread_declare_data(type, tsd) \ __thread type tsd -#define \ -nxt_thread_init_data(tsd) +#define nxt_thread_init_data(tsd) -#define \ -nxt_thread_get_data(tsd) \ +#define nxt_thread_get_data(tsd) \ &tsd @@ -67,18 +63,15 @@ typedef struct { } nxt_thread_specific_data_t[1]; -#define \ -nxt_thread_extern_data(type, tsd) \ +#define nxt_thread_extern_data(type, tsd) \ NXT_EXPORT extern nxt_thread_specific_data_t tsd -#define \ -nxt_thread_declare_data(type, tsd) \ +#define nxt_thread_declare_data(type, tsd) \ nxt_thread_specific_data_t tsd = { { (nxt_atomic_int_t) -1, sizeof(type) } } NXT_EXPORT void nxt_thread_init_data(nxt_thread_specific_data_t tsd); -#define \ -nxt_thread_get_data(tsd) \ +#define nxt_thread_get_data(tsd) \ pthread_getspecific((pthread_key_t) tsd->key) #endif @@ -101,8 +94,7 @@ NXT_EXPORT void nxt_thread_cancel(nxt_thread_handle_t handle); NXT_EXPORT void nxt_thread_wait(nxt_thread_handle_t handle); -#define \ -nxt_thread_handle() \ +#define nxt_thread_handle() \ pthread_self() @@ -125,18 +117,15 @@ NXT_EXPORT nxt_err_t nxt_thread_cond_wait(nxt_thread_cond_t *cond, #if (NXT_HAVE_PTHREAD_YIELD) -#define \ -nxt_thread_yield() \ +#define nxt_thread_yield() \ pthread_yield() #elif (NXT_HAVE_PTHREAD_YIELD_NP) -#define \ -nxt_thread_yield() \ +#define nxt_thread_yield() \ pthread_yield_np() #else -#define \ -nxt_thread_yield() \ +#define nxt_thread_yield() \ nxt_sched_yield() #endif diff --git a/src/nxt_thread_id.h b/src/nxt_thread_id.h index 3263a47a..764c9934 100644 --- a/src/nxt_thread_id.h +++ b/src/nxt_thread_id.h @@ -179,12 +179,10 @@ NXT_EXPORT nxt_tid_t nxt_thread_tid(nxt_thread_t *thr); typedef pthread_t nxt_thread_handle_t; -#define \ -nxt_thread_handle_clear(th) \ +#define nxt_thread_handle_clear(th) \ th = (pthread_t) 0 -#define \ -nxt_thread_handle_equal(th0, th1) \ +#define nxt_thread_handle_equal(th0, th1) \ pthread_equal(th0, th1) diff --git a/src/nxt_thread_time.h b/src/nxt_thread_time.h index 05ecd938..77eaea49 100644 --- a/src/nxt_thread_time.h +++ b/src/nxt_thread_time.h @@ -70,21 +70,18 @@ NXT_EXPORT u_char *nxt_thread_time_string(nxt_thread_t *thr, void nxt_time_thread_start(nxt_msec_t interval); -#define \ -nxt_thread_monotonic_time(thr) \ +#define nxt_thread_monotonic_time(thr) \ (thr)->time.now.monotonic #if (NXT_DEBUG) -#define \ -nxt_thread_time_debug_update(thr) \ +#define nxt_thread_time_debug_update(thr) \ nxt_thread_time_update(thr) #else -#define \ -nxt_thread_time_debug_update(thr) +#define nxt_thread_time_debug_update(thr) #endif diff --git a/src/nxt_time.h b/src/nxt_time.h index d6785eb2..9617b3d4 100644 --- a/src/nxt_time.h +++ b/src/nxt_time.h @@ -74,20 +74,17 @@ NXT_EXPORT void nxt_timezone_update(void); #if (NXT_HAVE_TM_GMTOFF) -#define \ -nxt_timezone(tm) \ +#define nxt_timezone(tm) \ ((tm)->tm_gmtoff) #elif (NXT_HAVE_ALTZONE) -#define \ -nxt_timezone(tm) \ +#define nxt_timezone(tm) \ (-(((tm)->tm_isdst > 0) ? altzone : timezone)) #else -#define \ -nxt_timezone(tm) \ +#define nxt_timezone(tm) \ (-(((tm)->tm_isdst > 0) ? timezone + 3600 : timezone)) #endif @@ -103,8 +100,7 @@ typedef int32_t nxt_msec_int_t; * every 49 days. This signed subtraction takes into account that overflow. * "nxt_msec_diff(m1, m2) < 0" means that m1 is lesser than m2. */ -#define \ -nxt_msec_diff(m1, m2) \ +#define nxt_msec_diff(m1, m2) \ ((int32_t) ((m1) - (m2))) diff --git a/src/nxt_unix.h b/src/nxt_unix.h index 393f61d9..d8eaabc3 100644 --- a/src/nxt_unix.h +++ b/src/nxt_unix.h @@ -275,23 +275,19 @@ typedef struct iovec nxt_iobuf_t; -#define \ -nxt_iobuf_data(iob) \ +#define nxt_iobuf_data(iob) \ (iob)->iov_base -#define \ -nxt_iobuf_size(iob) \ +#define nxt_iobuf_size(iob) \ (iob)->iov_len -#define \ -nxt_iobuf_set(iob, p, size) \ +#define nxt_iobuf_set(iob, p, size) \ do { \ (iob)->iov_base = (void *) p; \ (iob)->iov_len = size; \ } while (0) -#define \ -nxt_iobuf_add(iob, size) \ +#define nxt_iobuf_add(iob, size) \ (iob)->iov_len += size diff --git a/src/nxt_vector.h b/src/nxt_vector.h index e8836dbf..dcac53d4 100644 --- a/src/nxt_vector.h +++ b/src/nxt_vector.h @@ -41,19 +41,16 @@ NXT_EXPORT void *nxt_vector_zero_add(nxt_vector_t *vector, NXT_EXPORT void nxt_vector_remove(nxt_vector_t *vector, void *item); -#define \ -nxt_vector_last(vector) \ +#define nxt_vector_last(vector) \ nxt_pointer_to((vector)->start, \ (vector)->item_size * ((vector)->items - 1)) -#define \ -nxt_vector_reset(vector) \ +#define nxt_vector_reset(vector) \ (vector)->items = 0; -#define \ -nxt_vector_is_empty(vector) \ +#define nxt_vector_is_empty(vector) \ ((vector)->items == 0) diff --git a/src/nxt_work_queue.h b/src/nxt_work_queue.h index ffa21d27..b6aa4d4c 100644 --- a/src/nxt_work_queue.h +++ b/src/nxt_work_queue.h @@ -109,8 +109,7 @@ NXT_EXPORT void nxt_work_queue_thread_adopt(nxt_work_queue_t *wq); #else -#define \ -nxt_work_queue_name(_wq, _name) +#define nxt_work_queue_name(_wq, _name) #define nxt_work_queue_thread_adopt(_wq) diff --git a/src/test/nxt_rbtree1_test.c b/src/test/nxt_rbtree1_test.c index d4783ea1..1f23998c 100644 --- a/src/test/nxt_rbtree1_test.c +++ b/src/test/nxt_rbtree1_test.c @@ -9,13 +9,11 @@ #include "nxt_rbtree1.h" -#define \ -nxt_rbtree1_is_empty(tree) \ +#define nxt_rbtree1_is_empty(tree) \ (((tree)->root) == (tree)->sentinel) -#define \ -nxt_rbtree1_is_there_successor(tree, node) \ +#define nxt_rbtree1_is_there_successor(tree, node) \ ((node) != (tree)->sentinel) -- cgit From 0032543fa65f454c471c968998190b027c1ff270 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 9 Mar 2022 13:29:43 +0800 Subject: Ruby: added the Rack environment parameter "SCRIPT_NAME". --- src/ruby/nxt_ruby.c | 45 +++++++++++++++++++++++++++++++++++++++++---- src/ruby/nxt_ruby.h | 1 + 2 files changed, 42 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index 62498127..8f4afd35 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -29,6 +29,7 @@ typedef struct { static nxt_int_t nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data); static VALUE nxt_ruby_init_basic(VALUE arg); +static VALUE nxt_ruby_script_basename(nxt_str_t *script); static VALUE nxt_ruby_hook_procs_load(VALUE path); static VALUE nxt_ruby_hook_register(VALUE arg); @@ -49,7 +50,7 @@ static void *nxt_ruby_thread_create_gvl(void *rctx); static VALUE nxt_ruby_thread_func(VALUE arg); static void *nxt_ruby_unit_run(void *ctx); static void nxt_ruby_ubf(void *ctx); -static int nxt_ruby_init_threads(nxt_ruby_app_conf_t *c); +static int nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c); static void nxt_ruby_join_threads(nxt_unit_ctx_t *ctx, nxt_ruby_app_conf_t *c); @@ -260,7 +261,7 @@ static nxt_int_t nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) { int state, rc; - VALUE res, path; + VALUE res, path, script; nxt_ruby_ctx_t ruby_ctx; nxt_unit_ctx_t *unit_ctx; nxt_unit_init_t ruby_unit_init; @@ -282,7 +283,10 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) ruby_options(2, argv); ruby_script("NGINX_Unit"); + script = nxt_ruby_script_basename(&c->script); + ruby_ctx.env = Qnil; + ruby_ctx.script = script; ruby_ctx.io_input = Qnil; ruby_ctx.io_error = Qnil; ruby_ctx.thread = Qnil; @@ -352,7 +356,7 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) goto fail; } - rc = nxt_ruby_init_threads(c); + rc = nxt_ruby_init_threads(script, c); if (nxt_slow_path(rc == NXT_UNIT_ERROR)) { goto fail; } @@ -420,6 +424,37 @@ fail: } +static VALUE +nxt_ruby_script_basename(nxt_str_t *script) +{ + size_t len; + u_char *p, *last; + + last = NULL; + p = script->start + script->length; + + while (p > script->start) { + + if (p[-1] == '/') { + last = p; + break; + } + + p--; + } + + if (last != NULL) { + len = script->length - (last - script->start); + + } else { + last = script->start; + len = script->length; + } + + return rb_str_new((const char *) last, len); +} + + static VALUE nxt_ruby_init_basic(VALUE arg) { @@ -563,6 +598,7 @@ nxt_ruby_rack_env_create(VALUE arg) rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MAJOR)); rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MINOR)); + rb_hash_aset(hash_env, rb_str_new2("SCRIPT_NAME"), rctx->script); rb_hash_aset(hash_env, rb_str_new2("rack.version"), version); rb_hash_aset(hash_env, rb_str_new2("rack.input"), rctx->io_input); rb_hash_aset(hash_env, rb_str_new2("rack.errors"), rctx->io_error); @@ -1357,7 +1393,7 @@ nxt_ruby_ubf(void *ctx) static int -nxt_ruby_init_threads(nxt_ruby_app_conf_t *c) +nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c) { int state; uint32_t i; @@ -1379,6 +1415,7 @@ nxt_ruby_init_threads(nxt_ruby_app_conf_t *c) rctx = &nxt_ruby_ctxs[i]; rctx->env = Qnil; + rctx->script = script; rctx->io_input = Qnil; rctx->io_error = Qnil; rctx->thread = Qnil; diff --git a/src/ruby/nxt_ruby.h b/src/ruby/nxt_ruby.h index 26430021..3bdd567a 100644 --- a/src/ruby/nxt_ruby.h +++ b/src/ruby/nxt_ruby.h @@ -22,6 +22,7 @@ typedef struct { VALUE env; + VALUE script; VALUE io_input; VALUE io_error; VALUE thread; -- cgit From 5665838b680cdc06d6eb83107e4d46db6cfae0c4 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Thu, 12 May 2022 12:04:47 +0400 Subject: Using OPENSSL_SUPPRESS_DEPRECATED. The macro is used to suppress deprecation warnings with OpenSSL 3.0. Unlike OPENSSL_API_COMPAT, it works well with OpenSSL built with no-deprecated. In particular, it doesn't unhide various macros in OpenSSL includes, which are meant to be hidden under OPENSSL_NO_DEPRECATED. --- src/nxt_openssl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index 59c58b2b..38cf652d 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -6,6 +6,9 @@ #include #include + +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include -- cgit From 6cfa1c397005dc9b2904da2934120d98fe451079 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Thu, 12 May 2022 12:04:54 +0400 Subject: Using SSL_OP_IGNORE_UNEXPECTED_EOF. A new behaviour was introduced in OpenSSL 1.1.1e, when a peer does not send close_notify before closing the connection. Previously, it was to return SSL_ERROR_SYSCALL with errno 0, known since at least OpenSSL 0.9.7, and is handled gracefully in unitd. Now it returns SSL_ERROR_SSL with a distinct reason SSL_R_UNEXPECTED_EOF_WHILE_READING ("unexpected eof while reading"). This leads to critical errors seen in nginx within various routines such as SSL_do_handshake(), SSL_read(), SSL_shutdown(). The behaviour was restored in OpenSSL 1.1.1f, but presents in OpenSSL 3.0 by default. Use of the SSL_OP_IGNORE_UNEXPECTED_EOF option added in OpenSSL 3.0 allows setting a compatible behaviour to return SSL_ERROR_ZERO_RETURN: https://git.openssl.org/?p=openssl.git;a=commitdiff;h=09b90e0 See for additional details: https://github.com/openssl/openssl/issues/11381 --- src/nxt_openssl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index 38cf652d..e19b1381 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -326,6 +326,11 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_mp_t *mp, SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); #endif +#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF + /* Request SSL_ERROR_ZERO_RETURN on EOF. */ + SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); +#endif + #ifdef SSL_MODE_RELEASE_BUFFERS if (nxt_openssl_version >= 10001078) { -- cgit From 5883a2670fbeb1610014ec122a5fd20312399a90 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 13 May 2022 19:33:40 +0800 Subject: Ruby: added stream IO "close" required by Rack specification. This closes #654 issue on Github. --- src/ruby/nxt_ruby_stream_io.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/ruby/nxt_ruby_stream_io.c b/src/ruby/nxt_ruby_stream_io.c index 82ad3908..4ef69cee 100644 --- a/src/ruby/nxt_ruby_stream_io.c +++ b/src/ruby/nxt_ruby_stream_io.c @@ -18,6 +18,7 @@ static VALUE nxt_ruby_stream_io_puts(VALUE obj, VALUE args); static VALUE nxt_ruby_stream_io_write(VALUE obj, VALUE args); nxt_inline long nxt_ruby_stream_io_s_write(nxt_ruby_ctx_t *rctx, VALUE val); static VALUE nxt_ruby_stream_io_flush(VALUE obj); +static VALUE nxt_ruby_stream_io_close(VALUE obj); VALUE @@ -38,6 +39,7 @@ nxt_ruby_stream_io_input_init(void) rb_define_method(stream_io, "each", nxt_ruby_stream_io_each, 0); rb_define_method(stream_io, "read", nxt_ruby_stream_io_read, -2); rb_define_method(stream_io, "rewind", nxt_ruby_stream_io_rewind, 0); + rb_define_method(stream_io, "close", nxt_ruby_stream_io_close, 0); return stream_io; } @@ -60,6 +62,7 @@ nxt_ruby_stream_io_error_init(void) rb_define_method(stream_io, "puts", nxt_ruby_stream_io_puts, -2); rb_define_method(stream_io, "write", nxt_ruby_stream_io_write, -2); rb_define_method(stream_io, "flush", nxt_ruby_stream_io_flush, 0); + rb_define_method(stream_io, "close", nxt_ruby_stream_io_close, 0); return stream_io; } @@ -257,3 +260,10 @@ nxt_ruby_stream_io_flush(VALUE obj) { return Qnil; } + + +static VALUE +nxt_ruby_stream_io_close(VALUE obj) +{ + return Qnil; +} -- cgit From 5302faace297f2e9b104fbebafb46cc0521d2a5a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 9 Dec 2021 02:46:20 +0100 Subject: Renamed nxt_http_static_ctx_t field 'index' to 'share_idx'. Having a configurable index filename will require adding an index field to this structure. The most natural name for that field is 'index', so the current index field should be renamed to allow for that. A sensible name is 'share_idx', since it's the index of the shares array in 'nxt_http_static_conf_t'. Instead of 'share_index' I opted for the shorter 'share_idx'. Also, when 'index' allows an array of filenames in a following commit, another similar variable 'index_idx' should be created, and having a different prefix and suffix seems more readable than for example 'index_index'. --- src/nxt_http_static.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 5231f98e..c9483b63 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -33,7 +33,7 @@ typedef struct { #if (NXT_HAVE_OPENAT2) nxt_str_t chroot; #endif - uint32_t index; + uint32_t share_idx; uint8_t need_body; /* 1 bit */ } nxt_http_static_ctx_t; @@ -218,7 +218,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, conf = ctx->action->u.conf; - share = &conf->shares[ctx->index]; + share = &conf->shares[ctx->share_idx]; #if (NXT_DEBUG) nxt_str_t shr; @@ -245,7 +245,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, nxt_var_raw(share->var, &ctx->share); #if (NXT_HAVE_OPENAT2) - if (conf->chroot != NULL && ctx->index == 0) { + if (conf->chroot != NULL && ctx->share_idx == 0) { nxt_var_raw(conf->chroot, &ctx->chroot); } #endif @@ -262,7 +262,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, nxt_var_query(task, r->var_query, share->var, &ctx->share); #if (NXT_HAVE_OPENAT2) - if (conf->chroot != NULL && ctx->index == 0) { + if (conf->chroot != NULL && ctx->share_idx == 0) { nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot); } #endif @@ -357,7 +357,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) nxt_uint_t resolve; nxt_http_static_share_t *share; - share = &conf->shares[ctx->index]; + share = &conf->shares[ctx->share_idx]; resolve = conf->resolve; chr = &ctx->chroot; @@ -659,9 +659,9 @@ nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r, action = ctx->action; conf = action->u.conf; - ctx->index++; + ctx->share_idx++; - if (ctx->index < conf->nshares) { + if (ctx->share_idx < conf->nshares) { nxt_http_static_iterate(task, r, ctx); return; } -- cgit From 7066acb2ce438526fb0d60df443320d1c8366760 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 9 Apr 2022 21:27:12 +0200 Subject: Supporting empty Location URIs. An empty string in Location was being handled specially by not sending a Location header. This may occur after variable resolution, so we need to consider this scenario. The obsolete RFC 2616 defined the Location header as consisting of an absolute URI , which cannot be an empty string. However, the current RFC 7231 allows the Location to be a relative URI , and a relative URI may be an empty string . Due to these considerations, this patch allows sending an empty Location header without handling this case specially. This behavior will probably be more straightforward to users, too. It also simplifies the code, which is now more readable, fast, and conformant to the current RFC. We're skipping an allocation at request time in a common case such as "action": {"return": 404} --- src/nxt_http.h | 2 +- src/nxt_http_return.c | 53 ++++++++++++++++++++++++--------------------------- src/nxt_http_route.c | 2 +- 3 files changed, 27 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/nxt_http.h b/src/nxt_http.h index 7cef1345..36bc089d 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -206,7 +206,7 @@ typedef struct nxt_http_route_addr_rule_s nxt_http_route_addr_rule_t; typedef struct { nxt_conf_value_t *pass; nxt_conf_value_t *ret; - nxt_str_t location; + nxt_conf_value_t *location; nxt_conf_value_t *proxy; nxt_conf_value_t *share; nxt_str_t chroot; diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index 92dfa465..e3dd02ad 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -11,12 +11,10 @@ typedef struct { nxt_http_status_t status; nxt_var_t *location; nxt_str_t encoded; - uint8_t loc_is_const; } nxt_http_return_conf_t; typedef struct { - nxt_http_action_t *action; nxt_str_t location; nxt_str_t encoded; } nxt_http_return_ctx_t; @@ -38,7 +36,6 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, nxt_http_action_conf_t *acf) { nxt_str_t str; - nxt_var_t *var; nxt_http_return_conf_t *conf; conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t)); @@ -51,20 +48,18 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, conf->status = nxt_conf_get_number(acf->ret); - if (acf->location.length == 0) { - conf->loc_is_const = 1; + if (acf->location == NULL) { return NXT_OK; } - var = nxt_var_compile(&acf->location, mp, 0); - if (nxt_slow_path(var == NULL)) { + nxt_conf_get_string(acf->location, &str); + + conf->location = nxt_var_compile(&str, mp, 0); + if (nxt_slow_path(conf->location == NULL)) { return NXT_ERROR; } - conf->location = var; - conf->loc_is_const = nxt_var_is_const(var); - - if (conf->loc_is_const) { + if (nxt_var_is_const(conf->location)) { nxt_var_raw(conf->location, &str); return nxt_http_return_encode(mp, &conf->encoded, &str); } @@ -100,17 +95,23 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, return NULL; } - ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_return_ctx_t)); - if (nxt_slow_path(ctx == NULL)) { - goto fail; + if (conf->location == NULL) { + ctx = NULL; + + } else { + ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_return_ctx_t)); + if (nxt_slow_path(ctx == NULL)) { + goto fail; + } } - ctx->action = action; r->status = conf->status; r->resp.content_length_n = 0; - if (conf->loc_is_const) { - ctx->encoded = conf->encoded; + if (ctx == NULL || nxt_var_is_const(conf->location)) { + if (ctx != NULL) { + ctx->encoded = conf->encoded; + } nxt_http_return_send_ready(task, r, ctx); @@ -167,25 +168,21 @@ nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) { nxt_int_t ret; nxt_http_field_t *field; - nxt_http_action_t *action; nxt_http_request_t *r; nxt_http_return_ctx_t *ctx; - nxt_http_return_conf_t *conf; r = obj; ctx = data; - action = ctx->action; - conf = action->u.conf; - if (!conf->loc_is_const) { - ret = nxt_http_return_encode(r->mem_pool, &ctx->encoded, - &ctx->location); - if (nxt_slow_path(ret == NXT_ERROR)) { - goto fail; + if (ctx != NULL) { + if (ctx->location.length > 0) { + ret = nxt_http_return_encode(r->mem_pool, &ctx->encoded, + &ctx->location); + if (nxt_slow_path(ret == NXT_ERROR)) { + goto fail; + } } - } - if (ctx->encoded.length > 0) { field = nxt_list_zero_add(r->resp.fields); if (nxt_slow_path(field == NULL)) { goto fail; diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index c2321906..af28400d 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -626,7 +626,7 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = { }, { nxt_string("location"), - NXT_CONF_MAP_STR, + NXT_CONF_MAP_PTR, offsetof(nxt_http_action_conf_t, location) }, { -- cgit From ba20fa3939c1505866d715a5a1a43f61a4f8de17 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 17 May 2022 11:18:58 +0200 Subject: Fixed memcpy(dest, NULL, 0) Undefined Behavior. nxt_str_null() setted the loc.start pointer to NULL, which was being passed to memcpy(3) through nxt_debug(). That caused Undefined Behavior, so we now pass an empty string. --- src/nxt_http_return.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index e3dd02ad..8832941f 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -80,7 +80,7 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, conf = action->u.conf; if (conf->location == NULL) { - nxt_str_null(&loc); + nxt_str_set(&loc, ""); } else { nxt_var_raw(conf->location, &loc); -- cgit From 7662ec5f1bf27de981a8aa100ab2c5c3fa985269 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 17 May 2022 12:20:19 +0200 Subject: Wrapped debug code in '#if (NXT_DEBUG)'. --- src/nxt_http_return.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index 8832941f..82c91568 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -73,12 +73,14 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action) { nxt_int_t ret; - nxt_str_t loc; nxt_http_return_ctx_t *ctx; nxt_http_return_conf_t *conf; conf = action->u.conf; +#if (NXT_DEBUG) + nxt_str_t loc; + if (conf->location == NULL) { nxt_str_set(&loc, ""); @@ -87,6 +89,7 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r, } nxt_debug(task, "http return: %d (loc: \"%V\")", conf->status, &loc); +#endif if (conf->status >= NXT_HTTP_BAD_REQUEST && conf->status <= NXT_HTTP_SERVER_ERROR_MAX) -- cgit From 6271479610c95d40daf9ed6ec2c7dead67c74f00 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 18 May 2022 21:18:40 +0800 Subject: HTTP: generalized argument and cookie parsing. No functional changes. --- src/nxt_http.h | 12 ++ src/nxt_http_request.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++ src/nxt_http_route.c | 294 +------------------------------------------------ 3 files changed, 291 insertions(+), 291 deletions(-) (limited to 'src') diff --git a/src/nxt_http.h b/src/nxt_http.h index 36bc089d..6b19d7df 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -198,6 +198,15 @@ struct nxt_http_request_s { }; +typedef struct { + uint16_t hash; + uint16_t name_length; + uint32_t value_length; + u_char *name; + u_char *value; +} nxt_http_name_value_t; + + typedef struct nxt_http_route_s nxt_http_route_t; typedef struct nxt_http_route_rule_s nxt_http_route_rule_t; typedef struct nxt_http_route_addr_rule_s nxt_http_route_addr_rule_t; @@ -311,6 +320,9 @@ nxt_int_t nxt_http_request_field(void *ctx, nxt_http_field_t *field, nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field, uintptr_t data); +nxt_array_t *nxt_http_arguments_parse(nxt_http_request_t *r); +nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r); + nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf); nxt_http_action_t *nxt_http_action_create(nxt_task_t *task, diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index ac614df6..04a6f7f3 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -24,6 +24,25 @@ static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data); static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); +static nxt_http_name_value_t *nxt_http_argument(nxt_array_t *array, + u_char *name, size_t name_length, uint32_t hash, u_char *start, + u_char *end); +static nxt_int_t nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, + u_char *end); +static nxt_http_name_value_t *nxt_http_cookie(nxt_array_t *array, u_char *name, + size_t name_length, u_char *start, u_char *end); + + +#define NXT_HTTP_COOKIE_HASH \ + (nxt_http_field_hash_end( \ + nxt_http_field_hash_char( \ + nxt_http_field_hash_char( \ + nxt_http_field_hash_char( \ + nxt_http_field_hash_char( \ + nxt_http_field_hash_char( \ + nxt_http_field_hash_char(NXT_HTTP_FIELD_HASH_INIT, \ + 'c'), 'o'), 'o'), 'k'), 'i'), 'e')) & 0xFFFF) + static const nxt_http_request_state_t nxt_http_request_init_state; static const nxt_http_request_state_t nxt_http_request_body_state; @@ -748,3 +767,260 @@ nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, { return nxt_http_date(buf, tm); } + + +nxt_array_t * +nxt_http_arguments_parse(nxt_http_request_t *r) +{ + size_t name_length; + u_char *p, *dst, *dst_start, *start, *end, *name; + uint8_t d0, d1; + uint32_t hash; + nxt_array_t *args; + nxt_http_name_value_t *nv; + + if (r->arguments != NULL) { + return r->arguments; + } + + args = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t)); + if (nxt_slow_path(args == NULL)) { + return NULL; + } + + hash = NXT_HTTP_FIELD_HASH_INIT; + name = NULL; + name_length = 0; + + dst_start = nxt_mp_nget(r->mem_pool, r->args->length); + if (nxt_slow_path(dst_start == NULL)) { + return NULL; + } + + r->args_decoded.start = dst_start; + + start = r->args->start; + end = start + r->args->length; + + for (p = start, dst = dst_start; p < end; p++, dst++) { + *dst = *p; + + switch (*p) { + case '=': + if (name == NULL) { + name_length = dst - dst_start; + name = dst_start; + dst_start = dst + 1; + } + + continue; + + case '&': + if (name_length != 0 || dst != dst_start) { + nv = nxt_http_argument(args, name, name_length, hash, dst_start, + dst); + if (nxt_slow_path(nv == NULL)) { + return NULL; + } + } + + hash = NXT_HTTP_FIELD_HASH_INIT; + name_length = 0; + name = NULL; + dst_start = dst + 1; + + continue; + + case '+': + *dst = ' '; + + break; + + case '%': + if (nxt_slow_path(end - p <= 2)) { + break; + } + + d0 = nxt_hex2int[p[1]]; + d1 = nxt_hex2int[p[2]]; + + if (nxt_slow_path((d0 | d1) >= 16)) { + break; + } + + p += 2; + *dst = (d0 << 4) + d1; + + break; + } + + if (name == NULL) { + hash = nxt_http_field_hash_char(hash, *dst); + } + } + + r->args_decoded.length = dst - r->args_decoded.start; + + if (name_length != 0 || dst != dst_start) { + nv = nxt_http_argument(args, name, name_length, hash, dst_start, dst); + if (nxt_slow_path(nv == NULL)) { + return NULL; + } + } + + r->arguments = args; + + return args; +} + + +static nxt_http_name_value_t * +nxt_http_argument(nxt_array_t *array, u_char *name, size_t name_length, + uint32_t hash, u_char *start, u_char *end) +{ + size_t length; + nxt_http_name_value_t *nv; + + nv = nxt_array_add(array); + if (nxt_slow_path(nv == NULL)) { + return NULL; + } + + nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF; + + length = end - start; + + if (name == NULL) { + name_length = length; + name = start; + length = 0; + } + + nv->name_length = name_length; + nv->value_length = length; + nv->name = name; + nv->value = start; + + return nv; +} + + +nxt_array_t * +nxt_http_cookies_parse(nxt_http_request_t *r) +{ + nxt_int_t ret; + nxt_array_t *cookies; + nxt_http_field_t *f; + + if (r->cookies != NULL) { + return r->cookies; + } + + cookies = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t)); + if (nxt_slow_path(cookies == NULL)) { + return NULL; + } + + nxt_list_each(f, r->fields) { + + if (f->hash != NXT_HTTP_COOKIE_HASH + || f->name_length != 6 + || nxt_strncasecmp(f->name, (u_char *) "Cookie", 6) != 0) + { + continue; + } + + ret = nxt_http_cookie_parse(cookies, f->value, + f->value + f->value_length); + if (ret != NXT_OK) { + return NULL; + } + + } nxt_list_loop; + + r->cookies = cookies; + + return cookies; +} + + +static nxt_int_t +nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end) +{ + size_t name_length; + u_char c, *p, *name; + nxt_http_name_value_t *nv; + + name = NULL; + name_length = 0; + + for (p = start; p < end; p++) { + c = *p; + + if (c == '=') { + while (start[0] == ' ') { start++; } + + name_length = p - start; + + if (name_length != 0) { + name = start; + } + + start = p + 1; + + } else if (c == ';') { + if (name != NULL) { + nv = nxt_http_cookie(cookies, name, name_length, start, p); + if (nxt_slow_path(nv == NULL)) { + return NXT_ERROR; + } + } + + name = NULL; + start = p + 1; + } + } + + if (name != NULL) { + nv = nxt_http_cookie(cookies, name, name_length, start, p); + if (nxt_slow_path(nv == NULL)) { + return NXT_ERROR; + } + } + + return NXT_OK; +} + + +static nxt_http_name_value_t * +nxt_http_cookie(nxt_array_t *array, u_char *name, size_t name_length, + u_char *start, u_char *end) +{ + u_char c, *p; + uint32_t hash; + nxt_http_name_value_t *nv; + + nv = nxt_array_add(array); + if (nxt_slow_path(nv == NULL)) { + return NULL; + } + + nv->name_length = name_length; + nv->name = name; + + hash = NXT_HTTP_FIELD_HASH_INIT; + + for (p = name; p < name + name_length; p++) { + c = *p; + hash = nxt_http_field_hash_char(hash, c); + } + + nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF; + + while (start < end && end[-1] == ' ') { end--; } + + nv->value_length = end - start; + nv->value = start; + + return nv; +} diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index af28400d..558dae9d 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -86,15 +86,6 @@ typedef struct { } nxt_http_route_pattern_t; -typedef struct { - uint16_t hash; - uint16_t name_length; - uint32_t value_length; - u_char *name; - u_char *value; -} nxt_http_name_value_t; - - typedef struct { uint16_t hash; uint16_t name_length; @@ -172,17 +163,6 @@ struct nxt_http_routes_s { }; -#define NXT_COOKIE_HASH \ - (nxt_http_field_hash_end( \ - nxt_http_field_hash_char( \ - nxt_http_field_hash_char( \ - nxt_http_field_hash_char( \ - nxt_http_field_hash_char( \ - nxt_http_field_hash_char( \ - nxt_http_field_hash_char(NXT_HTTP_FIELD_HASH_INIT, \ - 'c'), 'o'), 'o'), 'k'), 'i'), 'e')) & 0xFFFF) - - static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv); static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task, @@ -241,10 +221,6 @@ static nxt_int_t nxt_http_route_header(nxt_http_request_t *r, nxt_http_route_rule_t *rule); static nxt_int_t nxt_http_route_arguments(nxt_http_request_t *r, nxt_http_route_rule_t *rule); -static nxt_array_t *nxt_http_route_arguments_parse(nxt_http_request_t *r); -static nxt_http_name_value_t *nxt_http_route_argument(nxt_array_t *array, - u_char *name, size_t name_length, uint32_t hash, u_char *start, - u_char *end); static nxt_int_t nxt_http_route_test_argument(nxt_http_request_t *r, nxt_http_route_rule_t *rule, nxt_array_t *array); static nxt_int_t nxt_http_route_scheme(nxt_http_request_t *r, @@ -253,11 +229,6 @@ static nxt_int_t nxt_http_route_query(nxt_http_request_t *r, nxt_http_route_rule_t *rule); static nxt_int_t nxt_http_route_cookies(nxt_http_request_t *r, nxt_http_route_rule_t *rule); -static nxt_array_t *nxt_http_route_cookies_parse(nxt_http_request_t *r); -static nxt_int_t nxt_http_route_cookie_parse(nxt_array_t *cookies, - u_char *start, u_char *end); -static nxt_http_name_value_t *nxt_http_route_cookie(nxt_array_t *array, - u_char *name, size_t name_length, u_char *start, u_char *end); static nxt_int_t nxt_http_route_test_cookie(nxt_http_request_t *r, nxt_http_route_rule_t *rule, nxt_array_t *array); static nxt_int_t nxt_http_route_pattern(nxt_http_request_t *r, @@ -1995,7 +1966,7 @@ nxt_http_route_arguments(nxt_http_request_t *r, nxt_http_route_rule_t *rule) { nxt_array_t *arguments; - arguments = nxt_http_route_arguments_parse(r); + arguments = nxt_http_arguments_parse(r); if (nxt_slow_path(arguments == NULL)) { return -1; } @@ -2004,143 +1975,6 @@ nxt_http_route_arguments(nxt_http_request_t *r, nxt_http_route_rule_t *rule) } -static nxt_array_t * -nxt_http_route_arguments_parse(nxt_http_request_t *r) -{ - size_t name_length; - u_char *p, *dst, *dst_start, *start, *end, *name; - uint8_t d0, d1; - uint32_t hash; - nxt_array_t *args; - nxt_http_name_value_t *nv; - - if (r->arguments != NULL) { - return r->arguments; - } - - args = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t)); - if (nxt_slow_path(args == NULL)) { - return NULL; - } - - hash = NXT_HTTP_FIELD_HASH_INIT; - name = NULL; - name_length = 0; - - dst_start = nxt_mp_nget(r->mem_pool, r->args->length); - if (nxt_slow_path(dst_start == NULL)) { - return NULL; - } - - r->args_decoded.start = dst_start; - - start = r->args->start; - end = start + r->args->length; - - for (p = start, dst = dst_start; p < end; p++, dst++) { - *dst = *p; - - switch (*p) { - case '=': - if (name == NULL) { - name_length = dst - dst_start; - name = dst_start; - dst_start = dst + 1; - } - - continue; - - case '&': - if (name_length != 0 || dst != dst_start) { - nv = nxt_http_route_argument(args, name, name_length, hash, - dst_start, dst); - if (nxt_slow_path(nv == NULL)) { - return NULL; - } - } - - hash = NXT_HTTP_FIELD_HASH_INIT; - name_length = 0; - name = NULL; - dst_start = dst + 1; - - continue; - - case '+': - *dst = ' '; - - break; - - case '%': - if (nxt_slow_path(end - p <= 2)) { - break; - } - - d0 = nxt_hex2int[p[1]]; - d1 = nxt_hex2int[p[2]]; - - if (nxt_slow_path((d0 | d1) >= 16)) { - break; - } - - p += 2; - *dst = (d0 << 4) + d1; - - break; - } - - if (name == NULL) { - hash = nxt_http_field_hash_char(hash, *dst); - } - } - - r->args_decoded.length = dst - r->args_decoded.start; - - if (name_length != 0 || dst != dst_start) { - nv = nxt_http_route_argument(args, name, name_length, hash, dst_start, - dst); - if (nxt_slow_path(nv == NULL)) { - return NULL; - } - } - - r->arguments = args; - - return args; -} - - -static nxt_http_name_value_t * -nxt_http_route_argument(nxt_array_t *array, u_char *name, size_t name_length, - uint32_t hash, u_char *start, u_char *end) -{ - size_t length; - nxt_http_name_value_t *nv; - - nv = nxt_array_add(array); - if (nxt_slow_path(nv == NULL)) { - return NULL; - } - - nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF; - - length = end - start; - - if (name == NULL) { - name_length = length; - name = start; - length = 0; - } - - nv->name_length = name_length; - nv->value_length = length; - nv->name = name; - nv->value = start; - - return nv; -} - - static nxt_int_t nxt_http_route_test_argument(nxt_http_request_t *r, nxt_http_route_rule_t *rule, nxt_array_t *array) @@ -2196,7 +2030,7 @@ nxt_http_route_query(nxt_http_request_t *r, nxt_http_route_rule_t *rule) { nxt_array_t *arguments; - arguments = nxt_http_route_arguments_parse(r); + arguments = nxt_http_arguments_parse(r); if (nxt_slow_path(arguments == NULL)) { return -1; } @@ -2211,7 +2045,7 @@ nxt_http_route_cookies(nxt_http_request_t *r, nxt_http_route_rule_t *rule) { nxt_array_t *cookies; - cookies = nxt_http_route_cookies_parse(r); + cookies = nxt_http_cookies_parse(r); if (nxt_slow_path(cookies == NULL)) { return -1; } @@ -2220,128 +2054,6 @@ nxt_http_route_cookies(nxt_http_request_t *r, nxt_http_route_rule_t *rule) } -static nxt_array_t * -nxt_http_route_cookies_parse(nxt_http_request_t *r) -{ - nxt_int_t ret; - nxt_array_t *cookies; - nxt_http_field_t *f; - - if (r->cookies != NULL) { - return r->cookies; - } - - cookies = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t)); - if (nxt_slow_path(cookies == NULL)) { - return NULL; - } - - nxt_list_each(f, r->fields) { - - if (f->hash != NXT_COOKIE_HASH - || f->name_length != 6 - || nxt_strncasecmp(f->name, (u_char *) "Cookie", 6) != 0) - { - continue; - } - - ret = nxt_http_route_cookie_parse(cookies, f->value, - f->value + f->value_length); - if (ret != NXT_OK) { - return NULL; - } - - } nxt_list_loop; - - r->cookies = cookies; - - return cookies; -} - - -static nxt_int_t -nxt_http_route_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end) -{ - size_t name_length; - u_char c, *p, *name; - nxt_http_name_value_t *nv; - - name = NULL; - name_length = 0; - - for (p = start; p < end; p++) { - c = *p; - - if (c == '=') { - while (start[0] == ' ') { start++; } - - name_length = p - start; - - if (name_length != 0) { - name = start; - } - - start = p + 1; - - } else if (c == ';') { - if (name != NULL) { - nv = nxt_http_route_cookie(cookies, name, name_length, - start, p); - if (nxt_slow_path(nv == NULL)) { - return NXT_ERROR; - } - } - - name = NULL; - start = p + 1; - } - } - - if (name != NULL) { - nv = nxt_http_route_cookie(cookies, name, name_length, start, p); - if (nxt_slow_path(nv == NULL)) { - return NXT_ERROR; - } - } - - return NXT_OK; -} - - -static nxt_http_name_value_t * -nxt_http_route_cookie(nxt_array_t *array, u_char *name, size_t name_length, - u_char *start, u_char *end) -{ - u_char c, *p; - uint32_t hash; - nxt_http_name_value_t *nv; - - nv = nxt_array_add(array); - if (nxt_slow_path(nv == NULL)) { - return NULL; - } - - nv->name_length = name_length; - nv->name = name; - - hash = NXT_HTTP_FIELD_HASH_INIT; - - for (p = name; p < name + name_length; p++) { - c = *p; - hash = nxt_http_field_hash_char(hash, c); - } - - nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF; - - while (start < end && end[-1] == ' ') { end--; } - - nv->value_length = end - start; - nv->value = start; - - return nv; -} - - static nxt_int_t nxt_http_route_test_cookie(nxt_http_request_t *r, nxt_http_route_rule_t *rule, nxt_array_t *array) -- cgit From 27ca67f0df6c7b606c8496b1c57434032b2a577c Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 18 May 2022 12:49:52 +0200 Subject: Added const to remove unnecessary casts. Casts are usually very dangerous, disabling most compiler warnings and basically removing type safety. This change adds 'const' to a pointer where we don't need to write, improving type safety, and that also allows removing some casts. --- src/nxt_sprintf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nxt_sprintf.c b/src/nxt_sprintf.c index 50705ede..90d74335 100644 --- a/src/nxt_sprintf.c +++ b/src/nxt_sprintf.c @@ -97,7 +97,6 @@ static u_char *nxt_number(nxt_sprintf_t *spf, u_char *buf, double n); u_char * nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) { - u_char *p; int d; double f, i; size_t length; @@ -109,6 +108,7 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) nxt_msec_t ms; nxt_nsec_t ns; nxt_bool_t sign; + const u_char *p; nxt_sprintf_t spf; nxt_file_name_t *fn; @@ -150,7 +150,7 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) continue; case 's': - p = va_arg(args, u_char *); + p = va_arg(args, const u_char *); if (nxt_fast_path(p != NULL)) { while (*p != '\0' && buf < end) { @@ -168,7 +168,7 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) if (*fmt == 's') { fmt++; - p = va_arg(args, u_char *); + p = va_arg(args, const u_char *); if (nxt_fast_path(p != NULL)) { goto copy; @@ -378,13 +378,13 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) } if (nxt_slow_path(isnan(f))) { - p = (u_char *) nan; + p = nan; length = nxt_length(nan); goto copy; } else if (nxt_slow_path(isinf(f))) { - p = (u_char *) infinity; + p = infinity; length = nxt_length(infinity); goto copy; -- cgit From 02f50533c4a476b91e4b39a7a2d052095d970983 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 15 Feb 2022 12:30:51 +0100 Subject: Static: returning 404 when "index" is a non-regular file. Before this patch, if "index" was a file, but not a regular file nor a directory, so it may have been for example a FIFO, Unit returned 404. But if "index" was a directory, Unit returned 301. For consistency, this patch makes Unit return 404 for every non-regular file, including directories. --- src/nxt_http_static.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index c9483b63..8964dbbf 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -571,7 +571,9 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) /* Not a file. */ nxt_file_close(task, f); - if (nxt_slow_path(!nxt_is_dir(&fi))) { + if (nxt_slow_path(!nxt_is_dir(&fi) + || shr->start[shr->length - 1] == '/')) + { nxt_log(task, NXT_LOG_ERR, "\"%FN\" is not a regular file", f->name); -- cgit From 9af5f369511eefea691a5cb6787a31ef3af53a0a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 9 Dec 2021 03:00:23 +0100 Subject: Static: supporting new "index" option. This supports a new option "index" that configures a custom index file name to be served when a directory is requested. This initial support only allows a single fixed string. An example: { "share": "/www/data/static/$uri", "index": "lookatthis.htm" } When is requested, is served. Default is "index.html". === nxt_conf_validator.c: Accept "index" as a member of "share", and make sure it's a string. === I tried this feature in my own computer, where I tried the following: - Setting "index" to "lookatthis.htm", and check that the correct file is being served (check both a different name and a different extension). - Not setting "index", and check that is being served. - Settind "index" to an array of strings, and check that the configuration fails: { "error": "Invalid configuration.", "detail": "The \"index\" value must be a string, but not an array." } --- src/nxt_conf_validation.c | 3 +++ src/nxt_http.h | 1 + src/nxt_http_route.c | 5 +++++ src/nxt_http_static.c | 34 ++++++++++++++++++++++++---------- 4 files changed, 33 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 1b97bd0a..ee7ebe44 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -647,6 +647,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = { .name = nxt_string("share"), .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY, .validator = nxt_conf_vldt_share, + }, { + .name = nxt_string("index"), + .type = NXT_CONF_VLDT_STRING, }, { .name = nxt_string("types"), .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY, diff --git a/src/nxt_http.h b/src/nxt_http.h index 6b19d7df..d299fdd4 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -218,6 +218,7 @@ typedef struct { nxt_conf_value_t *location; nxt_conf_value_t *proxy; nxt_conf_value_t *share; + nxt_conf_value_t *index; nxt_str_t chroot; nxt_conf_value_t *follow_symlinks; nxt_conf_value_t *traverse_mounts; diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 558dae9d..9200dc52 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -610,6 +610,11 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = { NXT_CONF_MAP_PTR, offsetof(nxt_http_action_conf_t, share) }, + { + nxt_string("index"), + NXT_CONF_MAP_PTR, + offsetof(nxt_http_action_conf_t, index) + }, { nxt_string("chroot"), NXT_CONF_MAP_STR, diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 8964dbbf..61dd0cb3 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -19,6 +19,7 @@ typedef struct { typedef struct { nxt_uint_t nshares; nxt_http_static_share_t *shares; + nxt_str_t index; #if (NXT_HAVE_OPENAT2) nxt_var_t *chroot; nxt_uint_t resolve; @@ -75,7 +76,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, { uint32_t i; nxt_mp_t *mp; - nxt_str_t str; + nxt_str_t str, *ret; nxt_var_t *var; nxt_conf_value_t *cv; nxt_http_static_conf_t *conf; @@ -110,6 +111,18 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, conf->shares[i].is_const = nxt_var_is_const(var); } + if (acf->index == NULL) { + nxt_str_set(&conf->index, "index.html"); + + } else { + nxt_conf_get_string(acf->index, &str); + + ret = nxt_str_dup(mp, &conf->index, &str); + if (nxt_slow_path(ret == NULL)) { + return NXT_ERROR; + } + } + #if (NXT_HAVE_OPENAT2) if (acf->chroot.length > 0) { nxt_str_t chr, shr; @@ -222,8 +235,10 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, #if (NXT_DEBUG) nxt_str_t shr; + nxt_str_t idx; nxt_var_raw(share->var, &shr); + idx = conf->index; #if (NXT_HAVE_OPENAT2) nxt_str_t chr; @@ -235,9 +250,10 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, nxt_str_set(&chr, ""); } - nxt_debug(task, "http static: \"%V\" (chroot: \"%V\")", &shr, &chr); + nxt_debug(task, "http static: \"%V\", index: \"%V\" (chroot: \"%V\")", + &shr, &idx, &chr); #else - nxt_debug(task, "http static: \"%V\"", &shr); + nxt_debug(task, "http static: \"%V\", index: \"%V\"", &shr, &idx); #endif #endif /* NXT_DEBUG */ @@ -282,7 +298,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) struct tm tm; nxt_buf_t *fb; nxt_int_t ret; - nxt_str_t *shr, exten, *mtype; + nxt_str_t *shr, *index, exten, *mtype; nxt_uint_t level; nxt_file_t *f, file; nxt_file_info_t fi; @@ -295,8 +311,6 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) nxt_http_static_ctx_t *ctx; nxt_http_static_conf_t *conf; - static const nxt_str_t index = nxt_string("index.html"); - r = obj; ctx = data; action = ctx->action; @@ -307,12 +321,12 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) mtype = NULL; shr = &ctx->share; + index = &conf->index; if (shr->start[shr->length - 1] == '/') { - /* TODO: dynamic index setting. */ - nxt_str_set(&exten, ".html"); + nxt_http_static_extract_extension(index, &exten); - length = shr->length + index.length; + length = shr->length + index->length; fname = nxt_mp_nget(r->mem_pool, length + 1); if (nxt_slow_path(fname == NULL)) { @@ -321,7 +335,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) p = fname; p = nxt_cpymem(p, shr->start, shr->length); - p = nxt_cpymem(p, index.start, index.length); + p = nxt_cpymem(p, index->start, index->length); *p = '\0'; } else { -- cgit From 9bf614cd0874e0ef9fda3145faacd3ef3a5fb0ed Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 26 May 2022 14:38:42 +0200 Subject: Var: Added $request_uri (as in NGINX). This supports a new variable $request_uri that contains the path and the query (See RFC 3986, section 3). Its contents are percent encoded. This is useful for example to redirect HTTP to HTTPS: { "return": "301", "location": "https://$host$request_uri" } When is requested, the server redirects to . === Testing: //diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c //index 82c9156..adeb3a1 100644 //--- a/src/nxt_http_return.c //+++ b/src/nxt_http_return.c //@@ -196,6 +196,7 @@ nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) // field->value = ctx->encoded.start; // field->value_length = ctx->encoded.length; // } //+ fprintf(stderr, "ALX: target[%1$i]: <%2$.*1$s>\n", (int)r->target.length, r->target.start); // // r->state = &nxt_http_return_send_state; // { "listeners": { "*:81": { "pass": "routes/ru" } }, "routes": { "ru": [{ "action": { "return": 301, "location": "$request_uri" } }] } } $ curl -i http://localhost:81/*foo%2Abar?baz#arg HTTP/1.1 301 Moved Permanently Location: /*foo%2Abar?baz Server: Unit/1.27.0 Date: Mon, 30 May 2022 16:04:30 GMT Content-Length: 0 $ sudo cat /usr/local/unit.log | grep ALX ALX: target[15]: --- src/nxt_http_variables.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 1c0b561d..b765e177 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -9,6 +9,8 @@ static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, void *ctx); +static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, + nxt_var_query_t *query, nxt_str_t *str, void *ctx); static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, void *ctx); static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query, @@ -20,6 +22,10 @@ static nxt_var_decl_t nxt_http_vars[] = { &nxt_http_var_method, 0 }, + { nxt_string("request_uri"), + &nxt_http_var_request_uri, + 0 }, + { nxt_string("uri"), &nxt_http_var_uri, 0 }, @@ -51,6 +57,20 @@ nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, } +static nxt_int_t +nxt_http_var_request_uri(nxt_task_t *task, nxt_var_query_t *query, + nxt_str_t *str, void *ctx) +{ + nxt_http_request_t *r; + + r = ctx; + + *str = r->target; + + return NXT_OK; +} + + static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, void *ctx) -- cgit From caa05887ff70bbd6338b129959a234ef56f1a287 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 1 Jun 2022 16:40:34 +0100 Subject: Logging a NULL pointer instead of passing it in the memcpy(). --- src/nxt_sprintf.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nxt_sprintf.c b/src/nxt_sprintf.c index 90d74335..9c8e27ed 100644 --- a/src/nxt_sprintf.c +++ b/src/nxt_sprintf.c @@ -115,6 +115,7 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) static const u_char hexadecimal[16] = "0123456789abcdef"; static const u_char HEXADECIMAL[16] = "0123456789ABCDEF"; static const u_char nan[] = "[nan]"; + static const u_char null[] = "[null]"; static const u_char infinity[] = "[infinity]"; spf.end = end; @@ -150,15 +151,18 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) continue; case 's': + fmt++; + p = va_arg(args, const u_char *); - if (nxt_fast_path(p != NULL)) { - while (*p != '\0' && buf < end) { - *buf++ = *p++; - } + if (nxt_slow_path(p == NULL)) { + goto copy; + } + + while (*p != '\0' && buf < end) { + *buf++ = *p++; } - fmt++; continue; case '*': @@ -170,9 +174,7 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) fmt++; p = va_arg(args, const u_char *); - if (nxt_fast_path(p != NULL)) { - goto copy; - } + goto copy; } continue; @@ -554,7 +556,15 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args) copy: - buf = nxt_cpymem(buf, p, nxt_min((size_t) (end - buf), length)); + if (nxt_slow_path(p == NULL)) { + p = null; + length = nxt_length(null); + + } else { + length = nxt_min((size_t) (end - buf), length); + } + + buf = nxt_cpymem(buf, p, length); continue; } -- cgit From bd80039e07500021664a10984977cf64902a4b81 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 2 Jun 2022 11:48:27 +0100 Subject: Node.js: fixed ES modules format in loader.mjs. Before Node.js v16.14.0 the "format" value in defaultResolve was ignored so error was hidden. For more information see: https://github.com/nodejs/node/pull/40980 --- src/nodejs/unit-http/loader.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nodejs/unit-http/loader.mjs b/src/nodejs/unit-http/loader.mjs index 067d63d4..546548f5 100644 --- a/src/nodejs/unit-http/loader.mjs +++ b/src/nodejs/unit-http/loader.mjs @@ -4,13 +4,13 @@ export async function resolve(specifier, context, defaultResolver) { case "websocket": return { url: new URL("./websocket.js", import.meta.url).href, - format: "cjs" + format: "commonjs" } case "http": return { url: new URL("./http.js", import.meta.url).href, - format: "cjs" + format: "commonjs" } } -- cgit