From 015610f12d915d0ac28498bbd871ad5c67fd9b24 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 22 Nov 2021 07:23:07 +0300 Subject: Version bump. --- docs/changes.xml | 29 +++++++++++++++++++++++++++++ version | 4 ++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index df0b88c9..41adde1b 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -5,6 +5,35 @@ + + + + +NGINX Unit updated to 1.27.0. + + + + + + + + + + + diff --git a/version b/version index b890433f..1d59a58f 100644 --- a/version +++ b/version @@ -1,5 +1,5 @@ # Copyright (C) NGINX, Inc. -NXT_VERSION=1.26.0 -NXT_VERNUM=12600 +NXT_VERSION=1.27.0 +NXT_VERNUM=12700 -- cgit 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(-) 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(-) 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(-) 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(-) 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. --- docs/changes.xml | 7 +++++++ src/nxt_router.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 41adde1b..c0cc524e 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,6 +31,13 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> + + +the router process crash on reconfiguration if "access_log" was configured +without listeners. + + + 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 42e2105282cbfaf898d3f9b0eac7b288cc24cba1 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Thu, 25 Nov 2021 16:58:45 +0300 Subject: Added a changelog for 730e903f4534. --- docs/changes.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/changes.xml b/docs/changes.xml index c0cc524e..b3803ffe 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -38,6 +38,13 @@ without listeners. + + +occasionally, the Unit daemon was unable to fully terminate; the bug had +appeared in 1.26.0. + + + -- 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. --- docs/changes.xml | 7 +++++++ src/nxt_php_sapi.c | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index b3803ffe..1d4b9645 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -45,6 +45,13 @@ appeared in 1.26.0. + + +a segmentation fault occurred in the PHP module if chdir() or +fastcgi_finish_request() was called in the OPcache preloading script. + + + 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 ca0dc2954c254081a9b23c1e1f760de0c3fadc66 Mon Sep 17 00:00:00 2001 From: Andrei Belov Date: Wed, 1 Dec 2021 09:01:52 +0300 Subject: Packages: adjusted debhelper minimal version for Debian/Ubuntu. Forgotten in 199a11eceb3c. While here, Standards-Version increased to 4.1.4 (matches Ubuntu 18.04 as the oldest supported distro). --- pkg/deb/debian.module/control-noarch.in | 4 ++-- pkg/deb/debian.module/control.in | 4 ++-- pkg/deb/debian/control.in | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/deb/debian.module/control-noarch.in b/pkg/deb/debian.module/control-noarch.in index d9d9e5e1..323377d9 100644 --- a/pkg/deb/debian.module/control-noarch.in +++ b/pkg/deb/debian.module/control-noarch.in @@ -2,9 +2,9 @@ Source: %%NAME%% Section: admin Priority: extra Maintainer: %%PACKAGE_VENDOR%% -Build-Depends: debhelper (>= 9), +Build-Depends: debhelper (>= 11), linux-libc-dev%%MODULE_BUILD_DEPENDS%% -Standards-Version: 3.9.5 +Standards-Version: 4.1.4 Homepage: https://unit.nginx.org Package: %%NAME%% diff --git a/pkg/deb/debian.module/control.in b/pkg/deb/debian.module/control.in index 9a6fa797..f5ce8ae4 100644 --- a/pkg/deb/debian.module/control.in +++ b/pkg/deb/debian.module/control.in @@ -2,11 +2,11 @@ Source: %%NAME%% Section: admin Priority: extra Maintainer: %%PACKAGE_VENDOR%% -Build-Depends: debhelper (>= 9), +Build-Depends: debhelper (>= 11), linux-libc-dev, libssl-dev, libpcre2-dev%%MODULE_BUILD_DEPENDS%% -Standards-Version: 3.9.5 +Standards-Version: 4.1.4 Homepage: https://unit.nginx.org Package: %%NAME%% diff --git a/pkg/deb/debian/control.in b/pkg/deb/debian/control.in index 4d59520e..691bafed 100644 --- a/pkg/deb/debian/control.in +++ b/pkg/deb/debian/control.in @@ -2,11 +2,11 @@ Source: unit Section: admin Priority: extra Maintainer: %%PACKAGE_VENDOR%% -Build-Depends: debhelper (>= 9), +Build-Depends: debhelper (>= 11), linux-libc-dev, libssl-dev, libpcre2-dev -Standards-Version: 3.9.5 +Standards-Version: 4.1.4 Homepage: https://unit.nginx.org Package: unit -- cgit From c58601c11fd2f2c583d94f31b63c7d16319a2614 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Tue, 30 Nov 2021 17:00:47 +0300 Subject: Docker: respect the binary from CMD in the entrypoint. --- pkg/docker/docker-entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/docker/docker-entrypoint.sh b/pkg/docker/docker-entrypoint.sh index f455a958..59529925 100755 --- a/pkg/docker/docker-entrypoint.sh +++ b/pkg/docker/docker-entrypoint.sh @@ -24,7 +24,7 @@ if [ "$1" = "unitd" -o "$1" = "unitd-debug" ]; then else if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..." - /usr/sbin/unitd --control unix:/var/run/control.unit.sock + /usr/sbin/$1 --control unix:/var/run/control.unit.sock while [ ! -S /var/run/control.unit.sock ]; do echo "$0: Waiting for control socket to be created..."; /bin/sleep 0.1; done # even when the control socket exists, it does not mean unit has finished initialisation -- cgit From cebef9691b891f8cbf611ce65eea7bc8a07874b7 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 1 Dec 2021 11:25:34 +0000 Subject: Tests: fixed skipping tests with disabled OPcache. --- test/php/cwd/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/php/cwd/index.php b/test/php/cwd/index.php index de3797e4..eb2cc5b3 100644 --- a/test/php/cwd/index.php +++ b/test/php/cwd/index.php @@ -11,7 +11,7 @@ $opcache = -1; if (function_exists('opcache_get_status')) { $status = opcache_get_status(); - $opcache = $status['opcache_enabled']; + $opcache = $status['opcache_enabled'] ? '1' : '0'; } header('X-OPcache: ' . $opcache); -- 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(-) 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(+) 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. --- docs/changes.xml | 7 +++++++ src/nxt_application.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/docs/changes.xml b/docs/changes.xml index 1d4b9645..f5792e85 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -52,6 +52,13 @@ fastcgi_finish_request() was called in the OPcache preloading script. + + +a prototype process could crash on an application process exit; the bug had +appeared in 1.26.0. + + + 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 c6c74d117dee5ac747ae53ce7a1e75bb2b7470e1 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Wed, 1 Dec 2021 18:06:38 +0300 Subject: Disabling SCM_CREDS usage on DragonFly BSD. DragonFly BSD supports SCM_CREDS and SCM_RIGHTS, but only the first control message is passed correctly while the second one isn't processed by the kernel. This closes #599 issue on GitHub. --- auto/sockets | 62 +++++++++++++++++++++++++++++--------------------------- docs/changes.xml | 6 ++++++ 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/auto/sockets b/auto/sockets index 1b6b4368..e6ef326d 100644 --- a/auto/sockets +++ b/auto/sockets @@ -166,51 +166,53 @@ if [ $nxt_found = no ]; then fi -nxt_feature="sockopt SO_PASSCRED" -nxt_feature_name=NXT_HAVE_SOCKOPT_SO_PASSCRED -nxt_feature_run= -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="#define _GNU_SOURCE - #include +if [ $NXT_SYSTEM != DragonFly ]; then + nxt_feature="sockopt SO_PASSCRED" + nxt_feature_name=NXT_HAVE_SOCKOPT_SO_PASSCRED + nxt_feature_run= + nxt_feature_incs= + nxt_feature_libs= + nxt_feature_test="#define _GNU_SOURCE + #include - int main() { - return SO_PASSCRED == 0; - }" -. auto/feature + int main() { + return SO_PASSCRED == 0; + }" + . auto/feature -if [ $nxt_found = yes ]; then - nxt_feature="struct ucred" - nxt_feature_name=NXT_HAVE_UCRED + if [ $nxt_found = yes ]; then + nxt_feature="struct ucred" + nxt_feature_name=NXT_HAVE_UCRED + nxt_feature_run= + nxt_feature_incs= + nxt_feature_libs= + nxt_feature_test="#define _GNU_SOURCE + #include + #include + + int main() { + return sizeof(struct ucred); + }" + . auto/feature + fi + + + nxt_feature="struct cmsgcred" + nxt_feature_name=NXT_HAVE_MSGHDR_CMSGCRED nxt_feature_run= nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#define _GNU_SOURCE #include - #include int main() { - return sizeof(struct ucred); + return sizeof(struct cmsgcred); }" . auto/feature fi -nxt_feature="struct cmsgcred" -nxt_feature_name=NXT_HAVE_MSGHDR_CMSGCRED -nxt_feature_run= -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="#define _GNU_SOURCE - #include - - int main() { - return sizeof(struct cmsgcred); - }" -. auto/feature - - nxt_feature="sys/filio.h" nxt_feature_name=NXT_HAVE_SYS_FILIO_H nxt_feature_run= diff --git a/docs/changes.xml b/docs/changes.xml index f5792e85..737fcb33 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -59,6 +59,12 @@ appeared in 1.26.0. + + +fatal errors on DragonFly BSD; the bug had appeared in 1.26.0. + + + -- cgit From 7edc5b82d5e48d5f5d06334af82b891b0ccc3add Mon Sep 17 00:00:00 2001 From: Andrei Belov Date: Thu, 2 Dec 2021 08:52:52 +0300 Subject: Packages: added systemd service for debug binary. --- pkg/deb/debian/rules.in | 3 ++- pkg/deb/debian/unit-debug.service | 14 ++++++++++++++ pkg/rpm/rpmbuild/SOURCES/unit-debug.service | 26 ++++++++++++++++++++++++++ pkg/rpm/unit.spec.in | 12 ++++++++---- 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 pkg/deb/debian/unit-debug.service create mode 100644 pkg/rpm/rpmbuild/SOURCES/unit-debug.service diff --git a/pkg/deb/debian/rules.in b/pkg/deb/debian/rules.in index 3f1f9db8..fe7d5c7c 100644 --- a/pkg/deb/debian/rules.in +++ b/pkg/deb/debian/rules.in @@ -99,7 +99,8 @@ install: build do.tests dh_testroot dh_prep dh_installdirs - dh_installsystemd + dh_installsystemd -punit --name=unit unit.service + dh_installsystemd -punit --name=unit-debug --no-start --no-enable unit-debug.service dh_installlogrotate cd $(BUILDDIR_unit) && DESTDIR=$(INSTALLDIR) make install cd $(BUILDDIR_unit) && DESTDIR=$(INSTALLDIR_dev) make libunit-install diff --git a/pkg/deb/debian/unit-debug.service b/pkg/deb/debian/unit-debug.service new file mode 100644 index 00000000..252d8451 --- /dev/null +++ b/pkg/deb/debian/unit-debug.service @@ -0,0 +1,14 @@ +[Unit] +Description=NGINX Unit +Wants=network-online.target +After=network-online.target + +[Service] +Type=forking +PIDFile=/var/run/unit.pid +EnvironmentFile=-/etc/default/unit +ExecStart=/usr/sbin/unitd-debug $DAEMON_ARGS +ExecReload= + +[Install] +WantedBy=multi-user.target diff --git a/pkg/rpm/rpmbuild/SOURCES/unit-debug.service b/pkg/rpm/rpmbuild/SOURCES/unit-debug.service new file mode 100644 index 00000000..2cef24fb --- /dev/null +++ b/pkg/rpm/rpmbuild/SOURCES/unit-debug.service @@ -0,0 +1,26 @@ +# Modifying this file in-place is not recommended, because changes +# will be overwritten during package upgrades. To customize the +# behaviour, run "systemctl edit unit-debug" to create an override unit. + +# For example, to change options given to the unitd binary at startup, +# create an override unit (as is done by systemctl edit) and enter +# the following: + +# [Service] +# Environment="UNITD_OPTIONS=--log /var/log/unit/unit.log --pid /var/run/unit/unit.pid" + +[Unit] +Description=NGINX Unit +Wants=network-online.target +After=network-online.target + +[Service] +Type=simple +Environment="UNITD_OPTIONS=--log /var/log/unit/unit.log --pid /var/run/unit/unit.pid" +ExecStart=/usr/sbin/unitd-debug $UNITD_OPTIONS --no-daemon +ExecReload= +RuntimeDirectory=unit +RuntimeDirectoryMode=0755 + +[Install] +WantedBy=multi-user.target diff --git a/pkg/rpm/unit.spec.in b/pkg/rpm/unit.spec.in index b35b8998..f643b77f 100644 --- a/pkg/rpm/unit.spec.in +++ b/pkg/rpm/unit.spec.in @@ -39,8 +39,9 @@ Group: System Environment/Daemons Source0: unit-%{version}.tar.gz Source1: unit.service -Source2: unit.example.config -Source3: unit.logrotate +Source2: unit-debug.service +Source3: unit.example.config +Source4: unit.logrotate BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: systemd @@ -112,11 +113,11 @@ DESTDIR=%{buildroot} make unitd-install libunit-install manpage-install %{__mkdir} -p %{buildroot}%{_localstatedir}/log/unit %{__mkdir} -p %{buildroot}%{_localstatedir}/run/unit %{__mkdir} -p %{buildroot}%{_sysconfdir}/logrotate.d -%{__install} -m 644 -p %{SOURCE3} \ +%{__install} -m 644 -p %{SOURCE4} \ %{buildroot}%{_sysconfdir}/logrotate.d/unit %{__mkdir} -p %{buildroot}%{_sysconfdir}/unit %{__mkdir} -p %{buildroot}%{_datadir}/doc/unit/examples -%{__install} -m 644 -p %{SOURCE2} \ +%{__install} -m 644 -p %{SOURCE3} \ %{buildroot}%{_datadir}/doc/unit/examples/example.config %{__install} -m 644 -p CHANGES \ %{buildroot}%{_datadir}/doc/unit/ @@ -127,6 +128,7 @@ DESTDIR=%{buildroot} make unitd-install libunit-install manpage-install %{__rm} -rf %{buildroot}%{_initrddir}/ %{__install} -p -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/unit.service +%{__install} -p -D -m 0644 %{SOURCE2} %{buildroot}%{_unitdir}/unit-debug.service QA_SKIP_BUILD_ROOT=1 export QA_SKIP_BUILD_ROOT @@ -153,6 +155,7 @@ getent passwd unit >/dev/null || \ -d /nonexistent -c "unit user" unit if [ $1 -eq 1 ]; then /usr/bin/systemctl preset unit.service >/dev/null 2>&1 ||: + /usr/bin/systemctl preset unit-debug.service >/dev/null 2>&1 ||: cat < Date: Thu, 2 Dec 2021 14:12:13 +0000 Subject: Fixed grammar in "changes.xml". --- docs/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes.xml b/docs/changes.xml index 737fcb33..e7fe9532 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -33,7 +33,7 @@ NGINX Unit updated to 1.27.0. -the router process crash on reconfiguration if "access_log" was configured +the router process crashed on reconfiguration if "access_log" was configured without listeners. -- cgit From 2a087fa5654954878c00edef6b07a9fe4090475f Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Fri, 3 Dec 2021 03:11:06 +0300 Subject: Printing version in "./configure" output. --- auto/os/test | 3 ++- configure | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/auto/os/test b/auto/os/test index c37700a6..b7e73299 100644 --- a/auto/os/test +++ b/auto/os/test @@ -97,4 +97,5 @@ case "$NXT_SYSTEM" in esac -$echo configuring for $NXT_SYSTEM $NXT_SYSTEM_VERSION $NXT_SYSTEM_PLATFORM +$echo "configuring Unit $NXT_VERSION" \ + "for $NXT_SYSTEM $NXT_SYSTEM_VERSION $NXT_SYSTEM_PLATFORM" diff --git a/configure b/configure index c9264d59..bc21e579 100755 --- a/configure +++ b/configure @@ -67,6 +67,7 @@ case $nxt_module in esac +. ./version . auto/os/test . auto/options -- 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(-) 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 ad843df965f47b5d209603de49d0b3b16938149d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 10 Dec 2021 15:34:52 +0000 Subject: Tests: fixed path to the "php.ini" file. --- test/test_php_application.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/test_php_application.py b/test/test_php_application.py index d9c16a6d..194caa9f 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -294,20 +294,28 @@ class TestPHPApplication(TestApplicationPHP): self.load('ini_precision') assert 'success' in self.conf( - {"file": "php.ini", "admin": {"precision": "5"}}, + {"file": "ini/php.ini", "admin": {"precision": "5"}}, 'applications/ini_precision/options', ) + assert ( + self.get()['headers']['X-File'] + == option.test_dir + '/php/ini_precision/ini/php.ini' + ), 'ini file' assert self.get()['headers']['X-Precision'] == '5', 'ini value admin' def test_php_application_ini_user(self): self.load('ini_precision') assert 'success' in self.conf( - {"file": "php.ini", "user": {"precision": "5"}}, + {"file": "ini/php.ini", "user": {"precision": "5"}}, 'applications/ini_precision/options', ) + assert ( + self.get()['headers']['X-File'] + == option.test_dir + '/php/ini_precision/ini/php.ini' + ), 'ini file' assert self.get()['headers']['X-Precision'] == '5', 'ini value user' def test_php_application_ini_user_2(self): -- cgit From 4b3efcea0dfcc842fb1a0f62b610652323844d35 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Sat, 11 Dec 2021 00:16:59 +0000 Subject: Tests: added more OPcache tests. --- test/php/opcache/index.php | 2 +- test/php/opcache/preload/chdir.php | 7 +++ .../php/opcache/preload/fastcgi_finish_request.php | 5 ++ test/test_php_application.py | 65 ++++++++++++++++++---- 4 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 test/php/opcache/preload/chdir.php create mode 100644 test/php/opcache/preload/fastcgi_finish_request.php diff --git a/test/php/opcache/index.php b/test/php/opcache/index.php index de4002bb..cf67c4c2 100644 --- a/test/php/opcache/index.php +++ b/test/php/opcache/index.php @@ -12,7 +12,7 @@ if (function_exists('opcache_is_script_cached')) { opcache_compile_file(__DIR__ . '/test.php'); } } else { - header('X-Cached: -1'); + header('X-OPcache: -1'); } ?> diff --git a/test/php/opcache/preload/chdir.php b/test/php/opcache/preload/chdir.php new file mode 100644 index 00000000..ad75e6ad --- /dev/null +++ b/test/php/opcache/preload/chdir.php @@ -0,0 +1,7 @@ + diff --git a/test/php/opcache/preload/fastcgi_finish_request.php b/test/php/opcache/preload/fastcgi_finish_request.php new file mode 100644 index 00000000..31630cfa --- /dev/null +++ b/test/php/opcache/preload/fastcgi_finish_request.php @@ -0,0 +1,5 @@ + diff --git a/test/test_php_application.py b/test/test_php_application.py index 194caa9f..97bb9437 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -1,3 +1,4 @@ +import getpass import os import re import shutil @@ -18,18 +19,43 @@ class TestPHPApplication(TestApplicationPHP): assert re.search(r'time: \d+', body), 'disable_functions before time' assert re.search(r'exec: \/\w+', body), 'disable_functions before exec' + def check_opcache(self): + resp = self.get() + assert resp['status'] == 200, 'status' + + headers = resp['headers'] + if 'X-OPcache' in headers and headers['X-OPcache'] == '-1': + pytest.skip('opcache is not supported') + + return resp + def set_opcache(self, app, val): assert 'success' in self.conf( {"admin": {"opcache.enable": val, "opcache.enable_cli": val}}, 'applications/' + app + '/options', ) - opcache = self.get()['headers']['X-OPcache'] - - if not opcache or opcache == '-1': - pytest.skip('opcache is not supported') + r = self.check_opcache() + assert r['headers']['X-OPcache'] == val, 'opcache value' + + def set_preload(self, preload): + with open(option.temp_dir + '/php.ini', 'w') as f: + f.write( + """opcache.preload = %(test_dir)s/php/opcache/preload\ +/%(preload)s +opcache.preload_user = %(user)s +""" + % { + 'test_dir': option.test_dir, + 'preload': preload, + 'user': option.user or getpass.getuser(), + } + ) - assert opcache == val, 'opcache value' + assert 'success' in self.conf( + {"file": option.temp_dir + "/php.ini"}, + 'applications/opcache/options', + ) def test_php_application_variables(self): self.load('variables') @@ -725,16 +751,31 @@ class TestPHPApplication(TestApplicationPHP): def test_php_application_shared_opcache(self): self.load('opcache', limits={'requests': 1}) - r = self.get() - cached = r['headers']['X-Cached'] - if cached == '-1': - pytest.skip('opcache is not supported') - + r = self.check_opcache() pid = r['headers']['X-Pid'] - - assert cached == '0', 'not cached' + assert r['headers']['X-Cached'] == '0', 'not cached' r = self.get() assert r['headers']['X-Pid'] != pid, 'new instance' assert r['headers']['X-Cached'] == '1', 'cached' + + def test_php_application_opcache_preload_chdir(self, temp_dir): + self.load('opcache') + + self.check_opcache() + + self.set_preload('chdir.php') + + assert self.get()['headers']['X-Cached'] == '0', 'not cached' + assert self.get()['headers']['X-Cached'] == '1', 'cached' + + def test_php_application_opcache_preload_ffr(self, temp_dir): + self.load('opcache') + + self.check_opcache() + + self.set_preload('fastcgi_finish_request.php') + + assert self.get()['headers']['X-Cached'] == '0', 'not cached' + assert self.get()['headers']['X-Cached'] == '1', 'cached' -- cgit From 9bea8c452ffea1d9ff78a1bc3ce5c4d2f0d6b95f Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Sun, 12 Dec 2021 21:36:44 +0000 Subject: Tests: fixed type of applications. --- test/test_asgi_lifespan.py | 2 +- test/test_asgi_targets.py | 2 +- test/test_java_application.py | 2 +- test/test_php_application.py | 6 +++--- test/test_php_targets.py | 4 ++-- test/test_proxy.py | 10 +++++----- test/test_python_targets.py | 2 +- test/test_routing.py | 16 ++++++++-------- test/test_upstreams_rr.py | 2 +- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index 912d0d85..dcdd107d 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -67,7 +67,7 @@ class TestASGILifespan(TestApplicationPython): ], "applications": { "targets": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "working_directory": option.test_dir + "/python/lifespan/empty", diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py index b9489cd3..73929783 100644 --- a/test/test_asgi_targets.py +++ b/test/test_asgi_targets.py @@ -28,7 +28,7 @@ class TestASGITargets(TestApplicationPython): ], "applications": { "targets": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "working_directory": option.test_dir + "/python/targets/", diff --git a/test/test_java_application.py b/test/test_java_application.py index 3fd5c26e..aba49e48 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -22,7 +22,7 @@ class TestJavaApplication(TestApplicationJava): "listeners": {"*:7080": {"pass": "applications/app"}}, "applications": { "app": { - "type": "java", + "type": self.get_application_type(), "processes": 1, "working_directory": option.test_dir + "/java/empty", "webapp": temp_dir + "/java", diff --git a/test/test_php_application.py b/test/test_php_application.py index 97bb9437..e6540318 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -600,7 +600,7 @@ opcache.preload_user = %(user)s "listeners": {"*:7080": {"pass": "applications/script"}}, "applications": { "script": { - "type": "php", + "type": self.get_application_type(), "processes": {"spare": 0}, "root": option.test_dir + "/php/script", "script": "phpinfo.php", @@ -620,7 +620,7 @@ opcache.preload_user = %(user)s "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, "applications": { "phpinfo": { - "type": "php", + "type": self.get_application_type(), "processes": {"spare": 0}, "root": option.test_dir + "/php/phpinfo", } @@ -647,7 +647,7 @@ opcache.preload_user = %(user)s "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, "applications": { "phpinfo": { - "type": "php", + "type": self.get_application_type(), "processes": {"spare": 0}, "root": new_root, "working_directory": new_root, diff --git a/test/test_php_targets.py b/test/test_php_targets.py index 76326131..918c5fda 100644 --- a/test/test_php_targets.py +++ b/test/test_php_targets.py @@ -22,7 +22,7 @@ class TestPHPTargets(TestApplicationPHP): ], "applications": { "targets": { - "type": "php", + "type": self.get_application_type(), "processes": {"spare": 0}, "targets": { "1": { @@ -66,7 +66,7 @@ class TestPHPTargets(TestApplicationPHP): }, "applications": { "targets": { - "type": "php", + "type": self.get_application_type(), "processes": {"spare": 0}, "targets": { "default": { diff --git a/test/test_proxy.py b/test/test_proxy.py index 553cb07c..9245ef1c 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -72,7 +72,7 @@ Content-Length: 10 "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}], "applications": { "mirror": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/mirror", "working_directory": option.test_dir @@ -80,7 +80,7 @@ Content-Length: 10 "module": "wsgi", }, "custom_header": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/custom_header", "working_directory": option.test_dir @@ -88,7 +88,7 @@ Content-Length: 10 "module": "wsgi", }, "delayed": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/delayed", "working_directory": option.test_dir @@ -123,7 +123,7 @@ Content-Length: 10 }, "applications": { "mirror": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/mirror", "working_directory": option.test_dir @@ -499,7 +499,7 @@ Content-Length: 10 "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}], "applications": { "mirror": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/mirror", "working_directory": option.test_dir diff --git a/test/test_python_targets.py b/test/test_python_targets.py index e5dca870..8e9ecb87 100644 --- a/test/test_python_targets.py +++ b/test/test_python_targets.py @@ -21,7 +21,7 @@ class TestPythonTargets(TestApplicationPython): ], "applications": { "targets": { - "type": "python", + "type": self.get_application_type(), "working_directory": option.test_dir + "/python/targets/", "path": option.test_dir + '/python/targets/', diff --git a/test/test_routing.py b/test/test_routing.py index 167d2640..a45d0309 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import pytest -from unit.applications.proto import TestApplicationProto +from unit.applications.lang.python import TestApplicationPython from unit.option import option -class TestRouting(TestApplicationProto): +class TestRouting(TestApplicationPython): prerequisites = {'modules': {'python': 'any'}} def setup_method(self): @@ -289,7 +289,7 @@ class TestRouting(TestApplicationProto): "listeners": {"*:7080": {"pass": "applications/" + path}}, "applications": { name: { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + '/python/empty', "working_directory": option.test_dir @@ -313,7 +313,7 @@ class TestRouting(TestApplicationProto): "listeners": {"*:7080": {"pass": "applications/" + path}}, "applications": { name: { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + '/python/empty', "working_directory": option.test_dir @@ -333,7 +333,7 @@ class TestRouting(TestApplicationProto): "listeners": {"*:7081": {"pass": "applications/empty"}}, "applications": { "empty": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + '/python/empty', "working_directory": option.test_dir + '/python/empty', @@ -387,7 +387,7 @@ class TestRouting(TestApplicationProto): { "applications": { "app": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": "/app", "module": "wsgi", @@ -430,7 +430,7 @@ class TestRouting(TestApplicationProto): { "applications": { "app": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": "/app", "module": "wsgi", @@ -476,7 +476,7 @@ class TestRouting(TestApplicationProto): "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}], "applications": { "app": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": "/app", "module": "wsgi", diff --git a/test/test_upstreams_rr.py b/test/test_upstreams_rr.py index 163eb646..4cb6bb2e 100644 --- a/test/test_upstreams_rr.py +++ b/test/test_upstreams_rr.py @@ -274,7 +274,7 @@ Connection: close ], "applications": { "delayed": { - "type": "python", + "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/delayed", "working_directory": option.test_dir -- cgit From 3e0ece20b5ad106905faffa9a0a3a527c3aba88c Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Wed, 1 Dec 2021 18:34:20 +0300 Subject: Docker: made Dockerfiles architecture agnostic. --- pkg/docker/Makefile | 4 ++-- pkg/docker/template.Dockerfile | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index a2c1a52b..18c406a9 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -23,7 +23,7 @@ CONTAINER_go ?= golang:$(VERSION_go) CONFIGURE_go ?= go --go-path=$$GOPATH INSTALL_go ?= go-install-src libunit-install define COPY_go -COPY --from=BUILDER /usr/lib/x86_64-linux-gnu/libunit.a /usr/lib/x86_64-linux-gnu/\n\$ +COPY --from=BUILDER /usr/lib/\*-linux-gnu/libunit.a /tmp/\n\$ COPY --from=BUILDER /usr/include/nxt_* /usr/include/\n\$ COPY --from=BUILDER /go/src/ /go/src/ endef @@ -39,7 +39,7 @@ CONTAINER_node ?= node:$(VERSION_node) CONFIGURE_node ?= nodejs --node-gyp=/usr/local/lib/node_modules/npm/bin/node-gyp-bin/node-gyp INSTALL_node ?= node node-install libunit-install define COPY_node -COPY --from=BUILDER /usr/lib/x86_64-linux-gnu/libunit.a /usr/lib/x86_64-linux-gnu/\n\$ +COPY --from=BUILDER /usr/lib/\*-linux-gnu/libunit.a /tmp/\n\$ COPY --from=BUILDER /usr/include/nxt_* /usr/include/\n\$ COPY --from=BUILDER /usr/local/lib/node_modules/unit-http/ /usr/local/lib/node_modules/unit-http/ endef diff --git a/pkg/docker/template.Dockerfile b/pkg/docker/template.Dockerfile index 55feecc6..2d964eb6 100644 --- a/pkg/docker/template.Dockerfile +++ b/pkg/docker/template.Dockerfile @@ -48,6 +48,10 @@ COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ COPY --from=BUILDER /requirements.apt /requirements.apt @@COPY@@ RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ && mkdir -p /var/lib/unit/ \ && mkdir /docker-entrypoint.d/ \ && addgroup --system unit \ -- cgit From 650784928293bb07b5b4acf4b14d3845b011556d Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Fri, 17 Dec 2021 17:15:55 +0300 Subject: Docker: bumped PHP image version. --- pkg/docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 18c406a9..91038b4c 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -50,7 +50,7 @@ CONFIGURE_perl ?= perl INSTALL_perl ?= perl-install COPY_perl = -VERSION_php ?= 8.0 +VERSION_php ?= 8.1 CONTAINER_php ?= php:$(VERSION_php)-cli CONFIGURE_php ?= php INSTALL_php ?= php-install -- 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. --- docs/changes.xml | 6 ++ src/perl/nxt_perl_psgi.c | 188 +++++++++++++++------------------- src/perl/nxt_perl_psgi_layer.c | 64 +++--------- src/perl/nxt_perl_psgi_layer.h | 28 ++--- test/perl/input_buffered_read/psgi.pl | 17 +++ test/perl/input_close/psgi.pl | 8 ++ test/test_perl_application.py | 22 ++++ 7 files changed, 166 insertions(+), 167 deletions(-) create mode 100644 test/perl/input_buffered_read/psgi.pl create mode 100644 test/perl/input_close/psgi.pl diff --git a/docs/changes.xml b/docs/changes.xml index 8890e4dc..4428401a 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,6 +31,12 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> + + +some Perl applications failed to process the request body, notably with Plack. + + + 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_ */ diff --git a/test/perl/input_buffered_read/psgi.pl b/test/perl/input_buffered_read/psgi.pl new file mode 100644 index 00000000..4ca699d7 --- /dev/null +++ b/test/perl/input_buffered_read/psgi.pl @@ -0,0 +1,17 @@ +use FileHandle; + +my $app = sub { + my ($environ) = @_; + + $environ->{'psgi.input'}->read(my $body, 1024); + + open my $io, "<", \$body; + + # This makes $io work as FileHandle under 5.8, .10 and .11. + bless $io, 'FileHandle'; + + $environ->{'psgix.input.buffered'} = 1; + $environ->{'psgi.input'} = $io; + + return ['200', ['Content-Length' => length $body], [$body]]; +}; diff --git a/test/perl/input_close/psgi.pl b/test/perl/input_close/psgi.pl new file mode 100644 index 00000000..4a2d9bb9 --- /dev/null +++ b/test/perl/input_close/psgi.pl @@ -0,0 +1,8 @@ +my $app = sub { + my ($environ) = @_; + + $environ->{'psgi.input'}->read(my $body, 1024); + $environ->{'psgi.input'}->close(); + + return ['200', ['Content-Length' => length $body], [$body]]; +}; diff --git a/test/test_perl_application.py b/test/test_perl_application.py index dfd8be6c..6803ff76 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -100,6 +100,28 @@ class TestPerlApplication(TestApplicationPerl): self.post(body='0123456789')['body'] == '0123456789' ), 'input read parts' + def test_perl_application_input_buffered_read(self): + self.load('input_buffered_read') + + assert ( + self.post(body='012345')['body'] == '012345' + ), 'buffered read #1' + + assert ( + self.post(body='9876543210')['body'] == '9876543210' + ), 'buffered read #2' + + def test_perl_application_input_close(self): + self.load('input_close') + + assert ( + self.post(body='012345')['body'] == '012345' + ), 'input close #1' + + assert ( + self.post(body='9876543210')['body'] == '9876543210' + ), 'input close #2' + @pytest.mark.skip('not yet') def test_perl_application_input_read_offset(self): self.load('input_read_offset') -- 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. --- docs/changes.xml | 6 ++++++ src/java/nginx/unit/Context.java | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 4428401a..64a35da8 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -37,6 +37,12 @@ some Perl applications failed to process the request body, notably with Plack. + + +some Spring Boot applications failed to start, notably with Grails. + + + 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 1297e8a16a2fb0ccc195c0dd14b678bb2d7fc9fc Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Mon, 10 Jan 2022 16:07:31 +0300 Subject: Tests: using modules in Go. --- auto/modules/go | 3 ++- go/go.mod | 1 + test/conftest.py | 4 +--- test/unit/applications/lang/go.py | 43 +++++++++++++++++++++++++++++---------- test/unit/check/go.py | 36 +++++--------------------------- 5 files changed, 41 insertions(+), 46 deletions(-) create mode 100644 go/go.mod diff --git a/auto/modules/go b/auto/modules/go index 7324ffbe..a8596bf3 100644 --- a/auto/modules/go +++ b/auto/modules/go @@ -111,7 +111,8 @@ install: ${NXT_GO}-install ${NXT_GO}: ${NXT_GO}-install: ${NXT_GO}-install-src ${NXT_GO}-install-env - GOPATH=\$(DESTDIR)\$(GOPATH) GO111MODULE=auto ${NXT_GO} build ${NXT_GO_PKG} + cd \$(DESTDIR)\$(NXT_GO_DST)/src/${NXT_GO_PKG} && \ + GOPATH=\$(DESTDIR)\$(GOPATH) ${NXT_GO} build ${NXT_GO_PKG} ${NXT_GO}-install-src: install -d \$(DESTDIR)\$(NXT_GO_DST)/src/${NXT_GO_PKG} diff --git a/go/go.mod b/go/go.mod new file mode 100644 index 00000000..2c0431db --- /dev/null +++ b/go/go.mod @@ -0,0 +1 @@ +module unit.nginx.org/go diff --git a/test/conftest.py b/test/conftest.py index 689c857a..966bb8f5 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -203,9 +203,7 @@ def pytest_sessionstart(session): # discover modules from check option.available['modules']['openssl'] = check_openssl(unit['unitd']) - option.available['modules']['go'] = check_go( - option.current_dir, unit['temp_dir'], option.test_dir - ) + option.available['modules']['go'] = check_go() option.available['modules']['node'] = check_node(option.current_dir) option.available['modules']['regex'] = check_regex(unit['unitd']) diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 367059e6..67501e9c 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -1,4 +1,5 @@ import os +import shutil import subprocess from unit.applications.proto import TestApplicationProto @@ -6,14 +7,25 @@ from unit.option import option class TestApplicationGo(TestApplicationProto): - def prepare_env(self, script, name, static=False): - if not os.path.exists(option.temp_dir + '/go'): - os.mkdir(option.temp_dir + '/go') + @staticmethod + def prepare_env(script, name='app', static=False): + temp_dir = option.temp_dir + '/go/' + + if not os.path.exists(temp_dir): + os.mkdir(temp_dir) + + cache_dir = option.cache_dir + '/go-build' + + if not os.path.exists(cache_dir): + os.mkdir(cache_dir) env = os.environ.copy() env['GOPATH'] = option.current_dir + '/build/go' - env['GOCACHE'] = option.cache_dir + '/go' - env['GO111MODULE'] = 'auto' + env['GOCACHE'] = cache_dir + + shutil.copy2( + option.test_dir + '/go/' + script + '/' + name + '.go', + temp_dir) if static: args = [ @@ -24,23 +36,32 @@ class TestApplicationGo(TestApplicationProto): '-ldflags', '-extldflags "-static"', '-o', - option.temp_dir + '/go/' + name, - option.test_dir + '/go/' + script + '/' + name + '.go', + temp_dir + name, + temp_dir + name + '.go', ] else: args = [ 'go', 'build', '-o', - option.temp_dir + '/go/' + name, - option.test_dir + '/go/' + script + '/' + name + '.go', + temp_dir + name, + temp_dir + name + '.go', ] + replace_path = option.current_dir + '/build/go/src/unit.nginx.org/go' + + with open(temp_dir + 'go.mod', 'w') as f: + f.write( + f"""module test/app +require unit.nginx.org/go v0.0.0 +replace unit.nginx.org/go => {replace_path} +""") + if option.detailed: print("\n$ GOPATH=" + env['GOPATH'] + " " + " ".join(args)) try: - process = subprocess.run(args, env=env) + process = subprocess.run(args, env=env, cwd=temp_dir) except KeyboardInterrupt: raise @@ -61,7 +82,7 @@ class TestApplicationGo(TestApplicationProto): executable = "/go/" + name static_build = True - self.prepare_env(script, name, static=static_build) + TestApplicationGo.prepare_env(script, name, static=static_build) conf = { "listeners": {"*:7080": {"pass": "applications/" + script}}, diff --git a/test/unit/check/go.py b/test/unit/check/go.py index cc17f0fe..3d9d13e7 100644 --- a/test/unit/check/go.py +++ b/test/unit/check/go.py @@ -1,34 +1,8 @@ -import os -import subprocess +from unit.applications.lang.go import TestApplicationGo -def check_go(current_dir, temp_dir, test_dir): - if not os.path.exists(temp_dir + '/go'): - os.mkdir(temp_dir + '/go') +def check_go(): + process = TestApplicationGo.prepare_env('empty') - env = os.environ.copy() - env['GOPATH'] = current_dir + '/build/go' - env['GO111MODULE'] = 'auto' - - try: - process = subprocess.run( - [ - 'go', - 'build', - '-o', - temp_dir + '/go/app', - test_dir + '/go/empty/app.go', - ], - env=env, - stderr=subprocess.STDOUT, - stdout=subprocess.PIPE, - ) - - if process.returncode == 0: - return True - - except KeyboardInterrupt: - raise - - except subprocess.CalledProcessError: - return None + if process != None and process.returncode == 0: + return True -- cgit From 485886d8f9a665e9c416a98dd00e5c836b6bf27c Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 13 Jan 2022 11:35:12 +0300 Subject: Docker: bumped Python image version. --- pkg/docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 91038b4c..39261b0a 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -56,7 +56,7 @@ CONFIGURE_php ?= php INSTALL_php ?= php-install COPY_php = RUN ldconfig -VERSION_python ?= 3.9 +VERSION_python ?= 3.10 CONTAINER_python ?= python:$(VERSION_python) CONFIGURE_python ?= python --config=/usr/local/bin/python3-config INSTALL_python ?= python3-install -- cgit From e53ce40c5854d95722cdfc198626fcd5aecbe563 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 31 Jan 2022 23:10:30 +0000 Subject: Tests: removed TestApplicationTLS.get_server_certificate(). distutils.version is replaced by packaging.version. Also minor style fixes. --- test/test_asgi_application.py | 6 ++++-- test/test_asgi_lifespan.py | 6 ++++-- test/test_asgi_targets.py | 7 ++++--- test/test_asgi_websockets.py | 6 ++++-- test/test_client_ip.py | 28 +++++++++++++++++++--------- test/test_go_application.py | 1 - test/test_node_es_modules.py | 5 ++--- test/test_perl_application.py | 10 ++-------- test/test_static.py | 3 ++- test/test_static_fallback.py | 5 ++++- test/test_static_types.py | 5 ++++- test/test_tls.py | 12 ++++++++---- test/test_variables.py | 12 ++++-------- test/unit/applications/tls.py | 15 --------------- 14 files changed, 61 insertions(+), 60 deletions(-) diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index 021aa2b2..60fcffc1 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -1,14 +1,16 @@ import re import time -from distutils.version import LooseVersion import pytest +from packaging import version from unit.applications.lang.python import TestApplicationPython class TestASGIApplication(TestApplicationPython): prerequisites = { - 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')} + 'modules': { + 'python': lambda v: version.parse(v) >= version.parse('3.5') + } } load_module = 'asgi' diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index dcdd107d..e295f7fa 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -1,14 +1,16 @@ import os -from distutils.version import LooseVersion from conftest import unit_stop +from packaging import version from unit.applications.lang.python import TestApplicationPython from unit.option import option class TestASGILifespan(TestApplicationPython): prerequisites = { - 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')} + 'modules': { + 'python': lambda v: version.parse(v) >= version.parse('3.5') + } } load_module = 'asgi' diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py index 73929783..c1e345ef 100644 --- a/test/test_asgi_targets.py +++ b/test/test_asgi_targets.py @@ -1,13 +1,14 @@ -from distutils.version import LooseVersion - import pytest +from packaging import version from unit.applications.lang.python import TestApplicationPython from unit.option import option class TestASGITargets(TestApplicationPython): prerequisites = { - 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')} + 'modules': { + 'python': lambda v: version.parse(v) >= version.parse('3.5') + } } load_module = 'asgi' diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py index bad54e22..feb99fbb 100644 --- a/test/test_asgi_websockets.py +++ b/test/test_asgi_websockets.py @@ -1,8 +1,8 @@ import struct import time -from distutils.version import LooseVersion import pytest +from packaging import version from unit.applications.lang.python import TestApplicationPython from unit.applications.websockets import TestApplicationWebsocket from unit.option import option @@ -10,7 +10,9 @@ from unit.option import option class TestASGIWebsockets(TestApplicationPython): prerequisites = { - 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')} + 'modules': { + 'python': lambda v: version.parse(v) >= version.parse('3.5') + } } load_module = 'asgi' diff --git a/test/test_client_ip.py b/test/test_client_ip.py index 4b2b2fa1..53e52201 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -7,10 +7,14 @@ class TestClientIP(TestApplicationPython): def client_ip(self, options): assert 'success' in self.conf( { - "127.0.0.1:7081": - {"client_ip": options, "pass": "applications/client_ip"}, - "[::1]:7082": - {"client_ip": options, "pass": "applications/client_ip"}, + "127.0.0.1:7081": { + "client_ip": options, + "pass": "applications/client_ip", + }, + "[::1]:7082": { + "client_ip": options, + "pass": "applications/client_ip", + }, }, 'listeners', ), 'listeners configure' @@ -48,9 +52,7 @@ class TestClientIP(TestApplicationPython): ), 'ipv6 default 2' assert self.get_xff('1.1.1.1') == '1.1.1.1', 'replace' assert self.get_xff('blah') == '127.0.0.1', 'bad header 2' - assert ( - self.get_xff('1.1.1.1', 'ipv6') == '::1' - ), 'bad source ipv6 2' + assert self.get_xff('1.1.1.1', 'ipv6') == '::1', 'bad source ipv6 2' self.client_ip({'header': 'X-Forwarded-For', 'source': '!127.0.0.1'}) @@ -118,10 +120,18 @@ class TestClientIP(TestApplicationPython): def test_settings_client_ip_invalid(self): assert 'error' in self.conf( - {"http": {"client_ip": {'header': 'X-Forwarded-For', 'source': []}}}, + { + "http": { + "client_ip": {'header': 'X-Forwarded-For', 'source': []} + } + }, 'settings', ), 'empty array source' assert 'error' in self.conf( - {"http":{"client_ip": {'header': 'X-Forwarded-For', 'source': 'a'}}}, + { + "http": { + "client_ip": {'header': 'X-Forwarded-For', 'source': 'a'} + } + }, 'settings', ), 'empty source invalid' diff --git a/test/test_go_application.py b/test/test_go_application.py index 94da1aee..7c897b20 100644 --- a/test/test_go_application.py +++ b/test/test_go_application.py @@ -1,7 +1,6 @@ import re import pytest - from unit.applications.lang.go import TestApplicationGo diff --git a/test/test_node_es_modules.py b/test/test_node_es_modules.py index 12788fa4..8a9cb181 100644 --- a/test/test_node_es_modules.py +++ b/test/test_node_es_modules.py @@ -1,5 +1,4 @@ -from distutils.version import LooseVersion - +from packaging import version from unit.applications.lang.node import TestApplicationNode from unit.applications.websockets import TestApplicationWebsocket @@ -7,7 +6,7 @@ from unit.applications.websockets import TestApplicationWebsocket class TestNodeESModules(TestApplicationNode): prerequisites = { 'modules': { - 'node': lambda v: LooseVersion(v) >= LooseVersion("14.16.0") + 'node': lambda v: version.parse(v) >= version.parse('14.16.0') } } diff --git a/test/test_perl_application.py b/test/test_perl_application.py index 6803ff76..32d2b703 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -103,10 +103,7 @@ class TestPerlApplication(TestApplicationPerl): def test_perl_application_input_buffered_read(self): self.load('input_buffered_read') - assert ( - self.post(body='012345')['body'] == '012345' - ), 'buffered read #1' - + assert self.post(body='012345')['body'] == '012345', 'buffered read #1' assert ( self.post(body='9876543210')['body'] == '9876543210' ), 'buffered read #2' @@ -114,10 +111,7 @@ class TestPerlApplication(TestApplicationPerl): def test_perl_application_input_close(self): self.load('input_close') - assert ( - self.post(body='012345')['body'] == '012345' - ), 'input close #1' - + assert self.post(body='012345')['body'] == '012345', 'input close #1' assert ( self.post(body='9876543210')['body'] == '9876543210' ), 'input close #2' diff --git a/test/test_static.py b/test/test_static.py index 80f4c610..1d9c754a 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -3,7 +3,8 @@ import shutil import socket import pytest -from conftest import unit_run, unit_stop +from conftest import unit_run +from conftest import unit_stop from unit.applications.proto import TestApplicationProto from unit.option import option from unit.utils import waitforfiles diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py index 71b268c8..1f1a1df7 100644 --- a/test/test_static_fallback.py +++ b/test/test_static_fallback.py @@ -82,7 +82,10 @@ class TestStaticFallback(TestApplicationProto): def test_static_fallback_share(self, temp_dir): self.action_update( - {"share": "/blah", "fallback": {"share": temp_dir + "/assets$uri"},} + { + "share": "/blah", + "fallback": {"share": temp_dir + "/assets$uri"}, + } ) resp = self.get() diff --git a/test/test_static_types.py b/test/test_static_types.py index 18564a21..0e86517b 100644 --- a/test/test_static_types.py +++ b/test/test_static_types.py @@ -85,7 +85,10 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_regex(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["~text/(html|plain)"]} + { + "share": temp_dir + "/assets$uri", + "types": ["~text/(html|plain)"], + } ) assert self.get(url='/file.php')['status'] == 403, 'regex fail' self.check_body('/file.html', '.html') diff --git a/test/test_tls.py b/test/test_tls.py index 01336765..c4471f3f 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -175,11 +175,13 @@ basicConstraints = critical,CA:TRUE""" self.add_tls() - cert_old = self.get_server_certificate() + cert_old = ssl.get_server_certificate(('127.0.0.1', 7080)) self.certificate() - assert cert_old != self.get_server_certificate(), 'update certificate' + assert cert_old != ssl.get_server_certificate( + ('127.0.0.1', 7080) + ), 'update certificate' @pytest.mark.skip('not yet') def test_tls_certificate_key_incorrect(self): @@ -200,11 +202,13 @@ basicConstraints = critical,CA:TRUE""" self.add_tls() - cert_old = self.get_server_certificate() + cert_old = ssl.get_server_certificate(('127.0.0.1', 7080)) self.add_tls(cert='new') - assert cert_old != self.get_server_certificate(), 'change certificate' + assert cert_old != ssl.get_server_certificate( + ('127.0.0.1', 7080) + ), 'change certificate' def test_tls_certificate_key_rsa(self): self.load('empty') diff --git a/test/test_variables.py b/test/test_variables.py index d8547b7b..f110fb74 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -103,20 +103,16 @@ class TestVariables(TestApplicationProto): def test_variables_empty(self): def update_pass(prefix): assert 'success' in self.conf( - { - "listeners": { - "*:7080": {"pass": prefix + "/$method"}, - }, - }, + {"listeners": {"*:7080": {"pass": prefix + "/$method"}}}, ), 'variables empty' - update_pass("routes"); + update_pass("routes") assert self.get(url='/1')['status'] == 404 - update_pass("upstreams"); + update_pass("upstreams") assert self.get(url='/2')['status'] == 404 - update_pass("applications"); + update_pass("applications") assert self.get(url='/3')['status'] == 404 def test_variables_invalid(self): diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py index c7254235..93400328 100644 --- a/test/unit/applications/tls.py +++ b/test/unit/applications/tls.py @@ -52,21 +52,6 @@ class TestApplicationTLS(TestApplicationProto): def post_ssl(self, **kwargs): return self.post(wrapper=self.context.wrap_socket, **kwargs) - def get_server_certificate(self, addr=('127.0.0.1', 7080)): - - ssl_list = dir(ssl) - - if 'PROTOCOL_TLS' in ssl_list: - ssl_version = ssl.PROTOCOL_TLS - - elif 'PROTOCOL_TLSv1_2' in ssl_list: - ssl_version = ssl.PROTOCOL_TLSv1_2 - - else: - ssl_version = ssl.PROTOCOL_TLSv1_1 - - return ssl.get_server_certificate(addr, ssl_version=ssl_version) - def openssl_conf(self, rewrite=False, alt_names=[]): conf_path = option.temp_dir + '/openssl.conf' -- 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. --- docs/changes.xml | 7 +++++++ src/python/nxt_python_asgi.c | 18 ++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 64a35da8..a6b1178d 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -43,6 +43,13 @@ some Spring Boot applications failed to start, notably with Grails. + + +incorrect Python protocol auto detection (ASGI or WSGI) for native callable +object, notably with Falcon. + + + 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(-) 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. --- docs/changes.xml | 7 +++++++ src/nxt_cert.c | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/changes.xml b/docs/changes.xml index a6b1178d..3ef1ac3f 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,6 +31,13 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> + + +the controller process could crash when a chain with more than 4 +certificates was uploaded. + + + some Perl applications failed to process the request body, notably with Plack. 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 5857754ec75312c426b9277a34d0b3cfd237d22e Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Tue, 15 Feb 2022 18:21:10 +0300 Subject: Updated copyright notice. --- NOTICE | 12 +++++++----- pkg/deb/debian.module/copyright.unit-jsc10 | 15 +++++++++++---- pkg/deb/debian.module/copyright.unit-jsc11 | 15 +++++++++++---- pkg/deb/debian.module/copyright.unit-jsc8 | 15 +++++++++++---- pkg/deb/debian/copyright | 12 +++++++----- pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 | 15 +++++++++++---- pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 | 15 +++++++++++---- pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 | 15 +++++++++++---- 8 files changed, 80 insertions(+), 34 deletions(-) diff --git a/NOTICE b/NOTICE index ef97b24f..73274140 100644 --- a/NOTICE +++ b/NOTICE @@ -1,13 +1,15 @@ NGINX Unit. - Copyright 2017-2021 NGINX, Inc. + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty Copyright 2017-2021 Igor Sysoev - Copyright 2017-2021 Valentin V. Bartenev - Copyright 2017-2021 Max Romanov - Copyright 2017-2021 Andrei Zeliankou Copyright 2017-2021 Andrei Belov - Copyright 2018-2021 Konstantin Pavlov Copyright 2019-2021 Tiago Natel de Moura Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov diff --git a/pkg/deb/debian.module/copyright.unit-jsc10 b/pkg/deb/debian.module/copyright.unit-jsc10 index dbad728b..42dbd3b9 100644 --- a/pkg/deb/debian.module/copyright.unit-jsc10 +++ b/pkg/deb/debian.module/copyright.unit-jsc10 @@ -1,10 +1,17 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty + Copyright 2017-2021 Igor Sysoev + Copyright 2017-2021 Andrei Belov + Copyright 2019-2021 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pkg/deb/debian.module/copyright.unit-jsc11 b/pkg/deb/debian.module/copyright.unit-jsc11 index 413c0094..b2e4a117 100644 --- a/pkg/deb/debian.module/copyright.unit-jsc11 +++ b/pkg/deb/debian.module/copyright.unit-jsc11 @@ -1,10 +1,17 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty + Copyright 2017-2021 Igor Sysoev + Copyright 2017-2021 Andrei Belov + Copyright 2019-2021 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pkg/deb/debian.module/copyright.unit-jsc8 b/pkg/deb/debian.module/copyright.unit-jsc8 index 96b62102..1dab9cce 100644 --- a/pkg/deb/debian.module/copyright.unit-jsc8 +++ b/pkg/deb/debian.module/copyright.unit-jsc8 @@ -1,10 +1,17 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty + Copyright 2017-2021 Igor Sysoev + Copyright 2017-2021 Andrei Belov + Copyright 2019-2021 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pkg/deb/debian/copyright b/pkg/deb/debian/copyright index 2a2c5fd0..487c92c5 100644 --- a/pkg/deb/debian/copyright +++ b/pkg/deb/debian/copyright @@ -1,13 +1,15 @@ NGINX Unit. - Copyright 2017-2021 NGINX, Inc. + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty Copyright 2017-2021 Igor Sysoev - Copyright 2017-2021 Valentin V. Bartenev - Copyright 2017-2021 Max Romanov - Copyright 2017-2021 Andrei Zeliankou Copyright 2017-2021 Andrei Belov - Copyright 2018-2021 Konstantin Pavlov Copyright 2019-2021 Tiago Natel de Moura Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov diff --git a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 index 665785b2..c7860e4b 100644 --- a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 +++ b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 @@ -1,10 +1,17 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty + Copyright 2017-2021 Igor Sysoev + Copyright 2017-2021 Andrei Belov + Copyright 2019-2021 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 index e92a8245..b08fcc34 100644 --- a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 +++ b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 @@ -1,10 +1,17 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty + Copyright 2017-2021 Igor Sysoev + Copyright 2017-2021 Andrei Belov + Copyright 2019-2021 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 index 1e7dbff6..5e31863d 100644 --- a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 +++ b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 @@ -1,10 +1,17 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2022 NGINX, Inc. + Copyright 2017-2022 Valentin V. Bartenev + Copyright 2017-2022 Max Romanov + Copyright 2017-2022 Andrei Zeliankou + Copyright 2018-2022 Konstantin Pavlov + Copyright 2021-2022 Zhidao Hong + Copyright 2021-2022 Oisín Canty + Copyright 2017-2021 Igor Sysoev + Copyright 2017-2021 Andrei Belov + Copyright 2019-2021 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); -- cgit From 170752e96fe06cbf78037ad50563d25ce5e668ec Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 15 Feb 2022 21:43:02 +0000 Subject: Tests: added test with long certificate chain. --- test/test_tls.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/test_tls.py b/test/test_tls.py index c4471f3f..fb28bc88 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -389,6 +389,51 @@ basicConstraints = critical,CA:TRUE""" self.get_ssl()['status'] == 200 ), 'certificate chain intermediate server' + def test_tls_certificate_chain_long(self, temp_dir): + self.load('empty') + + self.generate_ca_conf() + + # Minimum chain length is 3. + chain_length = 10 + + for i in range(chain_length): + if i == 0: + self.certificate('root', False) + elif i == chain_length - 1: + self.req('end') + else: + self.req('int{}'.format(i)) + + for i in range(chain_length - 1): + if i == 0: + self.ca(cert='root', out='int1') + elif i == chain_length - 2: + self.ca(cert='int{}'.format(chain_length - 2), out='end') + else: + self.ca(cert='int{}'.format(i), out='int{}'.format(i + 1)) + + for i in range(chain_length - 1, 0, -1): + path = temp_dir + ( + '/end.crt' if i == chain_length - 1 else '/int{}.crt'.format(i) + ) + + with open(temp_dir + '/all.crt', 'a') as chain, open(path) as cert: + chain.write(cert.read()) + + self.set_certificate_req_context() + + assert 'success' in self.certificate_load( + 'all', 'end' + ), 'certificate chain upload' + + chain = self.conf_get('/certificates/all/chain') + assert len(chain) == chain_length - 1, 'certificate chain length' + + self.add_tls(cert='all') + + assert self.get_ssl()['status'] == 200, 'certificate chain long' + def test_tls_certificate_empty_cn(self, temp_dir): self.certificate('root', False) -- 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. --- docs/changes.xml | 6 ++++++ src/nxt_malloc.c | 13 ++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 3ef1ac3f..2e2f9b04 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,6 +31,12 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> + + +compatibility with GCC 12. + + + the controller process could crash when a chain with more than 4 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 0f725346603f4de4473d12da502104b188ac02a4 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 11 Apr 2022 21:05:14 +0100 Subject: Tests: style. --- test/conftest.py | 24 +++++----- test/python/204_no_content/asgi.py | 12 +++-- test/test_asgi_websockets.py | 92 ++++++++++++++++++------------------ test/test_go_application.py | 8 +--- test/test_go_isolation.py | 4 +- test/test_http_header.py | 16 +++---- test/test_java_application.py | 44 +++++------------ test/test_java_isolation_rootfs.py | 5 +- test/test_java_websockets.py | 90 +++++++++++++++++------------------ test/test_node_application.py | 4 +- test/test_node_websockets.py | 90 +++++++++++++++++------------------ test/test_perl_application.py | 3 +- test/test_php_application.py | 11 ++--- test/test_proxy.py | 9 ++-- test/test_proxy_chunked.py | 14 +++--- test/test_python_application.py | 4 +- test/test_python_isolation.py | 7 +-- test/test_python_isolation_chroot.py | 4 +- test/test_respawn.py | 3 +- test/test_routing.py | 41 +++++++++------- test/test_ruby_application.py | 9 ++-- test/test_ruby_hooks.py | 5 +- test/test_ruby_isolation.py | 6 ++- test/test_settings.py | 20 ++------ test/test_static.py | 28 ++++++----- test/test_static_chroot.py | 27 +++++++---- test/test_static_mount.py | 4 +- test/test_tls.py | 4 +- test/test_tls_sni.py | 7 ++- test/test_tls_tickets.py | 7 ++- test/test_upstreams_rr.py | 3 +- test/test_usr1.py | 4 +- test/unit/applications/lang/go.py | 7 +-- test/unit/applications/websockets.py | 10 ++-- test/unit/control.py | 4 -- test/unit/http.py | 4 +- 36 files changed, 291 insertions(+), 343 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 966bb8f5..bed56331 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -159,9 +159,7 @@ def pytest_generate_tests(metafunc): type + ' ' + available_versions[0] ) elif callable(prereq_version): - generate_tests( - list(filter(prereq_version, available_versions)) - ) + generate_tests(list(filter(prereq_version, available_versions))) else: raise ValueError( @@ -320,9 +318,7 @@ def run(request): public_dir(path) - if os.path.isfile(path) or stat.S_ISSOCK( - os.stat(path).st_mode - ): + if os.path.isfile(path) or stat.S_ISSOCK(os.stat(path).st_mode): os.remove(path) else: for attempt in range(10): @@ -520,7 +516,7 @@ def _clear_conf(sock, *, log=None): try: certs = json.loads( - http.get(url='/certificates', sock_type='unix', addr=sock,)['body'] + http.get(url='/certificates', sock_type='unix', addr=sock)['body'] ).keys() except json.JSONDecodeError: @@ -528,7 +524,9 @@ def _clear_conf(sock, *, log=None): for cert in certs: resp = http.delete( - url='/certificates/' + cert, sock_type='unix', addr=sock, + url='/certificates/' + cert, + sock_type='unix', + addr=sock, )['body'] assert 'success' in resp, 'remove certificate' @@ -554,9 +552,7 @@ def _check_fds(*, log=None): ) ps['fds'] += fds_diff - assert ( - fds_diff <= option.fds_threshold - ), 'descriptors leak main process' + assert fds_diff <= option.fds_threshold, 'descriptors leak main process' else: ps['fds'] = _count_fds(unit_instance['pid']) @@ -588,7 +584,8 @@ def _count_fds(pid): try: out = subprocess.check_output( - ['procstat', '-f', pid], stderr=subprocess.STDOUT, + ['procstat', '-f', pid], + stderr=subprocess.STDOUT, ).decode() return len(out.splitlines()) @@ -597,7 +594,8 @@ def _count_fds(pid): try: out = subprocess.check_output( - ['lsof', '-n', '-p', pid], stderr=subprocess.STDOUT, + ['lsof', '-n', '-p', pid], + stderr=subprocess.STDOUT, ).decode() return len(out.splitlines()) diff --git a/test/python/204_no_content/asgi.py b/test/python/204_no_content/asgi.py index 634facc2..5dbb67d0 100644 --- a/test/python/204_no_content/asgi.py +++ b/test/python/204_no_content/asgi.py @@ -1,8 +1,10 @@ async def application(scope, receive, send): assert scope['type'] == 'http' - await send({ - 'type': 'http.response.start', - 'status': 204, - 'headers': [], - }) + await send( + { + 'type': 'http.response.start', + 'status': 204, + 'headers': [], + } + ) diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py index feb99fbb..975be90a 100644 --- a/test/test_asgi_websockets.py +++ b/test/test_asgi_websockets.py @@ -164,7 +164,7 @@ class TestASGIWebsockets(TestApplicationPython): self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False) self.ws.frame_write( - sock, self.ws.OP_CONT, 'fragment2', length=2 ** 64 - 1 + sock, self.ws.OP_CONT, 'fragment2', length=2**64 - 1 ) self.check_close(sock, 1009) # 1009 - CLOSE_TOO_LARGE @@ -942,9 +942,7 @@ class TestASGIWebsockets(TestApplicationPython): frame = self.ws.frame_read(sock) if frame['opcode'] == self.ws.OP_TEXT: - self.check_frame( - frame, True, self.ws.OP_TEXT, 'fragment1fragment2' - ) + self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') frame = None self.check_close(sock, 1002, frame=frame) @@ -1189,7 +1187,7 @@ class TestASGIWebsockets(TestApplicationPython): _, sock, _ = self.ws.upgrade() - self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10) + self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10) self.ws.frame_write(sock, self.ws.OP_TEXT, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) @@ -1351,62 +1349,62 @@ class TestASGIWebsockets(TestApplicationPython): def check_message(opcode, f_size): if opcode == self.ws.OP_TEXT: - payload = '*' * 4 * 2 ** 20 + payload = '*' * 4 * 2**20 else: - payload = b'*' * 4 * 2 ** 20 + payload = b'*' * 4 * 2**20 self.ws.message(sock, opcode, payload, fragmention_size=f_size) frame = self.ws.frame_read(sock, read_timeout=5) self.check_frame(frame, True, opcode, payload) - check_payload(op_text, 64 * 2 ** 10) # 9_1_1 - check_payload(op_text, 256 * 2 ** 10) # 9_1_2 - check_payload(op_text, 2 ** 20) # 9_1_3 - check_payload(op_text, 4 * 2 ** 20) # 9_1_4 - check_payload(op_text, 8 * 2 ** 20) # 9_1_5 - check_payload(op_text, 16 * 2 ** 20) # 9_1_6 + check_payload(op_text, 64 * 2**10) # 9_1_1 + check_payload(op_text, 256 * 2**10) # 9_1_2 + check_payload(op_text, 2**20) # 9_1_3 + check_payload(op_text, 4 * 2**20) # 9_1_4 + check_payload(op_text, 8 * 2**20) # 9_1_5 + check_payload(op_text, 16 * 2**20) # 9_1_6 - check_payload(op_binary, 64 * 2 ** 10) # 9_2_1 - check_payload(op_binary, 256 * 2 ** 10) # 9_2_2 - check_payload(op_binary, 2 ** 20) # 9_2_3 - check_payload(op_binary, 4 * 2 ** 20) # 9_2_4 - check_payload(op_binary, 8 * 2 ** 20) # 9_2_5 - check_payload(op_binary, 16 * 2 ** 20) # 9_2_6 + check_payload(op_binary, 64 * 2**10) # 9_2_1 + check_payload(op_binary, 256 * 2**10) # 9_2_2 + check_payload(op_binary, 2**20) # 9_2_3 + check_payload(op_binary, 4 * 2**20) # 9_2_4 + check_payload(op_binary, 8 * 2**20) # 9_2_5 + check_payload(op_binary, 16 * 2**20) # 9_2_6 if option.system != 'Darwin' and option.system != 'FreeBSD': check_message(op_text, 64) # 9_3_1 check_message(op_text, 256) # 9_3_2 - check_message(op_text, 2 ** 10) # 9_3_3 - check_message(op_text, 4 * 2 ** 10) # 9_3_4 - check_message(op_text, 16 * 2 ** 10) # 9_3_5 - check_message(op_text, 64 * 2 ** 10) # 9_3_6 - check_message(op_text, 256 * 2 ** 10) # 9_3_7 - check_message(op_text, 2 ** 20) # 9_3_8 - check_message(op_text, 4 * 2 ** 20) # 9_3_9 + check_message(op_text, 2**10) # 9_3_3 + check_message(op_text, 4 * 2**10) # 9_3_4 + check_message(op_text, 16 * 2**10) # 9_3_5 + check_message(op_text, 64 * 2**10) # 9_3_6 + check_message(op_text, 256 * 2**10) # 9_3_7 + check_message(op_text, 2**20) # 9_3_8 + check_message(op_text, 4 * 2**20) # 9_3_9 check_message(op_binary, 64) # 9_4_1 check_message(op_binary, 256) # 9_4_2 - check_message(op_binary, 2 ** 10) # 9_4_3 - check_message(op_binary, 4 * 2 ** 10) # 9_4_4 - check_message(op_binary, 16 * 2 ** 10) # 9_4_5 - check_message(op_binary, 64 * 2 ** 10) # 9_4_6 - check_message(op_binary, 256 * 2 ** 10) # 9_4_7 - check_message(op_binary, 2 ** 20) # 9_4_8 - check_message(op_binary, 4 * 2 ** 20) # 9_4_9 - - check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1 - check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2 - check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3 - check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4 - check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5 - check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6 - - check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1 - check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2 - check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3 - check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4 - check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5 - check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6 + check_message(op_binary, 2**10) # 9_4_3 + check_message(op_binary, 4 * 2**10) # 9_4_4 + check_message(op_binary, 16 * 2**10) # 9_4_5 + check_message(op_binary, 64 * 2**10) # 9_4_6 + check_message(op_binary, 256 * 2**10) # 9_4_7 + check_message(op_binary, 2**20) # 9_4_8 + check_message(op_binary, 4 * 2**20) # 9_4_9 + + check_payload(op_text, 2**20, chopsize=64) # 9_5_1 + check_payload(op_text, 2**20, chopsize=128) # 9_5_2 + check_payload(op_text, 2**20, chopsize=256) # 9_5_3 + check_payload(op_text, 2**20, chopsize=512) # 9_5_4 + check_payload(op_text, 2**20, chopsize=1024) # 9_5_5 + check_payload(op_text, 2**20, chopsize=2048) # 9_5_6 + + check_payload(op_binary, 2**20, chopsize=64) # 9_6_1 + check_payload(op_binary, 2**20, chopsize=128) # 9_6_2 + check_payload(op_binary, 2**20, chopsize=256) # 9_6_3 + check_payload(op_binary, 2**20, chopsize=512) # 9_6_4 + check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5 + check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6 self.close_connection(sock) diff --git a/test/test_go_application.py b/test/test_go_application.py index 7c897b20..c8cf3e53 100644 --- a/test/test_go_application.py +++ b/test/test_go_application.py @@ -157,9 +157,7 @@ class TestGoApplication(TestApplicationGo): 'applications/command_line_arguments/arguments', ) - assert ( - self.get()['body'] == arg1 + ',' + arg2 + ',' + arg3 - ), 'arguments' + assert self.get()['body'] == arg1 + ',' + arg2 + ',' + arg3, 'arguments' def test_go_application_command_line_arguments_change(self): self.load('command_line_arguments') @@ -176,6 +174,4 @@ class TestGoApplication(TestApplicationGo): assert 'success' in self.conf('[]', args_path) - assert ( - self.get()['headers']['Content-Length'] == '0' - ), 'arguments empty' + assert self.get()['headers']['Content-Length'] == '0', 'arguments empty' diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index 72988a34..c3f92679 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -167,9 +167,7 @@ class TestGoIsolation(TestApplicationGo): user='nobody', isolation={ 'namespaces': {'credential': True}, - 'uidmap': [ - {'container': 0, 'host': 0, 'size': nobody_uid + 1} - ], + 'uidmap': [{'container': 0, 'host': 0, 'size': nobody_uid + 1}], }, ) diff --git a/test/test_http_header.py b/test/test_http_header.py index ca355eb7..6773c44f 100644 --- a/test/test_http_header.py +++ b/test/test_http_header.py @@ -213,7 +213,7 @@ Connection: close self.post( headers={ 'Host': 'localhost', - 'Content-Length': str(2 ** 64), + 'Content-Length': str(2**64), 'Connection': 'close', }, body='X' * 1000, @@ -325,9 +325,7 @@ Connection: close def test_http_header_host_port_empty(self): self.load('host') - resp = self.get( - headers={'Host': 'exmaple.com:', 'Connection': 'close'} - ) + resp = self.get(headers={'Host': 'exmaple.com:', 'Connection': 'close'}) assert resp['status'] == 200, 'Host port empty status' assert ( @@ -376,9 +374,7 @@ Connection: close def test_http_header_host_trailing_period_2(self): self.load('host') - resp = self.get( - headers={'Host': 'EXAMPLE.COM.', 'Connection': 'close'} - ) + resp = self.get(headers={'Host': 'EXAMPLE.COM.', 'Connection': 'close'}) assert resp['status'] == 200, 'Host trailing period 2 status' assert ( @@ -453,14 +449,16 @@ Connection: close assert 'CUSTOM' not in resp['headers']['All-Headers'] assert 'success' in self.conf( - {'http': {'discard_unsafe_fields': False}}, 'settings', + {'http': {'discard_unsafe_fields': False}}, + 'settings', ) resp = check_status("!#$%&'*+.^`|~Custom_Header") assert 'CUSTOM' in resp['headers']['All-Headers'] assert 'success' in self.conf( - {'http': {'discard_unsafe_fields': True}}, 'settings', + {'http': {'discard_unsafe_fields': True}}, + 'settings', ) resp = check_status("!Custom-Header") diff --git a/test/test_java_application.py b/test/test_java_application.py index aba49e48..adcb4eca 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -173,9 +173,7 @@ class TestJavaApplication(TestApplicationJava): } ) - assert ( - resp['headers']['X-Session-Id'] == session_id - ), 'session active 2' + assert resp['headers']['X-Session-Id'] == session_id, 'session active 2' time.sleep(2) @@ -187,9 +185,7 @@ class TestJavaApplication(TestApplicationJava): } ) - assert ( - resp['headers']['X-Session-Id'] == session_id - ), 'session active 3' + assert resp['headers']['X-Session-Id'] == session_id, 'session active 3' def test_java_application_session_inactive(self): self.load('session_inactive') @@ -213,9 +209,7 @@ class TestJavaApplication(TestApplicationJava): } ) - assert ( - resp['headers']['X-Session-Id'] != session_id - ), 'session inactive' + assert resp['headers']['X-Session-Id'] != session_id, 'session inactive' def test_java_application_session_invalidate(self): self.load('session_invalidate') @@ -391,9 +385,7 @@ class TestJavaApplication(TestApplicationJava): assert ( headers['X-Content-Type'] == 'text/plain;charset=utf-8' ), '#1 response Content-Type' - assert ( - headers['X-Character-Encoding'] == 'utf-8' - ), '#1 response charset' + assert headers['X-Character-Encoding'] == 'utf-8', '#1 response charset' headers = self.get(url='/2')['headers'] @@ -445,15 +437,11 @@ class TestJavaApplication(TestApplicationJava): headers = self.get(url='/6')['headers'] - assert ( - 'Content-Type' in headers - ) == False, '#6 no Content-Type header' + assert ('Content-Type' in headers) == False, '#6 no Content-Type header' assert ( 'X-Content-Type' in headers ) == False, '#6 no response Content-Type' - assert ( - headers['X-Character-Encoding'] == 'utf-8' - ), '#6 response charset' + assert headers['X-Character-Encoding'] == 'utf-8', '#6 response charset' headers = self.get(url='/7')['headers'] @@ -463,9 +451,7 @@ class TestJavaApplication(TestApplicationJava): assert ( headers['X-Content-Type'] == 'text/plain;charset=utf-8' ), '#7 response Content-Type' - assert ( - headers['X-Character-Encoding'] == 'utf-8' - ), '#7 response charset' + assert headers['X-Character-Encoding'] == 'utf-8', '#7 response charset' headers = self.get(url='/8')['headers'] @@ -475,9 +461,7 @@ class TestJavaApplication(TestApplicationJava): assert ( headers['X-Content-Type'] == 'text/html;charset=utf-8' ), '#8 response Content-Type' - assert ( - headers['X-Character-Encoding'] == 'utf-8' - ), '#8 response charset' + assert headers['X-Character-Encoding'] == 'utf-8', '#8 response charset' def test_java_application_welcome_files(self): self.load('welcome_files') @@ -490,9 +474,7 @@ class TestJavaApplication(TestApplicationJava): resp = self.get(url='/dir1/') - assert ( - 'This is index.txt.' in resp['body'] - ) == True, 'dir1 index body' + assert ('This is index.txt.' in resp['body']) == True, 'dir1 index body' assert resp['headers']['X-TXT-Filter'] == '1', 'TXT Filter header' headers = self.get(url='/dir2/')['headers'] @@ -655,9 +637,7 @@ class TestJavaApplication(TestApplicationJava): assert ( headers['X-FORWARD-Id'] == 'data' ), 'forward request servlet mapping' - assert ( - headers['X-FORWARD-Request-URI'] == '/fwd' - ), 'forward request uri' + assert headers['X-FORWARD-Request-URI'] == '/fwd', 'forward request uri' assert ( headers['X-FORWARD-Servlet-Path'] == '/fwd' ), 'forward request servlet path' @@ -1003,9 +983,7 @@ class TestJavaApplication(TestApplicationJava): ) assert resp['status'] == 200, 'multipart status' - assert re.search( - r'sample\.txt created', resp['body'] - ), 'multipart body' + assert re.search(r'sample\.txt created', resp['body']), 'multipart body' assert ( self.search_in_log( r'^Data from sample file$', name=reldst + '/sample.txt' diff --git a/test/test_java_isolation_rootfs.py b/test/test_java_isolation_rootfs.py index eac86a0c..3c6a45a3 100644 --- a/test/test_java_isolation_rootfs.py +++ b/test/test_java_isolation_rootfs.py @@ -11,7 +11,7 @@ class TestJavaIsolationRootfs(TestApplicationJava): def setup_method(self, is_su): if not is_su: - return + pytest.skip('require root') os.makedirs(option.temp_dir + '/jars') os.makedirs(option.temp_dir + '/tmp') @@ -61,7 +61,8 @@ class TestJavaIsolationRootfs(TestApplicationJava): self.load('empty_war', isolation=isolation) assert 'success' in self.conf( - '"/"', '/config/applications/empty_war/working_directory', + '"/"', + '/config/applications/empty_war/working_directory', ) assert 'success' in self.conf( diff --git a/test/test_java_websockets.py b/test/test_java_websockets.py index a80d3bf3..362c8619 100644 --- a/test/test_java_websockets.py +++ b/test/test_java_websockets.py @@ -869,9 +869,7 @@ class TestJavaWebsockets(TestApplicationJava): frame = self.ws.frame_read(sock) if frame['opcode'] == self.ws.OP_TEXT: - self.check_frame( - frame, True, self.ws.OP_TEXT, 'fragment1fragment2' - ) + self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') frame = None self.check_close(sock, 1002, frame=frame) @@ -1116,7 +1114,7 @@ class TestJavaWebsockets(TestApplicationJava): _, sock, _ = self.ws.upgrade() - self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10) + self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10) self.ws.frame_write(sock, self.ws.OP_TEXT, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) @@ -1278,62 +1276,62 @@ class TestJavaWebsockets(TestApplicationJava): def check_message(opcode, f_size): if opcode == self.ws.OP_TEXT: - payload = '*' * 4 * 2 ** 20 + payload = '*' * 4 * 2**20 else: - payload = b'*' * 4 * 2 ** 20 + payload = b'*' * 4 * 2**20 self.ws.message(sock, opcode, payload, fragmention_size=f_size) frame = self.ws.frame_read(sock, read_timeout=5) self.check_frame(frame, True, opcode, payload) - check_payload(op_text, 64 * 2 ** 10) # 9_1_1 - check_payload(op_text, 256 * 2 ** 10) # 9_1_2 - check_payload(op_text, 2 ** 20) # 9_1_3 - check_payload(op_text, 4 * 2 ** 20) # 9_1_4 - check_payload(op_text, 8 * 2 ** 20) # 9_1_5 - check_payload(op_text, 16 * 2 ** 20) # 9_1_6 + check_payload(op_text, 64 * 2**10) # 9_1_1 + check_payload(op_text, 256 * 2**10) # 9_1_2 + check_payload(op_text, 2**20) # 9_1_3 + check_payload(op_text, 4 * 2**20) # 9_1_4 + check_payload(op_text, 8 * 2**20) # 9_1_5 + check_payload(op_text, 16 * 2**20) # 9_1_6 - check_payload(op_binary, 64 * 2 ** 10) # 9_2_1 - check_payload(op_binary, 256 * 2 ** 10) # 9_2_2 - check_payload(op_binary, 2 ** 20) # 9_2_3 - check_payload(op_binary, 4 * 2 ** 20) # 9_2_4 - check_payload(op_binary, 8 * 2 ** 20) # 9_2_5 - check_payload(op_binary, 16 * 2 ** 20) # 9_2_6 + check_payload(op_binary, 64 * 2**10) # 9_2_1 + check_payload(op_binary, 256 * 2**10) # 9_2_2 + check_payload(op_binary, 2**20) # 9_2_3 + check_payload(op_binary, 4 * 2**20) # 9_2_4 + check_payload(op_binary, 8 * 2**20) # 9_2_5 + check_payload(op_binary, 16 * 2**20) # 9_2_6 if option.system != 'Darwin' and option.system != 'FreeBSD': check_message(op_text, 64) # 9_3_1 check_message(op_text, 256) # 9_3_2 - check_message(op_text, 2 ** 10) # 9_3_3 - check_message(op_text, 4 * 2 ** 10) # 9_3_4 - check_message(op_text, 16 * 2 ** 10) # 9_3_5 - check_message(op_text, 64 * 2 ** 10) # 9_3_6 - check_message(op_text, 256 * 2 ** 10) # 9_3_7 - check_message(op_text, 2 ** 20) # 9_3_8 - check_message(op_text, 4 * 2 ** 20) # 9_3_9 + check_message(op_text, 2**10) # 9_3_3 + check_message(op_text, 4 * 2**10) # 9_3_4 + check_message(op_text, 16 * 2**10) # 9_3_5 + check_message(op_text, 64 * 2**10) # 9_3_6 + check_message(op_text, 256 * 2**10) # 9_3_7 + check_message(op_text, 2**20) # 9_3_8 + check_message(op_text, 4 * 2**20) # 9_3_9 check_message(op_binary, 64) # 9_4_1 check_message(op_binary, 256) # 9_4_2 - check_message(op_binary, 2 ** 10) # 9_4_3 - check_message(op_binary, 4 * 2 ** 10) # 9_4_4 - check_message(op_binary, 16 * 2 ** 10) # 9_4_5 - check_message(op_binary, 64 * 2 ** 10) # 9_4_6 - check_message(op_binary, 256 * 2 ** 10) # 9_4_7 - check_message(op_binary, 2 ** 20) # 9_4_8 - check_message(op_binary, 4 * 2 ** 20) # 9_4_9 - - check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1 - check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2 - check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3 - check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4 - check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5 - check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6 - - check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1 - check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2 - check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3 - check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4 - check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5 - check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6 + check_message(op_binary, 2**10) # 9_4_3 + check_message(op_binary, 4 * 2**10) # 9_4_4 + check_message(op_binary, 16 * 2**10) # 9_4_5 + check_message(op_binary, 64 * 2**10) # 9_4_6 + check_message(op_binary, 256 * 2**10) # 9_4_7 + check_message(op_binary, 2**20) # 9_4_8 + check_message(op_binary, 4 * 2**20) # 9_4_9 + + check_payload(op_text, 2**20, chopsize=64) # 9_5_1 + check_payload(op_text, 2**20, chopsize=128) # 9_5_2 + check_payload(op_text, 2**20, chopsize=256) # 9_5_3 + check_payload(op_text, 2**20, chopsize=512) # 9_5_4 + check_payload(op_text, 2**20, chopsize=1024) # 9_5_5 + check_payload(op_text, 2**20, chopsize=2048) # 9_5_6 + + check_payload(op_binary, 2**20, chopsize=64) # 9_6_1 + check_payload(op_binary, 2**20, chopsize=128) # 9_6_2 + check_payload(op_binary, 2**20, chopsize=256) # 9_6_3 + check_payload(op_binary, 2**20, chopsize=512) # 9_6_4 + check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5 + check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6 self.close_connection(sock) diff --git a/test/test_node_application.py b/test/test_node_application.py index 62a09c43..fc722582 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -218,9 +218,7 @@ class TestNodeApplication(TestApplicationNode): def test_node_application_status_message(self): self.load('status_message') - assert re.search( - r'200 blah', self.get(raw_resp=True) - ), 'status message' + assert re.search(r'200 blah', self.get(raw_resp=True)), 'status message' def test_node_application_get_header_type(self): self.load('get_header_type') diff --git a/test/test_node_websockets.py b/test/test_node_websockets.py index e4c8a05e..1f9a2e6b 100644 --- a/test/test_node_websockets.py +++ b/test/test_node_websockets.py @@ -888,9 +888,7 @@ class TestNodeWebsockets(TestApplicationNode): frame = self.ws.frame_read(sock) if frame['opcode'] == self.ws.OP_TEXT: - self.check_frame( - frame, True, self.ws.OP_TEXT, 'fragment1fragment2' - ) + self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2') frame = None self.check_close(sock, 1002, frame=frame) @@ -1135,7 +1133,7 @@ class TestNodeWebsockets(TestApplicationNode): _, sock, _ = self.ws.upgrade() - self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10) + self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10) self.ws.frame_write(sock, self.ws.OP_TEXT, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close()) @@ -1297,62 +1295,62 @@ class TestNodeWebsockets(TestApplicationNode): def check_message(opcode, f_size): if opcode == self.ws.OP_TEXT: - payload = '*' * 4 * 2 ** 20 + payload = '*' * 4 * 2**20 else: - payload = b'*' * 4 * 2 ** 20 + payload = b'*' * 4 * 2**20 self.ws.message(sock, opcode, payload, fragmention_size=f_size) frame = self.ws.frame_read(sock, read_timeout=5) self.check_frame(frame, True, opcode, payload) - check_payload(op_text, 64 * 2 ** 10) # 9_1_1 - check_payload(op_text, 256 * 2 ** 10) # 9_1_2 - check_payload(op_text, 2 ** 20) # 9_1_3 - check_payload(op_text, 4 * 2 ** 20) # 9_1_4 - check_payload(op_text, 8 * 2 ** 20) # 9_1_5 - check_payload(op_text, 16 * 2 ** 20) # 9_1_6 + check_payload(op_text, 64 * 2**10) # 9_1_1 + check_payload(op_text, 256 * 2**10) # 9_1_2 + check_payload(op_text, 2**20) # 9_1_3 + check_payload(op_text, 4 * 2**20) # 9_1_4 + check_payload(op_text, 8 * 2**20) # 9_1_5 + check_payload(op_text, 16 * 2**20) # 9_1_6 - check_payload(op_binary, 64 * 2 ** 10) # 9_2_1 - check_payload(op_binary, 256 * 2 ** 10) # 9_2_2 - check_payload(op_binary, 2 ** 20) # 9_2_3 - check_payload(op_binary, 4 * 2 ** 20) # 9_2_4 - check_payload(op_binary, 8 * 2 ** 20) # 9_2_5 - check_payload(op_binary, 16 * 2 ** 20) # 9_2_6 + check_payload(op_binary, 64 * 2**10) # 9_2_1 + check_payload(op_binary, 256 * 2**10) # 9_2_2 + check_payload(op_binary, 2**20) # 9_2_3 + check_payload(op_binary, 4 * 2**20) # 9_2_4 + check_payload(op_binary, 8 * 2**20) # 9_2_5 + check_payload(op_binary, 16 * 2**20) # 9_2_6 if option.system != 'Darwin' and option.system != 'FreeBSD': check_message(op_text, 64) # 9_3_1 check_message(op_text, 256) # 9_3_2 - check_message(op_text, 2 ** 10) # 9_3_3 - check_message(op_text, 4 * 2 ** 10) # 9_3_4 - check_message(op_text, 16 * 2 ** 10) # 9_3_5 - check_message(op_text, 64 * 2 ** 10) # 9_3_6 - check_message(op_text, 256 * 2 ** 10) # 9_3_7 - check_message(op_text, 2 ** 20) # 9_3_8 - check_message(op_text, 4 * 2 ** 20) # 9_3_9 + check_message(op_text, 2**10) # 9_3_3 + check_message(op_text, 4 * 2**10) # 9_3_4 + check_message(op_text, 16 * 2**10) # 9_3_5 + check_message(op_text, 64 * 2**10) # 9_3_6 + check_message(op_text, 256 * 2**10) # 9_3_7 + check_message(op_text, 2**20) # 9_3_8 + check_message(op_text, 4 * 2**20) # 9_3_9 check_message(op_binary, 64) # 9_4_1 check_message(op_binary, 256) # 9_4_2 - check_message(op_binary, 2 ** 10) # 9_4_3 - check_message(op_binary, 4 * 2 ** 10) # 9_4_4 - check_message(op_binary, 16 * 2 ** 10) # 9_4_5 - check_message(op_binary, 64 * 2 ** 10) # 9_4_6 - check_message(op_binary, 256 * 2 ** 10) # 9_4_7 - check_message(op_binary, 2 ** 20) # 9_4_8 - check_message(op_binary, 4 * 2 ** 20) # 9_4_9 - - check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1 - check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2 - check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3 - check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4 - check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5 - check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6 - - check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1 - check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2 - check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3 - check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4 - check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5 - check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6 + check_message(op_binary, 2**10) # 9_4_3 + check_message(op_binary, 4 * 2**10) # 9_4_4 + check_message(op_binary, 16 * 2**10) # 9_4_5 + check_message(op_binary, 64 * 2**10) # 9_4_6 + check_message(op_binary, 256 * 2**10) # 9_4_7 + check_message(op_binary, 2**20) # 9_4_8 + check_message(op_binary, 4 * 2**20) # 9_4_9 + + check_payload(op_text, 2**20, chopsize=64) # 9_5_1 + check_payload(op_text, 2**20, chopsize=128) # 9_5_2 + check_payload(op_text, 2**20, chopsize=256) # 9_5_3 + check_payload(op_text, 2**20, chopsize=512) # 9_5_4 + check_payload(op_text, 2**20, chopsize=1024) # 9_5_5 + check_payload(op_text, 2**20, chopsize=2048) # 9_5_6 + + check_payload(op_binary, 2**20, chopsize=64) # 9_6_1 + check_payload(op_binary, 2**20, chopsize=128) # 9_6_2 + check_payload(op_binary, 2**20, chopsize=256) # 9_6_3 + check_payload(op_binary, 2**20, chopsize=512) # 9_6_4 + check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5 + check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6 self.close_connection(sock) diff --git a/test/test_perl_application.py b/test/test_perl_application.py index 32d2b703..0d1d7906 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -134,8 +134,7 @@ class TestPerlApplication(TestApplicationPerl): assert self.get()['body'] == '1', 'errors result' assert ( - self.wait_for_record(r'\[error\].+Error in application') - is not None + self.wait_for_record(r'\[error\].+Error in application') is not None ), 'errors print' def test_perl_application_header_equal_names(self): diff --git a/test/test_php_application.py b/test/test_php_application.py index e6540318..606ac723 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -419,9 +419,7 @@ opcache.preload_user = %(user)s body = self.get()['body'] - assert not re.search( - r'time: \d+', body - ), 'disable_functions comma time' + assert not re.search(r'time: \d+', body), 'disable_functions comma time' assert not re.search( r'exec: \/\w+', body ), 'disable_functions comma exec' @@ -498,9 +496,7 @@ opcache.preload_user = %(user)s body = self.get()['body'] - assert not re.search( - r'time: \d+', body - ), 'disable_functions space time' + assert not re.search(r'time: \d+', body), 'disable_functions space time' assert not re.search( r'exec: \/\w+', body ), 'disable_functions space exec' @@ -671,7 +667,8 @@ opcache.preload_user = %(user)s assert resp['body'] == script_cwd, 'default cwd' assert 'success' in self.conf( - '"' + option.test_dir + '"', 'applications/cwd/working_directory', + '"' + option.test_dir + '"', + 'applications/cwd/working_directory', ) resp = self.get() diff --git a/test/test_proxy.py b/test/test_proxy.py index 9245ef1c..68ae2394 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -75,8 +75,7 @@ Content-Length: 10 "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/mirror", - "working_directory": option.test_dir - + "/python/mirror", + "working_directory": option.test_dir + "/python/mirror", "module": "wsgi", }, "custom_header": { @@ -126,8 +125,7 @@ Content-Length: 10 "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/mirror", - "working_directory": option.test_dir - + "/python/mirror", + "working_directory": option.test_dir + "/python/mirror", "module": "wsgi", } }, @@ -502,8 +500,7 @@ Content-Length: 10 "type": self.get_application_type(), "processes": {"spare": 0}, "path": option.test_dir + "/python/mirror", - "working_directory": option.test_dir - + "/python/mirror", + "working_directory": option.test_dir + "/python/mirror", "module": "wsgi", }, }, diff --git a/test/test_proxy_chunked.py b/test/test_proxy_chunked.py index 73d94332..f024eaf5 100644 --- a/test/test_proxy_chunked.py +++ b/test/test_proxy_chunked.py @@ -90,12 +90,13 @@ class TestProxyChunked(TestApplicationPython): assert 'success' in self.conf( { - "listeners": {"*:7080": {"pass": "routes"},}, + "listeners": { + "*:7080": {"pass": "routes"}, + }, "routes": [ { "action": { - "proxy": "http://127.0.0.1:" - + str(self.SERVER_PORT) + "proxy": "http://127.0.0.1:" + str(self.SERVER_PORT) } } ], @@ -166,9 +167,7 @@ class TestProxyChunked(TestApplicationPython): assert ( self.get_http10( - body=self.chunks( - [('1', hex(i % 16)[2:]) for i in range(4096)] - ), + body=self.chunks([('1', hex(i % 16)[2:]) for i in range(4096)]), )['body'] == part * 256 ) @@ -210,8 +209,7 @@ class TestProxyChunked(TestApplicationPython): assert resp['body'][-5:] != '0\r\n\r\n', 'no zero chunk' assert ( - self.get_http10(body='\r\n\r\n80000000\r\nA X 100')['status'] - == 200 + self.get_http10(body='\r\n\r\n80000000\r\nA X 100')['status'] == 200 ) assert ( self.get_http10(body='\r\n\r\n10000000000000000\r\nA X 100')[ diff --git a/test/test_python_application.py b/test/test_python_application.py index 7bd43664..9463b792 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -735,9 +735,7 @@ last line: 987654321 'nobody uid user=nobody group=%s' % group ) - assert obj['GID'] == group_id, ( - 'nobody gid user=nobody group=%s' % group - ) + assert obj['GID'] == group_id, 'nobody gid user=nobody group=%s' % group self.load('user_group', group=group) diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py index 53d28285..8cef6812 100644 --- a/test/test_python_isolation.py +++ b/test/test_python_isolation.py @@ -56,9 +56,7 @@ class TestPythonIsolation(TestApplicationPython): ret = self.getjson(url='/?path=/app/python/ns_inspect') - assert ( - ret['body']['FileExists'] == True - ), 'application exists in rootfs' + assert ret['body']['FileExists'] == True, 'application exists in rootfs' def test_python_isolation_rootfs_no_language_deps(self, is_su, temp_dir): if not is_su: @@ -93,8 +91,7 @@ class TestPythonIsolation(TestApplicationPython): self.load('ns_inspect', isolation=isolation) assert ( - self.getjson(url='/?path=/proc/self')['body']['FileExists'] - == False + self.getjson(url='/?path=/proc/self')['body']['FileExists'] == False ), 'no /proc/self' isolation['automount']['procfs'] = True diff --git a/test/test_python_isolation_chroot.py b/test/test_python_isolation_chroot.py index 1554fb72..8e5b5fce 100644 --- a/test/test_python_isolation_chroot.py +++ b/test/test_python_isolation_chroot.py @@ -35,6 +35,4 @@ class TestPythonIsolation(TestApplicationPython): ret = self.getjson(url='/?path=/app/python/ns_inspect') - assert ( - ret['body']['FileExists'] == True - ), 'application exists in rootfs' + assert ret['body']['FileExists'] == True, 'application exists in rootfs' diff --git a/test/test_respawn.py b/test/test_respawn.py index 5a5d6126..19d97d37 100644 --- a/test/test_respawn.py +++ b/test/test_respawn.py @@ -82,8 +82,7 @@ class TestRespawn(TestApplicationPython): skip_alert(r'process %s exited on signal 9' % pid) assert ( - self.wait_for_process(self.PATTERN_CONTROLLER, unit_pid) - is not None + self.wait_for_process(self.PATTERN_CONTROLLER, unit_pid) is not None ) assert self.get()['status'] == 200 diff --git a/test/test_routing.py b/test/test_routing.py index a45d0309..fda429a4 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -12,7 +12,10 @@ class TestRouting(TestApplicationPython): { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ - {"match": {"method": "GET"}, "action": {"return": 200},} + { + "match": {"method": "GET"}, + "action": {"return": 200}, + } ], "applications": {}, } @@ -490,11 +493,15 @@ class TestRouting(TestApplicationPython): 'routes/0/action', ), 'proxy share' assert 'error' in self.conf( - {"proxy": "http://127.0.0.1:7081", "pass": "applications/app",}, + { + "proxy": "http://127.0.0.1:7081", + "pass": "applications/app", + }, 'routes/0/action', ), 'proxy pass' assert 'error' in self.conf( - {"share": temp_dir, "pass": "applications/app"}, 'routes/0/action', + {"share": temp_dir, "pass": "applications/app"}, + 'routes/0/action', ), 'share pass' def test_routes_rules_two(self): @@ -693,7 +700,8 @@ class TestRouting(TestApplicationPython): assert self.post()['status'] == 404, 'routes edit POST' assert 'success' in self.conf_post( - {"match": {"method": "POST"}, "action": {"return": 200}}, 'routes', + {"match": {"method": "POST"}, "action": {"return": 200}}, + 'routes', ), 'routes edit configure 2' assert 'GET' == self.conf_get( 'routes/0/match/method' @@ -733,7 +741,8 @@ class TestRouting(TestApplicationPython): assert self.post()['status'] == 404, 'routes edit POST 5' assert 'success' in self.conf_post( - {"match": {"method": "POST"}, "action": {"return": 200}}, 'routes', + {"match": {"method": "POST"}, "action": {"return": 200}}, + 'routes', ), 'routes edit configure 6' assert self.get()['status'] == 404, 'routes edit GET 6' @@ -1042,9 +1051,7 @@ class TestRouting(TestApplicationPython): def check_headers(hds): hds = dict({"Host": "localhost", "Connection": "close"}, **hds) - assert ( - self.get(headers=hds)['status'] == 200 - ), 'headers array match' + assert self.get(headers=hds)['status'] == 200, 'headers array match' def check_headers_404(hds): hds = dict({"Host": "localhost", "Connection": "close"}, **hds) @@ -1262,9 +1269,7 @@ class TestRouting(TestApplicationPython): self.get(url='/?foo=bar&blah=test')['status'] == 200 ), 'multiple 2' assert self.get(url='/?foo=bar&blah')['status'] == 404, 'multiple 3' - assert ( - self.get(url='/?foo=bar&blah=tes')['status'] == 404 - ), 'multiple 4' + assert self.get(url='/?foo=bar&blah=tes')['status'] == 404, 'multiple 4' assert ( self.get(url='/?foo=b%61r&bl%61h=t%65st')['status'] == 200 ), 'multiple 5' @@ -1494,9 +1499,7 @@ class TestRouting(TestApplicationPython): sock, port = sock_port() sock2, port2 = sock_port() - self.route_match( - {"source": "127.0.0.1:" + str(port) + "-" + str(port)} - ) + self.route_match({"source": "127.0.0.1:" + str(port) + "-" + str(port)}) assert self.get(sock=sock)['status'] == 200, 'range single' assert self.get(sock=sock2)['status'] == 404, 'range single 2' @@ -1544,7 +1547,10 @@ class TestRouting(TestApplicationPython): def test_routes_source_addr(self): assert 'success' in self.conf( - {"*:7080": {"pass": "routes"}, "[::1]:7081": {"pass": "routes"},}, + { + "*:7080": {"pass": "routes"}, + "[::1]:7081": {"pass": "routes"}, + }, 'listeners', ), 'source listeners configure' @@ -1650,7 +1656,10 @@ class TestRouting(TestApplicationPython): def test_routes_source_cidr(self): assert 'success' in self.conf( - {"*:7080": {"pass": "routes"}, "[::1]:7081": {"pass": "routes"},}, + { + "*:7080": {"pass": "routes"}, + "[::1]:7081": {"pass": "routes"}, + }, 'listeners', ), 'source listeners configure' diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index ed0200d9..319dfb4f 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -175,8 +175,7 @@ class TestRubyApplication(TestApplicationRuby): self.get() assert ( - self.wait_for_record(r'\[error\].+Error in application') - is not None + self.wait_for_record(r'\[error\].+Error in application') is not None ), 'errors puts' def test_ruby_application_errors_puts_int(self): @@ -194,8 +193,7 @@ class TestRubyApplication(TestApplicationRuby): self.get() assert ( - self.wait_for_record(r'\[error\].+Error in application') - is not None + self.wait_for_record(r'\[error\].+Error in application') is not None ), 'errors write' def test_ruby_application_errors_write_to_s_custom(self): @@ -229,7 +227,8 @@ class TestRubyApplication(TestApplicationRuby): try: locales = ( subprocess.check_output( - ['locale', '-a'], stderr=subprocess.STDOUT, + ['locale', '-a'], + stderr=subprocess.STDOUT, ) .decode() .split('\n') diff --git a/test/test_ruby_hooks.py b/test/test_ruby_hooks.py index 20980ad7..b4a79ebb 100644 --- a/test/test_ruby_hooks.py +++ b/test/test_ruby_hooks.py @@ -81,7 +81,10 @@ class TestRubyHooks(TestApplicationRuby): threads = 1 self.load( - 'hooks', processes=processes, threads=threads, hooks='multiple.rb', + 'hooks', + processes=processes, + threads=threads, + hooks='multiple.rb', ) hooked = self._wait_cookie('worker_boot.*', processes) diff --git a/test/test_ruby_isolation.py b/test/test_ruby_isolation.py index 940427f1..ea208523 100644 --- a/test/test_ruby_isolation.py +++ b/test/test_ruby_isolation.py @@ -34,11 +34,13 @@ class TestRubyIsolation(TestApplicationRuby): self.load('status_int', isolation=isolation) assert 'success' in self.conf( - '"/ruby/status_int/config.ru"', 'applications/status_int/script', + '"/ruby/status_int/config.ru"', + 'applications/status_int/script', ) assert 'success' in self.conf( - '"/ruby/status_int"', 'applications/status_int/working_directory', + '"/ruby/status_int"', + 'applications/status_int/working_directory', ) assert self.get()['status'] == 200, 'status int' diff --git a/test/test_settings.py b/test/test_settings.py index a16e35e8..ea3cfb99 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -207,9 +207,7 @@ Connection: close {"unix:" + addr: {'application': 'body_generate'}}, 'listeners' ) - assert 'success' in self.conf( - {'http': {'send_timeout': 1}}, 'settings' - ) + assert 'success' in self.conf({'http': {'send_timeout': 1}}, 'settings') data = req(addr, data_len) assert re.search(r'200 OK', data), 'send timeout status' @@ -237,14 +235,10 @@ Connection: close assert self.get()['status'] == 200, 'init' - assert 'success' in self.conf( - {'http': {'idle_timeout': 2}}, 'settings' - ) + assert 'success' in self.conf({'http': {'idle_timeout': 2}}, 'settings') assert req()['status'] == 408, 'status idle timeout' - assert 'success' in self.conf( - {'http': {'idle_timeout': 7}}, 'settings' - ) + assert 'success' in self.conf({'http': {'idle_timeout': 7}}, 'settings') assert req()['status'] == 200, 'status idle timeout 2' def test_settings_idle_timeout_2(self): @@ -259,14 +253,10 @@ Connection: close assert self.get()['status'] == 200, 'init' - assert 'success' in self.conf( - {'http': {'idle_timeout': 1}}, 'settings' - ) + assert 'success' in self.conf({'http': {'idle_timeout': 1}}, 'settings') assert req()['status'] == 408, 'status idle timeout' - assert 'success' in self.conf( - {'http': {'idle_timeout': 7}}, 'settings' - ) + assert 'success' in self.conf({'http': {'idle_timeout': 7}}, 'settings') assert req()['status'] == 200, 'status idle timeout 2' def test_settings_max_body_size(self): diff --git a/test/test_static.py b/test/test_static.py index 1d9c754a..5ec49f38 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -133,7 +133,8 @@ class TestStatic(TestApplicationProto): def test_static_space_in_name(self, temp_dir): os.rename( - temp_dir + '/assets/dir/file', temp_dir + '/assets/dir/fi le', + temp_dir + '/assets/dir/file', + temp_dir + '/assets/dir/fi le', ) assert waitforfiles(temp_dir + '/assets/dir/fi le') assert self.get(url='/dir/fi le')['body'] == 'blah', 'file name' @@ -154,9 +155,7 @@ class TestStatic(TestApplicationProto): assert ( self.get(url='/ di r %2Ffi le')['body'] == 'blah' ), 'slash encoded' - assert ( - self.get(url='/ di r /fi%20le')['body'] == 'blah' - ), 'file encoded' + assert self.get(url='/ di r /fi%20le')['body'] == 'blah', 'file encoded' assert ( self.get(url='/%20di%20r%20%2Ffi%20le')['body'] == 'blah' ), 'encoded' @@ -195,7 +194,8 @@ class TestStatic(TestApplicationProto): ), 'file name 2' os.rename( - temp_dir + '/assets/ di r ', temp_dir + '/assets/ди ректория', + temp_dir + '/assets/ di r ', + temp_dir + '/assets/ди ректория', ) assert waitforfiles(temp_dir + '/assets/ди ректория/фа йл') assert ( @@ -266,13 +266,14 @@ class TestStatic(TestApplicationProto): self.get(url='/')['headers']['Content-Type'] == 'text/plain' ), 'mime_types index default' assert ( - self.get(url='/dir/file')['headers']['Content-Type'] - == 'text/plain' + self.get(url='/dir/file')['headers']['Content-Type'] == 'text/plain' ), 'mime_types file in dir' def test_static_mime_types_partial_match(self): assert 'success' in self.conf( - {"text/x-blah": ["ile", "fil", "f", "e", ".file"],}, + { + "text/x-blah": ["ile", "fil", "f", "e", ".file"], + }, 'settings/http/static/mime_types', ), 'configure mime_types' assert 'Content-Type' not in self.get(url='/dir/file'), 'partial match' @@ -313,16 +314,14 @@ class TestStatic(TestApplicationProto): '"file"', 'settings/http/static/mime_types/text%2Fplain' ), 'mime_types add array element' assert ( - self.get(url='/dir/file')['headers']['Content-Type'] - == 'text/plain' + self.get(url='/dir/file')['headers']['Content-Type'] == 'text/plain' ), 'mime_types reverted' assert 'success' in self.conf( '"file"', 'settings/http/static/mime_types/text%2Fplain' ), 'configure mime_types update' assert ( - self.get(url='/dir/file')['headers']['Content-Type'] - == 'text/plain' + self.get(url='/dir/file')['headers']['Content-Type'] == 'text/plain' ), 'mime_types updated' assert ( 'Content-Type' not in self.get(url='/log.log')['headers'] @@ -346,7 +345,10 @@ class TestStatic(TestApplicationProto): 'settings/http/static/mime_types', ), 'mime_types same extensions array' assert 'error' in self.conf( - {"text/x-code": [".h", ".c", "readme"], "text/plain": "README",}, + { + "text/x-code": [".h", ".c", "readme"], + "text/plain": "README", + }, 'settings/http/static/mime_types', ), 'mime_types same extensions case insensitive' diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index 62288807..b896a9b9 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -26,13 +26,14 @@ class TestStaticChroot(TestApplicationProto): def update_action(self, share, chroot): return self.conf( - {"share": share, "chroot": chroot}, 'routes/0/action', + {"share": share, "chroot": chroot}, + 'routes/0/action', ) def get_custom(self, uri, host): - return self.get( - url=uri, headers={'Host': host, 'Connection': 'close'} - )['status'] + return self.get(url=uri, headers={'Host': host, 'Connection': 'close'})[ + 'status' + ] def test_static_chroot(self, temp_dir): assert self.get(url='/dir/file')['status'] == 200, 'default chroot' @@ -101,7 +102,8 @@ class TestStaticChroot(TestApplicationProto): ), 'chroot empty absolute' assert 'success' in self.conf( - {"share": ".$uri", "chroot": ""}, 'routes/0/action', + {"share": ".$uri", "chroot": ""}, + 'routes/0/action', ), 'configure chroot empty relative' assert ( @@ -120,13 +122,15 @@ class TestStaticChroot(TestApplicationProto): assert self.get(url='/dir/file')['status'] == 403, 'relative chroot' assert 'success' in self.conf( - {"share": ".$uri"}, 'routes/0/action', + {"share": ".$uri"}, + 'routes/0/action', ), 'configure relative share' assert self.get(url=self.test_path)['status'] == 200, 'relative share' assert 'success' in self.conf( - {"share": ".$uri", "chroot": "."}, 'routes/0/action', + {"share": ".$uri", "chroot": "."}, + 'routes/0/action', ), 'configure relative' assert self.get(url=self.test_path)['status'] == 200, 'relative' @@ -208,13 +212,16 @@ class TestStaticChroot(TestApplicationProto): def test_static_chroot_invalid(self, temp_dir): assert 'error' in self.conf( - {"share": temp_dir, "chroot": True}, 'routes/0/action', + {"share": temp_dir, "chroot": True}, + 'routes/0/action', ), 'configure chroot error' assert 'error' in self.conf( - {"share": temp_dir, "symlinks": "True"}, 'routes/0/action', + {"share": temp_dir, "symlinks": "True"}, + 'routes/0/action', ), 'configure symlink error' assert 'error' in self.conf( - {"share": temp_dir, "mount": "True"}, 'routes/0/action', + {"share": temp_dir, "mount": "True"}, + 'routes/0/action', ), 'configure mount error' assert 'error' in self.update_action( diff --git a/test/test_static_mount.py b/test/test_static_mount.py index 82eda956..91cf836c 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -41,9 +41,7 @@ class TestStaticMount(TestApplicationProto): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [ - {"action": {"share": temp_dir + "/assets/dir$uri"}} - ], + "routes": [{"action": {"share": temp_dir + "/assets/dir$uri"}}], } ) diff --git a/test/test_tls.py b/test/test_tls.py index fb28bc88..dab8ffba 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -358,9 +358,7 @@ basicConstraints = critical,CA:TRUE""" self.add_tls(cert='int') - assert ( - self.get_ssl()['status'] == 200 - ), 'certificate chain intermediate' + assert self.get_ssl()['status'] == 200, 'certificate chain intermediate' # intermediate server diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index d5f205cf..dbd5d900 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -178,7 +178,8 @@ basicConstraints = critical,CA:TRUE""" self.add_tls(["localhost.com", "example.com"]) resp, sock = self.get_ssl( - headers={'Content-Length': '0', 'Connection': 'close'}, start=True, + headers={'Content-Length': '0', 'Connection': 'close'}, + start=True, ) assert resp['status'] == 200 assert ( @@ -272,9 +273,7 @@ basicConstraints = critical,CA:TRUE""" ) assert resp['status'] == 200 - assert ( - sock.getpeercert()['subjectAltName'][0][1] == 'alt.localhost.com' - ) + assert sock.getpeercert()['subjectAltName'][0][1] == 'alt.localhost.com' def test_tls_sni_invalid(self): self.config_bundles({"localhost": {"subj": "subj1", "alt_names": ''}}) diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py index 6899eaa1..5399fae7 100644 --- a/test/test_tls_tickets.py +++ b/test/test_tls_tickets.py @@ -17,9 +17,7 @@ class TestTLSTicket(TestApplicationTLS): prerequisites = {'modules': {'openssl': 'any'}} ticket = 'U1oDTh11mMxODuw12gS0EXX1E/PkZG13cJNQ6m5+6BGlfPTjNlIEw7PSVU3X1gTE' - ticket2 = ( - '5AV0DSYIYbZWZQB7fCnTHZmMxtotb/aXjam+n2XS79lTvX3Tq9xGqpC8XKNEF2lt' - ) + ticket2 = '5AV0DSYIYbZWZQB7fCnTHZmMxtotb/aXjam+n2XS79lTvX3Tq9xGqpC8XKNEF2lt' ticket80 = '6Pfil8lv/k8zf8MndPpfXaO5EAV6dhME6zs6CfUyq2yziynQwSywtKQMqHGnJ2HR\ 49TZXi/Y4/8RSIO7QPsU51/HLR1gWIMhVM2m9yh93Bw=' @@ -182,7 +180,8 @@ class TestTLSTicket(TestApplicationTLS): def test_tls_ticket_invalid(self): def check_tickets(tickets): assert 'error' in self.conf( - {"tickets": tickets}, 'listeners/*:7080/tls/session', + {"tickets": tickets}, + 'listeners/*:7080/tls/session', ) check_tickets({}) diff --git a/test/test_upstreams_rr.py b/test/test_upstreams_rr.py index 4cb6bb2e..dd64e1d9 100644 --- a/test/test_upstreams_rr.py +++ b/test/test_upstreams_rr.py @@ -342,7 +342,8 @@ Connection: close assert self.get()['body'] == '' assert 'success' in self.conf( - {"127.0.0.1:7083": {"weight": 2}}, 'upstreams/one/servers', + {"127.0.0.1:7083": {"weight": 2}}, + 'upstreams/one/servers', ), 'active req new server' assert 'success' in self.conf_delete( 'upstreams/one/servers/127.0.0.1:7083' diff --git a/test/test_usr1.py b/test/test_usr1.py index 9a12b747..3d190935 100644 --- a/test/test_usr1.py +++ b/test/test_usr1.py @@ -59,9 +59,7 @@ class TestUSR1(TestApplicationPython): body = 'body_for_a_log_new\n' assert self.post(body=body)['status'] == 200 - assert ( - self.wait_for_record(body, log_new) is not None - ), 'rename new' + assert self.wait_for_record(body, log_new) is not None, 'rename new' assert not os.path.isfile(log_path), 'rename old' os.kill(unit_pid, signal.SIGUSR1) diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 67501e9c..04af26e1 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -24,8 +24,8 @@ class TestApplicationGo(TestApplicationProto): env['GOCACHE'] = cache_dir shutil.copy2( - option.test_dir + '/go/' + script + '/' + name + '.go', - temp_dir) + option.test_dir + '/go/' + script + '/' + name + '.go', temp_dir + ) if static: args = [ @@ -55,7 +55,8 @@ class TestApplicationGo(TestApplicationProto): f"""module test/app require unit.nginx.org/go v0.0.0 replace unit.nginx.org/go => {replace_path} -""") +""" + ) if option.detailed: print("\n$ GOPATH=" + env['GOPATH'] + " " + " ".join(args)) diff --git a/test/unit/applications/websockets.py b/test/unit/applications/websockets.py index aa83339c..d647ce9b 100644 --- a/test/unit/applications/websockets.py +++ b/test/unit/applications/websockets.py @@ -43,7 +43,11 @@ class TestApplicationWebsocket(TestApplicationProto): 'Sec-WebSocket-Version': 13, } - _, sock = self.get(headers=headers, no_recv=True, start=True,) + _, sock = self.get( + headers=headers, + no_recv=True, + start=True, + ) resp = '' while True: @@ -218,9 +222,7 @@ class TestApplicationWebsocket(TestApplicationProto): while pos < message_len: end = min(pos + fragmention_size, message_len) fin = end == message_len - self.frame_write( - sock, op_code, message[pos:end], fin=fin, **kwargs - ) + self.frame_write(sock, op_code, message[pos:end], fin=fin, **kwargs) op_code = self.OP_CONT pos = end diff --git a/test/unit/control.py b/test/unit/control.py index 3008a64b..99436ca0 100644 --- a/test/unit/control.py +++ b/test/unit/control.py @@ -30,10 +30,6 @@ def args_handler(conf_func): class TestControl(TestHTTP): - - # TODO socket reuse - # TODO http client - @args_handler def conf(self, conf, url): return self.put(**self._get_args(url, conf))['body'] diff --git a/test/unit/http.py b/test/unit/http.py index dcfcd232..b4a1a17b 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -328,9 +328,7 @@ class TestHTTP: datatype = value['type'] if not isinstance(value['data'], io.IOBase): - pytest.fail( - 'multipart encoding of file requires a stream.' - ) + pytest.fail('multipart encoding of file requires a stream.') data = value['data'].read() -- cgit From 8138d15f76b1017ba61273f69416ffbe028b0d67 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 12 Apr 2022 04:16:00 +0100 Subject: Tests: added check for zombie processes. --- test/conftest.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/conftest.py b/test/conftest.py index bed56331..904abc32 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -334,6 +334,10 @@ def run(request): _check_fds(log=log) + # check processes id's and amount + + _check_processes() + # print unit.log in case of error if hasattr(request.node, 'rep_call') and request.node.rep_call.failed: @@ -433,6 +437,16 @@ def unit_stop(): return + # check zombies + + out = subprocess.check_output( + ['ps', 'ax', '-o', 'state', '-o', 'ppid'] + ).decode() + z_ppids = re.findall(r'Z\s*(\d+)', out) + assert unit_instance['pid'] not in z_ppids, 'no zombies' + + # terminate unit + p = unit_instance['process'] if p.poll() is not None: @@ -532,6 +546,50 @@ def _clear_conf(sock, *, log=None): assert 'success' in resp, 'remove certificate' +def _check_processes(): + router_pid = _fds_info['router']['pid'] + controller_pid = _fds_info['controller']['pid'] + unit_pid = unit_instance['pid'] + + for i in range(600): + out = ( + subprocess.check_output( + ['ps', '-ax', '-o', 'pid', '-o', 'ppid', '-o', 'command'] + ) + .decode() + .splitlines() + ) + out = [l for l in out if unit_pid in l] + + if len(out) <= 3: + break + + time.sleep(0.1) + + assert len(out) == 3, 'main, router, and controller expected' + + out = [l for l in out if 'unit: main' not in l] + assert len(out) == 2, 'one main' + + out = [ + l + for l in out + if re.search(router_pid + r'\s+' + unit_pid + r'.*unit: router', l) + is None + ] + assert len(out) == 1, 'one router' + + out = [ + l + for l in out + if re.search( + controller_pid + r'\s+' + unit_pid + r'.*unit: controller', l + ) + is None + ] + assert len(out) == 0, 'one controller' + + @print_log_on_assert def _check_fds(*, log=None): def waitforfds(diff): -- 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(-) 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(+) 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(-) 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(-) 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. --- auto/clang | 18 ++++++++++++++++++ src/nxt_clang.h | 11 +++++++++++ src/nxt_conf_validation.c | 3 ++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/auto/clang b/auto/clang index 8639457a..1a05b5a3 100644 --- a/auto/clang +++ b/auto/clang @@ -176,3 +176,21 @@ nxt_feature_test="struct s { return 1; }" . auto/feature + + +nxt_feature="GCC __attribute__ unused" +nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_UNUSED +nxt_feature_run= +nxt_feature_incs= +nxt_feature_libs= +nxt_feature_test="static void f(void) __attribute__ ((__unused__)); + + static void f(void) + { + return; + } + + int main(void) { + return 0; + }" +. auto/feature 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 60a584cfab19d6c671b4aeebf32d0b36a4bc1b77 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 10 Mar 2022 21:19:01 +0100 Subject: Workarounded Clang bug triggered by Ruby. Add -fdeclspec to NXT_RUBY_CFLAGS for Clang, if it's available. Clang incorrectly reports 1 for __has_declspec_attribute(x) in some cases, such as MacOS or Cygwin. That causes ruby code to break. ruby added -fdeclspec to their CFLAGS in 2019 to workaround this bug, since it enables __declspec() and therefore, the compiler behavior matches what it reports. Since we don't know what are all the architectures that trigger the clang bug, let's add the flag for all of them (especially since it should be harmless). Add this workaround only at the time of configuring the ruby module. This way we don't clutter the global NXT_CFLAGS with an unnecessary flag. Link: unit bug Link: ruby bug Link: LLVM bug Commit: LLVM: Add -fdeclspec Commit: ruby: Use -fdeclspec <0958e19ffb047781fe1506760c7cbd8d7fe74e57> --- auto/modules/ruby | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/auto/modules/ruby b/auto/modules/ruby index 68324b44..dbedfd72 100644 --- a/auto/modules/ruby +++ b/auto/modules/ruby @@ -56,6 +56,7 @@ nxt_found=no if /bin/sh -c "$NXT_RUBY -v" >> $NXT_AUTOCONF_ERR 2>&1; then + NXT_RUBY_CFLAGS= NXT_RUBY_RUBYHDRDIR=`$NXT_RUBY -rrbconfig -e 'print RbConfig::CONFIG["rubyhdrdir"]'` NXT_RUBY_ARCHHDRDIR=`$NXT_RUBY -rrbconfig -e 'print RbConfig::CONFIG["rubyarchhdrdir"]'` NXT_RUBY_SITEDIR=`$NXT_RUBY -rrbconfig -e 'print RbConfig::CONFIG["sitedir"]'` @@ -72,6 +73,31 @@ if /bin/sh -c "$NXT_RUBY -v" >> $NXT_AUTOCONF_ERR 2>&1; then NXT_RUBY_LIBPATH=`$NXT_RUBY -rrbconfig -e 'print RbConfig::CONFIG["libdir"]'` NXT_RUBY_LIBS="-l$NXT_RUBY_LIBNAME $NXT_RUBY_LIBSCONF" + if [ $NXT_CC_NAME = clang ]; then + # Workaround Clang bug + nxt_feature="-fdeclspec" + nxt_feature_name= + nxt_feature_run= + nxt_feature_incs="-fdeclspec" + nxt_feature_libs= + nxt_feature_test="#include + + __declspec(noreturn) static void f(void); + + static void f(void) { + exit(0); + } + + int main(void) { + f(); + }" + . auto/feature + + if [ $nxt_found = yes ]; then + NXT_RUBY_CFLAGS="$NXT_RUBY_CFLAGS -fdeclspec" + fi + fi + nxt_feature="Ruby library" nxt_feature_name="" nxt_feature_run=value @@ -205,7 +231,7 @@ for nxt_src in $NXT_RUBY_MODULE_SRCS; do $NXT_BUILD_DIR/$nxt_obj: $nxt_src $NXT_VERSION_H mkdir -p $NXT_BUILD_DIR/src/ruby - \$(CC) -c \$(CFLAGS) -DNXT_RUBY_MOUNTS_H=\"$NXT_RUBY_MOUNTS_HEADER\" \\ + \$(CC) -c \$(CFLAGS) $NXT_RUBY_CFLAGS -DNXT_RUBY_MOUNTS_H=\"$NXT_RUBY_MOUNTS_HEADER\" \\ \$(NXT_INCS) $NXT_RUBY_INCPATH \\ $nxt_dep_flags \\ -o $NXT_BUILD_DIR/$nxt_obj $nxt_src -- 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 --- docs/changes.xml | 6 ++ src/nxt_conf_validation.c | 1 + src/nxt_http_return.c | 183 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 153 insertions(+), 37 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 2e2f9b04..e1774e9d 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,6 +31,12 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> + + +variables support in the "location" option of the "return" action. + + + compatibility with GCC 12. 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 6d017dfbe473f6770c4eacce8ef0c957719c6b5a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 22 Mar 2022 01:41:16 +0100 Subject: Tests: Changed tests to accept variables in "location". --- test/test_return.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_return.py b/test/test_return.py index 2f7b7ae4..31d055ce 100644 --- a/test/test_return.py +++ b/test/test_return.py @@ -83,7 +83,7 @@ Connection: close assert resp['body'] == '' def test_return_location(self): - reserved = ":/?#[]@!$&'()*+,;=" + reserved = ":/?#[]@!&'()*+,;=" unreserved = ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789-._~" @@ -107,15 +107,15 @@ Connection: close check_location(reserved) # After first "?" all other "?" encoded. - check_location("/?" + reserved, "/?:/%3F#[]@!$&'()*+,;=") + check_location("/?" + reserved, "/?:/%3F#[]@!&'()*+,;=") check_location("???", "?%3F%3F") # After first "#" all other "?" or "#" encoded. - check_location("/#" + reserved, "/#:/%3F%23[]@!$&'()*+,;=") + check_location("/#" + reserved, "/#:/%3F%23[]@!&'()*+,;=") check_location("##?#?", "#%23%3F%23%3F") # After first "?" next "#" not encoded. - check_location("/?#" + reserved, "/?#:/%3F%23[]@!$&'()*+,;=") + check_location("/?#" + reserved, "/?#:/%3F%23[]@!&'()*+,;=") check_location("??##", "?%3F#%23") check_location("/?##?", "/?#%23%3F") -- cgit From d929fbe1a4e0365b294e36aed4b5f12ee2a2210e Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 22 Mar 2022 01:58:56 +0100 Subject: Tests: Added tests for variables in "location". --- test/test_return.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/test_return.py b/test/test_return.py index 31d055ce..ff2e4566 100644 --- a/test/test_return.py +++ b/test/test_return.py @@ -161,6 +161,23 @@ Connection: close ), 'location method not allowed' assert self.get()['headers']['Location'] == 'blah' + assert 'success' in self.conf( + '"https://${host}${uri}"', 'routes/0/action/location' + ), 'location with variables' + assert self.get()['headers']['Location'] == 'https://localhost/' + + assert 'success' in self.conf( + '"/#$host"', 'routes/0/action/location' + ), 'location with encoding and a variable' + assert self.get()['headers']['Location'] == '/#localhost' + + assert ( + self.get(headers={"Host": "#foo?bar", "Connection": "close"})[ + 'headers' + ]['Location'] + == "/#%23foo%3Fbar" + ), 'location with a variable with encoding' + def test_return_invalid(self): def check_error(conf): assert 'error' in self.conf(conf, 'routes/0/action') @@ -171,6 +188,8 @@ Connection: close check_error({"return": 1000}) check_error({"return": -1}) check_error({"return": 200, "share": "/blah"}) + check_error({"return": 200, "location": "$hos"}) + check_error({"return": 200, "location": "$hostblah"}) assert 'error' in self.conf( '001', 'routes/0/action/return' -- 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(-) 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 9c276d4d609577d574de6f1cc6fbe8101fa8536a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 15 Dec 2021 12:18:59 +0100 Subject: Added .gitignore. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..91875722 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/build/ +Makefile +*.pyc +__pycache__/ -- cgit From 03a7701133887dbf7e8eb8d80c4d2473f97477a7 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 9 May 2022 10:14:29 +0100 Subject: Tests: added more tests with reconfiguration. --- test/test_python_application.py | 30 ------------ test/test_reconfigure.py | 53 +++++++++++++++++++++ test/test_reconfigure_tls.py | 102 ++++++++++++++++++++++++++++++++++++++++ test/test_tls.py | 21 --------- 4 files changed, 155 insertions(+), 51 deletions(-) create mode 100644 test/test_reconfigure.py create mode 100644 test/test_reconfigure_tls.py diff --git a/test/test_python_application.py b/test/test_python_application.py index 9463b792..befbd4d8 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -293,36 +293,6 @@ custom-header: BLAH assert resp == {}, 'reconfigure 2 keep-alive 3' - def test_python_keepalive_reconfigure_3(self): - self.load('empty') - - assert self.get()['status'] == 200, 'init' - - (_, sock) = self.http( - b"""GET / HTTP/1.1 -""", - start=True, - raw=True, - no_recv=True, - ) - - assert self.get()['status'] == 200 - - assert 'success' in self.conf( - {"listeners": {}, "applications": {}} - ), 'reconfigure 3 clear configuration' - - resp = self.http( - b"""Host: localhost -Connection: close - -""", - sock=sock, - raw=True, - ) - - assert resp['status'] == 200, 'reconfigure 3' - def test_python_atexit(self): self.load('atexit') diff --git a/test/test_reconfigure.py b/test/test_reconfigure.py new file mode 100644 index 00000000..ab05a1c8 --- /dev/null +++ b/test/test_reconfigure.py @@ -0,0 +1,53 @@ +import time + +import pytest +from unit.applications.proto import TestApplicationProto + + +class TestReconfigure(TestApplicationProto): + prerequisites = {} + + @pytest.fixture(autouse=True) + def setup_method_fixture(self): + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [{"action": {"return": 200}}], + "applications": {}, + } + ) + + def clear_conf(self): + assert 'success' in self.conf({"listeners": {}, "applications": {}}) + + def test_reconfigure(self): + (_, sock) = self.http( + b"""GET / HTTP/1.1 +""", + start=True, + raw=True, + no_recv=True, + ) + + self.clear_conf() + + resp = self.http( + b"""Host: localhost +Connection: close + +""", + sock=sock, + raw=True, + ) + assert resp['status'] == 200, 'finish request' + + def test_reconfigure_2(self): + (_, sock) = self.http(b'', raw=True, start=True, no_recv=True) + + # Waiting for connection completion. + # Delay should be more than TCP_DEFER_ACCEPT. + time.sleep(1.5) + + self.clear_conf() + + assert self.get(sock=sock)['status'] == 408, 'request timeout' diff --git a/test/test_reconfigure_tls.py b/test/test_reconfigure_tls.py new file mode 100644 index 00000000..28a3fc66 --- /dev/null +++ b/test/test_reconfigure_tls.py @@ -0,0 +1,102 @@ +import socket +import ssl +import time + +import pytest +from unit.applications.tls import TestApplicationTLS + + +class TestReconfigureTLS(TestApplicationTLS): + prerequisites = {'modules': {'openssl': 'any'}} + + @pytest.fixture(autouse=True) + def setup_method_fixture(self): + self.certificate() + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": { + "pass": "routes", + "tls": {"certificate": "default"}, + } + }, + "routes": [{"action": {"return": 200}}], + "applications": {}, + } + ), 'load application configuration' + + def create_socket(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + ctx.verify_mode = ssl.CERT_NONE + ctx.check_hostname = False + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + ssl_sock = ctx.wrap_socket( + s, server_hostname='localhost', do_handshake_on_connect=False + ) + ssl_sock.connect(('127.0.0.1', 7080)) + + return ssl_sock + + def clear_conf(self): + assert 'success' in self.conf({"listeners": {}, "applications": {}}) + + @pytest.mark.skip('not yet') + def test_reconfigure_tls_switch(self): + assert 'success' in self.conf_delete('listeners/*:7080/tls') + + (_, sock) = self.get( + headers={'Host': 'localhost', 'Connection': 'keep-alive'}, + start=True, + read_timeout=1, + ) + + assert 'success' in self.conf( + {"pass": "routes", "tls": {"certificate": "default"}}, + 'listeners/*:7080', + ) + + assert self.get(sock=sock)['status'] == 200, 'reconfigure' + assert self.get_ssl()['status'] == 200, 'reconfigure tls' + + def test_reconfigure_tls(self): + ssl_sock = self.create_socket() + + ssl_sock.sendall("""GET / HTTP/1.1\r\n""".encode()) + + self.clear_conf() + + ssl_sock.sendall( + """Host: localhost\r\nConnection: close\r\n\r\n""".encode() + ) + + assert ( + self.recvall(ssl_sock).decode().startswith('HTTP/1.1 200 OK') + ), 'finish request' + + def test_reconfigure_tls_2(self): + ssl_sock = self.create_socket() + + # Waiting for connection completion. + # Delay should be more than TCP_DEFER_ACCEPT. + time.sleep(1.5) + + self.clear_conf() + + try: + ssl_sock.do_handshake() + except ssl.SSLError: + ssl_sock.close() + success = True + + if not success: + pytest.fail('Connection is not closed.') + + def test_reconfigure_tls_3(self): + ssl_sock = self.create_socket() + ssl_sock.do_handshake() + + self.clear_conf() + + assert self.get(sock=ssl_sock)['status'] == 408, 'request timeout' diff --git a/test/test_tls.py b/test/test_tls.py index dab8ffba..56ee8298 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -493,27 +493,6 @@ basicConstraints = critical,CA:TRUE""" }, 'subject alt_names' assert cert['chain'][0]['issuer']['common_name'] == 'root', 'issuer' - @pytest.mark.skip('not yet') - def test_tls_reconfigure(self): - self.load('empty') - - assert self.get()['status'] == 200, 'init' - - self.certificate() - - (resp, sock) = self.get( - headers={'Host': 'localhost', 'Connection': 'keep-alive'}, - start=True, - read_timeout=1, - ) - - assert resp['status'] == 200, 'initial status' - - self.add_tls() - - assert self.get(sock=sock)['status'] == 200, 'reconfigure status' - assert self.get_ssl()['status'] == 200, 'reconfigure tls status' - def test_tls_keepalive(self): self.load('mirror') -- 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". --- docs/changes.xml | 6 ++++++ src/ruby/nxt_ruby.c | 45 +++++++++++++++++++++++++++++++++++++++++---- src/ruby/nxt_ruby.h | 1 + 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index e1774e9d..ba7e41a3 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,6 +31,12 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> + + +Ruby Rack environment parameter "SCRIPT_NAME" support. + + + variables support in the "location" option of the "return" action. 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 1bffba6d1e798825a00e0b754a62b5b3961a7363 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 10 May 2022 01:53:23 +0100 Subject: Tests: added test for "SCRIPT_NAME" variable in Ruby. --- test/ruby/variables/config.ru | 1 + test/test_ruby_application.py | 1 + 2 files changed, 2 insertions(+) diff --git a/test/ruby/variables/config.ru b/test/ruby/variables/config.ru index 55d01796..e335e049 100644 --- a/test/ruby/variables/config.ru +++ b/test/ruby/variables/config.ru @@ -8,6 +8,7 @@ app = Proc.new do |env| 'Request-Method' => env['REQUEST_METHOD'], 'Request-Uri' => env['REQUEST_URI'], 'Http-Host' => env['HTTP_HOST'], + 'Script-Name' => env['SCRIPT_NAME'], 'Server-Protocol' => env['SERVER_PROTOCOL'], 'Server-Software' => env['SERVER_SOFTWARE'], 'Custom-Header' => env['HTTP_CUSTOM_HEADER'], diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index 319dfb4f..c2931e65 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -44,6 +44,7 @@ class TestRubyApplication(TestApplicationRuby): 'Request-Method': 'POST', 'Request-Uri': '/', 'Http-Host': 'localhost', + 'Script-Name': 'config.ru', 'Server-Protocol': 'HTTP/1.1', 'Custom-Header': 'blah', 'Rack-Version': '13', -- 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(+) 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(+) 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 967fa8f78afd0cd960e0159e61dbbe9ca8eabf91 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Wed, 11 May 2022 12:59:39 +0400 Subject: Docker: bumped language versions. --- pkg/docker/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 39261b0a..5c48f925 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -18,7 +18,7 @@ INSTALL_minimal ?= version define COPY_minimal endef -VERSION_go ?= 1.17 +VERSION_go ?= 1.18 CONTAINER_go ?= golang:$(VERSION_go) CONFIGURE_go ?= go --go-path=$$GOPATH INSTALL_go ?= go-install-src libunit-install @@ -62,7 +62,7 @@ CONFIGURE_python ?= python --config=/usr/local/bin/python3-config INSTALL_python ?= python3-install COPY_python = -VERSION_ruby ?= 3.0 +VERSION_ruby ?= 3.1 CONTAINER_ruby ?= ruby:$(VERSION_ruby) CONFIGURE_ruby ?= ruby INSTALL_ruby ?= ruby-install -- cgit From 1fe389c2e216f21ba12ac7e373bcc26e43bde710 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Wed, 11 May 2022 13:06:17 +0400 Subject: Regenerated Dockerfiles. --- pkg/docker/Dockerfile.go1.17 | 75 -------------------------------------- pkg/docker/Dockerfile.go1.18 | 79 ++++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.jsc11 | 4 ++ pkg/docker/Dockerfile.minimal | 4 ++ pkg/docker/Dockerfile.node16 | 6 ++- pkg/docker/Dockerfile.perl5.34 | 4 ++ pkg/docker/Dockerfile.php8.0 | 73 ------------------------------------- pkg/docker/Dockerfile.php8.1 | 77 +++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.python3.10 | 77 +++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.python3.9 | 73 ------------------------------------- pkg/docker/Dockerfile.ruby3.0 | 73 ------------------------------------- pkg/docker/Dockerfile.ruby3.1 | 77 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 327 insertions(+), 295 deletions(-) delete mode 100644 pkg/docker/Dockerfile.go1.17 create mode 100644 pkg/docker/Dockerfile.go1.18 delete mode 100644 pkg/docker/Dockerfile.php8.0 create mode 100644 pkg/docker/Dockerfile.php8.1 create mode 100644 pkg/docker/Dockerfile.python3.10 delete mode 100644 pkg/docker/Dockerfile.python3.9 delete mode 100644 pkg/docker/Dockerfile.ruby3.0 create mode 100644 pkg/docker/Dockerfile.ruby3.1 diff --git a/pkg/docker/Dockerfile.go1.17 b/pkg/docker/Dockerfile.go1.17 deleted file mode 100644 index e7443e8c..00000000 --- a/pkg/docker/Dockerfile.go1.17 +++ /dev/null @@ -1,75 +0,0 @@ -FROM golang:1.17 as BUILDER - -LABEL maintainer="NGINX Docker Maintainers " - -RUN set -ex \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ - && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ - && hg clone https://hg.nginx.org/unit \ - && cd unit \ - && hg up 1.26.1 \ - && NCPU="$(getconf _NPROCESSORS_ONLN)" \ - && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ - && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ - && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ - && CONFIGURE_ARGS="--prefix=/usr \ - --state=/var/lib/unit \ - --control=unix:/var/run/control.unit.sock \ - --pid=/var/run/unit.pid \ - --log=/var/log/unit.log \ - --tmp=/var/tmp \ - --user=unit \ - --group=unit \ - --openssl \ - --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd-debug \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && ./configure go --go-path=$GOPATH \ - && make -j $NCPU go-install-src libunit-install \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ - && ./configure go --go-path=$GOPATH \ - && make -j $NCPU go-install-src libunit-install \ - && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt - -FROM golang:1.17 -COPY docker-entrypoint.sh /usr/local/bin/ -COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd -COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug -COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ -COPY --from=BUILDER /requirements.apt /requirements.apt -COPY --from=BUILDER /usr/lib/x86_64-linux-gnu/libunit.a /usr/lib/x86_64-linux-gnu/ -COPY --from=BUILDER /usr/include/nxt_* /usr/include/ -COPY --from=BUILDER /go/src/ /go/src/ -RUN set -x \ - && mkdir -p /var/lib/unit/ \ - && mkdir /docker-entrypoint.d/ \ - && addgroup --system unit \ - && adduser \ - --system \ - --disabled-login \ - --ingroup unit \ - --no-create-home \ - --home /nonexistent \ - --gecos "unit user" \ - --shell /bin/false \ - unit \ - && apt update \ - && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ - && apt-get clean && rm -rf /var/lib/apt/lists/* \ - && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log - -STOPSIGNAL SIGTERM - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] - -CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.go1.18 b/pkg/docker/Dockerfile.go1.18 new file mode 100644 index 00000000..f76fd229 --- /dev/null +++ b/pkg/docker/Dockerfile.go1.18 @@ -0,0 +1,79 @@ +FROM golang:1.18 as BUILDER + +LABEL maintainer="NGINX Docker Maintainers " + +RUN set -ex \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && hg clone https://hg.nginx.org/unit \ + && cd unit \ + && hg up 1.26.1 \ + && NCPU="$(getconf _NPROCESSORS_ONLN)" \ + && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ + && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ + && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ + && CONFIGURE_ARGS="--prefix=/usr \ + --state=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --pid=/var/run/unit.pid \ + --log=/var/log/unit.log \ + --tmp=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && ./configure go --go-path=$GOPATH \ + && make -j $NCPU go-install-src libunit-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ + && ./configure go --go-path=$GOPATH \ + && make -j $NCPU go-install-src libunit-install \ + && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt + +FROM golang:1.18 +COPY docker-entrypoint.sh /usr/local/bin/ +COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd +COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug +COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ +COPY --from=BUILDER /requirements.apt /requirements.apt +COPY --from=BUILDER /usr/lib/*-linux-gnu/libunit.a /tmp/ +COPY --from=BUILDER /usr/include/nxt_* /usr/include/ +COPY --from=BUILDER /go/src/ /go/src/ +RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ + && mkdir -p /var/lib/unit/ \ + && mkdir /docker-entrypoint.d/ \ + && addgroup --system unit \ + && adduser \ + --system \ + --disabled-login \ + --ingroup unit \ + --no-create-home \ + --home /nonexistent \ + --gecos "unit user" \ + --shell /bin/false \ + unit \ + && apt update \ + && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stdout /var/log/unit.log + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] + +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index 8e89fc22..a6b1a006 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -48,6 +48,10 @@ COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ COPY --from=BUILDER /requirements.apt /requirements.apt COPY --from=BUILDER /usr/share/unit-jsc-common/ /usr/share/unit-jsc-common/ RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ && mkdir -p /var/lib/unit/ \ && mkdir /docker-entrypoint.d/ \ && addgroup --system unit \ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 36c9af1c..c594c9ab 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -48,6 +48,10 @@ COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ COPY --from=BUILDER /requirements.apt /requirements.apt RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ && mkdir -p /var/lib/unit/ \ && mkdir /docker-entrypoint.d/ \ && addgroup --system unit \ diff --git a/pkg/docker/Dockerfile.node16 b/pkg/docker/Dockerfile.node16 index 3b4a98e2..90fa25fc 100644 --- a/pkg/docker/Dockerfile.node16 +++ b/pkg/docker/Dockerfile.node16 @@ -46,10 +46,14 @@ COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ COPY --from=BUILDER /requirements.apt /requirements.apt -COPY --from=BUILDER /usr/lib/x86_64-linux-gnu/libunit.a /usr/lib/x86_64-linux-gnu/ +COPY --from=BUILDER /usr/lib/*-linux-gnu/libunit.a /tmp/ COPY --from=BUILDER /usr/include/nxt_* /usr/include/ COPY --from=BUILDER /usr/local/lib/node_modules/unit-http/ /usr/local/lib/node_modules/unit-http/ RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ && mkdir -p /var/lib/unit/ \ && mkdir /docker-entrypoint.d/ \ && addgroup --system unit \ diff --git a/pkg/docker/Dockerfile.perl5.34 b/pkg/docker/Dockerfile.perl5.34 index cee1a829..5c52cafc 100644 --- a/pkg/docker/Dockerfile.perl5.34 +++ b/pkg/docker/Dockerfile.perl5.34 @@ -48,6 +48,10 @@ COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ COPY --from=BUILDER /requirements.apt /requirements.apt RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ && mkdir -p /var/lib/unit/ \ && mkdir /docker-entrypoint.d/ \ && addgroup --system unit \ diff --git a/pkg/docker/Dockerfile.php8.0 b/pkg/docker/Dockerfile.php8.0 deleted file mode 100644 index 07290b74..00000000 --- a/pkg/docker/Dockerfile.php8.0 +++ /dev/null @@ -1,73 +0,0 @@ -FROM php:8.0-cli as BUILDER - -LABEL maintainer="NGINX Docker Maintainers " - -RUN set -ex \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ - && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ - && hg clone https://hg.nginx.org/unit \ - && cd unit \ - && hg up 1.26.1 \ - && NCPU="$(getconf _NPROCESSORS_ONLN)" \ - && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ - && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ - && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ - && CONFIGURE_ARGS="--prefix=/usr \ - --state=/var/lib/unit \ - --control=unix:/var/run/control.unit.sock \ - --pid=/var/run/unit.pid \ - --log=/var/log/unit.log \ - --tmp=/var/tmp \ - --user=unit \ - --group=unit \ - --openssl \ - --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd-debug \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && ./configure php \ - && make -j $NCPU php-install \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ - && ./configure php \ - && make -j $NCPU php-install \ - && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt - -FROM php:8.0-cli -COPY docker-entrypoint.sh /usr/local/bin/ -COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd -COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug -COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ -COPY --from=BUILDER /requirements.apt /requirements.apt -RUN ldconfig -RUN set -x \ - && mkdir -p /var/lib/unit/ \ - && mkdir /docker-entrypoint.d/ \ - && addgroup --system unit \ - && adduser \ - --system \ - --disabled-login \ - --ingroup unit \ - --no-create-home \ - --home /nonexistent \ - --gecos "unit user" \ - --shell /bin/false \ - unit \ - && apt update \ - && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ - && apt-get clean && rm -rf /var/lib/apt/lists/* \ - && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log - -STOPSIGNAL SIGTERM - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] - -CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.php8.1 b/pkg/docker/Dockerfile.php8.1 new file mode 100644 index 00000000..68c4b915 --- /dev/null +++ b/pkg/docker/Dockerfile.php8.1 @@ -0,0 +1,77 @@ +FROM php:8.1-cli as BUILDER + +LABEL maintainer="NGINX Docker Maintainers " + +RUN set -ex \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && hg clone https://hg.nginx.org/unit \ + && cd unit \ + && hg up 1.26.1 \ + && NCPU="$(getconf _NPROCESSORS_ONLN)" \ + && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ + && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ + && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ + && CONFIGURE_ARGS="--prefix=/usr \ + --state=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --pid=/var/run/unit.pid \ + --log=/var/log/unit.log \ + --tmp=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && ./configure php \ + && make -j $NCPU php-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ + && ./configure php \ + && make -j $NCPU php-install \ + && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt + +FROM php:8.1-cli +COPY docker-entrypoint.sh /usr/local/bin/ +COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd +COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug +COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ +COPY --from=BUILDER /requirements.apt /requirements.apt +RUN ldconfig +RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ + && mkdir -p /var/lib/unit/ \ + && mkdir /docker-entrypoint.d/ \ + && addgroup --system unit \ + && adduser \ + --system \ + --disabled-login \ + --ingroup unit \ + --no-create-home \ + --home /nonexistent \ + --gecos "unit user" \ + --shell /bin/false \ + unit \ + && apt update \ + && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stdout /var/log/unit.log + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] + +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.python3.10 b/pkg/docker/Dockerfile.python3.10 new file mode 100644 index 00000000..50094af4 --- /dev/null +++ b/pkg/docker/Dockerfile.python3.10 @@ -0,0 +1,77 @@ +FROM python:3.10 as BUILDER + +LABEL maintainer="NGINX Docker Maintainers " + +RUN set -ex \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && hg clone https://hg.nginx.org/unit \ + && cd unit \ + && hg up 1.26.1 \ + && NCPU="$(getconf _NPROCESSORS_ONLN)" \ + && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ + && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ + && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ + && CONFIGURE_ARGS="--prefix=/usr \ + --state=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --pid=/var/run/unit.pid \ + --log=/var/log/unit.log \ + --tmp=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && ./configure python --config=/usr/local/bin/python3-config \ + && make -j $NCPU python3-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ + && ./configure python --config=/usr/local/bin/python3-config \ + && make -j $NCPU python3-install \ + && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt + +FROM python:3.10 +COPY docker-entrypoint.sh /usr/local/bin/ +COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd +COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug +COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ +COPY --from=BUILDER /requirements.apt /requirements.apt + +RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ + && mkdir -p /var/lib/unit/ \ + && mkdir /docker-entrypoint.d/ \ + && addgroup --system unit \ + && adduser \ + --system \ + --disabled-login \ + --ingroup unit \ + --no-create-home \ + --home /nonexistent \ + --gecos "unit user" \ + --shell /bin/false \ + unit \ + && apt update \ + && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stdout /var/log/unit.log + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] + +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.python3.9 b/pkg/docker/Dockerfile.python3.9 deleted file mode 100644 index 22491edb..00000000 --- a/pkg/docker/Dockerfile.python3.9 +++ /dev/null @@ -1,73 +0,0 @@ -FROM python:3.9 as BUILDER - -LABEL maintainer="NGINX Docker Maintainers " - -RUN set -ex \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ - && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ - && hg clone https://hg.nginx.org/unit \ - && cd unit \ - && hg up 1.26.1 \ - && NCPU="$(getconf _NPROCESSORS_ONLN)" \ - && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ - && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ - && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ - && CONFIGURE_ARGS="--prefix=/usr \ - --state=/var/lib/unit \ - --control=unix:/var/run/control.unit.sock \ - --pid=/var/run/unit.pid \ - --log=/var/log/unit.log \ - --tmp=/var/tmp \ - --user=unit \ - --group=unit \ - --openssl \ - --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd-debug \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && ./configure python --config=/usr/local/bin/python3-config \ - && make -j $NCPU python3-install \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ - && ./configure python --config=/usr/local/bin/python3-config \ - && make -j $NCPU python3-install \ - && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt - -FROM python:3.9 -COPY docker-entrypoint.sh /usr/local/bin/ -COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd -COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug -COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ -COPY --from=BUILDER /requirements.apt /requirements.apt - -RUN set -x \ - && mkdir -p /var/lib/unit/ \ - && mkdir /docker-entrypoint.d/ \ - && addgroup --system unit \ - && adduser \ - --system \ - --disabled-login \ - --ingroup unit \ - --no-create-home \ - --home /nonexistent \ - --gecos "unit user" \ - --shell /bin/false \ - unit \ - && apt update \ - && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ - && apt-get clean && rm -rf /var/lib/apt/lists/* \ - && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log - -STOPSIGNAL SIGTERM - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] - -CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.ruby3.0 b/pkg/docker/Dockerfile.ruby3.0 deleted file mode 100644 index 8da13e20..00000000 --- a/pkg/docker/Dockerfile.ruby3.0 +++ /dev/null @@ -1,73 +0,0 @@ -FROM ruby:3.0 as BUILDER - -LABEL maintainer="NGINX Docker Maintainers " - -RUN set -ex \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ - && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ - && hg clone https://hg.nginx.org/unit \ - && cd unit \ - && hg up 1.26.1 \ - && NCPU="$(getconf _NPROCESSORS_ONLN)" \ - && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ - && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ - && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ - && CONFIGURE_ARGS="--prefix=/usr \ - --state=/var/lib/unit \ - --control=unix:/var/run/control.unit.sock \ - --pid=/var/run/unit.pid \ - --log=/var/log/unit.log \ - --tmp=/var/tmp \ - --user=unit \ - --group=unit \ - --openssl \ - --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd-debug \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ - && make -j $NCPU unitd \ - && install -pm755 build/unitd /usr/sbin/unitd \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ - && ./configure ruby \ - && make -j $NCPU ruby-install \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ - && ./configure ruby \ - && make -j $NCPU ruby-install \ - && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt - -FROM ruby:3.0 -COPY docker-entrypoint.sh /usr/local/bin/ -COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd -COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug -COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ -COPY --from=BUILDER /requirements.apt /requirements.apt -RUN gem install rack -RUN set -x \ - && mkdir -p /var/lib/unit/ \ - && mkdir /docker-entrypoint.d/ \ - && addgroup --system unit \ - && adduser \ - --system \ - --disabled-login \ - --ingroup unit \ - --no-create-home \ - --home /nonexistent \ - --gecos "unit user" \ - --shell /bin/false \ - unit \ - && apt update \ - && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ - && apt-get clean && rm -rf /var/lib/apt/lists/* \ - && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log - -STOPSIGNAL SIGTERM - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] - -CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.ruby3.1 b/pkg/docker/Dockerfile.ruby3.1 new file mode 100644 index 00000000..47dec1ed --- /dev/null +++ b/pkg/docker/Dockerfile.ruby3.1 @@ -0,0 +1,77 @@ +FROM ruby:3.1 as BUILDER + +LABEL maintainer="NGINX Docker Maintainers " + +RUN set -ex \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && hg clone https://hg.nginx.org/unit \ + && cd unit \ + && hg up 1.26.1 \ + && NCPU="$(getconf _NPROCESSORS_ONLN)" \ + && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ + && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ + && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \ + && CONFIGURE_ARGS="--prefix=/usr \ + --state=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --pid=/var/run/unit.pid \ + --log=/var/log/unit.log \ + --tmp=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/unitd /usr/sbin/unitd \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \ + && ./configure ruby \ + && make -j $NCPU ruby-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \ + && ./configure ruby \ + && make -j $NCPU ruby-install \ + && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt + +FROM ruby:3.1 +COPY docker-entrypoint.sh /usr/local/bin/ +COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd +COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug +COPY --from=BUILDER /usr/lib/unit/ /usr/lib/unit/ +COPY --from=BUILDER /requirements.apt /requirements.apt +RUN gem install rack +RUN set -x \ + && if [ -f "/tmp/libunit.a" ]; then \ + mv /tmp/libunit.a /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/libunit.a; \ + rm -f /tmp/libunit.a; \ + fi \ + && mkdir -p /var/lib/unit/ \ + && mkdir /docker-entrypoint.d/ \ + && addgroup --system unit \ + && adduser \ + --system \ + --disabled-login \ + --ingroup unit \ + --no-create-home \ + --home /nonexistent \ + --gecos "unit user" \ + --shell /bin/false \ + unit \ + && apt update \ + && apt --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stdout /var/log/unit.log + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] + +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] -- 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. --- docs/changes.xml | 6 ++++++ src/ruby/nxt_ruby_stream_io.c | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/docs/changes.xml b/docs/changes.xml index ba7e41a3..af963bbb 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -49,6 +49,12 @@ compatibility with GCC 12. + + +Ruby Sinatra applications don't work without custom logging. + + + the controller process could crash when a chain with more than 4 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 de0a0beb837323a73edc5882dc7071979054d7be Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 13 May 2022 15:43:57 +0100 Subject: Tests: added tests for Ruby stream IO.close(). --- test/ruby/errors_write/config.ru | 2 ++ test/ruby/input_gets/config.ru | 1 + test/test_ruby_application.py | 12 +++++------- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/test/ruby/errors_write/config.ru b/test/ruby/errors_write/config.ru index 47619d6b..79ee4d1d 100644 --- a/test/ruby/errors_write/config.ru +++ b/test/ruby/errors_write/config.ru @@ -1,5 +1,7 @@ app = Proc.new do |env| env['rack.errors'].write('Error in application') + env['rack.errors'].flush + env['rack.errors'].close ['200', {'Content-Length' => '0'}, ['']] end diff --git a/test/ruby/input_gets/config.ru b/test/ruby/input_gets/config.ru index 1a6633ab..151fe235 100644 --- a/test/ruby/input_gets/config.ru +++ b/test/ruby/input_gets/config.ru @@ -1,5 +1,6 @@ app = Proc.new do |env| body = env['rack.input'].gets + env['rack.input'].close ['200', { 'Content-Length' => body.length.to_s }, [body]] diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index c2931e65..95c75d47 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -173,7 +173,7 @@ class TestRubyApplication(TestApplicationRuby): def test_ruby_application_errors_puts(self): self.load('errors_puts') - self.get() + assert self.get()['status'] == 200 assert ( self.wait_for_record(r'\[error\].+Error in application') is not None @@ -182,7 +182,7 @@ class TestRubyApplication(TestApplicationRuby): def test_ruby_application_errors_puts_int(self): self.load('errors_puts_int') - self.get() + assert self.get()['status'] == 200 assert ( self.wait_for_record(r'\[error\].+1234567890') is not None @@ -191,8 +191,7 @@ class TestRubyApplication(TestApplicationRuby): def test_ruby_application_errors_write(self): self.load('errors_write') - self.get() - + assert self.get()['status'] == 200 assert ( self.wait_for_record(r'\[error\].+Error in application') is not None ), 'errors write' @@ -205,8 +204,7 @@ class TestRubyApplication(TestApplicationRuby): def test_ruby_application_errors_write_int(self): self.load('errors_write_int') - self.get() - + assert self.get()['status'] == 200 assert ( self.wait_for_record(r'\[error\].+1234567890') is not None ), 'errors write int' @@ -214,7 +212,7 @@ class TestRubyApplication(TestApplicationRuby): def test_ruby_application_at_exit(self): self.load('at_exit') - self.get() + assert self.get()['status'] == 200 assert 'success' in self.conf({"listeners": {}, "applications": {}}) -- cgit From fa42d858a2967d49e1ee832b145dfcace89aeed7 Mon Sep 17 00:00:00 2001 From: Artem Konev Date: Fri, 13 May 2022 17:13:23 +0100 Subject: Adding GitHub-styled README and CONTRIBUTING files in Markdown. --- CONTRIBUTING.md | 90 ++++++++++++++++++++++++++ README | 24 ------- README.md | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/unitlogo.png | Bin 0 -> 29600 bytes 4 files changed, 274 insertions(+), 24 deletions(-) create mode 100644 CONTRIBUTING.md delete mode 100644 README create mode 100644 README.md create mode 100644 docs/unitlogo.png diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..a7bc357b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,90 @@ +# Contributing Guidelines + +The following is a set of guidelines for contributing to NGINX Unit. We do +appreciate that you are considering contributing! + +## Table Of Contents + +- [Getting Started](#getting-started) +- [Ask a Question](#ask-a-question) +- [Contributing](#contributing) +- [Git Style Guide](#git-style-guide) + + +## Getting Started + +Check out the [Quick Installation](README.md#quick-installation) and +[Howto](https://unit.nginx.org/howto/) guides to get NGINX Unit up and running. + + +## Ask a Question + +Please open an [issue](https://github.com/nginx/unit/issues/new) on GitHub with +the label `question`. You can also ask a question on +[Slack](https://nginxcommunity.slack.com) or the NGINX Unit mailing list, +unit@nginx.org (subscribe +[here](https://mailman.nginx.org/mailman3/lists/unit.nginx.org/)). + + +## Contributing + +### Report a Bug + +Ensure the bug was not already reported by searching on GitHub under +[Issues](https://github.com/nginx/unit/issues). + +If the bug is a potential security vulnerability, please report using our +[security policy](https://unit.nginx.org/troubleshooting/#getting-support). + +To report a non-security bug, open an +[issue](https://github.com/nginx/unit/issues/new) on GitHub with the label +`bug`. Be sure to include a title and clear description, as much relevant +information as possible, and a code sample or an executable test case showing +the expected behavior that doesn't occur. + + +### Suggest an Enhancement + +To suggest an enhancement, open an +[issue](https://github.com/nginx/unit/issues/new) on GitHub with the label +`enhancement`. Please do this before implementing a new feature to discuss the +feature first. + + +### Open a Pull Request + +Before submitting a PR, please read the NGINX Unit code guidelines to know more +about coding conventions and benchmarks. Fork the repo, create a branch, and +submit a PR when your changes are tested and ready for review. Again, if you'd +like to implement a new feature, please consider creating a feature request +issue first to start a discussion about the feature. + + +## Git Style Guide + +- Keep a clean, concise and meaningful `git commit` history on your branch, + rebasing locally and squashing before submitting a PR + +- For any user-visible changes, updates, and bugfixes, add a note to + `docs/changes.xml` under the section for the upcoming release, using `` for new functionality, `` for changed + behavior, and `` for bug fixes. + +- In the subject line, use the past tense ("Added feature", not "Add feature"); + also, use past tense to describe past scenarios, and present tense for + current behavior + +- Limit the subject line to 67 characters, and the rest of the commit message + to 80 characters + +- Use subject line prefixes for commits that affect a specific portion of the + code; examples include "Tests:", "Packages:", or "Docker:", and also + individual languages such as "Java:" or "Ruby:" + +- Reference issues and PRs liberally after the subject line; if the commit + remedies a GitHub issue, [name + it](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) + accordingly + +- Don't rely on command-line commit messages with `-m`; use the editor instead + diff --git a/README b/README deleted file mode 100644 index f0b84a42..00000000 --- a/README +++ /dev/null @@ -1,24 +0,0 @@ - -NGINX Unit ----------- - -The documentation and binary packages are available online: - - http://unit.nginx.org - -The source code is provided under the terms of Apache License 2.0: - - http://hg.nginx.org/unit - -Please ask questions, report issues, and send patches to the mailing list: - - unit@nginx.org (http://mailman.nginx.org/mailman/listinfo/unit) - -or via Github: - - https://github.com/nginx/unit - --- -NGINX, Inc. -http://nginx.com - diff --git a/README.md b/README.md new file mode 100644 index 00000000..05bdbb91 --- /dev/null +++ b/README.md @@ -0,0 +1,184 @@ +# NGINX Unit + +## Universal Web App Server + +![NGINX Unit Logo](docs/unitlogo.png) + +NGINX Unit is a lightweight and versatile open-source server that has +three core capabilities: + +- it is an HTTP reverse proxy, +- a web server for static media assets, +- and an application server that runs code in seven languages. + +We are building a universal tool that compresses several layers of the modern +application stack into a potent, coherent solution with a focus on performance, +low latency, and scalability. It is intended as a building block for any web +architecture regardless of its complexity, from enterprise-scale deployments to +your pet's homepage. + +Unit's native RESTful JSON API enables dynamic updates with zero interruptions +and flexible configuration, while its out-of-the-box productivity reliably +scales to production-grade workloads. We achieve that with a complex, +asynchronous, multithreading architecture comprising multiple processes to +ensure security and robustness while getting the most out of today's computing +platforms. + + +## Quick Installation + +### macOS + +``` console +$ brew install nginx/unit/unit +``` + +For details and available language packages, see the +[docs](https://unit.nginx.org/installation/#homebrew). + + +### Docker + +``` console +$ docker pull docker.io/nginx/unit +``` + +For a description of image tags, see the +[docs](https://unit.nginx.org/installation/#docker-images). + + +### Amazon Linux, Fedora, RedHat + +``` console +$ curl -sL 'https://unit.nginx.org/_downloads/setup-unit.sh' | sudo -E bash +# yum install unit +``` + +For details and available language packages, see the +[docs](https://unit.nginx.org/installation/#official-packages). + + +### Debian, Ubuntu + +``` console +$ curl -sL 'https://unit.nginx.org/_downloads/setup-unit.sh' | sudo -E bash + +# apt install unit +``` + +For details and available language packages, see the +[docs](https://unit.nginx.org/installation/#official-packages). + + +## Running a Hello World App + +Suppose you saved a PHP script as `/www/helloworld/index.php`: +``` php + +``` + +To run it on Unit with the `unit-php` module installed, first set up an +application object. Let's store our first config snippet in a file called +`config.json`: + +``` json +{ + "helloworld": { + "type": "php", + "root": "/www/helloworld/" + } +} +``` + +Saving it as a file isn't necessary, but can come in handy with larger objects. + +Now, `PUT` it into the `config/applications` section of Unit's control API, +usually available by default via a Unix domain socket: + +``` console +# curl -X PUT --data-binary @config.json --unix-socket \ + /path/to/control.unit.sock http://localhost/config/applications +``` +``` json + +{ + "success": "Reconfiguration done." +} +``` + +Next, reference the app from a listener object in the `config/listeners` +section of the API. This time, we pass the config snippet straight from the +command line: + +``` console +# curl -X PUT -d '{"127.0.0.1:8000": {"pass": "applications/helloworld"}}' \ + --unix-socket /path/to/control.unit.sock http://localhost/config/listeners +``` +``` json +{ + "success": "Reconfiguration done." +} +``` + +Now Unit accepts requests at the specified IP and port, passing them to the +application process. Your app works! + +``` console +$ curl 127.0.0.1:8080 + + Hello, PHP on Unit! +``` + +Finally, query the entire `/config` section of the control API: + +``` console +# curl --unix-socket /path/to/control.unit.sock http://localhost/config/ +``` + +Unit's output should contain both snippets, neatly organized: + +``` json +{ + "listeners": { + "127.0.0.1:8080": { + "pass": "applications/helloworld" + } + }, + + "applications": { + "helloworld": { + "type": "php", + "root": "/www/helloworld/" + } + } +} +``` + +For full details of configuration management, see the +[docs](https://unit.nginx.org/configuration/#configuration-management). + + +## Community + +- The go-to place to start asking questions and share your thoughts is + our [Slack channel](https://nginxcommunity.slack.com/). + +- Our [GitHub issues page](https://github.com/nginx/unit/issues) offers + space for a more technical discussion at your own pace. + +- The [project map](https://github.com/orgs/nginx/projects/1) on + GitHub sheds some light on our current work and plans for the future. + +- Our [official website](https://unit.nginx.org/) may provide answers + not easily found otherwise. + +- Get involved with the project by contributing! See the + [contributing guide](CONTRIBUTING.md) for details. + +- To reach the team directly, subscribe to the + [mailing list](https://mailman.nginx.org/mailman/listinfo/unit). + +- For security issues, [email us](security-alert@nginx.org), mentioning + NGINX Unit in the subject and following the [CVSS + v3.1](https://www.first.org/cvss/v3.1/specification-document) spec. + diff --git a/docs/unitlogo.png b/docs/unitlogo.png new file mode 100644 index 00000000..dbd87fd8 Binary files /dev/null and b/docs/unitlogo.png differ -- 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(-) 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 bc639b50d18112ec5e24157a2d69beff6231a9fd Mon Sep 17 00:00:00 2001 From: Artem Konev Date: Mon, 16 May 2022 11:16:08 +0100 Subject: Deleted extra line in README.md. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 05bdbb91..2c3b7d1f 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,6 @@ For details and available language packages, see the ``` console $ curl -sL 'https://unit.nginx.org/_downloads/setup-unit.sh' | sudo -E bash - # apt install unit ``` -- 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} --- docs/changes.xml | 6 ++++++ src/nxt_http.h | 2 +- src/nxt_http_return.c | 53 ++++++++++++++++++++++++--------------------------- src/nxt_http_route.c | 2 +- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index af963bbb..98650051 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -37,6 +37,12 @@ Ruby Rack environment parameter "SCRIPT_NAME" support. + + +supporting empty strings in the "location" option of the "return" action. + + + variables support in the "location" option of the "return" action. 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 c60f678485b986172b56a6367a581bb6d7668865 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 22 Mar 2022 01:58:56 +0100 Subject: Tests: Added tests for empty "location". --- test/test_return.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_return.py b/test/test_return.py index ff2e4566..82bf1e64 100644 --- a/test/test_return.py +++ b/test/test_return.py @@ -178,6 +178,21 @@ Connection: close == "/#%23foo%3Fbar" ), 'location with a variable with encoding' + assert 'success' in self.conf( + '""', 'routes/0/action/location' + ), 'location empty' + assert self.get()['headers']['Location'] == '' + + assert 'success' in self.conf( + '"${host}"', 'routes/0/action/location' + ), 'location empty with variable' + assert ( + self.get(headers={"Host": "", "Connection": "close"})['headers'][ + 'Location' + ] + == "" + ), 'location with empty variable' + def test_return_invalid(self): def check_error(conf): assert 'error' in self.conf(conf, 'routes/0/action') -- cgit From b512eff4acb97955ba48797d1299c27070a57e1a Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 5 May 2022 13:25:52 +0400 Subject: Packages: added Ubuntu 22.04 "jammy" support. --- pkg/deb/Makefile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/deb/Makefile b/pkg/deb/Makefile index 66a5f33a..3e1d53c5 100644 --- a/pkg/deb/Makefile +++ b/pkg/deb/Makefile @@ -19,6 +19,20 @@ BUILD_DEPENDS = $(BUILD_DEPENDS_unit) MODULES= +# Ubuntu 22.04 +ifeq ($(CODENAME),jammy) +include Makefile.php +include Makefile.python27 +include Makefile.python310 +include Makefile.go +include Makefile.perl +include Makefile.ruby +include Makefile.jsc-common +include Makefile.jsc11 +include Makefile.jsc17 +include Makefile.jsc18 +endif + # Ubuntu 21.10 ifeq ($(CODENAME),impish) include Makefile.php -- 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(-) 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(-) 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 3e06ae3b34fa1fb1aff15186ddd4588f4f5aa3b3 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Mon, 16 May 2022 17:22:40 +0400 Subject: Packages: ship README.md and CONTRIBUTING.md. --- pkg/deb/Makefile | 2 +- pkg/deb/debian.module/rules-noarch.in | 3 ++- pkg/deb/debian.module/rules.in | 3 ++- pkg/deb/debian/rules.in | 6 ++++-- pkg/rpm/Makefile | 2 +- pkg/rpm/unit.spec.in | 4 +++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/deb/Makefile b/pkg/deb/Makefile index 3e1d53c5..52813e37 100644 --- a/pkg/deb/Makefile +++ b/pkg/deb/Makefile @@ -194,7 +194,7 @@ endif debuild/unit_$(VERSION).orig.tar.gz: | debuild/$(SRCDIR)/debian cd ../.. && tar -czf pkg/deb/debuild/$(SRCDIR).tar.gz \ --transform "s#^#$(SRCDIR)/#" \ - LICENSE NOTICE CHANGES README configure auto src test version go docs/man/unitd.8.in + LICENSE NOTICE CHANGES README.md CONTRIBUTING.md configure auto src test version go docs/man/unitd.8.in mv debuild/$(SRCDIR).tar.gz debuild/unit_$(VERSION).orig.tar.gz cd debuild && tar zxf unit_$(VERSION).orig.tar.gz diff --git a/pkg/deb/debian.module/rules-noarch.in b/pkg/deb/debian.module/rules-noarch.in index a24602c4..0f05aaba 100644 --- a/pkg/deb/debian.module/rules-noarch.in +++ b/pkg/deb/debian.module/rules-noarch.in @@ -26,7 +26,8 @@ config.env.%: cp -Pa $(CURDIR)/CHANGES $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/LICENSE $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/NOTICE $(BUILDDIR_$*)/ - cp -Pa $(CURDIR)/README $(BUILDDIR_$*)/ + cp -Pa $(CURDIR)/README.md $(BUILDDIR_$*)/ + cp -Pa $(CURDIR)/CONTRIBUTING.md $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/go $(BUILDDIR_$*)/ touch $@ diff --git a/pkg/deb/debian.module/rules.in b/pkg/deb/debian.module/rules.in index 8ee277b3..f1217553 100755 --- a/pkg/deb/debian.module/rules.in +++ b/pkg/deb/debian.module/rules.in @@ -26,7 +26,8 @@ config.env.%: cp -Pa $(CURDIR)/CHANGES $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/LICENSE $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/NOTICE $(BUILDDIR_$*)/ - cp -Pa $(CURDIR)/README $(BUILDDIR_$*)/ + cp -Pa $(CURDIR)/README.md $(BUILDDIR_$*)/ + cp -Pa $(CURDIR)/CONTRIBUTING.md $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/go $(BUILDDIR_$*)/ touch $@ diff --git a/pkg/deb/debian/rules.in b/pkg/deb/debian/rules.in index fe7d5c7c..d2e34796 100644 --- a/pkg/deb/debian/rules.in +++ b/pkg/deb/debian/rules.in @@ -31,7 +31,8 @@ config.env.%: cp -Pa $(CURDIR)/CHANGES $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/LICENSE $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/NOTICE $(BUILDDIR_$*)/ - cp -Pa $(CURDIR)/README $(BUILDDIR_$*)/ + cp -Pa $(CURDIR)/README.md $(BUILDDIR_$*)/ + cp -Pa $(CURDIR)/CONTRIBUTING.md $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/go $(BUILDDIR_$*)/ mkdir -p $(BUILDDIR_$*)/docs/man cp -Pa $(CURDIR)/docs/man/unitd.8.in $(BUILDDIR_$*)/docs/man/ @@ -109,7 +110,8 @@ install: build do.tests mkdir -p $(INSTALLDIR)/usr/share/doc/unit/examples install -m 644 debian/unit.example.config $(INSTALLDIR)/usr/share/doc/unit/examples/example.config install -m 644 CHANGES $(INSTALLDIR)/usr/share/doc/unit/changelog - install -m 644 README $(INSTALLDIR)/usr/share/doc/unit/ + install -m 644 README.md $(INSTALLDIR)/usr/share/doc/unit/ + install -m 644 CONTRIBUTING.md $(INSTALLDIR)/usr/share/doc/unit/ install -m 644 NOTICE $(INSTALLDIR)/usr/share/doc/unit/ binary-indep: build install diff --git a/pkg/rpm/Makefile b/pkg/rpm/Makefile index 011eba5b..73a111c8 100644 --- a/pkg/rpm/Makefile +++ b/pkg/rpm/Makefile @@ -223,7 +223,7 @@ endif rpmbuild/SOURCES/unit-$(VERSION).tar.gz: cd ../.. && tar -czf pkg/rpm/rpmbuild/SOURCES/unit-$(VERSION).tar.gz \ --transform "s#^#unit-$(VERSION)/#" \ - LICENSE NOTICE CHANGES README configure auto src test version go docs/man/unitd.8.in + LICENSE NOTICE CHANGES README.md CONTRIBUTING.md configure auto src test version go docs/man/unitd.8.in unit: check-build-depends-unit rpmbuild/SPECS/unit.spec rpmbuild/SOURCES/unit-$(VERSION).tar.gz @echo "===> Building $@ package" ; \ diff --git a/pkg/rpm/unit.spec.in b/pkg/rpm/unit.spec.in index f643b77f..4cbc7358 100644 --- a/pkg/rpm/unit.spec.in +++ b/pkg/rpm/unit.spec.in @@ -123,7 +123,9 @@ DESTDIR=%{buildroot} make unitd-install libunit-install manpage-install %{buildroot}%{_datadir}/doc/unit/ %{__install} -m 644 -p NOTICE \ %{buildroot}%{_datadir}/doc/unit/COPYRIGHT -%{__install} -m 644 -p README \ +%{__install} -m 644 -p README.md \ + %{buildroot}%{_datadir}/doc/unit/ +%{__install} -m 644 -p CONTRIBUTING.md \ %{buildroot}%{_datadir}/doc/unit/ %{__rm} -rf %{buildroot}%{_initrddir}/ -- 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(-) 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(-) 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(-) 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 237ddbe1770485eab0723aac3a5dca92e1a0c5d9 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 26 May 2022 10:52:58 +0400 Subject: Packaging: Go: use GO111MODULE=auto in build instructions. --- pkg/deb/Makefile.go | 2 +- pkg/rpm/Makefile.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/deb/Makefile.go b/pkg/deb/Makefile.go index cdccb5ed..b9463076 100644 --- a/pkg/deb/Makefile.go +++ b/pkg/deb/Makefile.go @@ -36,7 +36,7 @@ The $(MODULE_SUMMARY_go) has been installed. To check out the sample app, run these commands: - GOPATH=/usr/share/gocode go build -o /tmp/go-app /usr/share/doc/unit-$(MODULE_SUFFIX_go)/examples/go-app/let-my-people.go + GOPATH=/usr/share/gocode GO111MODULE=auto go build -o /tmp/go-app /usr/share/doc/unit-$(MODULE_SUFFIX_go)/examples/go-app/let-my-people.go sudo service unit restart cd /usr/share/doc/unit-$(MODULE_SUFFIX_go)/examples sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config diff --git a/pkg/rpm/Makefile.go b/pkg/rpm/Makefile.go index e3891ab4..a1421bee 100644 --- a/pkg/rpm/Makefile.go +++ b/pkg/rpm/Makefile.go @@ -65,7 +65,7 @@ The $(MODULE_SUMMARY_go) has been installed. To check the sample app, run these commands: - GOPATH=%{gopath} go build -o /tmp/go-app /usr/share/doc/unit-go/examples/go-app/let-my-people.go + GOPATH=%{gopath} GO111MODULE=auto go build -o /tmp/go-app /usr/share/doc/unit-go/examples/go-app/let-my-people.go sudo service unit start cd /usr/share/doc/%{name}/examples sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/unit/control.sock http://localhost/config -- 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." } --- docs/changes.xml | 6 ++++++ src/nxt_conf_validation.c | 3 +++ src/nxt_http.h | 1 + src/nxt_http_route.c | 5 +++++ src/nxt_http_static.c | 34 ++++++++++++++++++++++++---------- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 98650051..db352022 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -43,6 +43,12 @@ supporting empty strings in the "location" option of the "return" action. + + +ability to specify a custom index file name when serving static files. + + + variables support in the "location" option of the "return" action. 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 8027e7ce0f3c7558647661864fd742d9afb33374 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Mon, 21 Feb 2022 23:02:51 +0100 Subject: Tests: added tests for "index" (string) option. --- test/test_static.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/test_static.py b/test/test_static.py index 5ec49f38..b9c78fdd 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -87,6 +87,22 @@ class TestStatic(TestApplicationProto): assert self.get(url='/')['body'] == '0123456789', 'before 1.26.0 2' def test_static_index(self): + def set_index(index): + assert 'success' in self.conf( + {"share": option.temp_dir + "/assets$uri", "index": index}, + 'routes/0/action', + ), 'configure index' + + set_index('README') + assert self.get()['body'] == 'readme', 'index' + + self.conf_delete('routes/0/action/index') + assert self.get()['body'] == '0123456789', 'delete index' + + set_index('') + assert self.get()['status'] == 404, 'index empty' + + def test_static_index_default(self): assert self.get(url='/index.html')['body'] == '0123456789', 'index' assert self.get(url='/')['body'] == '0123456789', 'index 2' assert self.get(url='//')['body'] == '0123456789', 'index 3' @@ -102,6 +118,18 @@ class TestStatic(TestApplicationProto): resp['headers']['Content-Type'] == 'text/html' ), 'index not found 2 Content-Type' + def test_static_index_invalid(self, skip_alert): + skip_alert(r'failed to apply new conf') + + def check_index(index): + assert 'error' in self.conf( + {"share": option.temp_dir + "/assets$uri", "index": index}, + 'routes/0/action', + ) + + check_index({}) + check_index(['index.html', '$blah']) + def test_static_large_file(self, temp_dir): file_size = 32 * 1024 * 1024 with open(temp_dir + '/assets/large', 'wb') as f: -- 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]: --- docs/changes.xml | 6 ++++++ src/nxt_http_variables.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/docs/changes.xml b/docs/changes.xml index db352022..c1cf96d2 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -55,6 +55,12 @@ variables support in the "location" option of the "return" action. + + +added new variable $request_uri with the same meaning as in NGINX. + + + compatibility with GCC 12. 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 aee8b9bfb25df4490d137655d0ce097a6b9706fc Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Mon, 30 May 2022 17:53:12 +0200 Subject: Tests: Added tests for $request_uri. --- test/test_variables.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test_variables.py b/test/test_variables.py index f110fb74..728e86b0 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -17,6 +17,7 @@ class TestVariables(TestApplicationProto): "5GET": [{"action": {"return": 206}}], "GETGET": [{"action": {"return": 207}}], "localhost": [{"action": {"return": 208}}], + "9*?q": [{"action": {"return": 209}}], }, }, ), 'configure routes' @@ -28,6 +29,14 @@ class TestVariables(TestApplicationProto): assert self.get()['status'] == 201, 'method GET' assert self.post()['status'] == 202, 'method POST' + def test_variables_request_uri(self): + self.conf_routes("\"routes$request_uri\"") + + assert self.get(url='/3')['status'] == 203, 'request_uri' + assert self.get(url='/4*')['status'] == 204, 'request_uri 2' + assert self.get(url='/4%2A')['status'] == 204, 'request_uri 3' + assert self.get(url='/9%2A?q')['status'] == 209, 'request_uri & query' + def test_variables_uri(self): self.conf_routes("\"routes$uri\"") -- cgit From 880c8e51c335caa93a62c7cbcfb53391a1d7c54d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 1 Jun 2022 00:15:15 +0100 Subject: Tests: removed deprecated ssl.PROTOCOL_TLSv1_2 constant. --- test/test_reconfigure_tls.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/test_reconfigure_tls.py b/test/test_reconfigure_tls.py index 28a3fc66..0f92a419 100644 --- a/test/test_reconfigure_tls.py +++ b/test/test_reconfigure_tls.py @@ -11,6 +11,9 @@ class TestReconfigureTLS(TestApplicationTLS): @pytest.fixture(autouse=True) def setup_method_fixture(self): + if 'HAS_TLSv1_2' not in dir(ssl) or not ssl.HAS_TLSv1_2: + pytest.skip('OpenSSL too old') + self.certificate() assert 'success' in self.conf( @@ -27,9 +30,9 @@ class TestReconfigureTLS(TestApplicationTLS): ), 'load application configuration' def create_socket(self): - ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) - ctx.verify_mode = ssl.CERT_NONE + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ssl_sock = ctx.wrap_socket( -- cgit From 0d5d81b2717a1707fc22020e6b27b4dea23d7595 Mon Sep 17 00:00:00 2001 From: Artem Konev Date: Wed, 1 Jun 2022 14:54:13 +0100 Subject: Fixed minor issues in "changes.xml". --- docs/changes.xml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index c1cf96d2..ce136e8d 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -31,33 +31,34 @@ NGINX Unit updated to 1.27.0. date="" time="" packager="Andrei Belov <defan@nginx.com>"> - + -Ruby Rack environment parameter "SCRIPT_NAME" support. +ability to specify a custom index file name when serving static files. - + -supporting empty strings in the "location" option of the "return" action. +variables support in the "location" option of the "return" action. -ability to specify a custom index file name when serving static files. +support empty strings in the "location" option of the "return" action. -variables support in the "location" option of the "return" action. +added a new variable, $request_uri, that includes both the path and the query +parts as per RFC 3986, sections 3-4. -added new variable $request_uri with the same meaning as in NGINX. +Ruby Rack environment parameter "SCRIPT_NAME" support. @@ -75,7 +76,7 @@ Ruby Sinatra applications don't work without custom logging. -the controller process could crash when a chain with more than 4 +the controller process could crash when a chain of more than four certificates was uploaded. -- cgit From 161230b955ba8a6a22888c21f1b067de61af78dd Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 1 Jun 2022 16:40:27 +0100 Subject: Tests: improved test for $request_uri variable. --- test/test_variables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_variables.py b/test/test_variables.py index 728e86b0..71553685 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -17,7 +17,7 @@ class TestVariables(TestApplicationProto): "5GET": [{"action": {"return": 206}}], "GETGET": [{"action": {"return": 207}}], "localhost": [{"action": {"return": 208}}], - "9*?q": [{"action": {"return": 209}}], + "9?q#a": [{"action": {"return": 209}}], }, }, ), 'configure routes' @@ -35,7 +35,7 @@ class TestVariables(TestApplicationProto): assert self.get(url='/3')['status'] == 203, 'request_uri' assert self.get(url='/4*')['status'] == 204, 'request_uri 2' assert self.get(url='/4%2A')['status'] == 204, 'request_uri 3' - assert self.get(url='/9%2A?q')['status'] == 209, 'request_uri & query' + assert self.get(url='/9?q#a')['status'] == 209, 'request_uri query' def test_variables_uri(self): self.conf_routes("\"routes$uri\"") -- 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(-) 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 3d53bba5b373fc80d9bf7f3e50f63639637e228c Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Tue, 31 May 2022 18:35:39 +0400 Subject: Packaging: added support for RHEL 9. --- pkg/rpm/Makefile | 12 ++++++++++++ pkg/rpm/Makefile.python39 | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pkg/rpm/Makefile b/pkg/rpm/Makefile index 73a111c8..a360b36e 100644 --- a/pkg/rpm/Makefile +++ b/pkg/rpm/Makefile @@ -16,6 +16,8 @@ else ifeq ($(shell test `rpm --eval '0%{?rhel} -eq 7 -a 0%{?amzn} -eq 0'`; echo OSVER = centos7 else ifeq ($(shell rpm --eval "%{?rhel}"), 8) OSVER = centos8 +else ifeq ($(shell rpm --eval "%{?rhel}"), 9) +OSVER = centos9 else ifeq ($(shell rpm --eval "%{?amzn}"), 1) OSVER = amazonlinux1 else ifeq ($(shell rpm --eval "%{?amzn}"), 2) @@ -84,6 +86,16 @@ include Makefile.jsc8 include Makefile.jsc11 endif +ifeq ($(OSVER), centos9) +include Makefile.php +include Makefile.python39 +include Makefile.go +include Makefile.perl +include Makefile.jsc-common +include Makefile.jsc8 +include Makefile.jsc11 +endif + ifeq ($(OSVER), amazonlinux1) include Makefile.php include Makefile.python27 diff --git a/pkg/rpm/Makefile.python39 b/pkg/rpm/Makefile.python39 index 8e444e56..3f791111 100644 --- a/pkg/rpm/Makefile.python39 +++ b/pkg/rpm/Makefile.python39 @@ -13,7 +13,7 @@ MODULE_INSTARGS_python39= python3.9-install MODULE_SOURCES_python39= unit.example-python-app \ unit.example-python39-config -ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora amazonlinux2)) +ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora amazonlinux2 centos9)) BUILD_DEPENDS_python39= python3-devel else BUILD_DEPENDS_python39= python39-devel -- 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 --- docs/changes.xml | 6 ++++++ src/nodejs/unit-http/loader.mjs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index ce136e8d..ccd9439a 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -100,6 +100,12 @@ object, notably with Falcon. + + +ECMAScript modules did not work with the recent Node.js versions. + + + 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 From cf9b5bdb35cb3895dc802d38f6e7d63af39865ad Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 2 Jun 2022 13:30:52 +0100 Subject: Added version 1.27.0 CHANGES. --- CHANGES | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CHANGES b/CHANGES index d7fa5641..98208fa9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,40 @@ +Changes with Unit 1.27.0 02 Jun 2022 + + *) Feature: ability to specify a custom index file name when serving + static files. + + *) Feature: variables support in the "location" option of the "return" + action. + + *) Feature: support empty strings in the "location" option of the + "return" action. + + *) Feature: added a new variable, $request_uri, that includes both the + path and the query parts as per RFC 3986, sections 3-4. + + *) Feature: Ruby Rack environment parameter "SCRIPT_NAME" support. + + *) Feature: compatibility with GCC 12. + + *) Bugfix: Ruby Sinatra applications don't work without custom logging. + + *) Bugfix: the controller process could crash when a chain of more than + four certificates was uploaded. + + *) Bugfix: some Perl applications failed to process the request body, + notably with Plack. + + *) Bugfix: some Spring Boot applications failed to start, notably with + Grails. + + *) Bugfix: incorrect Python protocol auto detection (ASGI or WSGI) for + native callable object, notably with Falcon. + + *) Bugfix: ECMAScript modules did not work with the recent Node.js + versions. + + Changes with Unit 1.26.1 02 Dec 2021 *) Bugfix: occasionally, the Unit daemon was unable to fully terminate; -- cgit From 3d1fa29f1d03e392df534b6589d3e1d2ed883671 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 2 Jun 2022 12:31:55 +0000 Subject: Generated Dockerfiles for Unit 1.27.0. --- pkg/docker/Dockerfile.go1.18 | 2 +- pkg/docker/Dockerfile.jsc11 | 2 +- pkg/docker/Dockerfile.minimal | 2 +- pkg/docker/Dockerfile.node16 | 2 +- pkg/docker/Dockerfile.perl5.34 | 2 +- pkg/docker/Dockerfile.php8.1 | 2 +- pkg/docker/Dockerfile.python3.10 | 2 +- pkg/docker/Dockerfile.ruby3.1 | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/docker/Dockerfile.go1.18 b/pkg/docker/Dockerfile.go1.18 index f76fd229..9162d8cf 100644 --- a/pkg/docker/Dockerfile.go1.18 +++ b/pkg/docker/Dockerfile.go1.18 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index a6b1a006..69fc72ad 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index c594c9ab..730e1893 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.node16 b/pkg/docker/Dockerfile.node16 index 90fa25fc..246105d8 100644 --- a/pkg/docker/Dockerfile.node16 +++ b/pkg/docker/Dockerfile.node16 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.perl5.34 b/pkg/docker/Dockerfile.perl5.34 index 5c52cafc..db87d209 100644 --- a/pkg/docker/Dockerfile.perl5.34 +++ b/pkg/docker/Dockerfile.perl5.34 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.php8.1 b/pkg/docker/Dockerfile.php8.1 index 68c4b915..5c18a9bc 100644 --- a/pkg/docker/Dockerfile.php8.1 +++ b/pkg/docker/Dockerfile.php8.1 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.python3.10 b/pkg/docker/Dockerfile.python3.10 index 50094af4..09e7f42a 100644 --- a/pkg/docker/Dockerfile.python3.10 +++ b/pkg/docker/Dockerfile.python3.10 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.ruby3.1 b/pkg/docker/Dockerfile.ruby3.1 index 47dec1ed..0baedc32 100644 --- a/pkg/docker/Dockerfile.ruby3.1 +++ b/pkg/docker/Dockerfile.ruby3.1 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.26.1 \ + && hg up 1.27.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ -- cgit From 0d48fe73c4450901622373e35f6ff3a944ec13d6 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 2 Jun 2022 13:37:14 +0100 Subject: Unit 1.27.0 release. --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 7a1588e8..d9fe3e08 100644 --- a/.hgtags +++ b/.hgtags @@ -34,3 +34,4 @@ f804aaf7eee10a7d8116820840d6312dd4914a41 1.21.0 54ffe5ce4fb3c4304faf6d342d9b17dee2c745ac 1.25.0 2be7b623fbfafdb470d832a28abb1cd55c76e04f 1.26.0 1a08f884b24effa8b843d6aeeaf016b6354d1256 1.26.1 +8a9055cbe4ffd450fac4d7a849c00e0db5485ad3 1.27.0 -- cgit