From 299e783e5dfbd81678dd21545e1c48582a399fec Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 25 Oct 2023 14:00:38 +0200 Subject: .mailmap: updated address for Alex. Signed-off-by: Alejandro Colomar Signed-off-by: Andrew Clayton --- .mailmap | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index d6405683..cdacea39 100644 --- a/.mailmap +++ b/.mailmap @@ -1,4 +1,5 @@ -Alejandro Colomar -Alejandro Colomar +Alejandro Colomar +Alejandro Colomar +Alejandro Colomar Andrew Clayton Andrew Clayton -- cgit From 822303e23cb489efdc4fa3ca321f8468a2dd17fa Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 26 Oct 2023 14:26:53 +0100 Subject: Version bump. --- docs/changes.xml | 30 ++++++++++++++++++++++++++++++ version | 4 ++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index cd28bec3..74cd5db7 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -5,6 +5,36 @@ + + + + +NGINX Unit updated to 1.32.0. + + + + + + + + + + gids[i], - i+1 < uc->ngroups ? ',' : '\0'); + p = nxt_sprintf(p, end, "%d,", uc->gids[i]); + } + + if (uc->ngroups > 0) { + p--; } nxt_debug(task, "user \"%s\" has gids:%*s", uc->user, p - msg, msg); -- cgit From a88e857b5b4100bb62be8a73c1badd999561b328 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 8 Nov 2023 17:34:59 +0000 Subject: Var: $request_id variable. This variable contains a string that is formed using random data and can be used as a unique request identifier. This closes #714 issue on GitHub. --- docs/changes.xml | 7 +++++++ src/nxt_http_variables.c | 32 ++++++++++++++++++++++++++++++++ test/test_variables.py | 20 ++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/docs/changes.xml b/docs/changes.xml index 74cd5db7..2c01a1e0 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -26,6 +26,13 @@ NGINX Unit updated to 1.32.0. + + +$request_id variable contains a string that is formed using random data and +can be used as a unique request identifier. + + + diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 46594a6b..ec744317 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -28,6 +28,8 @@ static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data); +static nxt_int_t nxt_http_var_request_id(nxt_task_t *task, nxt_str_t *str, + void *ctx, void *data); static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data); static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, @@ -89,6 +91,10 @@ static nxt_var_decl_t nxt_http_vars[] = { .name = nxt_string("request_line"), .handler = nxt_http_var_request_line, .cacheable = 1, + }, { + .name = nxt_string("request_id"), + .handler = nxt_http_var_request_id, + .cacheable = 1, }, { .name = nxt_string("status"), .handler = nxt_http_var_status, @@ -395,6 +401,32 @@ nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, } +static nxt_int_t +nxt_http_var_request_id(nxt_task_t *task, nxt_str_t *str, void *ctx, + void *data) +{ + nxt_random_t *rand; + nxt_http_request_t *r; + + r = ctx; + + str->start = nxt_mp_nget(r->mem_pool, 32); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + str->length = 32; + + rand = &task->thread->random; + + (void) nxt_sprintf(str->start, str->start + 32, "%08xD%08xD%08xD%08xD", + nxt_random(rand), nxt_random(rand), + nxt_random(rand), nxt_random(rand)); + + return NXT_OK; +} + + static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) diff --git a/test/test_variables.py b/test/test_variables.py index c9b173fa..813bd8c6 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -211,6 +211,26 @@ def test_variables_request_line(search_in_file, wait_for_record): assert wait_for_record(reg, 'access.log') is not None +def test_variables_request_id(search_in_file, wait_for_record, findall): + set_format('$uri $request_id $request_id') + + assert search_in_file(r'/request_id', 'access.log') is None + assert client.get(url='/request_id_1')['status'] == 200 + assert client.get(url='/request_id_2')['status'] == 200 + assert wait_for_record(r'/request_id_2', 'access.log') is not None + + id1 = findall( + r'^\/request_id_1 ([0-9a-f]{32}) ([0-9a-f]{32})$', 'access.log' + )[0] + id2 = findall( + r'^\/request_id_2 ([0-9a-f]{32}) ([0-9a-f]{32})$', 'access.log' + )[0] + + assert id1[0] == id1[1], 'same ids first' + assert id2[0] == id2[1], 'same ids second' + assert id1[0] != id2[0], 'first id != second id' + + def test_variables_status(search_in_file, wait_for_record): set_format('$status') -- cgit From 78c133d0ca3c343135e123a087970837afdebed1 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 8 Nov 2023 17:38:07 +0000 Subject: Var: simplified length calculation for $status variable. --- src/nxt_http_variables.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index ec744317..a4205eec 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -455,7 +455,6 @@ nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { - u_char *p; nxt_http_request_t *r; r = ctx; @@ -465,9 +464,9 @@ nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) return NXT_ERROR; } - p = nxt_sprintf(str->start, str->start + 3, "%03d", r->status); + (void) nxt_sprintf(str->start, str->start + 3, "%03d", r->status); - str->length = p - str->start; + str->length = 3; return NXT_OK; } -- cgit From 0b85fe29f7e49c88cab88aa9303d5885fa9c9dd5 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 8 Nov 2023 18:37:02 +0000 Subject: Tests: 8XXX used as default port range. After the launch of the project, the testing infrastructure was shared with nginx project in some cases. To avoid port overlap, a decision was made to shift the port range for Unit tests. This problem was resolved a long time ago and is no longer relevant, so it is now safe to use port 8XXX range as the default, as it is more appropriate for testing purposes. --- test/go/404/app.go | 2 +- test/go/command_line_arguments/app.go | 2 +- test/go/cookies/app.go | 2 +- test/go/empty/app.go | 2 +- test/go/get_variables/app.go | 2 +- test/go/mirror/app.go | 2 +- test/go/ns_inspect/app.go | 2 +- test/go/post_variables/app.go | 2 +- test/go/variables/app.go | 2 +- test/node/404/app.js | 2 +- test/node/basic/app.js | 2 +- test/node/double_end/app.js | 2 +- test/node/get_header_names/app.js | 2 +- test/node/get_header_type/app.js | 2 +- test/node/get_variables/app.js | 2 +- test/node/has_header/app.js | 2 +- test/node/header_name_case/app.js | 2 +- test/node/header_name_valid/app.js | 2 +- test/node/header_value_object/app.js | 2 +- test/node/loader/es_modules_http/app.mjs | 2 +- .../loader/es_modules_http_indirect/module.mjs | 2 +- test/node/loader/es_modules_websocket/app.mjs | 2 +- .../es_modules_websocket_indirect/module.mjs | 2 +- .../transitive_dependency/transitive_http.js | 2 +- test/node/loader/unit_http/app.js | 2 +- test/node/mirror/app.js | 2 +- test/node/post_variables/app.js | 2 +- test/node/promise_end/app.js | 2 +- test/node/promise_handler/app.js | 2 +- test/node/remove_header/app.js | 2 +- test/node/set_header_array/app.js | 2 +- test/node/status_message/app.js | 2 +- test/node/update_header/app.js | 2 +- test/node/variables/app.js | 2 +- test/node/websockets/mirror/app.js | 2 +- test/node/websockets/mirror_fragmentation/app.js | 2 +- test/node/write_array/app.js | 2 +- test/node/write_before_write_head/app.js | 2 +- test/node/write_buffer/app.js | 2 +- test/node/write_callback/app.js | 2 +- test/node/write_multiple/app.js | 2 +- test/node/write_return/app.js | 2 +- test/test_access_log.py | 2 +- test/test_asgi_application.py | 4 +- test/test_asgi_lifespan.py | 2 +- test/test_asgi_targets.py | 2 +- test/test_client_ip.py | 20 +-- test/test_configuration.py | 28 ++-- test/test_forwarded_header.py | 10 +- test/test_http_header.py | 8 +- test/test_java_application.py | 2 +- test/test_njs.py | 2 +- test/test_njs_modules.py | 6 +- test/test_perl_application.py | 2 +- test/test_php_application.py | 14 +- test/test_php_basic.py | 22 +-- test/test_php_targets.py | 6 +- test/test_proxy.py | 60 ++++---- test/test_proxy_chunked.py | 2 +- test/test_python_application.py | 2 +- test/test_python_basic.py | 22 +-- test/test_python_isolation.py | 6 +- test/test_python_targets.py | 4 +- test/test_reconfigure.py | 2 +- test/test_reconfigure_tls.py | 8 +- test/test_response_headers.py | 8 +- test/test_return.py | 2 +- test/test_rewrite.py | 10 +- test/test_routing.py | 158 ++++++++++----------- test/test_routing_tls.py | 6 +- test/test_ruby_application.py | 2 +- test/test_settings.py | 8 +- test/test_static.py | 2 +- test/test_static_chroot.py | 2 +- test/test_static_fallback.py | 14 +- test/test_static_mount.py | 2 +- test/test_static_share.py | 2 +- test/test_static_symlink.py | 2 +- test/test_static_types.py | 10 +- test/test_static_variables.py | 2 +- test/test_status.py | 28 ++-- test/test_status_tls.py | 6 +- test/test_tls.py | 20 +-- test/test_tls_conf_command.py | 8 +- test/test_tls_session.py | 6 +- test/test_tls_sni.py | 8 +- test/test_tls_tickets.py | 42 +++--- test/test_unix_abstract.py | 10 +- test/test_upstreams_rr.py | 102 ++++++------- test/test_variables.py | 10 +- test/unit/applications/lang/go.py | 2 +- test/unit/applications/lang/java.py | 2 +- test/unit/applications/lang/node.py | 2 +- test/unit/applications/lang/perl.py | 2 +- test/unit/applications/lang/php.py | 2 +- test/unit/applications/lang/python.py | 2 +- test/unit/applications/lang/ruby.py | 2 +- test/unit/applications/tls.py | 2 +- test/unit/check/chroot.py | 2 +- test/unit/check/isolation.py | 14 +- test/unit/http.py | 2 +- 101 files changed, 412 insertions(+), 412 deletions(-) diff --git a/test/go/404/app.go b/test/go/404/app.go index 7eba2cf4..255f5dac 100644 --- a/test/go/404/app.go +++ b/test/go/404/app.go @@ -18,5 +18,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/command_line_arguments/app.go b/test/go/command_line_arguments/app.go index 1101e1cf..5da12ffe 100644 --- a/test/go/command_line_arguments/app.go +++ b/test/go/command_line_arguments/app.go @@ -19,5 +19,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/cookies/app.go b/test/go/cookies/app.go index 2216e153..49779d35 100644 --- a/test/go/cookies/app.go +++ b/test/go/cookies/app.go @@ -15,5 +15,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/empty/app.go b/test/go/empty/app.go index 9326a19b..61e27f67 100644 --- a/test/go/empty/app.go +++ b/test/go/empty/app.go @@ -9,5 +9,5 @@ func handler(w http.ResponseWriter, r *http.Request) {} func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/get_variables/app.go b/test/go/get_variables/app.go index 1c0205a8..d70669f2 100644 --- a/test/go/get_variables/app.go +++ b/test/go/get_variables/app.go @@ -13,5 +13,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/mirror/app.go b/test/go/mirror/app.go index 78f047c3..daf55df8 100644 --- a/test/go/mirror/app.go +++ b/test/go/mirror/app.go @@ -17,5 +17,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/ns_inspect/app.go b/test/go/ns_inspect/app.go index 570580e6..977f0d9c 100644 --- a/test/go/ns_inspect/app.go +++ b/test/go/ns_inspect/app.go @@ -97,5 +97,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/post_variables/app.go b/test/go/post_variables/app.go index e6279ac6..06900d4c 100644 --- a/test/go/post_variables/app.go +++ b/test/go/post_variables/app.go @@ -15,5 +15,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/go/variables/app.go b/test/go/variables/app.go index 4be60cb7..9ef18aae 100644 --- a/test/go/variables/app.go +++ b/test/go/variables/app.go @@ -26,5 +26,5 @@ func handler(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/", handler) - unit.ListenAndServe(":7080", nil) + unit.ListenAndServe(":8080", nil) } diff --git a/test/node/404/app.js b/test/node/404/app.js index ba15c104..8beec34a 100644 --- a/test/node/404/app.js +++ b/test/node/404/app.js @@ -3,4 +3,4 @@ var fs = require('fs'); require('http').createServer(function (req, res) { res.writeHead(404, {}).end(fs.readFileSync('404.html')); -}).listen(7080); +}).listen(8080); diff --git a/test/node/basic/app.js b/test/node/basic/app.js index 9092022c..2d870003 100644 --- a/test/node/basic/app.js +++ b/test/node/basic/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) .end('Hello World\n'); -}).listen(7080); +}).listen(8080); diff --git a/test/node/double_end/app.js b/test/node/double_end/app.js index 653e33b1..e721db77 100644 --- a/test/node/double_end/app.js +++ b/test/node/double_end/app.js @@ -1,4 +1,4 @@ require('http').createServer(function (req, res) { res.end().end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/get_header_names/app.js b/test/node/get_header_names/app.js index a938b762..77aa0327 100644 --- a/test/node/get_header_names/app.js +++ b/test/node/get_header_names/app.js @@ -4,4 +4,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Header', 'blah'); res.setHeader('X-Names', res.getHeaderNames()); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/get_header_type/app.js b/test/node/get_header_type/app.js index 6e45b71f..d5a591e8 100644 --- a/test/node/get_header_type/app.js +++ b/test/node/get_header_type/app.js @@ -3,4 +3,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Number', 100); res.setHeader('X-Type', typeof(res.getHeader('X-Number'))); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/get_variables/app.js b/test/node/get_variables/app.js index cded43d2..8f317cb4 100644 --- a/test/node/get_variables/app.js +++ b/test/node/get_variables/app.js @@ -5,4 +5,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Var-2', query.var2); res.setHeader('X-Var-3', query.var3); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/has_header/app.js b/test/node/has_header/app.js index 04b13916..30e75e4d 100644 --- a/test/node/has_header/app.js +++ b/test/node/has_header/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Has-Header', res.hasHeader(req.headers['x-header']) + ''); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/header_name_case/app.js b/test/node/header_name_case/app.js index af157547..45acd507 100644 --- a/test/node/header_name_case/app.js +++ b/test/node/header_name_case/app.js @@ -4,4 +4,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-header', '2'); res.setHeader('X-HEADER', '3'); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/header_name_valid/app.js b/test/node/header_name_valid/app.js index c0c36098..9ac0c3a2 100644 --- a/test/node/header_name_valid/app.js +++ b/test/node/header_name_valid/app.js @@ -3,4 +3,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, {}); res.setHeader('@$', 'test'); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/header_value_object/app.js b/test/node/header_value_object/app.js index bacdc7d5..6f3d74bc 100644 --- a/test/node/header_value_object/app.js +++ b/test/node/header_value_object/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Header', {}); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/loader/es_modules_http/app.mjs b/test/node/loader/es_modules_http/app.mjs index c7bcfe49..28ff08d8 100644 --- a/test/node/loader/es_modules_http/app.mjs +++ b/test/node/loader/es_modules_http/app.mjs @@ -3,4 +3,4 @@ import http from "http" http.createServer(function (req, res) { res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) .end('Hello World\n'); -}).listen(7080); +}).listen(8080); diff --git a/test/node/loader/es_modules_http_indirect/module.mjs b/test/node/loader/es_modules_http_indirect/module.mjs index c7bcfe49..28ff08d8 100644 --- a/test/node/loader/es_modules_http_indirect/module.mjs +++ b/test/node/loader/es_modules_http_indirect/module.mjs @@ -3,4 +3,4 @@ import http from "http" http.createServer(function (req, res) { res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) .end('Hello World\n'); -}).listen(7080); +}).listen(8080); diff --git a/test/node/loader/es_modules_websocket/app.mjs b/test/node/loader/es_modules_websocket/app.mjs index a71ffa9d..361d855b 100644 --- a/test/node/loader/es_modules_websocket/app.mjs +++ b/test/node/loader/es_modules_websocket/app.mjs @@ -4,7 +4,7 @@ import websocket from "websocket" let server = http.createServer(function() {}); let webSocketServer = websocket.server; -server.listen(7080, function() {}); +server.listen(8080, function() {}); var wsServer = new webSocketServer({ maxReceivedMessageSize: 0x1000000000, diff --git a/test/node/loader/es_modules_websocket_indirect/module.mjs b/test/node/loader/es_modules_websocket_indirect/module.mjs index a71ffa9d..361d855b 100644 --- a/test/node/loader/es_modules_websocket_indirect/module.mjs +++ b/test/node/loader/es_modules_websocket_indirect/module.mjs @@ -4,7 +4,7 @@ import websocket from "websocket" let server = http.createServer(function() {}); let webSocketServer = websocket.server; -server.listen(7080, function() {}); +server.listen(8080, function() {}); var wsServer = new webSocketServer({ maxReceivedMessageSize: 0x1000000000, diff --git a/test/node/loader/transitive_dependency/transitive_http.js b/test/node/loader/transitive_dependency/transitive_http.js index f1eb98e5..171758ed 100644 --- a/test/node/loader/transitive_dependency/transitive_http.js +++ b/test/node/loader/transitive_dependency/transitive_http.js @@ -3,6 +3,6 @@ const http = require("http"); http.createServer(function (req, res) { res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) .end('Hello World\n'); -}).listen(7080); +}).listen(8080); module.exports = http; diff --git a/test/node/loader/unit_http/app.js b/test/node/loader/unit_http/app.js index 9172e44f..0e0c2b24 100644 --- a/test/node/loader/unit_http/app.js +++ b/test/node/loader/unit_http/app.js @@ -1,4 +1,4 @@ require("unit-http").createServer(function (req, res) { res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) .end('Hello World\n'); -}).listen(7080); +}).listen(8080); diff --git a/test/node/mirror/app.js b/test/node/mirror/app.js index bdefe1cd..bdb89489 100644 --- a/test/node/mirror/app.js +++ b/test/node/mirror/app.js @@ -8,4 +8,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Length': Buffer.byteLength(body)}) .end(body); }); -}).listen(7080); +}).listen(8080); diff --git a/test/node/post_variables/app.js b/test/node/post_variables/app.js index 12b867cb..4d88434d 100644 --- a/test/node/post_variables/app.js +++ b/test/node/post_variables/app.js @@ -11,4 +11,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Var-3', query.var3); res.end(); }); -}).listen(7080); +}).listen(8080); diff --git a/test/node/promise_end/app.js b/test/node/promise_end/app.js index 373c3bc6..75c2ef7d 100644 --- a/test/node/promise_end/app.js +++ b/test/node/promise_end/app.js @@ -12,4 +12,4 @@ require('http').createServer(function (req, res) { fs.appendFile('callback', '', function() {}); }); -}).listen(7080); +}).listen(8080); diff --git a/test/node/promise_handler/app.js b/test/node/promise_handler/app.js index 32d7d7b9..7bcb1ae9 100644 --- a/test/node/promise_handler/app.js +++ b/test/node/promise_handler/app.js @@ -13,4 +13,4 @@ require('http').createServer(function (req, res) { fs.appendFile(data.toString(), '', function() {}); }); }); -}).listen(7080); +}).listen(8080); diff --git a/test/node/remove_header/app.js b/test/node/remove_header/app.js index 2a591235..877a7351 100644 --- a/test/node/remove_header/app.js +++ b/test/node/remove_header/app.js @@ -7,4 +7,4 @@ require('http').createServer(function (req, res) { res.setHeader('Has-Header', res.hasHeader('X-Header').toString()); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/set_header_array/app.js b/test/node/set_header_array/app.js index 965330e2..0dee477e 100644 --- a/test/node/set_header_array/app.js +++ b/test/node/set_header_array/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.setHeader('Set-Cookie', ['tc=one,two,three', 'tc=four,five,six']); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/status_message/app.js b/test/node/status_message/app.js index ba51d35b..53eea5c7 100644 --- a/test/node/status_message/app.js +++ b/test/node/status_message/app.js @@ -1,4 +1,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, 'blah', {'Content-Type': 'text/plain'}).end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/update_header/app.js b/test/node/update_header/app.js index 905ac294..dc3415e6 100644 --- a/test/node/update_header/app.js +++ b/test/node/update_header/app.js @@ -3,4 +3,4 @@ require('http').createServer(function (req, res) { res.setHeader('X-Header', 'test'); res.setHeader('X-Header', 'new'); res.end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/variables/app.js b/test/node/variables/app.js index a569dddd..b6f36f37 100644 --- a/test/node/variables/app.js +++ b/test/node/variables/app.js @@ -15,4 +15,4 @@ require('http').createServer(function (req, res) { res.setHeader('Http-Host', req.headers['host']); res.writeHead(200, {}).end(body); }); -}).listen(7080); +}).listen(8080); diff --git a/test/node/websockets/mirror/app.js b/test/node/websockets/mirror/app.js index 0443adb2..ee2bdd18 100644 --- a/test/node/websockets/mirror/app.js +++ b/test/node/websockets/mirror/app.js @@ -2,7 +2,7 @@ server = require('http').createServer(function() {}); webSocketServer = require('websocket').server; -server.listen(7080, function() {}); +server.listen(8080, function() {}); var wsServer = new webSocketServer({ maxReceivedMessageSize: 0x1000000000, diff --git a/test/node/websockets/mirror_fragmentation/app.js b/test/node/websockets/mirror_fragmentation/app.js index ea580ac2..ca539ad6 100644 --- a/test/node/websockets/mirror_fragmentation/app.js +++ b/test/node/websockets/mirror_fragmentation/app.js @@ -2,7 +2,7 @@ server = require('http').createServer(function() {}); webSocketServer = require('websocket').server; -server.listen(7080, function() {}); +server.listen(8080, function() {}); var wsServer = new webSocketServer({ httpServer: server diff --git a/test/node/write_array/app.js b/test/node/write_array/app.js index b7abb3fc..761e8537 100644 --- a/test/node/write_array/app.js +++ b/test/node/write_array/app.js @@ -1,4 +1,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Length': 5, 'Content-Type': 'text/plain'}) .end(new Uint8Array(Buffer.from('array', 'utf8'))); -}).listen(7080); +}).listen(8080); diff --git a/test/node/write_before_write_head/app.js b/test/node/write_before_write_head/app.js index 2293111a..10c8b9d6 100644 --- a/test/node/write_before_write_head/app.js +++ b/test/node/write_before_write_head/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.write('blah'); res.writeHead(200, {'Content-Type': 'text/plain'}).end(); -}).listen(7080); +}).listen(8080); diff --git a/test/node/write_buffer/app.js b/test/node/write_buffer/app.js index 72e9c600..24585ef2 100644 --- a/test/node/write_buffer/app.js +++ b/test/node/write_buffer/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}) .end(Buffer.from('buffer', 'utf8')); -}).listen(7080); +}).listen(8080); diff --git a/test/node/write_callback/app.js b/test/node/write_callback/app.js index 71eb4116..f03cb213 100644 --- a/test/node/write_callback/app.js +++ b/test/node/write_callback/app.js @@ -9,4 +9,4 @@ require('http').createServer(function (req, res) { fs.appendFile('callback', '', function() {}); }); res.end(a); -}).listen(7080); +}).listen(8080); diff --git a/test/node/write_multiple/app.js b/test/node/write_multiple/app.js index e9c51ae0..b1e485e7 100644 --- a/test/node/write_multiple/app.js +++ b/test/node/write_multiple/app.js @@ -4,4 +4,4 @@ require('http').createServer(function (req, res) { res.write('write'); res.write('write2'); res.end('end'); -}).listen(7080); +}).listen(8080); diff --git a/test/node/write_return/app.js b/test/node/write_return/app.js index 345b6c4b..d0b3d850 100644 --- a/test/node/write_return/app.js +++ b/test/node/write_return/app.js @@ -2,4 +2,4 @@ require('http').createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}) .end(res.write('body').toString()); -}).listen(7080); +}).listen(8080); diff --git a/test/test_access_log.py b/test/test_access_log.py index bccea56f..3c5e6cbb 100644 --- a/test/test_access_log.py +++ b/test/test_access_log.py @@ -93,7 +93,7 @@ def test_access_log_ipv6(wait_for_record): load('empty') assert 'success' in client.conf( - {"[::1]:7080": {"pass": "applications/empty"}}, 'listeners' + {"[::1]:8080": {"pass": "applications/empty"}}, 'listeners' ) client.get(sock_type='ipv6') diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index 98d4bcd5..4b59fafd 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -60,7 +60,7 @@ def test_asgi_application_ipv6(): client.load('empty') assert 'success' in client.conf( - {"[::1]:7080": {"pass": "applications/empty"}}, 'listeners' + {"[::1]:8080": {"pass": "applications/empty"}}, 'listeners' ) assert client.get(sock_type='ipv6')['status'] == 200 @@ -172,7 +172,7 @@ def test_asgi_application_server_port(): client.load('server_port') assert ( - client.get()['headers']['Server-Port'] == '7080' + client.get()['headers']['Server-Port'] == '8080' ), 'Server-Port header' diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index 499f523d..5df7475e 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -59,7 +59,7 @@ def test_asgi_lifespan_targets(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/1"}, diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py index c3ec22f0..63bde713 100644 --- a/test/test_asgi_targets.py +++ b/test/test_asgi_targets.py @@ -16,7 +16,7 @@ def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/1"}, diff --git a/test/test_client_ip.py b/test/test_client_ip.py index 82c76718..d7bc399d 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -15,11 +15,11 @@ def setup_method_fixture(): def client_ip(options): assert 'success' in client.conf( { - "127.0.0.1:7081": { + "127.0.0.1:8081": { "client_ip": options, "pass": "applications/client_ip", }, - "[::1]:7082": { + "[::1]:8082": { "client_ip": options, "pass": "applications/client_ip", }, @@ -34,8 +34,8 @@ def client_ip(options): def get_xff(xff, sock_type='ipv4'): address = { - 'ipv4': ('127.0.0.1', 7081), - 'ipv6': ('::1', 7082), + 'ipv4': ('127.0.0.1', 8081), + 'ipv6': ('::1', 8082), 'unix': (f'{option.temp_dir}/sock', None), } (addr, port) = address[sock_type] @@ -51,9 +51,9 @@ def get_xff(xff, sock_type='ipv4'): def test_client_ip_single_ip(): client_ip({'header': 'X-Forwarded-For', 'source': '123.123.123.123'}) - assert client.get(port=7081)['body'] == '127.0.0.1', 'ipv4 default' + assert client.get(port=8081)['body'] == '127.0.0.1', 'ipv4 default' assert ( - client.get(sock_type='ipv6', port=7082)['body'] == '::1' + client.get(sock_type='ipv6', port=8082)['body'] == '::1' ), 'ipv6 default' assert get_xff('1.1.1.1') == '127.0.0.1', 'bad source' assert get_xff('blah') == '127.0.0.1', 'bad header' @@ -61,9 +61,9 @@ def test_client_ip_single_ip(): client_ip({'header': 'X-Forwarded-For', 'source': '127.0.0.1'}) - assert client.get(port=7081)['body'] == '127.0.0.1', 'ipv4 default 2' + assert client.get(port=8081)['body'] == '127.0.0.1', 'ipv4 default 2' assert ( - client.get(sock_type='ipv6', port=7082)['body'] == '::1' + client.get(sock_type='ipv6', port=8082)['body'] == '::1' ), 'ipv6 default 2' assert get_xff('1.1.1.1') == '1.1.1.1', 'replace' assert get_xff('blah') == '127.0.0.1', 'bad header 2' @@ -159,7 +159,7 @@ def test_client_ip_empty_source(): def test_client_ip_invalid(): assert 'error' in client.conf( { - "127.0.0.1:7081": { + "127.0.0.1:8081": { "client_ip": {"source": '127.0.0.1'}, "pass": "applications/client_ip", } @@ -170,7 +170,7 @@ def test_client_ip_invalid(): def check_invalid_source(source): assert 'error' in client.conf( { - "127.0.0.1:7081": { + "127.0.0.1:8081": { "client_ip": { "header": "X-Forwarded-For", "source": source, diff --git a/test/test_configuration.py b/test/test_configuration.py index 19a2a1a5..a311922f 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -234,12 +234,12 @@ def test_applications_relative_path(): @pytest.mark.skip('not yet, unsafe') def test_listeners_empty(): - assert 'error' in client.conf({"*:7080": {}}, 'listeners'), 'listener empty' + assert 'error' in client.conf({"*:8080": {}}, 'listeners'), 'listener empty' def test_listeners_no_app(): assert 'error' in client.conf( - {"*:7080": {"pass": "applications/app"}}, 'listeners' + {"*:8080": {"pass": "applications/app"}}, 'listeners' ), 'listeners no app' @@ -254,9 +254,9 @@ def test_listeners_unix_abstract(system): def test_listeners_addr(): - assert 'success' in try_addr("*:7080"), 'wildcard' - assert 'success' in try_addr("127.0.0.1:7081"), 'explicit' - assert 'success' in try_addr("[::1]:7082"), 'explicit ipv6' + assert 'success' in try_addr("*:8080"), 'wildcard' + assert 'success' in try_addr("127.0.0.1:8081"), 'explicit' + assert 'success' in try_addr("[::1]:8082"), 'explicit ipv6' def test_listeners_addr_error(): @@ -266,7 +266,7 @@ def test_listeners_addr_error(): def test_listeners_addr_error_2(skip_alert): skip_alert(r'bind.*failed', r'failed to apply new conf') - assert 'error' in try_addr("[f607:7403:1e4b:6c66:33b2:843f:2517:da27]:7080") + assert 'error' in try_addr("[f607:7403:1e4b:6c66:33b2:843f:2517:da27]:8080") def test_listeners_port_release(): @@ -277,7 +277,7 @@ def test_listeners_port_release(): client.conf( { - "listeners": {"127.0.0.1:7080": {"pass": "routes"}}, + "listeners": {"127.0.0.1:8080": {"pass": "routes"}}, "routes": [], } ) @@ -285,7 +285,7 @@ def test_listeners_port_release(): resp = client.conf({"listeners": {}, "applications": {}}) try: - s.bind(('127.0.0.1', 7080)) + s.bind(('127.0.0.1', 8080)) s.listen() except OSError: @@ -302,7 +302,7 @@ def test_json_application_name_large(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": f"applications/{name}"}}, + "listeners": {"*:8080": {"pass": f"applications/{name}"}}, "applications": { name: { "type": "python", @@ -349,7 +349,7 @@ def test_json_application_python_prefix(): "prefix": "/app", } }, - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/app/*"}, @@ -378,7 +378,7 @@ def test_json_application_prefix_target(): }, } }, - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/app/*"}, @@ -405,7 +405,7 @@ def test_json_application_invalid_python_prefix(): "prefix": "app", } }, - "listeners": {"*:7080": {"pass": "applications/sub-app"}}, + "listeners": {"*:8080": {"pass": "applications/sub-app"}}, } assert 'error' in client.conf(conf) @@ -422,7 +422,7 @@ def test_json_application_empty_python_prefix(): "prefix": "", } }, - "listeners": {"*:7080": {"pass": "applications/sub-app"}}, + "listeners": {"*:8080": {"pass": "applications/sub-app"}}, } assert 'error' in client.conf(conf) @@ -441,7 +441,7 @@ def test_json_application_many2(): # open files limit due to the lack of file descriptors. for a in range(100) }, - "listeners": {"*:7080": {"pass": "applications/app-1"}}, + "listeners": {"*:8080": {"pass": "applications/app-1"}}, } assert 'success' in client.conf(conf) diff --git a/test/test_forwarded_header.py b/test/test_forwarded_header.py index c3f4a4c6..eaa83dce 100644 --- a/test/test_forwarded_header.py +++ b/test/test_forwarded_header.py @@ -14,11 +14,11 @@ def setup_method_fixture(): def forwarded_header(forwarded): assert 'success' in client.conf( { - "127.0.0.1:7081": { + "127.0.0.1:8081": { "forwarded": forwarded, "pass": "applications/forwarded_header", }, - "[::1]:7082": { + "[::1]:8082": { "forwarded": forwarded, "pass": "applications/forwarded_header", }, @@ -28,7 +28,7 @@ def forwarded_header(forwarded): def get_fwd(sock_type='ipv4', xff=None, xfp=None): - port = 7081 if sock_type == 'ipv4' else 7082 + port = 8081 if sock_type == 'ipv4' else 8082 headers = {'Connection': 'close'} @@ -243,7 +243,7 @@ def test_forwarded_header_source_range(): def test_forwarded_header_invalid(): assert 'error' in client.conf( { - "127.0.0.1:7081": { + "127.0.0.1:8081": { "forwarded": {"source": '127.0.0.1'}, "pass": "applications/forwarded_header", } @@ -254,7 +254,7 @@ def test_forwarded_header_invalid(): def check_invalid_source(source): assert 'error' in client.conf( { - "127.0.0.1:7081": { + "127.0.0.1:8081": { "forwarded": { "client_ip": "X-Forwarded-For", "source": source, diff --git a/test/test_http_header.py b/test/test_http_header.py index af836e6f..cf5866e9 100644 --- a/test/test_http_header.py +++ b/test/test_http_header.py @@ -333,7 +333,7 @@ def test_http_header_host_port(): client.load('host') resp = client.get( - headers={'Host': 'exmaple.com:7080', 'Connection': 'close'} + headers={'Host': 'exmaple.com:8080', 'Connection': 'close'} ) assert resp['status'] == 200, 'Host port status' @@ -341,7 +341,7 @@ def test_http_header_host_port(): resp['headers']['X-Server-Name'] == 'exmaple.com' ), 'Host port SERVER_NAME' assert ( - resp['headers']['X-Http-Host'] == 'exmaple.com:7080' + resp['headers']['X-Http-Host'] == 'exmaple.com:8080' ), 'Host port HTTP_HOST' @@ -373,14 +373,14 @@ def test_http_header_host_literal(): def test_http_header_host_literal_ipv6(): client.load('host') - resp = client.get(headers={'Host': '[::1]:7080', 'Connection': 'close'}) + resp = client.get(headers={'Host': '[::1]:8080', 'Connection': 'close'}) assert resp['status'] == 200, 'Host literal ipv6 status' assert ( resp['headers']['X-Server-Name'] == '[::1]' ), 'Host literal ipv6 SERVER_NAME' assert ( - resp['headers']['X-Http-Host'] == '[::1]:7080' + resp['headers']['X-Http-Host'] == '[::1]:8080' ), 'Host literal ipv6 HTTP_HOST' diff --git a/test/test_java_application.py b/test/test_java_application.py index eefc5c79..3a6a62d6 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -20,7 +20,7 @@ def test_java_conf_error(temp_dir, skip_alert): ) assert 'error' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/app"}}, + "listeners": {"*:8080": {"pass": "applications/app"}}, "applications": { "app": { "type": client.get_application_type(), diff --git a/test/test_njs.py b/test/test_njs.py index 162cc0bd..ce92e1ef 100644 --- a/test/test_njs.py +++ b/test/test_njs.py @@ -14,7 +14,7 @@ client = ApplicationProto() def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f"{temp_dir}/assets$uri"}}], } ) diff --git a/test/test_njs_modules.py b/test/test_njs_modules.py index d821d455..a639fabd 100644 --- a/test/test_njs_modules.py +++ b/test/test_njs_modules.py @@ -23,7 +23,7 @@ def test_njs_modules(): assert 'success' in client.conf( { "settings": {"js_module": "next"}, - "listeners": {"*:7080": {"pass": "routes/first"}}, + "listeners": {"*:8080": {"pass": "routes/first"}}, "routes": { "first": [{"action": {"pass": "`routes/${next.route()}`"}}], "next": [{"action": {"return": 200}}], @@ -68,7 +68,7 @@ def test_njs_modules_import(): assert 'success' in client.conf( { "settings": {"js_module": "import_from"}, - "listeners": {"*:7080": {"pass": "routes/first"}}, + "listeners": {"*:8080": {"pass": "routes/first"}}, "routes": { "first": [ {"action": {"pass": "`routes/${import_from.num()}`"}} @@ -86,7 +86,7 @@ def test_njs_modules_this(): assert 'success' in client.conf( { "settings": {"js_module": "global_this"}, - "listeners": {"*:7080": {"pass": "routes/first"}}, + "listeners": {"*:8080": {"pass": "routes/first"}}, "routes": { "first": [ {"action": {"pass": "`routes/${global_this.str()}`"}} diff --git a/test/test_perl_application.py b/test/test_perl_application.py index 7e6571fb..115b0ec7 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -88,7 +88,7 @@ def test_perl_application_server_port(): client.load('server_port') assert ( - client.get()['headers']['Server-Port'] == '7080' + client.get()['headers']['Server-Port'] == '8080' ), 'Server-Port header' diff --git a/test/test_php_application.py b/test/test_php_application.py index 17440909..8a6641cb 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -174,7 +174,7 @@ def test_php_application_query_string_empty(): def test_php_application_query_string_rewrite(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { @@ -678,7 +678,7 @@ def test_php_application_error_log(findall, wait_for_record): def test_php_application_script(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/script"}}, + "listeners": {"*:8080": {"pass": "applications/script"}}, "applications": { "script": { "type": client.get_application_type(), @@ -699,7 +699,7 @@ def test_php_application_script(): def test_php_application_index_default(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, + "listeners": {"*:8080": {"pass": "applications/phpinfo"}}, "applications": { "phpinfo": { "type": client.get_application_type(), @@ -727,7 +727,7 @@ def test_php_application_trailing_slash(temp_dir): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "applications/php-path"}, + "*:8080": {"pass": "applications/php-path"}, f'unix:{addr}': {"pass": "applications/php-path"}, }, "applications": { @@ -745,7 +745,7 @@ def test_php_application_trailing_slash(temp_dir): resp = client.get(url='/path?q=a') assert resp['status'] == 301, 'uri without trailing /' assert ( - resp['headers']['Location'] == 'http://localhost:7080/path/?q=a' + resp['headers']['Location'] == 'http://localhost:8080/path/?q=a' ), 'Location with query string' resp = client.get( @@ -767,7 +767,7 @@ def test_php_application_forbidden(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/php-path"}}, + "listeners": {"*:8080": {"pass": "applications/php-path"}}, "applications": { "php-path": { "type": client.get_application_type(), @@ -792,7 +792,7 @@ def test_php_application_extension_check(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, + "listeners": {"*:8080": {"pass": "applications/phpinfo"}}, "applications": { "phpinfo": { "type": client.get_application_type(), diff --git a/test/test_php_basic.py b/test/test_php_basic.py index 64754961..076b7498 100644 --- a/test/test_php_basic.py +++ b/test/test_php_basic.py @@ -14,7 +14,7 @@ conf_app = { } conf_basic = { - "listeners": {"*:7080": {"pass": "applications/app"}}, + "listeners": {"*:8080": {"pass": "applications/app"}}, "applications": conf_app, } @@ -60,14 +60,14 @@ def test_php_get_listeners(): assert 'success' in client.conf(conf_basic) assert client.conf_get()['listeners'] == { - "*:7080": {"pass": "applications/app"} + "*:8080": {"pass": "applications/app"} }, 'listeners' assert client.conf_get('listeners') == { - "*:7080": {"pass": "applications/app"} + "*:8080": {"pass": "applications/app"} }, 'listeners prefix' - assert client.conf_get('listeners/*:7080') == { + assert client.conf_get('listeners/*:8080') == { "pass": "applications/app" }, 'listeners prefix 2' @@ -75,23 +75,23 @@ def test_php_get_listeners(): def test_php_change_listener(): assert 'success' in client.conf(conf_basic) assert 'success' in client.conf( - {"*:7081": {"pass": "applications/app"}}, 'listeners' + {"*:8081": {"pass": "applications/app"}}, 'listeners' ) assert client.conf_get('listeners') == { - "*:7081": {"pass": "applications/app"} + "*:8081": {"pass": "applications/app"} }, 'change listener' def test_php_add_listener(): assert 'success' in client.conf(conf_basic) assert 'success' in client.conf( - {"pass": "applications/app"}, 'listeners/*:7082' + {"pass": "applications/app"}, 'listeners/*:8082' ) assert client.conf_get('listeners') == { - "*:7080": {"pass": "applications/app"}, - "*:7082": {"pass": "applications/app"}, + "*:8080": {"pass": "applications/app"}, + "*:8082": {"pass": "applications/app"}, }, 'add listener' @@ -113,7 +113,7 @@ def test_php_delete(): assert 'success' in client.conf(conf_basic) assert 'error' in client.conf_delete('applications/app') - assert 'success' in client.conf_delete('listeners/*:7080') + assert 'success' in client.conf_delete('listeners/*:8080') assert 'success' in client.conf_delete('applications/app') assert 'error' in client.conf_delete('applications/app') @@ -126,5 +126,5 @@ def test_php_delete_blocks(): assert 'success' in client.conf(conf_app, 'applications') assert 'success' in client.conf( - {"*:7081": {"pass": "applications/app"}}, 'listeners' + {"*:8081": {"pass": "applications/app"}}, 'listeners' ), 'applications restore' diff --git a/test/test_php_targets.py b/test/test_php_targets.py index 857a2dc8..6085db40 100644 --- a/test/test_php_targets.py +++ b/test/test_php_targets.py @@ -10,7 +10,7 @@ def test_php_application_targets(): targets_dir = f"{option.test_dir}/php/targets" assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/1"}, @@ -65,7 +65,7 @@ def test_php_application_targets(): def test_php_application_targets_error(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/targets/default"}}, + "listeners": {"*:8080": {"pass": "applications/targets/default"}}, "applications": { "targets": { "type": client.get_application_type(), @@ -83,7 +83,7 @@ def test_php_application_targets_error(): assert client.get()['status'] == 200 assert 'error' in client.conf( - {"pass": "applications/targets/blah"}, 'listeners/*:7080' + {"pass": "applications/targets/blah"}, 'listeners/*:8080' ), 'invalid targets pass' assert 'error' in client.conf( f'"{option.test_dir}/php/targets"', diff --git a/test/test_proxy.py b/test/test_proxy.py index 207e90e7..b64e19db 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -23,10 +23,10 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "applications/mirror"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "applications/mirror"}, }, - "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}], + "routes": [{"action": {"proxy": "http://127.0.0.1:8081"}}], "applications": { "mirror": { "type": client.get_application_type(), @@ -110,19 +110,19 @@ def test_proxy_chain(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes/first"}, - "*:7081": {"pass": "routes/second"}, - "*:7082": {"pass": "routes/third"}, - "*:7083": {"pass": "routes/fourth"}, - "*:7084": {"pass": "routes/fifth"}, - "*:7085": {"pass": "applications/mirror"}, + "*:8080": {"pass": "routes/first"}, + "*:8081": {"pass": "routes/second"}, + "*:8082": {"pass": "routes/third"}, + "*:8083": {"pass": "routes/fourth"}, + "*:8084": {"pass": "routes/fifth"}, + "*:8085": {"pass": "applications/mirror"}, }, "routes": { - "first": [{"action": {"proxy": "http://127.0.0.1:7081"}}], - "second": [{"action": {"proxy": "http://127.0.0.1:7082"}}], - "third": [{"action": {"proxy": "http://127.0.0.1:7083"}}], - "fourth": [{"action": {"proxy": "http://127.0.0.1:7084"}}], - "fifth": [{"action": {"proxy": "http://127.0.0.1:7085"}}], + "first": [{"action": {"proxy": "http://127.0.0.1:8081"}}], + "second": [{"action": {"proxy": "http://127.0.0.1:8082"}}], + "third": [{"action": {"proxy": "http://127.0.0.1:8083"}}], + "fourth": [{"action": {"proxy": "http://127.0.0.1:8084"}}], + "fifth": [{"action": {"proxy": "http://127.0.0.1:8085"}}], }, "applications": { "mirror": { @@ -210,7 +210,7 @@ def test_proxy_parallel(): def test_proxy_header(): assert 'success' in client.conf( - {"pass": "applications/custom_header"}, 'listeners/*:7081' + {"pass": "applications/custom_header"}, 'listeners/*:8081' ), 'custom_header configure' header_value = 'blah' @@ -325,7 +325,7 @@ def test_proxy_fragmented_body_close(): def test_proxy_nowhere(): assert 'success' in client.conf( - [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes' + [{"action": {"proxy": "http://127.0.0.1:8082"}}], 'routes' ), 'proxy path changed' assert get_http10()['status'] == 502, 'status' @@ -334,14 +334,14 @@ def test_proxy_nowhere(): def test_proxy_ipv6(): assert 'success' in client.conf( { - "*:7080": {"pass": "routes"}, - "[::1]:7081": {'application': 'mirror'}, + "*:8080": {"pass": "routes"}, + "[::1]:8081": {'application': 'mirror'}, }, 'listeners', ), 'add ipv6 listener configure' assert 'success' in client.conf( - [{"action": {"proxy": "http://[::1]:7081"}}], 'routes' + [{"action": {"proxy": "http://[::1]:8081"}}], 'routes' ), 'proxy ipv6 configure' assert get_http10()['status'] == 200, 'status' @@ -352,7 +352,7 @@ def test_proxy_unix(temp_dir): assert 'success' in client.conf( { - "*:7080": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, f'unix:{addr}': {'application': 'mirror'}, }, 'listeners', @@ -367,7 +367,7 @@ def test_proxy_unix(temp_dir): def test_proxy_delayed(): assert 'success' in client.conf( - {"pass": "applications/delayed"}, 'listeners/*:7081' + {"pass": "applications/delayed"}, 'listeners/*:8081' ), 'delayed configure' body = '0123456789' * 1000 @@ -400,7 +400,7 @@ def test_proxy_delayed(): def test_proxy_delayed_close(): assert 'success' in client.conf( - {"pass": "applications/delayed"}, 'listeners/*:7081' + {"pass": "applications/delayed"}, 'listeners/*:8081' ), 'delayed configure' sock = post_http10( @@ -469,11 +469,11 @@ def test_proxy_invalid(): check_proxy('http://127.0.0.1:') check_proxy('http://127.0.0.1:blah') check_proxy('http://127.0.0.1:-1') - check_proxy('http://127.0.0.1:7080b') + check_proxy('http://127.0.0.1:8080b') check_proxy('http://[]') - check_proxy('http://[]:7080') - check_proxy('http://[:]:7080') - check_proxy('http://[::7080') + check_proxy('http://[]:8080') + check_proxy('http://[:]:8080') + check_proxy('http://[::8080') @pytest.mark.skip('not yet') @@ -486,11 +486,11 @@ def test_proxy_loop(skip_alert): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "applications/mirror"}, - "*:7082": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "applications/mirror"}, + "*:8082": {"pass": "routes"}, }, - "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}], + "routes": [{"action": {"proxy": "http://127.0.0.1:8082"}}], "applications": { "mirror": { "type": client.get_application_type(), diff --git a/test/test_proxy_chunked.py b/test/test_proxy_chunked.py index a066e1e8..f9e9fe10 100644 --- a/test/test_proxy_chunked.py +++ b/test/test_proxy_chunked.py @@ -22,7 +22,7 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, }, "routes": [ {"action": {"proxy": f'http://127.0.0.1:{SERVER_PORT}'}} diff --git a/test/test_python_application.py b/test/test_python_application.py index 18473d59..058a87df 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -160,7 +160,7 @@ def test_python_application_server_port(): client.load('server_port') assert ( - client.get()['headers']['Server-Port'] == '7080' + client.get()['headers']['Server-Port'] == '8080' ), 'Server-Port header' diff --git a/test/test_python_basic.py b/test/test_python_basic.py index 37859c8c..81c768aa 100644 --- a/test/test_python_basic.py +++ b/test/test_python_basic.py @@ -14,7 +14,7 @@ conf_app = { } conf_basic = { - "listeners": {"*:7080": {"pass": "applications/app"}}, + "listeners": {"*:8080": {"pass": "applications/app"}}, "applications": conf_app, } @@ -64,14 +64,14 @@ def test_python_get_listeners(): assert 'success' in client.conf(conf_basic) assert client.conf_get()['listeners'] == { - "*:7080": {"pass": "applications/app"} + "*:8080": {"pass": "applications/app"} }, 'listeners' assert client.conf_get('listeners') == { - "*:7080": {"pass": "applications/app"} + "*:8080": {"pass": "applications/app"} }, 'listeners prefix' - assert client.conf_get('listeners/*:7080') == { + assert client.conf_get('listeners/*:8080') == { "pass": "applications/app" }, 'listeners prefix 2' @@ -79,23 +79,23 @@ def test_python_get_listeners(): def test_python_change_listener(): assert 'success' in client.conf(conf_basic) assert 'success' in client.conf( - {"*:7081": {"pass": "applications/app"}}, 'listeners' + {"*:8081": {"pass": "applications/app"}}, 'listeners' ) assert client.conf_get('listeners') == { - "*:7081": {"pass": "applications/app"} + "*:8081": {"pass": "applications/app"} }, 'change listener' def test_python_add_listener(): assert 'success' in client.conf(conf_basic) assert 'success' in client.conf( - {"pass": "applications/app"}, 'listeners/*:7082' + {"pass": "applications/app"}, 'listeners/*:8082' ) assert client.conf_get('listeners') == { - "*:7080": {"pass": "applications/app"}, - "*:7082": {"pass": "applications/app"}, + "*:8080": {"pass": "applications/app"}, + "*:8082": {"pass": "applications/app"}, }, 'add listener' @@ -117,7 +117,7 @@ def test_python_delete(): assert 'success' in client.conf(conf_basic) assert 'error' in client.conf_delete('applications/app') - assert 'success' in client.conf_delete('listeners/*:7080') + assert 'success' in client.conf_delete('listeners/*:8080') assert 'success' in client.conf_delete('applications/app') assert 'error' in client.conf_delete('applications/app') @@ -130,5 +130,5 @@ def test_python_delete_blocks(): assert 'success' in client.conf(conf_app, 'applications') assert 'success' in client.conf( - {"*:7081": {"pass": "applications/app"}}, 'listeners' + {"*:8081": {"pass": "applications/app"}}, 'listeners' ), 'applications restore' diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py index 260a87a2..5b97e292 100644 --- a/test/test_python_isolation.py +++ b/test/test_python_isolation.py @@ -151,8 +151,8 @@ def test_python_isolation_cgroup_two(require): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "applications/one"}, - "*:7081": {"pass": "applications/two"}, + "*:8080": {"pass": "applications/one"}, + "*:8081": {"pass": "applications/two"}, }, "applications": { "one": { @@ -193,7 +193,7 @@ def test_python_isolation_cgroup_invalid(require): script_path = f'{option.test_dir}/python/empty' assert 'error' in client.conf( { - "listeners": {"*:7080": {"pass": "applications/empty"}}, + "listeners": {"*:8080": {"pass": "applications/empty"}}, "applications": { "empty": { "type": "python", diff --git a/test/test_python_targets.py b/test/test_python_targets.py index 46e77c19..10f10b70 100644 --- a/test/test_python_targets.py +++ b/test/test_python_targets.py @@ -11,7 +11,7 @@ def test_python_targets(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/1"}, @@ -56,7 +56,7 @@ def test_python_targets_prefix(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": ["/app*"]}, diff --git a/test/test_reconfigure.py b/test/test_reconfigure.py index 53258b41..a5fe1b1a 100644 --- a/test/test_reconfigure.py +++ b/test/test_reconfigure.py @@ -10,7 +10,7 @@ client = ApplicationProto() def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"return": 200}}], "applications": {}, } diff --git a/test/test_reconfigure_tls.py b/test/test_reconfigure_tls.py index b473b147..50638391 100644 --- a/test/test_reconfigure_tls.py +++ b/test/test_reconfigure_tls.py @@ -20,7 +20,7 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": { + "*:8080": { "pass": "routes", "tls": {"certificate": "default"}, } @@ -40,7 +40,7 @@ def create_socket(): ssl_sock = ctx.wrap_socket( s, server_hostname='localhost', do_handshake_on_connect=False ) - ssl_sock.connect(('127.0.0.1', 7080)) + ssl_sock.connect(('127.0.0.1', 8080)) return ssl_sock @@ -51,7 +51,7 @@ def clear_conf(): @pytest.mark.skip('not yet') def test_reconfigure_tls_switch(): - assert 'success' in client.conf_delete('listeners/*:7080/tls') + assert 'success' in client.conf_delete('listeners/*:8080/tls') (_, sock) = client.get( headers={'Host': 'localhost', 'Connection': 'keep-alive'}, @@ -61,7 +61,7 @@ def test_reconfigure_tls_switch(): assert 'success' in client.conf( {"pass": "routes", "tls": {"certificate": "default"}}, - 'listeners/*:7080', + 'listeners/*:8080', ) assert client.get(sock=sock)['status'] == 200, 'reconfigure' diff --git a/test/test_response_headers.py b/test/test_response_headers.py index 50f47d9a..ec07c8c4 100644 --- a/test/test_response_headers.py +++ b/test/test_response_headers.py @@ -17,7 +17,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, }, "routes": [ { @@ -59,7 +59,7 @@ def test_response_last_action(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes/first"}, + "*:8080": {"pass": "routes/first"}, }, "routes": { "first": [ @@ -91,7 +91,7 @@ def test_response_pass(require): assert 'success' in client_python.conf( { "listeners": { - "*:7080": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, }, "routes": [ { @@ -121,7 +121,7 @@ def test_response_pass(require): def test_response_fallback(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { diff --git a/test/test_return.py b/test/test_return.py index 35525ed5..3ffcaa4e 100644 --- a/test/test_return.py +++ b/test/test_return.py @@ -10,7 +10,7 @@ client = ApplicationProto() def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"return": 200}}], "applications": {}, } diff --git a/test/test_rewrite.py b/test/test_rewrite.py index 8d81ec49..0a4ffe42 100644 --- a/test/test_rewrite.py +++ b/test/test_rewrite.py @@ -10,7 +10,7 @@ client = ApplicationProto() def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/"}, @@ -112,7 +112,7 @@ def test_rewrite_location(): def check_location(rewrite, expect): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { @@ -141,7 +141,7 @@ def test_rewrite_share(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { @@ -162,7 +162,7 @@ def test_rewrite_share(temp_dir): index_path = f'{temp_dir}${{request_uri}}/index.html' assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/foo"}, @@ -182,7 +182,7 @@ def test_rewrite_share(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/foo"}, diff --git a/test/test_routing.py b/test/test_routing.py index a18edb04..ce5952eb 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -12,7 +12,7 @@ client = ApplicationPython() def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": {"method": "GET"}, @@ -322,7 +322,7 @@ def test_routes_pass_encode(): def check_pass(path, name): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": f'applications/{path}'}}, + "listeners": {"*:8080": {"pass": f'applications/{path}'}}, "applications": { name: { "type": client.get_application_type(), @@ -345,7 +345,7 @@ def test_routes_pass_encode(): def check_pass_error(path, name): assert 'error' in client.conf( { - "listeners": {"*:7080": {"pass": f'applications/{path}'}}, + "listeners": {"*:8080": {"pass": f'applications/{path}'}}, "applications": { name: { "type": client.get_application_type(), @@ -365,7 +365,7 @@ def test_routes_pass_encode(): def test_routes_absent(): assert 'success' in client.conf( { - "listeners": {"*:7081": {"pass": "applications/empty"}}, + "listeners": {"*:8081": {"pass": "applications/empty"}}, "applications": { "empty": { "type": client.get_application_type(), @@ -378,19 +378,19 @@ def test_routes_absent(): } ) - assert client.get(port=7081)['status'] == 200, 'routes absent' + assert client.get(port=8081)['status'] == 200, 'routes absent' def test_routes_pass_invalid(): assert 'error' in client.conf( - {"pass": "routes/blah"}, 'listeners/*:7080' + {"pass": "routes/blah"}, 'listeners/*:8080' ), 'routes invalid' def test_route_empty(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/main"}}, + "listeners": {"*:8080": {"pass": "routes/main"}}, "routes": {"main": []}, "applications": {}, } @@ -437,14 +437,14 @@ def test_routes_route_pass(): "upstreams": { "one": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, "two": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, }, @@ -480,14 +480,14 @@ def test_routes_route_pass_invalid(): "upstreams": { "one": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, "two": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, }, @@ -512,10 +512,10 @@ def test_routes_action_unique(temp_dir): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "applications/app"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "applications/app"}, }, - "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}], + "routes": [{"action": {"proxy": "http://127.0.0.1:8081"}}], "applications": { "app": { "type": client.get_application_type(), @@ -528,12 +528,12 @@ def test_routes_action_unique(temp_dir): ) assert 'error' in client.conf( - {"proxy": "http://127.0.0.1:7081", "share": temp_dir}, + {"proxy": "http://127.0.0.1:8081", "share": temp_dir}, 'routes/0/action', ), 'proxy share' assert 'error' in client.conf( { - "proxy": "http://127.0.0.1:7081", + "proxy": "http://127.0.0.1:8081", "pass": "applications/app", }, 'routes/0/action', @@ -560,7 +560,7 @@ def test_routes_rules_two(): def test_routes_two(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/first"}}, + "listeners": {"*:8080": {"pass": "routes/first"}}, "routes": { "first": [ { @@ -606,14 +606,14 @@ def test_routes_match_host_ipv4(): route_match({"host": "127.0.0.1"}) host('127.0.0.1', 200) - host('127.0.0.1:7080', 200) + host('127.0.0.1:8080', 200) def test_routes_match_host_ipv6(): route_match({"host": "[::1]"}) host('[::1]', 200) - host('[::1]:7080', 200) + host('[::1]:8080', 200) def test_routes_match_host_positive_many(): @@ -649,7 +649,7 @@ def test_routes_match_host_case_insensitive(): def test_routes_match_host_port(): route_match({"host": "example.com"}) - host('example.com:7080', 200) + host('example.com:8080', 200) def test_routes_match_host_empty(): @@ -718,7 +718,7 @@ def test_routes_reconfigure(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/main"}}, + "listeners": {"*:8080": {"pass": "routes/main"}}, "routes": {"main": [{"action": {"return": 200}}]}, "applications": {}, } @@ -801,7 +801,7 @@ def test_routes_edit(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/main"}}, + "listeners": {"*:8080": {"pass": "routes/main"}}, "routes": {"main": [{"action": {"return": 200}}]}, "applications": {}, } @@ -817,7 +817,7 @@ def test_routes_edit(): assert client.get()['status'] == 200, 'routes edit GET 7' assert 'success' in client.conf_delete( - 'listeners/*:7080' + 'listeners/*:8080' ), 'route edit configure 8' assert 'success' in client.conf_delete( 'routes/main' @@ -1646,14 +1646,14 @@ def test_routes_source_port(): def test_routes_source_addr(): assert 'success' in client.conf( { - "*:7080": {"pass": "routes"}, - "[::1]:7081": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, + "[::1]:8081": {"pass": "routes"}, }, 'listeners', ), 'source listeners configure' def get_ipv6(): - return client.get(sock_type='ipv6', port=7081) + return client.get(sock_type='ipv6', port=8081) route_match({"source": "127.0.0.1"}) assert client.get()['status'] == 200, 'exact' @@ -1707,64 +1707,64 @@ def test_routes_source_addr(): def test_routes_source_ipv6(): assert 'success' in client.conf( { - "[::1]:7080": {"pass": "routes"}, - "127.0.0.1:7081": {"pass": "routes"}, + "[::1]:8080": {"pass": "routes"}, + "127.0.0.1:8081": {"pass": "routes"}, }, 'listeners', ), 'source listeners configure' route_match({"source": "::1"}) assert client.get(sock_type='ipv6')['status'] == 200, 'exact' - assert client.get(port=7081)['status'] == 404, 'exact ipv4' + assert client.get(port=8081)['status'] == 404, 'exact ipv4' route_match({"source": ["::1"]}) assert client.get(sock_type='ipv6')['status'] == 200, 'exact 2' - assert client.get(port=7081)['status'] == 404, 'exact 2 ipv4' + assert client.get(port=8081)['status'] == 404, 'exact 2 ipv4' route_match({"source": "!::1"}) assert client.get(sock_type='ipv6')['status'] == 404, 'exact neg' - assert client.get(port=7081)['status'] == 200, 'exact neg ipv4' + assert client.get(port=8081)['status'] == 200, 'exact neg ipv4' route_match({"source": "::2"}) assert client.get(sock_type='ipv6')['status'] == 404, 'exact 3' - assert client.get(port=7081)['status'] == 404, 'exact 3 ipv4' + assert client.get(port=8081)['status'] == 404, 'exact 3 ipv4' route_match({"source": "::1-::1"}) assert client.get(sock_type='ipv6')['status'] == 200, 'range' - assert client.get(port=7081)['status'] == 404, 'range ipv4' + assert client.get(port=8081)['status'] == 404, 'range ipv4' route_match({"source": "::2-::2"}) assert client.get(sock_type='ipv6')['status'] == 404, 'range 2' - assert client.get(port=7081)['status'] == 404, 'range 2 ipv4' + assert client.get(port=8081)['status'] == 404, 'range 2 ipv4' route_match({"source": "::2-::3"}) assert client.get(sock_type='ipv6')['status'] == 404, 'range 3' - assert client.get(port=7081)['status'] == 404, 'range 3 ipv4' + assert client.get(port=8081)['status'] == 404, 'range 3 ipv4' route_match({"source": "::1-::2"}) assert client.get(sock_type='ipv6')['status'] == 200, 'range 4' - assert client.get(port=7081)['status'] == 404, 'range 4 ipv4' + assert client.get(port=8081)['status'] == 404, 'range 4 ipv4' route_match({"source": "::0-::2"}) assert client.get(sock_type='ipv6')['status'] == 200, 'range 5' - assert client.get(port=7081)['status'] == 404, 'range 5 ipv4' + assert client.get(port=8081)['status'] == 404, 'range 5 ipv4' route_match({"source": "::0-::1"}) assert client.get(sock_type='ipv6')['status'] == 200, 'range 6' - assert client.get(port=7081)['status'] == 404, 'range 6 ipv4' + assert client.get(port=8081)['status'] == 404, 'range 6 ipv4' def test_routes_source_cidr(): assert 'success' in client.conf( { - "*:7080": {"pass": "routes"}, - "[::1]:7081": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, + "[::1]:8081": {"pass": "routes"}, }, 'listeners', ), 'source listeners configure' def get_ipv6(): - return client.get(sock_type='ipv6', port=7081) + return client.get(sock_type='ipv6', port=8081) route_match({"source": "127.0.0.1/32"}) assert client.get()['status'] == 200, '32' @@ -1790,35 +1790,35 @@ def test_routes_source_cidr(): def test_routes_source_cidr_ipv6(): assert 'success' in client.conf( { - "[::1]:7080": {"pass": "routes"}, - "127.0.0.1:7081": {"pass": "routes"}, + "[::1]:8080": {"pass": "routes"}, + "127.0.0.1:8081": {"pass": "routes"}, }, 'listeners', ), 'source listeners configure' route_match({"source": "::1/128"}) assert client.get(sock_type='ipv6')['status'] == 200, '128' - assert client.get(port=7081)['status'] == 404, '128 ipv4' + assert client.get(port=8081)['status'] == 404, '128 ipv4' route_match({"source": "::0/128"}) assert client.get(sock_type='ipv6')['status'] == 404, '128 2' - assert client.get(port=7081)['status'] == 404, '128 ipv4' + assert client.get(port=8081)['status'] == 404, '128 ipv4' route_match({"source": "::0/127"}) assert client.get(sock_type='ipv6')['status'] == 200, '127' - assert client.get(port=7081)['status'] == 404, '127 ipv4' + assert client.get(port=8081)['status'] == 404, '127 ipv4' route_match({"source": "::0/32"}) assert client.get(sock_type='ipv6')['status'] == 200, '32' - assert client.get(port=7081)['status'] == 404, '32 ipv4' + assert client.get(port=8081)['status'] == 404, '32 ipv4' route_match({"source": "::0/1"}) assert client.get(sock_type='ipv6')['status'] == 200, '1' - assert client.get(port=7081)['status'] == 404, '1 ipv4' + assert client.get(port=8081)['status'] == 404, '1 ipv4' route_match({"source": "::/0"}) assert client.get(sock_type='ipv6')['status'] == 200, '0' - assert client.get(port=7081)['status'] == 404, '0 ipv4' + assert client.get(port=8081)['status'] == 404, '0 ipv4' def test_routes_source_unix(temp_dir): @@ -1826,7 +1826,7 @@ def test_routes_source_unix(temp_dir): assert 'success' in client.conf( { - "127.0.0.1:7081": {"pass": "routes"}, + "127.0.0.1:8081": {"pass": "routes"}, f'unix:{addr}': {"pass": "routes"}, }, 'listeners', @@ -1843,7 +1843,7 @@ def test_routes_source_unix(temp_dir): ), 'unix ipv6 neg' route_match({"source": "unix"}) - assert client.get(port=7081)['status'] == 404, 'unix ipv4' + assert client.get(port=8081)['status'] == 404, 'unix ipv4' assert client.get(sock_type='unix', addr=addr)['status'] == 200, 'unix' @@ -1916,7 +1916,7 @@ def test_routes_match_source_invalid(): route_match_invalid({"source": "2001::/129"}) route_match_invalid({"source": "::FFFFF"}) route_match_invalid({"source": "[::1]:"}) - route_match_invalid({"source": "[:::]:7080"}) + route_match_invalid({"source": "[:::]:8080"}) route_match_invalid({"source": "*:"}) route_match_invalid({"source": "*:1-a"}) route_match_invalid({"source": "*:65536"}) @@ -1929,74 +1929,74 @@ def test_routes_match_source_none(): def test_routes_match_destination(): assert 'success' in client.conf( - {"*:7080": {"pass": "routes"}, "*:7081": {"pass": "routes"}}, + {"*:8080": {"pass": "routes"}, "*:8081": {"pass": "routes"}}, 'listeners', ), 'listeners configure' - route_match({"destination": "*:7080"}) + route_match({"destination": "*:8080"}) assert client.get()['status'] == 200, 'dest' - assert client.get(port=7081)['status'] == 404, 'dest 2' + assert client.get(port=8081)['status'] == 404, 'dest 2' - route_match({"destination": ["127.0.0.1:7080"]}) + route_match({"destination": ["127.0.0.1:8080"]}) assert client.get()['status'] == 200, 'dest 3' - assert client.get(port=7081)['status'] == 404, 'dest 4' + assert client.get(port=8081)['status'] == 404, 'dest 4' - route_match({"destination": "!*:7080"}) + route_match({"destination": "!*:8080"}) assert client.get()['status'] == 404, 'dest neg' - assert client.get(port=7081)['status'] == 200, 'dest neg 2' + assert client.get(port=8081)['status'] == 200, 'dest neg 2' - route_match({"destination": ['!*:7080', '!*:7081']}) + route_match({"destination": ['!*:8080', '!*:8081']}) assert client.get()['status'] == 404, 'dest neg 3' - assert client.get(port=7081)['status'] == 404, 'dest neg 4' + assert client.get(port=8081)['status'] == 404, 'dest neg 4' - route_match({"destination": ['!*:7081', '!*:7082']}) + route_match({"destination": ['!*:8081', '!*:8082']}) assert client.get()['status'] == 200, 'dest neg 5' - route_match({"destination": ['*:7080', '!*:7080']}) + route_match({"destination": ['*:8080', '!*:8080']}) assert client.get()['status'] == 404, 'dest neg 6' - route_match({"destination": ['127.0.0.1:7080', '*:7081', '!*:7080']}) + route_match({"destination": ['127.0.0.1:8080', '*:8081', '!*:8080']}) assert client.get()['status'] == 404, 'dest neg 7' - assert client.get(port=7081)['status'] == 200, 'dest neg 8' + assert client.get(port=8081)['status'] == 200, 'dest neg 8' - route_match({"destination": ['!*:7081', '!*:7082', '*:7083']}) + route_match({"destination": ['!*:8081', '!*:8082', '*:8083']}) assert client.get()['status'] == 404, 'dest neg 9' - route_match({"destination": ['*:7081', '!127.0.0.1:7080', '*:7080']}) + route_match({"destination": ['*:8081', '!127.0.0.1:8080', '*:8080']}) assert client.get()['status'] == 404, 'dest neg 10' - assert client.get(port=7081)['status'] == 200, 'dest neg 11' + assert client.get(port=8081)['status'] == 200, 'dest neg 11' assert 'success' in client.conf_delete( 'routes/0/match/destination/0' ), 'remove destination rule' assert client.get()['status'] == 404, 'dest neg 12' - assert client.get(port=7081)['status'] == 404, 'dest neg 13' + assert client.get(port=8081)['status'] == 404, 'dest neg 13' assert 'success' in client.conf_delete( 'routes/0/match/destination/0' ), 'remove destination rule 2' assert client.get()['status'] == 200, 'dest neg 14' - assert client.get(port=7081)['status'] == 404, 'dest neg 15' + assert client.get(port=8081)['status'] == 404, 'dest neg 15' assert 'success' in client.conf_post( "\"!127.0.0.1\"", 'routes/0/match/destination' ), 'add destination rule' assert client.get()['status'] == 404, 'dest neg 16' - assert client.get(port=7081)['status'] == 404, 'dest neg 17' + assert client.get(port=8081)['status'] == 404, 'dest neg 17' def test_routes_match_destination_proxy(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes/first"}, - "*:7081": {"pass": "routes/second"}, + "*:8080": {"pass": "routes/first"}, + "*:8081": {"pass": "routes/second"}, }, "routes": { - "first": [{"action": {"proxy": "http://127.0.0.1:7081"}}], + "first": [{"action": {"proxy": "http://127.0.0.1:8081"}}], "second": [ { - "match": {"destination": ["127.0.0.1:7081"]}, + "match": {"destination": ["127.0.0.1:8081"]}, "action": {"return": 200}, } ], diff --git a/test/test_routing_tls.py b/test/test_routing_tls.py index 4a97c8e4..f8cef546 100644 --- a/test/test_routing_tls.py +++ b/test/test_routing_tls.py @@ -11,8 +11,8 @@ def test_routes_match_scheme_tls(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": { + "*:8080": {"pass": "routes"}, + "*:8081": { "pass": "routes", "tls": {"certificate": 'default'}, }, @@ -26,4 +26,4 @@ def test_routes_match_scheme_tls(): ), 'scheme configure' assert client.get()['status'] == 200, 'http' - assert client.get_ssl(port=7081)['status'] == 201, 'https' + assert client.get_ssl(port=8081)['status'] == 201, 'https' diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index 6f533b70..f187cc45 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -91,7 +91,7 @@ def test_ruby_application_server_port(): client.load('server_port') assert ( - client.get()['headers']['Server-Port'] == '7080' + client.get()['headers']['Server-Port'] == '8080' ), 'Server-Port header' diff --git a/test/test_settings.py b/test/test_settings.py index 33180046..0cdc6c0d 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -460,7 +460,7 @@ def test_settings_log_route(findall, search_in_file, wait_for_record): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "match": { @@ -487,7 +487,7 @@ def test_settings_log_route(findall, search_in_file, wait_for_record): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/main"}}, + "listeners": {"*:8080": {"pass": "routes/main"}}, "routes": { "main": [ { @@ -516,7 +516,7 @@ def test_settings_log_route(findall, search_in_file, wait_for_record): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/first"}}, + "listeners": {"*:8080": {"pass": "routes/first"}}, "routes": { "first": [ { @@ -541,7 +541,7 @@ def test_settings_log_route(findall, search_in_file, wait_for_record): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes/fall"}}, + "listeners": {"*:8080": {"pass": "routes/fall"}}, "routes": { "fall": [ { diff --git a/test/test_static.py b/test/test_static.py index d46247d9..98f27c7f 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -26,7 +26,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{assets_dir}$uri'}}], "settings": { "http": { diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index 6b4dd89a..fb14d7ab 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -20,7 +20,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], } ) diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py index ffc888ab..25e466a3 100644 --- a/test/test_static_fallback.py +++ b/test/test_static_fallback.py @@ -19,8 +19,8 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "routes"}, }, "routes": [{"action": {"share": f'{assets_dir}$uri'}}], "applications": {}, @@ -108,13 +108,13 @@ def test_static_fallback_proxy(): assert 'success' in client.conf( [ { - "match": {"destination": "*:7081"}, + "match": {"destination": "*:8081"}, "action": {"return": 200}, }, { "action": { "share": "/blah", - "fallback": {"proxy": "http://127.0.0.1:7081"}, + "fallback": {"proxy": "http://127.0.0.1:8081"}, } }, ], @@ -136,11 +136,11 @@ def test_static_fallback_proxy_loop(skip_alert): ) action_update( - {"share": "/blah", "fallback": {"proxy": "http://127.0.0.1:7080"}} + {"share": "/blah", "fallback": {"proxy": "http://127.0.0.1:8080"}} ) client.get(no_recv=True) - assert 'success' in client.conf_delete('listeners/*:7081') + assert 'success' in client.conf_delete('listeners/*:8081') client.get(read_timeout=1) @@ -152,6 +152,6 @@ def test_static_fallback_invalid(): check_error({"share": "/blah", "fallback": ""}) check_error({"return": 200, "fallback": {"share": "/blah"}}) check_error( - {"proxy": "http://127.0.0.1:7081", "fallback": {"share": "/blah"}} + {"proxy": "http://127.0.0.1:8081", "fallback": {"share": "/blah"}} ) check_error({"fallback": {"share": "/blah"}}) diff --git a/test/test_static_mount.py b/test/test_static_mount.py index ccd18919..d8d3b698 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -38,7 +38,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{temp_dir}/assets/dir$uri'}}], } ) diff --git a/test/test_static_share.py b/test/test_static_share.py index ac5afb50..fa16d267 100644 --- a/test/test_static_share.py +++ b/test/test_static_share.py @@ -17,7 +17,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], "applications": {}, } diff --git a/test/test_static_symlink.py b/test/test_static_symlink.py index 1f7d7907..3b04d70c 100644 --- a/test/test_static_symlink.py +++ b/test/test_static_symlink.py @@ -17,7 +17,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], } ) diff --git a/test/test_static_types.py b/test/test_static_types.py index 8cd28ca4..a468319a 100644 --- a/test/test_static_types.py +++ b/test/test_static_types.py @@ -17,8 +17,8 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "routes"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "routes"}, }, "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], "applications": {}, @@ -124,14 +124,14 @@ def test_static_types_fallback(temp_dir): assert 'success' in client.conf( [ { - "match": {"destination": "*:7081"}, + "match": {"destination": "*:8081"}, "action": {"return": 200}, }, { "action": { "share": f'{temp_dir}/assets$uri', "types": ["!application/x-httpd-php"], - "fallback": {"proxy": "http://127.0.0.1:7081"}, + "fallback": {"proxy": "http://127.0.0.1:8081"}, } }, ], @@ -155,7 +155,7 @@ def test_static_types_index(temp_dir): def test_static_types_custom_mime(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], "applications": {}, "settings": { diff --git a/test/test_static_variables.py b/test/test_static_variables.py index bc39e90e..5afd0127 100644 --- a/test/test_static_variables.py +++ b/test/test_static_variables.py @@ -17,7 +17,7 @@ def setup_method_fixture(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], } ) diff --git a/test/test_status.py b/test/test_status.py index 11b140cf..a52f7486 100644 --- a/test/test_status.py +++ b/test/test_status.py @@ -39,9 +39,9 @@ def test_status_requests(skip_alert): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "applications/empty"}, - "*:7082": {"pass": "applications/blah"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "applications/empty"}, + "*:8082": {"pass": "applications/blah"}, }, "routes": [{"action": {"return": 200}}], "applications": { @@ -60,7 +60,7 @@ def test_status_requests(skip_alert): assert client.get()['status'] == 200 assert Status.get('/requests/total') == 1, '2xx' - assert client.get(port=7081)['status'] == 200 + assert client.get(port=8081)['status'] == 200 assert Status.get('/requests/total') == 2, '2xx app' assert ( @@ -69,7 +69,7 @@ def test_status_requests(skip_alert): ) assert Status.get('/requests/total') == 3, '4xx' - assert client.get(port=7082)['status'] == 503 + assert client.get(port=8082)['status'] == 503 assert Status.get('/requests/total') == 4, '5xx' client.http( @@ -85,7 +85,7 @@ Connection: close ) assert Status.get('/requests/total') == 6, 'pipeline' - sock = client.get(port=7081, no_recv=True) + sock = client.get(port=8081, no_recv=True) time.sleep(1) @@ -98,8 +98,8 @@ def test_status_connections(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "applications/delayed"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "applications/delayed"}, }, "routes": [{"action": {"return": 200}}], "applications": { @@ -136,7 +136,7 @@ def test_status_connections(): 'X-Delay': '2', 'Connection': 'close', }, - port=7081, + port=8081, start=True, read_timeout=1, ) @@ -194,8 +194,8 @@ def test_status_applications(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "applications/restart"}, - "*:7081": {"pass": "applications/delayed"}, + "*:8080": {"pass": "applications/restart"}, + "*:8081": {"pass": "applications/delayed"}, }, "routes": [], "applications": { @@ -220,13 +220,13 @@ def test_status_proxy(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": {"pass": "applications/empty"}, + "*:8080": {"pass": "routes"}, + "*:8081": {"pass": "applications/empty"}, }, "routes": [ { "match": {"uri": "/"}, - "action": {"proxy": "http://127.0.0.1:7081"}, + "action": {"proxy": "http://127.0.0.1:8081"}, } ], "applications": { diff --git a/test/test_status_tls.py b/test/test_status_tls.py index 784b4960..f69f021e 100644 --- a/test/test_status_tls.py +++ b/test/test_status_tls.py @@ -12,8 +12,8 @@ def test_status_tls_requests(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "routes"}, - "*:7081": { + "*:8080": {"pass": "routes"}, + "*:8081": { "pass": "routes", "tls": {"certificate": "default"}, }, @@ -26,6 +26,6 @@ def test_status_tls_requests(): Status.init() assert client.get()['status'] == 200 - assert client.get_ssl(port=7081)['status'] == 200 + assert client.get_ssl(port=8081)['status'] == 200 assert Status.get('/requests/total') == 2 diff --git a/test/test_tls.py b/test/test_tls.py index 54fdb665..a56d5428 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -12,7 +12,7 @@ prerequisites = {'modules': {'python': 'any', 'openssl': 'any'}} client = ApplicationTLS() -def add_tls(application='empty', cert='default', port=7080): +def add_tls(application='empty', cert='default', port=8080): assert 'success' in client.conf( { "pass": f"applications/{application}", @@ -85,7 +85,7 @@ basicConstraints = critical,CA:TRUE""" f.write('') -def remove_tls(application='empty', port=7080): +def remove_tls(application='empty', port=8080): assert 'success' in client.conf( {"pass": f"applications/{application}"}, f'listeners/*:{port}' ) @@ -178,12 +178,12 @@ def test_tls_certificate_update(): add_tls() - cert_old = ssl.get_server_certificate(('127.0.0.1', 7080)) + cert_old = ssl.get_server_certificate(('127.0.0.1', 8080)) client.certificate() assert cert_old != ssl.get_server_certificate( - ('127.0.0.1', 7080) + ('127.0.0.1', 8080) ), 'update certificate' @@ -207,12 +207,12 @@ def test_tls_certificate_change(): add_tls() - cert_old = ssl.get_server_certificate(('127.0.0.1', 7080)) + cert_old = ssl.get_server_certificate(('127.0.0.1', 8080)) add_tls(cert='new') assert cert_old != ssl.get_server_certificate( - ('127.0.0.1', 7080) + ('127.0.0.1', 8080) ), 'change certificate' @@ -542,7 +542,7 @@ def test_tls_no_close_notify(): assert 'success' in client.conf( { "listeners": { - "*:7080": { + "*:8080": { "pass": "routes", "tls": {"certificate": "default"}, } @@ -576,7 +576,7 @@ def test_tls_keepalive_certificate_remove(): ) assert 'success' in client.conf( - {"pass": "applications/empty"}, 'listeners/*:7080' + {"pass": "applications/empty"}, 'listeners/*:8080' ) assert 'success' in client.conf_delete('/certificates/default') @@ -697,8 +697,8 @@ def test_tls_multi_listener(): client.certificate() add_tls() - add_tls(port=7081) + add_tls(port=8081) assert client.get_ssl()['status'] == 200, 'listener #1' - assert client.get_ssl(port=7081)['status'] == 200, 'listener #2' + assert client.get_ssl(port=8081)['status'] == 200, 'listener #2' diff --git a/test/test_tls_conf_command.py b/test/test_tls_conf_command.py index 49df7bf3..4d772c83 100644 --- a/test/test_tls_conf_command.py +++ b/test/test_tls_conf_command.py @@ -15,7 +15,7 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": { + "*:8080": { "pass": "routes", "tls": {"certificate": "default"}, } @@ -55,7 +55,7 @@ def test_tls_conf_command(): "certificate": "default", "conf_commands": {"protocol": f'-{protocol}'}, }, - 'listeners/*:7080/tls', + 'listeners/*:8080/tls', ), 'protocol disabled' sock.close() @@ -84,7 +84,7 @@ def test_tls_conf_command(): "cipherstring": f"{cipher[1]}:!{cipher[0]}", }, }, - 'listeners/*:7080/tls', + 'listeners/*:8080/tls', ), 'cipher disabled' if len(ciphers) > 1: @@ -106,7 +106,7 @@ def test_tls_conf_command_invalid(skip_alert): def check_conf_commands(conf_commands): assert 'error' in client.conf( {"certificate": "default", "conf_commands": conf_commands}, - 'listeners/*:7080/tls', + 'listeners/*:8080/tls', ), 'ivalid conf_commands' check_conf_commands([]) diff --git a/test/test_tls_session.py b/test/test_tls_session.py index 8b2b04fd..8da0306a 100644 --- a/test/test_tls_session.py +++ b/test/test_tls_session.py @@ -26,7 +26,7 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": { + "*:8080": { "pass": "routes", "tls": {"certificate": "default", "session": {}}, } @@ -45,11 +45,11 @@ def add_session(cache_size=None, timeout=None): if timeout is not None: session['timeout'] = timeout - return client.conf(session, 'listeners/*:7080/tls/session') + return client.conf(session, 'listeners/*:8080/tls/session') def connect(ctx=None, session=None): - sock = socket.create_connection(('127.0.0.1', 7080)) + sock = socket.create_connection(('127.0.0.1', 8080)) if ctx is None: ctx = Context(TLSv1_2_METHOD) diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index 253d9813..aa7ed3c5 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -14,7 +14,7 @@ client = ApplicationTLS() def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"return": 200}}], "applications": {}, } @@ -24,7 +24,7 @@ def setup_method_fixture(): def add_tls(cert='default'): assert 'success' in client.conf( {"pass": "routes", "tls": {"certificate": cert}}, - 'listeners/*:7080', + 'listeners/*:8080', ) @@ -141,7 +141,7 @@ def load_certs(bundles): def remove_tls(): - assert 'success' in client.conf({"pass": "routes"}, 'listeners/*:7080') + assert 'success' in client.conf({"pass": "routes"}, 'listeners/*:8080') def test_tls_sni(): @@ -289,7 +289,7 @@ def test_tls_sni_invalid(): def check_certificate(cert): assert 'error' in client.conf( {"pass": "routes", "tls": {"certificate": cert}}, - 'listeners/*:7080', + 'listeners/*:8080', ) check_certificate('') diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py index 0d8e4f36..5e899a9b 100644 --- a/test/test_tls_tickets.py +++ b/test/test_tls_tickets.py @@ -36,9 +36,9 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": listener_conf, - "*:7081": listener_conf, - "*:7082": listener_conf, + "*:8080": listener_conf, + "*:8081": listener_conf, + "*:8082": listener_conf, }, "routes": [{"action": {"return": 200}}], "applications": {}, @@ -46,7 +46,7 @@ def setup_method_fixture(): ), 'load application configuration' -def connect(ctx=None, session=None, port=7080): +def connect(ctx=None, session=None, port=8080): sock = socket.create_connection(('127.0.0.1', port)) if ctx is None: @@ -72,7 +72,7 @@ def has_ticket(sess): return _lib.SSL_SESSION_has_ticket(sess._session) -def set_tickets(tickets=True, port=7080): +def set_tickets(tickets=True, port=8080): assert 'success' in client.conf( {"cache_size": 0, "tickets": tickets}, f'listeners/*:{port}/tls/session', @@ -98,7 +98,7 @@ def test_tls_ticket(): assert not has_ticket(sess), 'tickets False' assert 'success' in client.conf_delete( - 'listeners/*:7080/tls/session/tickets' + 'listeners/*:8080/tls/session/tickets' ), 'tickets default configure' sess, _, _ = connect() @@ -118,13 +118,13 @@ def test_tls_ticket_string(): assert has_ticket(sess2), 'tickets string reconnect' assert reused, 'tickets string reused' - sess2, _, reused = connect(ctx, sess, port=7081) + sess2, _, reused = connect(ctx, sess, port=8081) assert has_ticket(sess2), 'connect True' assert not reused, 'connect True not reused' - set_tickets(TICKET2, port=7081) + set_tickets(TICKET2, port=8081) - sess2, _, reused = connect(ctx, sess, port=7081) + sess2, _, reused = connect(ctx, sess, port=8081) assert has_ticket(sess2), 'wrong ticket' assert not reused, 'wrong ticket not reused' @@ -137,7 +137,7 @@ def test_tls_ticket_string(): assert has_ticket(sess2), 'tickets string 80 reconnect' assert reused, 'tickets string 80 reused' - sess2, _, reused = connect(ctx, sess, port=7081) + sess2, _, reused = connect(ctx, sess, port=8081) assert has_ticket(sess2), 'wrong ticket 80' assert not reused, 'wrong ticket 80 not reused' @@ -153,34 +153,34 @@ def test_tls_ticket_array(): assert not has_ticket(sess), 'tickets array empty' set_tickets([TICKET, TICKET2]) - set_tickets(TICKET, port=7081) - set_tickets(TICKET2, port=7082) + set_tickets(TICKET, port=8081) + set_tickets(TICKET2, port=8082) sess, ctx, _ = connect() - _, _, reused = connect(ctx, sess, port=7081) + _, _, reused = connect(ctx, sess, port=8081) assert not reused, 'not last ticket' - _, _, reused = connect(ctx, sess, port=7082) + _, _, reused = connect(ctx, sess, port=8082) assert reused, 'last ticket' - sess, ctx, _ = connect(port=7081) + sess, ctx, _ = connect(port=8081) _, _, reused = connect(ctx, sess) assert reused, 'first ticket' - sess, ctx, _ = connect(port=7082) + sess, ctx, _ = connect(port=8082) _, _, reused = connect(ctx, sess) assert reused, 'second ticket' assert 'success' in client.conf_delete( - 'listeners/*:7080/tls/session/tickets/0' + 'listeners/*:8080/tls/session/tickets/0' ), 'removed first ticket' assert 'success' in client.conf_post( - f'"{TICKET}"', 'listeners/*:7080/tls/session/tickets' + f'"{TICKET}"', 'listeners/*:8080/tls/session/tickets' ), 'add new ticket to the end of array' sess, ctx, _ = connect() - _, _, reused = connect(ctx, sess, port=7082) + _, _, reused = connect(ctx, sess, port=8082) assert not reused, 'not last ticket 2' - _, _, reused = connect(ctx, sess, port=7081) + _, _, reused = connect(ctx, sess, port=8081) assert reused, 'last ticket 2' @@ -188,7 +188,7 @@ def test_tls_ticket_invalid(): def check_tickets(tickets): assert 'error' in client.conf( {"tickets": tickets}, - 'listeners/*:7080/tls/session', + 'listeners/*:8080/tls/session', ) check_tickets({}) diff --git a/test/test_unix_abstract.py b/test/test_unix_abstract.py index 7ed2389c..6e304293 100644 --- a/test/test_unix_abstract.py +++ b/test/test_unix_abstract.py @@ -18,7 +18,7 @@ def test_unix_abstract_source(): assert 'success' in client.conf( { "listeners": { - "127.0.0.1:7080": {"pass": "routes"}, + "127.0.0.1:8080": {"pass": "routes"}, f"unix:@{addr[1:]}": {"pass": "routes"}, }, "routes": [ @@ -44,8 +44,8 @@ def test_unix_abstract_source(): def test_unix_abstract_client_ip(): def get_xff(xff, sock_type='ipv4'): address = { - 'ipv4': ('127.0.0.1', 7080), - 'ipv6': ('::1', 7081), + 'ipv4': ('127.0.0.1', 8080), + 'ipv6': ('::1', 8081), 'unix': ('\0sock', None), } (addr, port) = address[sock_type] @@ -61,14 +61,14 @@ def test_unix_abstract_client_ip(): assert 'success' in client.conf( { "listeners": { - "127.0.0.1:7080": { + "127.0.0.1:8080": { "client_ip": { "header": "X-Forwarded-For", "source": "unix", }, "pass": "applications/client_ip", }, - "[::1]:7081": { + "[::1]:8081": { "client_ip": { "header": "X-Forwarded-For", "source": "unix", diff --git a/test/test_upstreams_rr.py b/test/test_upstreams_rr.py index 046b5614..ecf24add 100644 --- a/test/test_upstreams_rr.py +++ b/test/test_upstreams_rr.py @@ -15,23 +15,23 @@ def setup_method_fixture(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "upstreams/one"}, - "*:7090": {"pass": "upstreams/two"}, - "*:7081": {"pass": "routes/one"}, - "*:7082": {"pass": "routes/two"}, - "*:7083": {"pass": "routes/three"}, + "*:8080": {"pass": "upstreams/one"}, + "*:8090": {"pass": "upstreams/two"}, + "*:8081": {"pass": "routes/one"}, + "*:8082": {"pass": "routes/two"}, + "*:8083": {"pass": "routes/three"}, }, "upstreams": { "one": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, "two": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, }, @@ -47,7 +47,7 @@ def setup_method_fixture(): client.cpu_count = os.cpu_count() -def get_resps(req=100, port=7080): +def get_resps(req=100, port=8080): resps = [0] for _ in range(req): @@ -64,7 +64,7 @@ def get_resps(req=100, port=7080): return resps -def get_resps_sc(req=100, port=7080): +def get_resps_sc(req=100, port=8080): to_send = b"""GET / HTTP/1.1 Host: localhost @@ -96,14 +96,14 @@ def test_upstreams_rr_no_weight(): assert abs(resps[0] - resps[1]) <= client.cpu_count, 'no weight' assert 'success' in client.conf_delete( - 'upstreams/one/servers/127.0.0.1:7081' + 'upstreams/one/servers/127.0.0.1:8081' ), 'no weight server remove' resps = get_resps(req=50) assert resps[1] == 50, 'no weight 2' assert 'success' in client.conf( - {}, 'upstreams/one/servers/127.0.0.1:7081' + {}, 'upstreams/one/servers/127.0.0.1:8081' ), 'no weight server revert' resps = get_resps() @@ -111,7 +111,7 @@ def test_upstreams_rr_no_weight(): assert abs(resps[0] - resps[1]) <= client.cpu_count, 'no weight 3' assert 'success' in client.conf( - {}, 'upstreams/one/servers/127.0.0.1:7083' + {}, 'upstreams/one/servers/127.0.0.1:8083' ), 'no weight server new' resps = get_resps() @@ -126,7 +126,7 @@ def test_upstreams_rr_no_weight(): def test_upstreams_rr_weight(): assert 'success' in client.conf( - {"weight": 3}, 'upstreams/one/servers/127.0.0.1:7081' + {"weight": 3}, 'upstreams/one/servers/127.0.0.1:8081' ), 'configure weight' resps = get_resps_sc() @@ -134,14 +134,14 @@ def test_upstreams_rr_weight(): assert resps[1] == 25, 'weight 3 1' assert 'success' in client.conf_delete( - 'upstreams/one/servers/127.0.0.1:7081/weight' + 'upstreams/one/servers/127.0.0.1:8081/weight' ), 'configure weight remove' resps = get_resps_sc(req=10) assert resps[0] == 5, 'weight 0 0' assert resps[1] == 5, 'weight 0 1' assert 'success' in client.conf( - '1', 'upstreams/one/servers/127.0.0.1:7081/weight' + '1', 'upstreams/one/servers/127.0.0.1:8081/weight' ), 'configure weight 1' resps = get_resps_sc() @@ -150,8 +150,8 @@ def test_upstreams_rr_weight(): assert 'success' in client.conf( { - "127.0.0.1:7081": {"weight": 3}, - "127.0.0.1:7083": {"weight": 2}, + "127.0.0.1:8081": {"weight": 3}, + "127.0.0.1:8083": {"weight": 2}, }, 'upstreams/one/servers', ), 'configure weight 2' @@ -165,8 +165,8 @@ def test_upstreams_rr_weight_rational(): def set_weights(w1, w2): assert 'success' in client.conf( { - "127.0.0.1:7081": {"weight": w1}, - "127.0.0.1:7082": {"weight": w2}, + "127.0.0.1:8081": {"weight": w1}, + "127.0.0.1:8082": {"weight": w2}, }, 'upstreams/one/servers', ), 'configure weights' @@ -195,15 +195,15 @@ def test_upstreams_rr_weight_rational(): set_weights(0.25, 0.25) assert 'success' in client.conf_delete( - 'upstreams/one/servers/127.0.0.1:7081/weight' + 'upstreams/one/servers/127.0.0.1:8081/weight' ), 'delete weight' check_reqs(1, 0.25) assert 'success' in client.conf( { - "127.0.0.1:7081": {"weight": 0.1}, - "127.0.0.1:7082": {"weight": 1}, - "127.0.0.1:7083": {"weight": 0.9}, + "127.0.0.1:8081": {"weight": 0.1}, + "127.0.0.1:8082": {"weight": 1}, + "127.0.0.1:8083": {"weight": 0.9}, }, 'upstreams/one/servers', ), 'configure weights' @@ -221,7 +221,7 @@ def test_upstreams_rr_independent(): return sum_r - resps = get_resps_sc(req=30, port=7090) + resps = get_resps_sc(req=30, port=8090) assert resps[0] == 15, 'dep two before 0' assert resps[1] == 15, 'dep two before 1' @@ -230,10 +230,10 @@ def test_upstreams_rr_independent(): assert resps[1] == 15, 'dep one before 1' assert 'success' in client.conf( - '2', 'upstreams/two/servers/127.0.0.1:7081/weight' + '2', 'upstreams/two/servers/127.0.0.1:8081/weight' ), 'configure dep weight' - resps = get_resps_sc(req=30, port=7090) + resps = get_resps_sc(req=30, port=8090) assert resps[0] == 20, 'dep two 0' assert resps[1] == 10, 'dep two 1' @@ -242,13 +242,13 @@ def test_upstreams_rr_independent(): assert resps[1] == 15, 'dep one 1' assert 'success' in client.conf( - '1', 'upstreams/two/servers/127.0.0.1:7081/weight' + '1', 'upstreams/two/servers/127.0.0.1:8081/weight' ), 'configure dep weight 1' r_one, r_two = [0, 0], [0, 0] for _ in range(10): r_one = sum_resps(r_one, get_resps(req=10)) - r_two = sum_resps(r_two, get_resps(req=10, port=7090)) + r_two = sum_resps(r_two, get_resps(req=10, port=8090)) assert sum(r_one) == 100, 'dep one mix sum' assert abs(r_one[0] - r_one[1]) <= client.cpu_count, 'dep one mix' @@ -261,25 +261,25 @@ def test_upstreams_rr_delay(): assert 'success' in client.conf( { "listeners": { - "*:7080": {"pass": "upstreams/one"}, - "*:7081": {"pass": "routes"}, - "*:7082": {"pass": "routes"}, + "*:8080": {"pass": "upstreams/one"}, + "*:8081": {"pass": "routes"}, + "*:8082": {"pass": "routes"}, }, "upstreams": { "one": { "servers": { - "127.0.0.1:7081": {}, - "127.0.0.1:7082": {}, + "127.0.0.1:8081": {}, + "127.0.0.1:8082": {}, }, }, }, "routes": [ { - "match": {"destination": "*:7081"}, + "match": {"destination": "*:8081"}, "action": {"pass": "applications/delayed"}, }, { - "match": {"destination": "*:7082"}, + "match": {"destination": "*:8082"}, "action": {"return": 201}, }, ], @@ -351,14 +351,14 @@ Connection: close assert client.get()['body'] == '' assert 'success' in client.conf( - {"127.0.0.1:7083": {"weight": 2}}, + {"127.0.0.1:8083": {"weight": 2}}, 'upstreams/one/servers', ), 'active req new server' assert 'success' in client.conf_delete( - 'upstreams/one/servers/127.0.0.1:7083' + 'upstreams/one/servers/127.0.0.1:8083' ), 'active req server remove' assert 'success' in client.conf_delete( - 'listeners/*:7080' + 'listeners/*:8080' ), 'delete listener' assert 'success' in client.conf_delete( 'upstreams/one' @@ -377,7 +377,7 @@ Connection: close def test_upstreams_rr_bad_server(): assert 'success' in client.conf( - {"weight": 1}, 'upstreams/one/servers/127.0.0.1:7084' + {"weight": 1}, 'upstreams/one/servers/127.0.0.1:8084' ), 'configure bad server' resps = get_resps_sc(req=30) @@ -409,7 +409,7 @@ def test_upstreams_rr_unix(temp_dir): assert 'success' in client.conf( { - "*:7080": {"pass": "upstreams/one"}, + "*:8080": {"pass": "upstreams/one"}, f"unix:{addr_0}": {"pass": "routes/one"}, f"unix:{addr_1}": {"pass": "routes/two"}, }, @@ -430,15 +430,15 @@ def test_upstreams_rr_unix(temp_dir): def test_upstreams_rr_ipv6(): assert 'success' in client.conf( { - "*:7080": {"pass": "upstreams/one"}, - "[::1]:7081": {"pass": "routes/one"}, - "[::1]:7082": {"pass": "routes/two"}, + "*:8080": {"pass": "upstreams/one"}, + "[::1]:8081": {"pass": "routes/one"}, + "[::1]:8082": {"pass": "routes/two"}, }, 'listeners', ), 'configure listeners ipv6' assert 'success' in client.conf( - {"[::1]:7081": {}, "[::1]:7082": {}}, 'upstreams/one/servers' + {"[::1]:8081": {}, "[::1]:8082": {}}, 'upstreams/one/servers' ), 'configure servers ipv6' resps = get_resps_sc() @@ -454,13 +454,13 @@ def test_upstreams_rr_servers_empty(): assert client.get()['status'] == 502, 'servers empty' assert 'success' in client.conf( - {"127.0.0.1:7081": {"weight": 0}}, 'upstreams/one/servers' + {"127.0.0.1:8081": {"weight": 0}}, 'upstreams/one/servers' ), 'configure servers empty one' assert client.get()['status'] == 502, 'servers empty one' assert 'success' in client.conf( { - "127.0.0.1:7081": {"weight": 0}, - "127.0.0.1:7082": {"weight": 0}, + "127.0.0.1:8081": {"weight": 0}, + "127.0.0.1:8082": {"weight": 0}, }, 'upstreams/one/servers', ), 'configure servers empty two' @@ -474,12 +474,12 @@ def test_upstreams_rr_invalid(): {}, 'upstreams/one/servers/127.0.0.1' ), 'invalid address' assert 'error' in client.conf( - {}, 'upstreams/one/servers/127.0.0.1:7081/blah' + {}, 'upstreams/one/servers/127.0.0.1:8081/blah' ), 'invalid server option' def check_weight(w): assert 'error' in client.conf( - w, 'upstreams/one/servers/127.0.0.1:7081/weight' + w, 'upstreams/one/servers/127.0.0.1:8081/weight' ), 'invalid weight option' check_weight({}) diff --git a/test/test_variables.py b/test/test_variables.py index 813bd8c6..0b7b9ea8 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -16,7 +16,7 @@ client_python = ApplicationPython() def setup_method_fixture(): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [{"action": {"return": 200}}], }, ), 'configure routes' @@ -132,7 +132,7 @@ def test_variables_uri_no_cache(temp_dir): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { @@ -163,7 +163,7 @@ def test_variables_host(search_in_file, wait_for_record): check_host('localhost') check_host('localhost1.', 'localhost1') - check_host('localhost2:7080', 'localhost2') + check_host('localhost2:8080', 'localhost2') check_host('.localhost') check_host('www.localhost') @@ -175,7 +175,7 @@ def test_variables_remote_addr(search_in_file, wait_for_record): assert wait_for_record(r'^127\.0\.0\.1$', 'access.log') is not None assert 'success' in client.conf( - {"[::1]:7080": {"pass": "routes"}}, 'listeners' + {"[::1]:8080": {"pass": "routes"}}, 'listeners' ) reg = r'^::1$' @@ -447,7 +447,7 @@ def test_variables_response_header(temp_dir, wait_for_record): assert 'success' in client.conf( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 93e0738b..5aca5048 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -91,7 +91,7 @@ replace unit.nginx.org/go => {replace_path} ApplicationGo.prepare_env(script, name, static=static_build) conf = { - "listeners": {"*:7080": {"pass": f"applications/{script}"}}, + "listeners": {"*:8080": {"pass": f"applications/{script}"}}, "applications": { script: { "type": "external", diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py index dc6d2bfc..4d207cea 100644 --- a/test/unit/applications/lang/java.py +++ b/test/unit/applications/lang/java.py @@ -97,7 +97,7 @@ class ApplicationJava(ApplicationProto): script_path = f'{option.test_dir}/java/{script}/' self._load_conf( { - "listeners": {"*:7080": {"pass": f"applications/{script}"}}, + "listeners": {"*:8080": {"pass": f"applications/{script}"}}, "applications": { script: { "unit_jars": f'{option.current_dir}/build', diff --git a/test/unit/applications/lang/node.py b/test/unit/applications/lang/node.py index 4f18c780..ff95fbd5 100644 --- a/test/unit/applications/lang/node.py +++ b/test/unit/applications/lang/node.py @@ -44,7 +44,7 @@ class ApplicationNode(ApplicationProto): self._load_conf( { "listeners": { - "*:7080": {"pass": f"applications/{quote(script, '')}"} + "*:8080": {"pass": f"applications/{quote(script, '')}"} }, "applications": { script: { diff --git a/test/unit/applications/lang/perl.py b/test/unit/applications/lang/perl.py index 037e98e8..e99c2aca 100644 --- a/test/unit/applications/lang/perl.py +++ b/test/unit/applications/lang/perl.py @@ -11,7 +11,7 @@ class ApplicationPerl(ApplicationProto): self._load_conf( { - "listeners": {"*:7080": {"pass": f"applications/{script}"}}, + "listeners": {"*:8080": {"pass": f"applications/{script}"}}, "applications": { script: { "type": self.get_application_type(), diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py index b9b6dbf1..2ab172b0 100644 --- a/test/unit/applications/lang/php.py +++ b/test/unit/applications/lang/php.py @@ -42,7 +42,7 @@ class ApplicationPHP(ApplicationProto): self._load_conf( { - "listeners": {"*:7080": {"pass": f"applications/{script}"}}, + "listeners": {"*:8080": {"pass": f"applications/{script}"}}, "applications": {script: app}, }, **kwargs, diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py index 4e1fd897..67304d12 100644 --- a/test/unit/applications/lang/python.py +++ b/test/unit/applications/lang/python.py @@ -59,7 +59,7 @@ class ApplicationPython(ApplicationProto): self._load_conf( { "listeners": { - "*:7080": {"pass": f"applications/{quote(name, '')}"} + "*:8080": {"pass": f"applications/{quote(name, '')}"} }, "applications": {name: app}, }, diff --git a/test/unit/applications/lang/ruby.py b/test/unit/applications/lang/ruby.py index f6c4f6c3..1268f8c7 100644 --- a/test/unit/applications/lang/ruby.py +++ b/test/unit/applications/lang/ruby.py @@ -37,7 +37,7 @@ class ApplicationRuby(ApplicationProto): self._load_conf( { - "listeners": {"*:7080": {"pass": f"applications/{script}"}}, + "listeners": {"*:8080": {"pass": f"applications/{script}"}}, "applications": {script: app}, }, **kwargs, diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py index e9bcc514..50a27348 100644 --- a/test/unit/applications/tls.py +++ b/test/unit/applications/tls.py @@ -97,7 +97,7 @@ distinguished_name = req_distinguished_name script_path = f'{option.test_dir}/python/{script}' self._load_conf( { - "listeners": {"*:7080": {"pass": f"applications/{name}"}}, + "listeners": {"*:8080": {"pass": f"applications/{name}"}}, "applications": { name: { "type": "python", diff --git a/test/unit/check/chroot.py b/test/unit/check/chroot.py index b749fab6..466b6ba4 100644 --- a/test/unit/check/chroot.py +++ b/test/unit/check/chroot.py @@ -15,7 +15,7 @@ def check_chroot(): addr=f'{option.temp_dir}/control.unit.sock', body=json.dumps( { - "listeners": {"*:7080": {"pass": "routes"}}, + "listeners": {"*:8080": {"pass": "routes"}}, "routes": [ { "action": { diff --git a/test/unit/check/isolation.py b/test/unit/check/isolation.py index e4674f4d..e31179e8 100644 --- a/test/unit/check/isolation.py +++ b/test/unit/check/isolation.py @@ -21,7 +21,7 @@ def check_isolation(): ApplicationGo().prepare_env('empty', 'app') conf = { - "listeners": {"*:7080": {"pass": "applications/empty"}}, + "listeners": {"*:8080": {"pass": "applications/empty"}}, "applications": { "empty": { "type": "external", @@ -35,7 +35,7 @@ def check_isolation(): elif 'python' in available['modules']: conf = { - "listeners": {"*:7080": {"pass": "applications/empty"}}, + "listeners": {"*:8080": {"pass": "applications/empty"}}, "applications": { "empty": { "type": "python", @@ -50,7 +50,7 @@ def check_isolation(): elif 'php' in available['modules']: conf = { - "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, + "listeners": {"*:8080": {"pass": "applications/phpinfo"}}, "applications": { "phpinfo": { "type": "php", @@ -67,7 +67,7 @@ def check_isolation(): ApplicationRuby().prepare_env('empty') conf = { - "listeners": {"*:7080": {"pass": "applications/empty"}}, + "listeners": {"*:8080": {"pass": "applications/empty"}}, "applications": { "empty": { "type": "ruby", @@ -83,7 +83,7 @@ def check_isolation(): ApplicationJava().prepare_env('empty') conf = { - "listeners": {"*:7080": {"pass": "applications/empty"}}, + "listeners": {"*:8080": {"pass": "applications/empty"}}, "applications": { "empty": { "unit_jars": f"{option.current_dir}/build", @@ -100,7 +100,7 @@ def check_isolation(): ApplicationNode().prepare_env('basic') conf = { - "listeners": {"*:7080": {"pass": "applications/basic"}}, + "listeners": {"*:8080": {"pass": "applications/basic"}}, "applications": { "basic": { "type": "external", @@ -114,7 +114,7 @@ def check_isolation(): elif 'perl' in available['modules']: conf = { - "listeners": {"*:7080": {"pass": "applications/body_empty"}}, + "listeners": {"*:8080": {"pass": "applications/body_empty"}}, "applications": { "body_empty": { "type": "perl", diff --git a/test/unit/http.py b/test/unit/http.py index 347382f5..5a6a1a1b 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -13,7 +13,7 @@ from unit.option import option class HTTP1: def http(self, start_str, **kwargs): sock_type = kwargs.get('sock_type', 'ipv4') - port = kwargs.get('port', 7080) + port = kwargs.get('port', 8080) url = kwargs.get('url', '/') http = 'HTTP/1.0' if 'http_10' in kwargs else 'HTTP/1.1' -- cgit From dd0c53a77dbd3c8b7e3496c5e15cef757346ef8b Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 26 May 2023 20:51:35 +0100 Subject: Python: Do nxt_unit_sptr_get() earlier in nxt_python_field_value(). This is a preparatory patch for fixing an issue with the encoding of http header field values. This patch simply moves the nxt_unit_sptr_get() to the top of the function where we will need it in the next commit. Signed-off-by: Andrew Clayton --- src/python/nxt_python_wsgi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python/nxt_python_wsgi.c b/src/python/nxt_python_wsgi.c index dfb31509..ce62534b 100644 --- a/src/python/nxt_python_wsgi.c +++ b/src/python/nxt_python_wsgi.c @@ -863,6 +863,8 @@ nxt_python_field_value(nxt_unit_field_t *f, int n, uint32_t vl) char *p, *src; PyObject *res; + src = nxt_unit_sptr_get(&f->value); + #if PY_MAJOR_VERSION == 3 res = PyUnicode_New(vl, 255); #else @@ -875,7 +877,6 @@ nxt_python_field_value(nxt_unit_field_t *f, int n, uint32_t vl) p = PyString_AS_STRING(res); - src = nxt_unit_sptr_get(&f->value); p = nxt_cpymem(p, src, f->value_length); for (i = 1; i < n; i++) { -- cgit From 5cfad9cc0bb3809f802cf83d2739739fdfaab7a8 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 26 May 2023 20:54:43 +0100 Subject: Python: Fix header field values character encoding. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On GitHub, @RomainMou reported an issue whereby HTTP header field values where being incorrectly reported as non-ascii by the Python .isacii() method. For example, using the following test application def application(environ, start_response): t = environ['HTTP_ASCIITEST'] t = "'" + t + "'" + " (" + str(len(t)) + ")" if t.isascii(): t = t + " [ascii]" else: t = t + " [non-ascii]" resp = t + "\n\n" start_response("200 OK", [("Content-Type", "text/plain")]) return (bytes(resp, 'latin1')) You would see the following $ curl -H "ASCIITEST: $" http://localhost:8080/ '$' (1) [non-ascii] '$' has an ASCII code of 0x24 (36). The initial idea was to adjust the second parameter to the PyUnicode_New() call from 255 to 127. This unfortunately had the opposite effect. $ curl -H "ASCIITEST: $" http://localhost:8080/ '$' (1) [ascii] Good. However... $ curl -H "ASCIITEST: £" http://localhost:8080/ '£' (2) [ascii] Not good. Let's take a closer look at this. '£' is not in basic ASCII, but is in extended ASCII with a value of 0xA3 (163). Its UTF-8 encoding is 0xC2 0xA3, hence the length of 2 bytes above. $ strace -s 256 -e sendto,recvfrom curl -H "ASCIITEST: £" http://localhost:8080/ sendto(5, "GET / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: curl/8.0.1\r\nAccept: */*\r\nASCIITEST: \302\243\r\n\r\n", 92, MSG_NOSIGNAL, NULL, 0) = 92 recvfrom(5, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nServer: Unit/1.30.0\r\nDate: Mon, 22 May 2023 12:44:11 GMT\r\nTransfer-Encoding: chunked\r\n\r\n12\r\n'\302\243' (2) [ascii]\n\n\r\n0\r\n\r\n", 102400, 0, NULL, NULL) = 160 '£' (2) [ascii] So we can see curl sent it UTF-8 encoded '\302\243\' which is C octal escaped UTF-8 for 0xC2 0xA3, and we got the same back. But it should not be marked as ASCII. When doing PyUnicode_New(size, 127) it sets the buffer as ASCII. So we need to use another function and that function would appear to be PyUnicode_DecodeCharmap() Which creates an Unicode object with the correct ascii/non-ascii properties based on the character encoding. With this function we now get $ curl -H "ASCIITEST: $" http://localhost:8080/ '$' (1) [ascii] $ curl -H "ASCIITEST: £" http://localhost:8080/ '£' (2) [non-ascii] and for good measure $ curl -H "ASCIITEST: $ £" http://localhost:8080/ '$ £' (4) [non-ascii] $ curl -H "ASCIITEST: $" -H "ASCIITEST: £" http://localhost:8080/ '$, £' (5) [non-ascii] PyUnicode_DecodeCharmap() does require having the full string upfront so we need to build up the potentially comma separated header field values string before invoking this function. I did not want to touch the Python 2.7 code (which may or may not even be affected by this) so kept these changes completely isolated from that, hence a slight duplication with the for () loop. Python 2.7 was sunset on January 1st 2020[0], so this code will hopefully just disappear soon anyway. I also purposefully didn't touch other code that may well have similar issues (such as the HTTP header field names) if we ever get issue reports about them, we'll deal with them then. [0]: Link: Closes: Reported-by: RomainMou Tested-by: RomainMou Signed-off-by: Andrew Clayton --- src/python/nxt_python_wsgi.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/python/nxt_python_wsgi.c b/src/python/nxt_python_wsgi.c index ce62534b..c621097e 100644 --- a/src/python/nxt_python_wsgi.c +++ b/src/python/nxt_python_wsgi.c @@ -866,10 +866,35 @@ nxt_python_field_value(nxt_unit_field_t *f, int n, uint32_t vl) src = nxt_unit_sptr_get(&f->value); #if PY_MAJOR_VERSION == 3 - res = PyUnicode_New(vl, 255); + if (nxt_slow_path(n > 1)) { + char *ptr; + + p = nxt_unit_malloc(NULL, vl + 1); + if (nxt_slow_path(p == NULL)) { + return NULL; + } + + ptr = p; + p = nxt_cpymem(p, src, f->value_length); + + for (i = 1; i < n; i++) { + p = nxt_cpymem(p, ", ", 2); + + src = nxt_unit_sptr_get(&f[i].value); + p = nxt_cpymem(p, src, f[i].value_length); + } + *p = '\0'; + + src = ptr; + } + + res = PyUnicode_DecodeCharmap(src, vl, NULL, NULL); + + if (nxt_slow_path(n > 1)) { + nxt_unit_free(NULL, src); + } #else res = PyString_FromStringAndSize(NULL, vl); -#endif if (nxt_slow_path(res == NULL)) { return NULL; @@ -885,6 +910,7 @@ nxt_python_field_value(nxt_unit_field_t *f, int n, uint32_t vl) src = nxt_unit_sptr_get(&f[i].value); p = nxt_cpymem(p, src, f[i].value_length); } +#endif return res; } -- cgit From dfdf948f899bda9120750d28c1be32f255ed941f Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Thu, 31 Dec 2020 20:49:19 +0000 Subject: Define nxt_cpu_pause for ARM64. The isb instruction fits for spin loops where it allows to save cpu power. Reviewed-by: Andrew Clayton Signed-off-by: Andrew Clayton --- src/nxt_atomic.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/nxt_atomic.h b/src/nxt_atomic.h index cd2e7253..dae999a9 100644 --- a/src/nxt_atomic.h +++ b/src/nxt_atomic.h @@ -58,6 +58,10 @@ typedef volatile nxt_atomic_uint_t nxt_atomic_t; #define nxt_cpu_pause() \ __asm__ ("pause") +#elif (__aarch64__ || __arm64__) +#define nxt_cpu_pause() \ + __asm__ ("isb") + #else #define nxt_cpu_pause() #endif -- cgit From 27c787f437ba94073d3349625c98c6d5c0a127ba Mon Sep 17 00:00:00 2001 From: Andrei Vasiliu Date: Sun, 21 May 2023 16:37:51 +0300 Subject: Fix comments for src/nxt_unit.h. This fixes some typos and grammatical errors in the comments of src/nxt_unit.h Link: [ Adjust summary and write commit message as this just contains the fixes from the PR and not actual changes - Andrew ] Signed-off-by: Andrew Clayton --- src/nxt_unit.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/nxt_unit.h b/src/nxt_unit.h index 35f9fa55..a50046a5 100644 --- a/src/nxt_unit.h +++ b/src/nxt_unit.h @@ -40,7 +40,7 @@ enum { /* * Mostly opaque structure with library state. * - * Only user defined 'data' pointer exposed here. The rest is unit + * Only the user defined 'data' pointer is exposed here. The rest is unit * implementation specific and hidden. */ struct nxt_unit_s { @@ -51,8 +51,8 @@ struct nxt_unit_s { * Thread context. * * First (main) context is provided 'for free'. To receive and process - * requests in other thread, one need to allocate context and use it - * further in this thread. + * requests in other threads, one needs to allocate a new context and use it + * further in that thread. */ struct nxt_unit_ctx_s { void *data; /* User context-specific data. */ @@ -72,7 +72,7 @@ struct nxt_unit_port_id_s { }; /* - * unit provides port storage which is able to store and find the following + * Unit provides port storage which is able to store and find the following * data structures. */ struct nxt_unit_port_s { @@ -114,13 +114,13 @@ struct nxt_unit_request_info_s { /* - * Set of application-specific callbacks. Application may leave all optional - * callbacks as NULL. + * Set of application-specific callbacks. The application may leave all + * optional callbacks as NULL. */ struct nxt_unit_callbacks_s { /* - * Process request. Unlike all other callback, this callback - * need to be defined by application. + * Process request. Unlike all other callbacks, this callback is required + * and needs to be defined by the application. */ void (*request_handler)(nxt_unit_request_info_t *req); @@ -201,15 +201,15 @@ struct nxt_unit_read_info_s { nxt_unit_ctx_t *nxt_unit_init(nxt_unit_init_t *); /* - * Main function useful in case when application does not have it's own - * event loop. nxt_unit_run() starts infinite message wait and process loop. + * Main function, useful in case the application does not have its own event + * loop. nxt_unit_run() starts an infinite message wait and process loop. * * for (;;) { * app_lib->port_recv(...); * nxt_unit_process_msg(...); * } * - * The normally function returns when QUIT message received from Unit. + * The function returns normally when a QUIT message is received from Unit. */ int nxt_unit_run(nxt_unit_ctx_t *); @@ -220,10 +220,10 @@ int nxt_unit_run_shared(nxt_unit_ctx_t *ctx); nxt_unit_request_info_t *nxt_unit_dequeue_request(nxt_unit_ctx_t *ctx); /* - * Receive and process one message, invoke configured callbacks. + * Receive and process one message, and invoke configured callbacks. * - * If application implements it's own event loop, each datagram received - * from port socket should be initially processed by unit. This function + * If the application implements its own event loop, each datagram received + * from the port socket should be initially processed by unit. This function * may invoke other application-defined callback for message processing. */ int nxt_unit_run_once(nxt_unit_ctx_t *ctx); @@ -234,8 +234,8 @@ int nxt_unit_process_port_msg(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port); void nxt_unit_done(nxt_unit_ctx_t *); /* - * Allocate and initialize new execution context with new listen port to - * process requests in other thread. + * Allocate and initialize a new execution context with a new listen port to + * process requests in another thread. */ nxt_unit_ctx_t *nxt_unit_ctx_alloc(nxt_unit_ctx_t *, void *); @@ -253,7 +253,7 @@ void nxt_unit_split_host(char *host_start, uint32_t host_length, void nxt_unit_request_group_dup_fields(nxt_unit_request_info_t *req); /* - * Allocate response structure capable to store limited numer of fields. + * Allocate response structure capable of storing a limited number of fields. * The structure may be accessed directly via req->response pointer or * filled step-by-step using functions add_field and add_content. */ @@ -273,8 +273,8 @@ int nxt_unit_response_add_content(nxt_unit_request_info_t *req, const void* src, uint32_t size); /* - * Send prepared response to Unit server. Response structure destroyed during - * this call. + * Send the prepared response to the Unit server. The Response structure is + * destroyed during this call. */ int nxt_unit_response_send(nxt_unit_request_info_t *req); -- cgit From 919cae7ff95a3ce5878731a8d23f34c75489d3b4 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 15 Nov 2023 03:34:49 +0000 Subject: PHP: Fix a possible file-pointer leak. In nxt_php_execute() it is possible we could bail out before cleaning up the FILE * representing the PHP script to execute. At this point we only need to call fclose(3) on it. We could have possibly moved the opening of this file to later in the function, but it is probably good to bail out as early as possible if we can't open it. This was found by Coverity. Fixes: bebc03c72 ("PHP: Implement better error handling.") Signed-off-by: Andrew Clayton --- src/nxt_php_sapi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c index ba000fc0..77117533 100644 --- a/src/nxt_php_sapi.c +++ b/src/nxt_php_sapi.c @@ -1225,6 +1225,8 @@ nxt_php_execute(nxt_php_run_ctx_t *ctx, nxt_unit_request_t *r) nxt_unit_req_debug(ctx->req, "php_request_startup() failed"); nxt_unit_request_done(ctx->req, NXT_UNIT_ERROR); + fclose(fp); + return; } -- cgit From 1443d623d4b5d59e4463e025b4125be9a5aa3436 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 17 Nov 2023 17:27:31 +0000 Subject: Node.js: ServerResponse.flushHeaders() implemented. This closes #1006 issue on GitHub. Reviewed-by: Andrew Clayton --- docs/changes.xml | 7 +++++++ src/nodejs/unit-http/http_server.js | 4 ++++ test/node/flush_headers/app.js | 7 +++++++ test/test_node_application.py | 4 ++++ 4 files changed, 22 insertions(+) create mode 100644 test/node/flush_headers/app.js diff --git a/docs/changes.xml b/docs/changes.xml index 2c01a1e0..6b1aaf71 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -33,6 +33,13 @@ can be used as a unique request identifier. + + +ServerRequest.flushHeaders() implemented in Node.js module to make it compatible +with Next.js. + + + diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js index 0f00b47f..8eb13d7f 100644 --- a/src/nodejs/unit-http/http_server.js +++ b/src/nodejs/unit-http/http_server.js @@ -138,6 +138,10 @@ ServerResponse.prototype.removeHeader = function removeHeader(name) { } }; +ServerResponse.prototype.flushHeaders = function flushHeaders() { + this._sendHeaders(); +}; + ServerResponse.prototype._removeHeader = function _removeHeader(lc_name) { let entry = this.headers[lc_name]; let name_len = Buffer.byteLength(entry[0] + "", 'latin1'); diff --git a/test/node/flush_headers/app.js b/test/node/flush_headers/app.js new file mode 100644 index 00000000..4c0e93bc --- /dev/null +++ b/test/node/flush_headers/app.js @@ -0,0 +1,7 @@ + +require('http').createServer(function (req, res) { + res.setHeader('X-Header', 'blah'); + res.flushHeaders(); + res.flushHeaders(); // Should be idempotent. + res.end(); +}).listen(8080); diff --git a/test/test_node_application.py b/test/test_node_application.py index ab8aa8f8..5077b9cb 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -303,6 +303,10 @@ def test_node_application_get_header_names(): 'x-header', ], 'get header names' +def test_node_application_flush_headers(): + client.load('flush_headers') + + assert client.get()['headers']['X-Header'] == 'blah' def test_node_application_has_header(): client.load('has_header') -- cgit From 8fbe437ca690d92a6d75b1d5314b5aa3bf8787b9 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 17 Nov 2023 17:28:44 +0000 Subject: Tests: Ruby input.rewind is no longer required. For more information see: https://github.com/rack/rack/commit/42aff22f708123839ba706cbe659d108b47c40c7 --- test/ruby/input_rewind/config.ru | 8 -------- test/test_ruby_application.py | 9 --------- 2 files changed, 17 deletions(-) delete mode 100644 test/ruby/input_rewind/config.ru diff --git a/test/ruby/input_rewind/config.ru b/test/ruby/input_rewind/config.ru deleted file mode 100644 index fc0d6535..00000000 --- a/test/ruby/input_rewind/config.ru +++ /dev/null @@ -1,8 +0,0 @@ -app = Proc.new do |env| - env['rack.input'].read - env['rack.input'].rewind - body = env['rack.input'].read - ['200', {'Content-Length' => body.length.to_s}, [body]] -end - -run app diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index f187cc45..fb161c61 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -163,15 +163,6 @@ def test_ruby_application_input_each(): assert client.post(body=body)['body'] == body, 'input each' -@pytest.mark.skip('not yet') -def test_ruby_application_input_rewind(): - client.load('input_rewind') - - body = '0123456789' - - assert client.post(body=body)['body'] == body, 'input rewind' - - @pytest.mark.skip('not yet') def test_ruby_application_syntax_error(skip_alert): skip_alert( -- cgit From 0fc5232107e8701dc0d1f2a6008e2dbecb73293b Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 17 Nov 2023 17:28:52 +0000 Subject: Tests: added more expected Ruby features. --- test/ruby/multipart/config.ru | 7 +++++++ test/ruby/session/config.ru | 6 ++++++ test/test_ruby_application.py | 14 ++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 test/ruby/multipart/config.ru create mode 100644 test/ruby/session/config.ru diff --git a/test/ruby/multipart/config.ru b/test/ruby/multipart/config.ru new file mode 100644 index 00000000..9187997c --- /dev/null +++ b/test/ruby/multipart/config.ru @@ -0,0 +1,7 @@ +app = Proc.new do |env| + [200, { + 'x-multipart-buffer' => env['rack.multipart.buffer_size'].to_s + }, []] +end + +run app diff --git a/test/ruby/session/config.ru b/test/ruby/session/config.ru new file mode 100644 index 00000000..8cea0588 --- /dev/null +++ b/test/ruby/session/config.ru @@ -0,0 +1,6 @@ +app = Proc.new do |env| + env['rack.session'].clear + [200, {}, []] +end + +run app diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index fb161c61..3ac62f71 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -315,6 +315,20 @@ def test_ruby_application_header_rack(): assert client.get()['status'] == 500, 'header rack' +@pytest.mark.skip('not yet') +def test_ruby_application_session(): + client.load('session') + + assert client.get()['status'] == 200 + + +@pytest.mark.skip('not yet') +def test_ruby_application_multipart(): + client.load('multipart') + + assert client.get()['status'] == 200 + + def test_ruby_application_body_empty(): client.load('body_empty') -- cgit From 6b6e3bd8971a5fade4a4c5ab90a4156789127e33 Mon Sep 17 00:00:00 2001 From: "Sergey A. Osokin" Date: Mon, 20 Nov 2023 10:56:41 -0500 Subject: Fixed the MD5Encoder deprecation warning. --- src/java/nginx/unit/websocket/DigestAuthenticator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/nginx/unit/websocket/DigestAuthenticator.java b/src/java/nginx/unit/websocket/DigestAuthenticator.java index 9530c303..eb91a9b4 100644 --- a/src/java/nginx/unit/websocket/DigestAuthenticator.java +++ b/src/java/nginx/unit/websocket/DigestAuthenticator.java @@ -22,7 +22,7 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Map; -import org.apache.tomcat.util.security.MD5Encoder; +import org.apache.tomcat.util.buf.HexUtils; /** * Authenticator supporting the DIGEST auth method. @@ -140,7 +140,7 @@ public class DigestAuthenticator extends Authenticator { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] thedigest = md.digest(bytesOfMessage); - return MD5Encoder.encode(thedigest); + return HexUtils.toHexString(thedigest); } @Override -- cgit From 73d723e56ab183185cc13d9c7863c7c7c8786280 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 13 Apr 2023 11:57:14 +0100 Subject: Red Hat should always be spelled as two words. Link: Link: Cc: Artem Konev Signed-off-by: Andrew Clayton --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index badd2391..af703a6b 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ For a description of image tags, see the [docs](https://unit.nginx.org/installation/#docker-images). -### Amazon Linux, Fedora, RedHat +### Amazon Linux, Fedora, Red Hat ``` console $ wget https://raw.githubusercontent.com/nginx/unit/master/tools/setup-unit && chmod +x setup-unit -- cgit From 3fdf8c63a2dd4b3d676754d2e605877a8689e4c9 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Wed, 8 Nov 2023 11:27:44 +0000 Subject: Fix port number in listener object for php hello world app. Signed-off-by: Andrew Clayton --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af703a6b..48b82b64 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ 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"}}' \ +# curl -X PUT -d '{"127.0.0.1:8080": {"pass": "applications/helloworld"}}' \ --unix-socket /path/to/control.unit.sock http://localhost/config/listeners ``` ``` json -- cgit From a922f9a6f0eb91f51262d02711fb39f7010e5c4e Mon Sep 17 00:00:00 2001 From: "Sergey A. Osokin" Date: Wed, 29 Nov 2023 10:28:44 -0500 Subject: Update third-party components for the Java module. --- auto/modules/java | 4 ++-- auto/modules/java_jar.sha512 | 20 ++++++++++---------- test/unit/applications/lang/java.py | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/auto/modules/java b/auto/modules/java index 53f99f7e..3727a111 100644 --- a/auto/modules/java +++ b/auto/modules/java @@ -238,7 +238,7 @@ cat << END > $NXT_JAVA_JARS static const char *nxt_java_system_jars[] = { END -NXT_TOMCAT_VERSION=9.0.82 +NXT_TOMCAT_VERSION=9.0.83 NXT_JAR_VERSION=$NXT_TOMCAT_VERSION @@ -297,7 +297,7 @@ NXT_JAR_NAME=jetty-http . auto/modules/java_get_jar NXT_JAR_NAME=classgraph -NXT_JAR_VERSION=4.8.162 +NXT_JAR_VERSION=4.8.165 NXT_JAR_NAMESPACE=io/github/classgraph/ . auto/modules/java_get_jar diff --git a/auto/modules/java_jar.sha512 b/auto/modules/java_jar.sha512 index e0a648af..13a7357c 100644 --- a/auto/modules/java_jar.sha512 +++ b/auto/modules/java_jar.sha512 @@ -1,14 +1,14 @@ -a117092f4ab77ef89b3b83a45b9e33c0360cb18098df17da77e5d765a6b5cea1fae6190399217236c0d970f2b3603bc8f408c2471cf8854de1282dba7525c335 classgraph-4.8.162.jar +d0c17607eee55e181baa03f1abb2cf77f50e5114c471c2031607206768d8549c74ebb0a276d87dd3f8ea44db5e54e56087311c229ba18ad6013c388fc861beed classgraph-4.8.165.jar ab441acf5551a7dc81c353eaccb3b3df9e89a48987294d19e39acdb83a5b640fcdff7414cee29f5b96eaa8826647f1d5323e185018fe33a64c402d69c73c9158 ecj-3.26.0.jar 867afb0e69ab225a3d57c0eda4e773ca2f41dcc6eb294e14aef4d69441314bee88221081f9edc6289b9e4a99184804b60c32f4443c8ff96eb34d6508b348b755 jetty-http-9.4.53.v20231009.jar aca14debabc0cc40e154d4de4de404c383c4611e9f2482911e17d9072f0941cef8a88511d5d49d70946e65872e1bc8d395b9401b2ec91132553d782d99140ce3 jetty-server-9.4.53.v20231009.jar 429b269e21c6e7bf86ba8a8b71569e3abf61b06ace9dd064a9c80af4282227e910a8d20be86ef6581895ff283a5aa4711bbb238de45dc7628f494624879c4d49 jetty-util-9.4.53.v20231009.jar -ee33bc0020ce5be2fbdb52352fb9b2846dc5898b2190e46b2a8efdfdb16a33a83538731a6d7eeeb91c7b81e8d1e022b15924fa30ee1e9770a9f9adf96989ffd7 tomcat-api-9.0.82.jar -dfb4a37dddf4bc4e9a41a1381544c81e3962a63833f024236d1ed28eabe8daae77cd79466881177ce9f729efad2f5169e9cf8a9e45c820b775c3a9223d258e6f tomcat-el-api-9.0.82.jar -db764d29d882458d8cc2aeded7b25b6129eeeb7d9ec5b77d380ca14add659a8c12f233802a5e8dfa287a1c1b9dbfd6a12fa053ec506443bde0dce9fb36081782 tomcat-jasper-9.0.82.jar -bcc9ffc0f4d50defb0fdb12c2f9a8bd89fd8758f768c2495baa9c0e77a0ae08f3e610f6893ecd30843cfda6021120d9886aab3e377309ded68cd83f3d32b654a tomcat-jasper-el-9.0.82.jar -d2d9154b622b18ef190146631984188d6353ad2cb3c6ec1922387c76ae4d279a511d76680271f29b861ee18b444894ed66e5e41030e0beb265bf47eecc1a3a81 tomcat-jsp-api-9.0.82.jar -e1c92251e2e1cd5fc99d304399fbb13af50b7d86e56ffca59edb85934474df2b8dd6b4ea3d949cc1d7cc21e673094a044b22d05bc45e540c9a0a211974ebee5c tomcat-juli-9.0.82.jar -7d30076e306403c243ed4d802fca6de7e827e7f6cef8827353fff4514bee484ff71abc61597fd92b63470c6477bb26c398d4cd9b293f059e0ff94156f0210106 tomcat-servlet-api-9.0.82.jar -b06b112011526911b08849093d61a4d4337283f4a54dee2d4f8f4ce55687eabdf5df97b9326e1430fe7cd4d043a16076e86c1354cc2661c19e87918c4635e3d1 tomcat-util-9.0.82.jar -dfe0beac3b4b8466454fb790e9dd7a17b97e62edb0f5caaaedab0360b32a0536b7d788f3d5511eb47ea3abca4f5751ab32c814c73dbf465529898d78b69fb8d6 tomcat-util-scan-9.0.82.jar +96af9145dfe3a9566af2a1c93085ed48d80fde0587db7e951b07ec32f1654aa17977b37d011589e2eec6f1f9b3ff52937d429a86d68febb23fde9572fda3b246 tomcat-api-9.0.83.jar +1b8a5de6e75664fdc1e8c1c1fd58694e0b4057ac33508c24fc95662f44fd177bc20c36d134926f68b93978fa659d3c9874e70a6f0e2ac8dd2dd9c7a7643d4ba3 tomcat-el-api-9.0.83.jar +71a560be521bb71366541ddac79b1a412e40e635165c18e9bd05dac59e4417557fe836109687181d4799c6089a375bc05d9fa86a14cd60b19e54e8828d00cf47 tomcat-jasper-9.0.83.jar +7a42a590f6af52e34aef323766295bb2b8ae87ac48b5bba0de6ac1240e262c0f37ef9ef4d185d4ec08249faff6125863d01256587810a3d9131bb20bf57159d1 tomcat-jasper-el-9.0.83.jar +4051eb6b13a7e59f64ffc99c6dad176e1908a4eb6936765f69c1df63048d3f28f94b93164ec7c9579ea8b37dff26a7f2e66354ddbcb594596839e9068fd8c18e tomcat-jsp-api-9.0.83.jar +2e1d417495b08cf3bf9d7f2806aee8fc96f42ad8152489497cb539dcb4d6668f3d6f6f7a6ae10df06abe7c9db3e11c7b03c9d46c35ec1074c8f7d6788a6cfc80 tomcat-juli-9.0.83.jar +96032c24db4336498d1b0328a48a6eae35010c840ceefd140c7c79a6fcdf5319ad5a16c4fc21de4ae1494c5b5eadcedca3da01a4584b27deb25dc80ac21ae4a9 tomcat-servlet-api-9.0.83.jar +ab0c1868ce50ec0d45c0d541921fd3e33b5b3bc314a97230467380461e8d80c54d08ba8ef94b0a28493ed3ffde3333623170850f3ad630485fc332dbceb2745b tomcat-util-9.0.83.jar +acc12ed11fce573003b4bd973a7dce311704a1c317811a8fd4086b9eb73296cc5f1e291f81c065869f578091cb508f49cbfbec32aba747b9367a504898bb4d04 tomcat-util-scan-9.0.83.jar diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py index 4d207cea..37dd1155 100644 --- a/test/unit/applications/lang/java.py +++ b/test/unit/applications/lang/java.py @@ -53,7 +53,7 @@ class ApplicationJava(ApplicationProto): os.makedirs(classes_path) classpath = ( - f'{option.current_dir}/build/tomcat-servlet-api-9.0.82.jar' + f'{option.current_dir}/build/tomcat-servlet-api-9.0.83.jar' ) ws_jars = glob.glob( -- cgit From 9a36de84c8534cdd8d22b33d90309519e03abf3b Mon Sep 17 00:00:00 2001 From: Danielle De Leo Date: Tue, 5 Dec 2023 10:42:28 -0500 Subject: Go: Use Homebrew include paths Fixes nginx/unit#967 --- go/ldflags-darwin.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 go/ldflags-darwin.go diff --git a/go/ldflags-darwin.go b/go/ldflags-darwin.go new file mode 100644 index 00000000..34cfac1a --- /dev/null +++ b/go/ldflags-darwin.go @@ -0,0 +1,14 @@ +//go:build darwin + +/* + * Copyright (C) Danielle De Leo + * Copyright (C) NGINX, Inc. + */ + +package unit + +/* +#cgo LDFLAGS: -L/opt/homebrew/lib +#cgo CFLAGS: -I/opt/homebrew/include +*/ +import "C" -- cgit From 846a7f483643a00322f81a7848ca556722e5469a Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 6 Dec 2023 13:52:44 +0000 Subject: .mailmap: Set correct address for Danielle Due to GH making a mess of merge commits, it used Danielle's personal email address for the merge, it also used a generic GH address for the committer but we can't do anything about that. However we can fix the 'Author' email address. If for some reason you want to see the original names/addresses used you can generally pass --no-mailmap to git commands. Signed-off-by: Andrew Clayton --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index cdacea39..f622acf3 100644 --- a/.mailmap +++ b/.mailmap @@ -3,3 +3,4 @@ Alejandro Colomar Alejandro Colomar Andrew Clayton Andrew Clayton +Danielle De Leo -- cgit From d9f5f1fb741109cc232cedd3574aa587626789c1 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 23 Oct 2023 14:24:01 +0100 Subject: Ruby: Handle response field arrays @xeron on GitHub reported an issue whereby with a Rails 7.1 application they were getting the following error 2023/10/22 20:57:28 [error] 56#56 [unit] #8: Ruby: Wrong header entry 'value' from application 2023/10/22 20:57:28 [error] 56#56 [unit] #8: Ruby: Failed to run ruby script After some back and forth debugging it turns out rack was trying to send back a header comprised of an array of values. E.g app = Proc.new do |env| ["200", { "Content-Type" => "text/plain", "X-Array-Header" => ["Item-1", "Item-2"], }, ["Hello World\n"]] end run app It seems this became a possibility in rack v3.0[0] So along with a header value type of T_STRING we need to also allow T_ARRAY. If we get a T_ARRAY we need to build up the header field using the given values. E.g "X-Array-Header" => ["Item-1", "", "Item-3", "Item-4"], becomes X-Array-Header: Item-1; ; Item-3; Item-4 [0]: Reported-by: Ivan Larionov Closes: Link: Tested-by: Timo Stark Signed-off-by: Andrew Clayton --- src/ruby/nxt_ruby.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index bcb48f6b..3a019c36 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -889,13 +889,37 @@ nxt_ruby_hash_info(VALUE r_key, VALUE r_value, VALUE arg) goto fail; } - if (nxt_slow_path(TYPE(r_value) != T_STRING)) { + if (nxt_slow_path(TYPE(r_value) != T_STRING && TYPE(r_value) != T_ARRAY)) { nxt_unit_req_error(headers_info->req, "Ruby: Wrong header entry 'value' from application"); goto fail; } + if (TYPE(r_value) == T_ARRAY) { + int i; + int arr_len = RARRAY_LEN(r_value); + VALUE item; + size_t len = 0; + + for (i = 0; i < arr_len; i++) { + item = rb_ary_entry(r_value, i); + if (TYPE(item) != T_STRING) { + nxt_unit_req_error(headers_info->req, + "Ruby: Wrong header entry in 'value' array " + "from application"); + goto fail; + } + + len += RSTRING_LEN(item) + 2; /* +2 for '; ' */ + } + + headers_info->fields++; + headers_info->size += RSTRING_LEN(r_key) + len - 2; + + return ST_CONTINUE; + } + value = RSTRING_PTR(r_value); value_end = value + RSTRING_LEN(r_value); @@ -941,11 +965,52 @@ nxt_ruby_hash_add(VALUE r_key, VALUE r_value, VALUE arg) headers_info = (void *) (uintptr_t) arg; rc = &headers_info->rc; + key_len = RSTRING_LEN(r_key); + + if (TYPE(r_value) == T_ARRAY) { + int i; + int arr_len = RARRAY_LEN(r_value); + char *field, *p; + VALUE item; + size_t len = 0; + + for (i = 0; i < arr_len; i++) { + item = rb_ary_entry(r_value, i); + + len += RSTRING_LEN(item) + 2; /* +2 for '; ' */ + } + + field = nxt_unit_malloc(NULL, len); + if (field == NULL) { + goto fail; + } + + p = field; + + for (i = 0; i < arr_len; i++) { + item = rb_ary_entry(r_value, i); + + p = nxt_cpymem(p, RSTRING_PTR(item), RSTRING_LEN(item)); + p = nxt_cpymem(p, "; ", 2); + } + + len -= 2; + + *rc = nxt_unit_response_add_field(headers_info->req, + RSTRING_PTR(r_key), key_len, + field, len); + nxt_unit_free(NULL, field); + + if (nxt_slow_path(*rc != NXT_UNIT_OK)) { + goto fail; + } + + return ST_CONTINUE; + } + value = RSTRING_PTR(r_value); value_end = value + RSTRING_LEN(r_value); - key_len = RSTRING_LEN(r_key); - pos = value; for ( ;; ) { -- cgit From 88854cf14688286f835f7177c6bfaa17f1962f67 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 13 Dec 2023 02:04:38 +0000 Subject: Ruby: Prevent a possible integer underflow Coverity picked up a potential issue with the previous commit d9f5f1fb7 ("Ruby: Handle response field arrays") in that a size_t could wrap around to SIZE_MAX - 1. This would happen if we were given an empty array of header values. Fixes: d9f5f1fb7 ("Ruby: Handle response field arrays") Signed-off-by: Andrew Clayton --- src/ruby/nxt_ruby.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index 3a019c36..27b868fe 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -914,8 +914,12 @@ nxt_ruby_hash_info(VALUE r_key, VALUE r_value, VALUE arg) len += RSTRING_LEN(item) + 2; /* +2 for '; ' */ } + if (arr_len > 0) { + len -= 2; + } + headers_info->fields++; - headers_info->size += RSTRING_LEN(r_key) + len - 2; + headers_info->size += RSTRING_LEN(r_key) + len; return ST_CONTINUE; } @@ -994,7 +998,9 @@ nxt_ruby_hash_add(VALUE r_key, VALUE r_value, VALUE arg) p = nxt_cpymem(p, "; ", 2); } - len -= 2; + if (arr_len > 0) { + len -= 2; + } *rc = nxt_unit_response_add_field(headers_info->req, RSTRING_PTR(r_key), key_len, -- cgit From 49aee6760a26b14c06180e4f25088cb18e2037a7 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 11 Dec 2023 10:46:58 +0800 Subject: HTTP: added TSTR validation flag to the rewrite option. This is to improve error messages for rewrite configuration. Take the configuration as an example: { "rewrite": "`${a + " } Previously, when applying it the user would see this error message: failed to apply previous configuration After this change, the user will see this improved error message: the previous configuration is invalid: "SyntaxError: Unexpected end of input in default:1" in the "rewrite" value. --- src/nxt_conf_validation.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index f00b28b8..32ed4ffd 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -690,6 +690,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_action_common_members[] = { { .name = nxt_string("rewrite"), .type = NXT_CONF_VLDT_STRING, + .flags = NXT_CONF_VLDT_TSTR, }, { .name = nxt_string("response_headers"), -- cgit From 263460d9302eb95f58fcd1216264e859bcafc3e9 Mon Sep 17 00:00:00 2001 From: Taryn Musgrave <34845739+tarynmusgrave@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:32:17 -0500 Subject: Docs: replaced the slack community links with GitHub Discussions --- CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a7bc357b..77343271 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ Check out the [Quick Installation](README.md#quick-installation) and 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, +[GitHub Discussions](https://github.com/nginx/unit/discussions) or the NGINX Unit mailing list, unit@nginx.org (subscribe [here](https://mailman.nginx.org/mailman3/lists/unit.nginx.org/)). diff --git a/README.md b/README.md index 48b82b64..4e230767 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ usability. ## Community - The go-to place to start asking questions and share your thoughts is - our [Slack channel](https://community.nginx.org/joinslack). + [GitHub Discussions](https://github.com/nginx/unit/discussions). - Our [GitHub issues page](https://github.com/nginx/unit/issues) offers space for a more technical discussion at your own pace. -- cgit From 7e03a6cc6b6c59c0aefa385d6405ad3814f153fa Mon Sep 17 00:00:00 2001 From: Danielle De Leo Date: Tue, 9 Jan 2024 13:14:41 -0500 Subject: Go: Add missing +build and go:build comments A RHEL 8 test was failing because it uses go1.16. The old style must be retained for backwards compat. Fixes: 9a36de84c ("Go: Use Homebrew include paths") Reviewed-by: Andrew Clayton Reviewed-by: Dylan Arbour Signed-off-by: Danielle De Leo --- go/ldflags-darwin.go | 1 + go/ldflags-lrt.go | 1 + 2 files changed, 2 insertions(+) diff --git a/go/ldflags-darwin.go b/go/ldflags-darwin.go index 34cfac1a..77114ee4 100644 --- a/go/ldflags-darwin.go +++ b/go/ldflags-darwin.go @@ -1,4 +1,5 @@ //go:build darwin +// +build darwin /* * Copyright (C) Danielle De Leo diff --git a/go/ldflags-lrt.go b/go/ldflags-lrt.go index f5a63508..68a29145 100644 --- a/go/ldflags-lrt.go +++ b/go/ldflags-lrt.go @@ -1,3 +1,4 @@ +//go:build linux || netbsd // +build linux netbsd /* -- cgit From 6ee5d5553fdf682b5df00d50e2a854e4f3162203 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 11 Jan 2024 01:05:31 +0000 Subject: .mailmap: Fix up Taryn's email address Map her GitHub noreply address to her @f5 one. You can always see the original address used by passing --no-mailmap to the various git commands. Note: We don't always need the name field, but we're keeping this file consistent and alphabetically ordered on first name... Signed-off-by: Andrew Clayton --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index f622acf3..5ec812a7 100644 --- a/.mailmap +++ b/.mailmap @@ -4,3 +4,4 @@ Alejandro Colomar Andrew Clayton Andrew Clayton Danielle De Leo +Taryn Musgrave <34845739+tarynmusgrave@users.noreply.github.com> -- cgit From b04455f6c15ef91b8e6a5dd236fcec1e73e744c9 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Tue, 9 Jan 2024 13:15:18 -0800 Subject: Updated security.txt Refs: https://github.com/nginx/unit-docs/pull/78 --- SECURITY.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/SECURITY.txt b/SECURITY.txt index a705bef7..2d2ad2b1 100644 --- a/SECURITY.txt +++ b/SECURITY.txt @@ -10,21 +10,21 @@ Contact: mailto:security-alert@nginx.org Encryption: https://nginx.org/keys/maxim.key Encryption: https://nginx.org/keys/sb.key Encryption: https://nginx.org/keys/thresh.key -Expires: 2024-01-01T00:00:00.000Z +Expires: 2025-01-01T00:00:00.000Z Policy: https://www.first.org/cvss/v3.1/specification-document Preferred-Languages: en -----BEGIN PGP SIGNATURE----- -iQHEBAEBCAAuFiEEE8gqY7YDV2FW4wpOoOqYG2aw2WcFAmN7X/UQHGsucGF2bG92 -QGY1LmNvbQAKCRCg6pgbZrDZZ4wFDADIZz5UwVUaxQ6mAfi+3Gs28NLXQp5kBILJ -PC9Rhjlksufbby5yd4lh+JMZ8U2YRQ8OWne6Kl0NvZHDcP2OyBOdiBUXvnE+ZcNz -ujT3JMk15l1FxKbIitUzwZ+QcXOKTqsoavPs5hrGrrJNQWLhqAH8uESDdI7AUM5R -BOQ9Z6ENw3rgEtrtMNMdwt+pt2/+1cuu/4PuIuFhjYyCuS7i7tyFtbkc9BTlx03I -99g9bqKltWAvxGrMi+xfFVOnTgWp0b+oKsN8jgQji1zNMSx7UmrFq8uSpNV3eR5t -a4iVZQsIRUVVSYh8VkZagtbiw4WXaEnbwUgxj/4K2rNvkn5jFk+NkzSALN8/7ocp -U5R5ctku511bJiwFSUkTx8nkd58bzqqQ0EHr/3uTmfXSTTZYdUXuXXCSMzuUBEOi -y9n+2JFRdlEXxqwhszJxAXhs6VH2su0laX2UOMMnw6X2GFF3CU4PK0qoalWLSh47 -6aiL99zgqrq0IFibRTXCo1a3RPqiYB0= -=GiB/ +iQGzBAEBCAAdFiEEE8gqY7YDV2FW4wpOoOqYG2aw2WcFAmWdrbkACgkQoOqYG2aw +2WdAIQv/UpQXSYWboNMq9DnXZsMNdeCdAg8nv1PdNYfDzr21YavHsdP3upEg2NUX +M/9WiyO5HwV7FAWKQ8J6T0vg8EZITij5Dxhia4Z/h9QE6bXTH4rD/UViJ+/RTtwF +3WvaMNGUSlTQUNCRQ0QGTAb/jXUQCE8OwFz2UM0ZgqyUmIdkuxMEhsNd4AfAUS4A +OOhM6qfXXAulPNVFZ65Lx7NIner37OyNuzhyuQxIFsnbGagMEIvptkevNIMEy8WO +BeseYx/fp1gHdLTIUKl+nvKR7as5O+fFZSm/eG3VpkS6Fall54WX6zzalhZN7Pie +pze8YdbUukdMUV6wQ/pQH4e/QyEEI8RCk95cZE9mSfxygpbIfBypj66GTaOUC/2z +iTv2tX/DXiGQbSpkNLzwntVvuN5P9BebxmSKdspwfszccPzNhhCVQMkkhzvNVeQ6 +UTorp2O3xvi5fBIUWQU5xkrKqwAmZBYHMPDA97H9hiTmHkytd7YYkvPmJKNDksSa +ui3gNrJe +=yDJD -----END PGP SIGNATURE----- -- cgit From e95a91cbfac018b9877d9e389e614e9f2a9f1313 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 12 Jan 2024 18:33:27 +0000 Subject: .mailmap: Add a few more entries Fix up a mixture of different names/email addresses people have used. You can always see the original names/addresses used by passing --no-mailmap to the various git commands. See gitmailmap(5) Signed-off-by: Andrew Clayton --- .mailmap | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.mailmap b/.mailmap index 5ec812a7..21085d68 100644 --- a/.mailmap +++ b/.mailmap @@ -1,7 +1,16 @@ Alejandro Colomar Alejandro Colomar Alejandro Colomar +Andrei Zeliankou Andrew Clayton Andrew Clayton +Artem Konev <41629299+artemkonev@users.noreply.github.com> Danielle De Leo +Konstantin Pavlov +Max Romanov +OutOfFocus4 +Sergey A. Osokin Taryn Musgrave <34845739+tarynmusgrave@users.noreply.github.com> +Tiago Natel de Moura +Timo Stark +Zhidao HONG -- cgit From 5a8337933df1cf3aba967d86549e236dd9173386 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 15 Jan 2024 15:48:58 +0000 Subject: Tests: pathlib used where appropriate Also fixed various pylint errors and style issues. --- test/conftest.py | 87 +++++++++++++++-------------- test/python/body_generate/wsgi.py | 4 +- test/python/delayed/asgi.py | 4 +- test/python/environment/wsgi.py | 6 +- test/python/iter_exception/wsgi.py | 4 +- test/python/legacy/asgi.py | 4 +- test/python/legacy_force/asgi.py | 9 +-- test/python/lifespan/empty/asgi.py | 2 +- test/python/lifespan/failed/asgi.py | 2 +- test/python/restart/longstart.py | 1 + test/python/unicode/wsgi.py | 2 +- test/python/user_group/wsgi.py | 7 ++- test/test_access_log.py | 13 +++-- test/test_asgi_application.py | 1 + test/test_asgi_application_unix_abstract.py | 1 + test/test_asgi_lifespan.py | 33 +++++------ test/test_asgi_targets.py | 1 + test/test_asgi_websockets.py | 1 + test/test_client_ip.py | 1 + test/test_configuration.py | 1 + test/test_forwarded_header.py | 1 + test/test_go_application.py | 2 +- test/test_go_isolation.py | 3 +- test/test_http_header.py | 1 + test/test_java_application.py | 5 +- test/test_java_isolation_rootfs.py | 3 + test/test_java_websockets.py | 1 + test/test_njs.py | 7 ++- test/test_node_application.py | 5 ++ test/test_node_es_modules.py | 1 + test/test_node_websockets.py | 1 + test/test_perl_application.py | 1 + test/test_php_application.py | 23 ++++---- test/test_proxy.py | 1 + test/test_proxy_chunked.py | 9 +-- test/test_python_application.py | 5 +- test/test_python_isolation.py | 6 +- test/test_python_procman.py | 1 + test/test_reconfigure.py | 1 + test/test_reconfigure_tls.py | 3 + test/test_respawn.py | 1 + test/test_response_headers.py | 5 +- test/test_return.py | 3 +- test/test_rewrite.py | 17 +++--- test/test_routing.py | 15 +++-- test/test_ruby_application.py | 1 + test/test_settings.py | 1 + test/test_static.py | 46 ++++++--------- test/test_static_chroot.py | 18 +++--- test/test_static_fallback.py | 3 +- test/test_static_mount.py | 9 ++- test/test_static_share.py | 5 +- test/test_static_symlink.py | 7 ++- test/test_static_types.py | 5 +- test/test_static_variables.py | 9 ++- test/test_tls.py | 31 +++++----- test/test_tls_conf_command.py | 1 + test/test_tls_sni.py | 7 ++- test/test_upstreams_rr.py | 1 + test/test_usr1.py | 22 ++++---- test/test_variables.py | 20 +++---- test/unit/applications/lang/go.py | 2 +- test/unit/applications/lang/php.py | 7 +-- test/unit/applications/lang/python.py | 7 +-- test/unit/applications/tls.py | 2 +- test/unit/applications/websockets.py | 13 +++-- test/unit/check/check_prerequisites.py | 1 + test/unit/check/isolation.py | 13 +++-- test/unit/check/node.py | 4 +- test/unit/control.py | 2 +- test/unit/http.py | 10 ++-- test/unit/status.py | 10 ++-- 72 files changed, 306 insertions(+), 256 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 8d2850fd..2fe4d8dc 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -11,10 +11,12 @@ import sys import tempfile import time from multiprocessing import Process +from pathlib import Path import pytest -from unit.check.discover_available import discover_available + from unit.check.check_prerequisites import check_prerequisites +from unit.check.discover_available import discover_available from unit.http import HTTP1 from unit.log import Log from unit.log import print_log_on_assert @@ -265,27 +267,26 @@ def unit_run(state_dir=None): if not option.restart and 'unitd' in unit_instance: return unit_instance - builddir = f'{option.current_dir}/build' - libdir = f'{builddir}/lib' + builddir = f'{option.current_dir}/build' + libdir = f'{builddir}/lib' modulesdir = f'{libdir}/unit/modules' - sbindir = f'{builddir}/sbin' - unitd = f'{sbindir}/unitd' + sbindir = f'{builddir}/sbin' + unitd = f'{sbindir}/unitd' - if not os.path.isfile(unitd): - exit('Could not find unit') + if not Path(unitd).is_file(): + sys.exit('Could not find unit') - temp_dir = tempfile.mkdtemp(prefix='unit-test-') - option.temp_dir = temp_dir - public_dir(temp_dir) + temporary_dir = tempfile.mkdtemp(prefix='unit-test-') + option.temp_dir = temporary_dir + public_dir(temporary_dir) - if oct(stat.S_IMODE(os.stat(builddir).st_mode)) != '0o777': + if oct(stat.S_IMODE(Path(builddir).stat().st_mode)) != '0o777': public_dir(builddir) - statedir = f'{temp_dir}/state' if state_dir is None else state_dir - if not os.path.isdir(statedir): - os.mkdir(statedir) + statedir = f'{temporary_dir}/state' if state_dir is None else state_dir + Path(statedir).mkdir(exist_ok=True) - control_sock = f'{temp_dir}/control.unit.sock' + control_sock = f'{temporary_dir}/control.unit.sock' unitd_args = [ unitd, @@ -295,31 +296,32 @@ def unit_run(state_dir=None): '--statedir', statedir, '--pid', - f'{temp_dir}/unit.pid', + f'{temporary_dir}/unit.pid', '--log', - f'{temp_dir}/unit.log', + f'{temporary_dir}/unit.log', '--control', - f'unix:{temp_dir}/control.unit.sock', + f'unix:{temporary_dir}/control.unit.sock', '--tmpdir', - temp_dir, + temporary_dir, ] if option.user: unitd_args.extend(['--user', option.user]) - with open(f'{temp_dir}/unit.log', 'w') as log: + with open(f'{temporary_dir}/unit.log', 'w', encoding='utf-8') as log: unit_instance['process'] = subprocess.Popen(unitd_args, stderr=log) if not waitforfiles(control_sock): Log.print_log() - exit('Could not start unit') + sys.exit('Could not start unit') - unit_instance['temp_dir'] = temp_dir + unit_instance['temp_dir'] = temporary_dir unit_instance['control_sock'] = control_sock unit_instance['unitd'] = unitd - with open(f'{temp_dir}/unit.pid', 'r') as f: - unit_instance['pid'] = f.read().rstrip() + unit_instance['pid'] = ( + Path(f'{temporary_dir}/unit.pid').read_text(encoding='utf-8').rstrip() + ) if state_dir is None: _clear_conf() @@ -424,26 +426,27 @@ def _clear_conf(*, log=None): def _clear_temp_dir(): - temp_dir = unit_instance['temp_dir'] + temporary_dir = unit_instance['temp_dir'] - if is_findmnt and not waitforunmount(temp_dir, timeout=600): - exit('Could not unmount some filesystems in tmpdir ({temp_dir}).') + if is_findmnt and not waitforunmount(temporary_dir, timeout=600): + sys.exit('Could not unmount filesystems in tmpdir ({temporary_dir}).') - for item in os.listdir(temp_dir): - if item not in [ + for item in Path(temporary_dir).iterdir(): + if item.name not in [ 'control.unit.sock', 'state', 'unit.pid', 'unit.log', ]: - path = os.path.join(temp_dir, item) - public_dir(path) - if os.path.isfile(path) or stat.S_ISSOCK(os.stat(path).st_mode): - os.remove(path) + + public_dir(item) + + if item.is_file() or stat.S_ISSOCK(item.stat().st_mode): + item.unlink() else: for _ in range(10): try: - shutil.rmtree(path) + shutil.rmtree(item) break except OSError as err: # OSError: [Errno 16] Device or resource busy @@ -456,7 +459,7 @@ def _clear_temp_dir(): def _check_processes(): router_pid = _fds_info['router']['pid'] controller_pid = _fds_info['controller']['pid'] - unit_pid = unit_instance['pid'] + main_pid = unit_instance['pid'] for _ in range(600): out = ( @@ -466,7 +469,7 @@ def _check_processes(): .decode() .splitlines() ) - out = [l for l in out if unit_pid in l] + out = [l for l in out if main_pid in l] if len(out) <= 3: break @@ -485,14 +488,14 @@ def _check_processes(): out = [ l for l in out - if re.search(fr'{router_pid}\s+{unit_pid}.*unit: router', l) is None + if re.search(fr'{router_pid}\s+{main_pid}.*unit: router', l) is None ] assert len(out) == 1, 'one router' out = [ l for l in out - if re.search(fr'{controller_pid}\s+{unit_pid}.*unit: controller', l) + if re.search(fr'{controller_pid}\s+{main_pid}.*unit: controller', l) is None ] assert len(out) == 0, 'one controller' @@ -542,9 +545,9 @@ def _check_fds(*, log=None): def _count_fds(pid): - procfile = f'/proc/{pid}/fd' - if os.path.isdir(procfile): - return len(os.listdir(procfile)) + procfile = Path(f'/proc/{pid}/fd') + if procfile.is_dir(): + return len(list(procfile.iterdir())) try: out = subprocess.check_output( @@ -616,7 +619,7 @@ def pytest_sessionfinish(): public_dir(option.cache_dir) shutil.rmtree(option.cache_dir) - if not option.save_log and os.path.isdir(option.temp_dir): + if not option.save_log and Path(option.temp_dir).is_dir(): public_dir(option.temp_dir) shutil.rmtree(option.temp_dir) diff --git a/test/python/body_generate/wsgi.py b/test/python/body_generate/wsgi.py index 73462be6..3d12ac60 100644 --- a/test/python/body_generate/wsgi.py +++ b/test/python/body_generate/wsgi.py @@ -1,6 +1,6 @@ def application(env, start_response): length = env.get('HTTP_X_LENGTH', '10') - bytes = b'X' * int(length) + body = b'X' * int(length) start_response('200', [('Content-Length', length)]) - return [bytes] + return [body] diff --git a/test/python/delayed/asgi.py b/test/python/delayed/asgi.py index 1cb15a92..3c25e49a 100644 --- a/test/python/delayed/asgi.py +++ b/test/python/delayed/asgi.py @@ -33,7 +33,9 @@ async def application(scope, receive, send): { 'type': 'http.response.start', 'status': 200, - 'headers': [(b'content-length', str(len(body)).encode()),], + 'headers': [ + (b'content-length', str(len(body)).encode()), + ], } ) diff --git a/test/python/environment/wsgi.py b/test/python/environment/wsgi.py index 91e0ba49..622b8bc0 100644 --- a/test/python/environment/wsgi.py +++ b/test/python/environment/wsgi.py @@ -2,9 +2,11 @@ import os def application(env, start_response): - vars = env.get('HTTP_X_VARIABLES').split(',') + variables = env.get('HTTP_X_VARIABLES').split(',') - body = ','.join([str(os.environ[var]) for var in vars if var in os.environ]) + body = ','.join( + [str(os.environ[var]) for var in variables if var in os.environ] + ) body = body.encode() start_response('200', [('Content-Length', str(len(body)))]) diff --git a/test/python/iter_exception/wsgi.py b/test/python/iter_exception/wsgi.py index 2779a845..66a09af7 100644 --- a/test/python/iter_exception/wsgi.py +++ b/test/python/iter_exception/wsgi.py @@ -8,9 +8,7 @@ class application: def __iter__(self): self.__i = 0 self._skip_level = int(self.environ.get('HTTP_X_SKIP', 0)) - self._not_skip_close = int( - self.environ.get('HTTP_X_NOT_SKIP_CLOSE', 0) - ) + self._not_skip_close = int(self.environ.get('HTTP_X_NOT_SKIP_CLOSE', 0)) self._is_chunked = self.environ.get('HTTP_X_CHUNKED') headers = [(('Content-Length', '10'))] diff --git a/test/python/legacy/asgi.py b/test/python/legacy/asgi.py index 1d45cc4f..8be8932e 100644 --- a/test/python/legacy/asgi.py +++ b/test/python/legacy/asgi.py @@ -9,6 +9,8 @@ async def app_http(receive, send): { 'type': 'http.response.start', 'status': 200, - 'headers': [(b'content-length', b'0'),], + 'headers': [ + (b'content-length', b'0'), + ], } ) diff --git a/test/python/legacy_force/asgi.py b/test/python/legacy_force/asgi.py index ad2785f2..56c7061d 100644 --- a/test/python/legacy_force/asgi.py +++ b/test/python/legacy_force/asgi.py @@ -1,11 +1,10 @@ def application(scope, receive=None, send=None): assert scope['type'] == 'http' - if receive == None and send == None: + if receive is None and send is None: return app_http - else: - return app_http(receive, send) + return app_http(receive, send) async def app_http(receive, send): @@ -13,6 +12,8 @@ async def app_http(receive, send): { 'type': 'http.response.start', 'status': 200, - 'headers': [(b'content-length', b'0'),], + 'headers': [ + (b'content-length', b'0'), + ], } ) diff --git a/test/python/lifespan/empty/asgi.py b/test/python/lifespan/empty/asgi.py index 27395a28..2071e6e0 100644 --- a/test/python/lifespan/empty/asgi.py +++ b/test/python/lifespan/empty/asgi.py @@ -3,7 +3,7 @@ import os async def handler(prefix, scope, receive, send): if scope['type'] == 'lifespan': - with open(f'{prefix}version', 'w+') as f: + with open(f'{prefix}version', 'w+', encoding='utf-8') as f: f.write( f"{scope['asgi']['version']} {scope['asgi']['spec_version']}" ) diff --git a/test/python/lifespan/failed/asgi.py b/test/python/lifespan/failed/asgi.py index 8f315f70..fbd006f9 100644 --- a/test/python/lifespan/failed/asgi.py +++ b/test/python/lifespan/failed/asgi.py @@ -6,6 +6,6 @@ async def application(scope, receive, send): await send({"type": "lifespan.startup.failed"}) raise Exception('Exception blah') - elif message['type'] == 'lifespan.shutdown': + if message['type'] == 'lifespan.shutdown': await send({'type': 'lifespan.shutdown.complete'}) return diff --git a/test/python/restart/longstart.py b/test/python/restart/longstart.py index 777398ac..3bc383b7 100644 --- a/test/python/restart/longstart.py +++ b/test/python/restart/longstart.py @@ -3,6 +3,7 @@ import time time.sleep(2) + def application(environ, start_response): body = str(os.getpid()).encode() diff --git a/test/python/unicode/wsgi.py b/test/python/unicode/wsgi.py index f2f85f5d..8c9a59dd 100644 --- a/test/python/unicode/wsgi.py +++ b/test/python/unicode/wsgi.py @@ -1,7 +1,7 @@ def application(environ, start_response): temp_dir = environ.get('HTTP_TEMP_DIR') - with open(f'{temp_dir}/tempfile', 'w') as f: + with open(f'{temp_dir}/tempfile', 'w', encoding='utf-8') as f: f.write('\u26a0\ufe0f') start_response('200', [('Content-Length', '0')]) diff --git a/test/python/user_group/wsgi.py b/test/python/user_group/wsgi.py index 4003c064..8f3ba50d 100644 --- a/test/python/user_group/wsgi.py +++ b/test/python/user_group/wsgi.py @@ -6,7 +6,12 @@ def application(environ, start_response): uid = os.geteuid() gid = os.getegid() - out = json.dumps({'UID': uid, 'GID': gid,}).encode('utf-8') + out = json.dumps( + { + 'UID': uid, + 'GID': gid, + } + ).encode('utf-8') start_response( '200 OK', diff --git a/test/test_access_log.py b/test/test_access_log.py index 3c5e6cbb..873c941a 100644 --- a/test/test_access_log.py +++ b/test/test_access_log.py @@ -1,6 +1,7 @@ import time import pytest + from unit.applications.lang.python import ApplicationPython from unit.option import option @@ -17,11 +18,11 @@ def load(script): ), 'access_log configure' -def set_format(format): +def set_format(log_format): assert 'success' in client.conf( { 'path': f'{option.temp_dir}/access.log', - 'format': format, + 'format': log_format, }, 'access_log', ), 'access_log format' @@ -283,14 +284,14 @@ def test_access_log_change(temp_dir, wait_for_record): def test_access_log_format(wait_for_record): load('empty') - def check_format(format, expect, url='/'): - set_format(format) + def check_format(log_format, expect, url='/'): + set_format(log_format) assert client.get(url=url)['status'] == 200 assert wait_for_record(expect, 'access.log') is not None, 'found' - format = 'BLAH\t0123456789' - check_format(format, format) + log_format = 'BLAH\t0123456789' + check_format(log_format, log_format) check_format('$uri $status $uri $status', '/ 200 / 200') diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index 4b59fafd..e6668b2f 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -3,6 +3,7 @@ import time import pytest from packaging import version + from unit.applications.lang.python import ApplicationPython prerequisites = { diff --git a/test/test_asgi_application_unix_abstract.py b/test/test_asgi_application_unix_abstract.py index 980a98a9..f35ce0d7 100644 --- a/test/test_asgi_application_unix_abstract.py +++ b/test/test_asgi_application_unix_abstract.py @@ -1,4 +1,5 @@ from packaging import version + from unit.applications.lang.python import ApplicationPython prerequisites = { diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index 5df7475e..e09ea1cc 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -1,7 +1,8 @@ -import os +from pathlib import Path -from conftest import unit_stop from packaging import version + +from conftest import unit_stop from unit.applications.lang.python import ApplicationPython from unit.option import option @@ -14,32 +15,26 @@ client = ApplicationPython(load_module='asgi') def assert_cookies(prefix): for name in ['startup', 'shutdown']: - path = f'{option.test_dir}/python/lifespan/empty/{prefix}{name}' - exists = os.path.isfile(path) - if exists: - os.remove(path) + path = Path(f'{option.test_dir}/python/lifespan/empty/{prefix}{name}') + exists = path.is_file() + path.unlink(missing_ok=True) assert not exists, name - path = f'{option.test_dir}/python/lifespan/empty/{prefix}version' + path = Path(f'{option.test_dir}/python/lifespan/empty/{prefix}version') + versions = path.read_text(encoding='utf-8') + path.unlink() - with open(path, 'r') as f: - version = f.read() - - os.remove(path) - - assert version == '3.0 2.0', 'version' + assert versions == '3.0 2.0', 'versions' def setup_cookies(prefix): - base_dir = f'{option.test_dir}/python/lifespan/empty' - - os.chmod(base_dir, 0o777) + base_dir = Path(f'{option.test_dir}/python/lifespan/empty') + base_dir.chmod(0o777) for name in ['startup', 'shutdown', 'version']: - path = f'{option.test_dir}/python/lifespan/empty/{prefix}{name}' - open(path, 'a').close() - os.chmod(path, 0o777) + path = Path(f'{option.test_dir}/python/lifespan/empty/{prefix}{name}') + path.touch(0o777) def test_asgi_lifespan(): diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py index 63bde713..3d4e2e24 100644 --- a/test/test_asgi_targets.py +++ b/test/test_asgi_targets.py @@ -1,5 +1,6 @@ import pytest from packaging import version + from unit.applications.lang.python import ApplicationPython from unit.option import option diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py index eb7a20e7..f93c97ab 100644 --- a/test/test_asgi_websockets.py +++ b/test/test_asgi_websockets.py @@ -3,6 +3,7 @@ import time import pytest from packaging import version + from unit.applications.lang.python import ApplicationPython from unit.applications.websockets import ApplicationWebsocket diff --git a/test/test_client_ip.py b/test/test_client_ip.py index d7bc399d..538db18b 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -1,4 +1,5 @@ import pytest + from unit.applications.lang.python import ApplicationPython from unit.option import option diff --git a/test/test_configuration.py b/test/test_configuration.py index a311922f..a7d519e9 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -1,6 +1,7 @@ import socket import pytest + from unit.control import Control prerequisites = {'modules': {'python': 'any'}} diff --git a/test/test_forwarded_header.py b/test/test_forwarded_header.py index eaa83dce..4b2f9424 100644 --- a/test/test_forwarded_header.py +++ b/test/test_forwarded_header.py @@ -1,4 +1,5 @@ import pytest + from unit.applications.lang.python import ApplicationPython prerequisites = {'modules': {'python': 'any'}} diff --git a/test/test_go_application.py b/test/test_go_application.py index 8f406744..469d4346 100644 --- a/test/test_go_application.py +++ b/test/test_go_application.py @@ -123,7 +123,7 @@ def test_go_application_command_line_arguments_type(): client.load('command_line_arguments') assert 'error' in client.conf( - '' "a b c", 'applications/command_line_arguments/arguments' + "a b c", 'applications/command_line_arguments/arguments' ), 'arguments type' diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index ba3390ea..a864e9f6 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -3,6 +3,7 @@ import os import pwd import pytest + from unit.applications.lang.go import ApplicationGo from unit.option import option from unit.utils import getns @@ -319,7 +320,7 @@ def test_go_isolation_rootfs_container_priv(require, temp_dir): def test_go_isolation_rootfs_automount_tmpfs(is_su, require, temp_dir): try: - open("/proc/self/mountinfo") + open("/proc/self/mountinfo", encoding='utf-8') except: pytest.skip('The system lacks /proc/self/mountinfo file') diff --git a/test/test_http_header.py b/test/test_http_header.py index cf5866e9..f6579df5 100644 --- a/test/test_http_header.py +++ b/test/test_http_header.py @@ -1,4 +1,5 @@ import pytest + from unit.applications.lang.python import ApplicationPython prerequisites = {'modules': {'python': 'any'}} diff --git a/test/test_java_application.py b/test/test_java_application.py index 3a6a62d6..33151182 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -1,7 +1,7 @@ import io -import os import re import time +from pathlib import Path from unit.applications.lang.java import ApplicationJava from unit.option import option @@ -875,6 +875,7 @@ def test_java_application_get_headers(): assert headers['X-Reply-0'] == 'blah', 'get headers' assert headers['X-Reply-1'] == 'blah', 'get headers 2' + def test_java_application_many_headers(): client.load('get_headers') @@ -956,7 +957,7 @@ def test_java_application_multipart(search_in_file, temp_dir): reldst = '/uploads' fulldst = f'{temp_dir}{reldst}' - os.mkdir(fulldst) + Path(fulldst).mkdir(parents=True) public_dir(fulldst) fields = { diff --git a/test/test_java_isolation_rootfs.py b/test/test_java_isolation_rootfs.py index 66b2a81e..0ed66133 100644 --- a/test/test_java_isolation_rootfs.py +++ b/test/test_java_isolation_rootfs.py @@ -2,6 +2,7 @@ import os import subprocess import pytest + from unit.applications.lang.java import ApplicationJava from unit.option import option @@ -25,6 +26,7 @@ def setup_method_fixture(temp_dir): f'{temp_dir}/jars', ], stderr=subprocess.STDOUT, + check=True, ) except KeyboardInterrupt: @@ -39,6 +41,7 @@ def setup_method_fixture(temp_dir): subprocess.run( ["umount", "--lazy", f"{option.temp_dir}/jars"], stderr=subprocess.STDOUT, + check=True, ) except KeyboardInterrupt: diff --git a/test/test_java_websockets.py b/test/test_java_websockets.py index c323830b..94ac6f86 100644 --- a/test/test_java_websockets.py +++ b/test/test_java_websockets.py @@ -2,6 +2,7 @@ import struct import time import pytest + from unit.applications.lang.java import ApplicationJava from unit.applications.websockets import ApplicationWebsocket diff --git a/test/test_njs.py b/test/test_njs.py index ce92e1ef..aaaa23aa 100644 --- a/test/test_njs.py +++ b/test/test_njs.py @@ -1,6 +1,7 @@ -import os +from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto from unit.option import option from unit.utils import waitforfiles @@ -22,9 +23,9 @@ def setup_method_fixture(temp_dir): def create_files(*files): assets_dir = f'{option.temp_dir}/assets/' - os.makedirs(assets_dir) + Path(assets_dir).mkdir() - [open(assets_dir + f, 'a') for f in files] + _ = [Path(assets_dir + f).touch() for f in files] waitforfiles(*[assets_dir + f for f in files]) diff --git a/test/test_node_application.py b/test/test_node_application.py index 5077b9cb..aaad2bcf 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -1,6 +1,7 @@ import re import pytest + from unit.applications.lang.node import ApplicationNode from unit.utils import waitforfiles @@ -149,11 +150,13 @@ def test_node_application_write_buffer(): assert client.get()['body'] == 'buffer', 'write buffer' + def test_node_application_write_array(): client.load('write_array') assert client.get()['body'] == 'array', 'write array' + def test_node_application_write_callback(temp_dir): client.load('write_callback') @@ -303,11 +306,13 @@ def test_node_application_get_header_names(): 'x-header', ], 'get header names' + def test_node_application_flush_headers(): client.load('flush_headers') assert client.get()['headers']['X-Header'] == 'blah' + def test_node_application_has_header(): client.load('has_header') diff --git a/test/test_node_es_modules.py b/test/test_node_es_modules.py index ac2c545f..4effafea 100644 --- a/test/test_node_es_modules.py +++ b/test/test_node_es_modules.py @@ -1,4 +1,5 @@ from packaging import version + from unit.applications.lang.node import ApplicationNode from unit.applications.websockets import ApplicationWebsocket diff --git a/test/test_node_websockets.py b/test/test_node_websockets.py index d26452aa..68bdd578 100644 --- a/test/test_node_websockets.py +++ b/test/test_node_websockets.py @@ -2,6 +2,7 @@ import struct import time import pytest + from unit.applications.lang.node import ApplicationNode from unit.applications.websockets import ApplicationWebsocket diff --git a/test/test_perl_application.py b/test/test_perl_application.py index 115b0ec7..ad355117 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -1,6 +1,7 @@ import re import pytest + from unit.applications.lang.perl import ApplicationPerl prerequisites = {'modules': {'perl': 'all'}} diff --git a/test/test_php_application.py b/test/test_php_application.py index 8a6641cb..90db38fa 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -7,6 +7,7 @@ import time from pathlib import Path import pytest + from unit.applications.lang.php import ApplicationPHP from unit.option import option @@ -93,13 +94,13 @@ def set_opcache(app, val): def set_preload(preload): - with open(f'{option.temp_dir}/php.ini', 'w') as ini: - ini.write( - f"""opcache.preload = {option.test_dir}/php/opcache/preload\ + Path(f'{option.temp_dir}/php.ini').write_text( + f"""opcache.preload = {option.test_dir}/php/opcache/preload\ /{preload} opcache.preload_user = {option.user or getpass.getuser()} -""" - ) +""", + encoding='utf-8', + ) assert 'success' in client.conf( {"file": f"{option.temp_dir}/php.ini"}, @@ -718,9 +719,11 @@ def test_php_application_index_default(): def test_php_application_trailing_slash(temp_dir): new_root = f'{temp_dir}/php-root' - os.makedirs(f'{new_root}/path') - Path(f'{new_root}/path/index.php').write_text('') + Path(f'{new_root}/path').mkdir(parents=True) + Path(f'{new_root}/path/index.php').write_text( + '', encoding='utf-8' + ) addr = f'{temp_dir}/sock' @@ -761,9 +764,7 @@ def test_php_application_trailing_slash(temp_dir): def test_php_application_forbidden(temp_dir): - new_root = f'{temp_dir}/php-root/path' - os.makedirs(new_root) - os.chmod(new_root, 0o000) + Path(f'{temp_dir}/php-root/path').mkdir(mode=0o000, parents=True) assert 'success' in client.conf( { @@ -787,7 +788,7 @@ def test_php_application_extension_check(temp_dir): assert client.get(url='/index.wrong')['status'] != 200, 'status' new_root = f'{temp_dir}/php' - os.mkdir(new_root) + Path(new_root).mkdir(parents=True) shutil.copy(f'{option.test_dir}/php/phpinfo/index.wrong', new_root) assert 'success' in client.conf( diff --git a/test/test_proxy.py b/test/test_proxy.py index b64e19db..cd16fe5e 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -3,6 +3,7 @@ import socket import time import pytest + from conftest import run_process from unit.applications.lang.python import ApplicationPython from unit.option import option diff --git a/test/test_proxy_chunked.py b/test/test_proxy_chunked.py index f9e9fe10..23476cd9 100644 --- a/test/test_proxy_chunked.py +++ b/test/test_proxy_chunked.py @@ -4,6 +4,7 @@ import socket import time import pytest + from conftest import run_process from unit.applications.lang.python import ApplicationPython from unit.utils import waitforsocket @@ -52,7 +53,7 @@ def run_server(server_port): part = sock.recv(buff_size) data += part - if not len(part): + if not part: break return data @@ -80,7 +81,7 @@ def run_server(server_port): req = f'{req}{add}\r\n' for chunk in re.split(r'([@#])', req): - if chunk == '@' or chunk == '#': + if chunk in ('@', '#'): if chunk == '#': time.sleep(0.1) continue @@ -90,10 +91,10 @@ def run_server(server_port): connection.close() -def chunks(chunks): +def chunks(chunks_lst): body = '\r\n\r\n' - for l, c in chunks: + for l, c in chunks_lst: body = f'{body}{l}\r\n{c}\r\n' return f'{body}0\r\n\r\n' diff --git a/test/test_python_application.py b/test/test_python_application.py index 058a87df..466a59a2 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -8,6 +8,7 @@ import venv import pytest from packaging import version + from unit.applications.lang.python import ApplicationPython prerequisites = {'modules': {'python': 'all'}} @@ -586,8 +587,8 @@ def test_python_application_encoding(): if not matches: pytest.skip('no available locales') - def unify(str): - str.upper().replace('-', '').replace('_', '') + def unify(enc): + enc.upper().replace('-', '').replace('_', '') for loc in matches: assert 'success' in client.conf( diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py index 5b97e292..fd692cb6 100644 --- a/test/test_python_isolation.py +++ b/test/test_python_isolation.py @@ -1,9 +1,9 @@ -import os import re import subprocess from pathlib import Path import pytest + from unit.applications.lang.python import ApplicationPython from unit.option import option from unit.utils import findmnt @@ -24,10 +24,10 @@ def get_cgroup(app_name): cgroup = f'/proc/{pid}/cgroup' - if not os.path.isfile(cgroup): + if not Path(cgroup).is_file(): pytest.skip(f'no cgroup at {cgroup}') - with open(cgroup, 'r') as f: + with open(cgroup, 'r', encoding='utf-8') as f: return f.read().rstrip() diff --git a/test/test_python_procman.py b/test/test_python_procman.py index 4643a9b8..b4378c4f 100644 --- a/test/test_python_procman.py +++ b/test/test_python_procman.py @@ -4,6 +4,7 @@ import subprocess import time import pytest + from unit.applications.lang.python import ApplicationPython from unit.option import option diff --git a/test/test_reconfigure.py b/test/test_reconfigure.py index a5fe1b1a..28d1b4c9 100644 --- a/test/test_reconfigure.py +++ b/test/test_reconfigure.py @@ -1,6 +1,7 @@ import time import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() diff --git a/test/test_reconfigure_tls.py b/test/test_reconfigure_tls.py index 50638391..3cd01b13 100644 --- a/test/test_reconfigure_tls.py +++ b/test/test_reconfigure_tls.py @@ -3,6 +3,7 @@ import ssl import time import pytest + from unit.applications.tls import ApplicationTLS prerequisites = {'modules': {'openssl': 'any'}} @@ -93,6 +94,8 @@ def test_reconfigure_tls_2(): clear_conf() + success = False + try: ssl_sock.do_handshake() except ssl.SSLError: diff --git a/test/test_respawn.py b/test/test_respawn.py index dc465cda..03254037 100644 --- a/test/test_respawn.py +++ b/test/test_respawn.py @@ -3,6 +3,7 @@ import subprocess import time import pytest + from unit.applications.lang.python import ApplicationPython prerequisites = {'modules': {'python': 'any'}} diff --git a/test/test_response_headers.py b/test/test_response_headers.py index ec07c8c4..e62c1293 100644 --- a/test/test_response_headers.py +++ b/test/test_response_headers.py @@ -1,8 +1,9 @@ from pathlib import Path import pytest -from unit.applications.proto import ApplicationProto + from unit.applications.lang.python import ApplicationPython +from unit.applications.proto import ApplicationProto from unit.option import option client = ApplicationProto() @@ -12,7 +13,7 @@ client_python = ApplicationPython() @pytest.fixture(autouse=True) def setup_method_fixture(temp_dir): path = Path(f'{temp_dir}/index.html') - path.write_text('0123456789') + path.write_text('0123456789', encoding='utf-8') assert 'success' in client.conf( { diff --git a/test/test_return.py b/test/test_return.py index 3ffcaa4e..af15b886 100644 --- a/test/test_return.py +++ b/test/test_return.py @@ -1,6 +1,7 @@ import re import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() @@ -90,7 +91,7 @@ def test_return_update(): def test_return_location(): reserved = ":/?#[]@!&'()*+,;=" unreserved = ( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789-._~" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" ) unsafe = " \"%<>\\^`{|}" unsafe_enc = "%20%22%25%3C%3E%5C%5E%60%7B%7C%7D" diff --git a/test/test_rewrite.py b/test/test_rewrite.py index 0a4ffe42..f94fb528 100644 --- a/test/test_rewrite.py +++ b/test/test_rewrite.py @@ -1,6 +1,7 @@ -import os +from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() @@ -39,9 +40,9 @@ def set_rewrite(rewrite, uri): def test_rewrite(findall, wait_for_record): assert client.get()['status'] == 200 - assert wait_for_record(rf'\[notice\].*"routes/1" selected') is not None - assert len(findall(rf'\[notice\].*URI rewritten to "/new"')) == 1 - assert len(findall(rf'\[notice\].*URI rewritten')) == 1 + assert wait_for_record(r'\[notice\].*"routes/1" selected') is not None + assert len(findall(r'\[notice\].*URI rewritten to "/new"')) == 1 + assert len(findall(r'\[notice\].*URI rewritten')) == 1 set_rewrite("", "") assert client.get()['status'] == 200 @@ -131,11 +132,9 @@ def test_rewrite_location(): def test_rewrite_share(temp_dir): - os.makedirs(f'{temp_dir}/dir') - os.makedirs(f'{temp_dir}/foo') - - with open(f'{temp_dir}/foo/index.html', 'w') as fooindex: - fooindex.write('fooindex') + Path(f'{temp_dir}/dir').mkdir() + Path(f'{temp_dir}/foo/').mkdir() + Path(f'{temp_dir}/foo/index.html').write_text('fooindex', encoding='utf-8') # same action block diff --git a/test/test_routing.py b/test/test_routing.py index ce5952eb..0b6eced2 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import pytest + from unit.applications.lang.python import ApplicationPython from unit.option import option @@ -24,8 +25,8 @@ def setup_method_fixture(): ), 'routing configure' -def route(route): - return client.conf([route], 'routes') +def route(conf_route): + return client.conf([conf_route], 'routes') def route_match(match): @@ -40,19 +41,21 @@ def route_match_invalid(match): ), 'route match configure invalid' -def host(host, status): +def host(host_header, status): assert ( - client.get(headers={'Host': host, 'Connection': 'close'})['status'] + client.get(headers={'Host': host_header, 'Connection': 'close'})[ + 'status' + ] == status ), 'match host' -def cookie(cookie, status): +def cookie(cookie_header, status): assert ( client.get( headers={ 'Host': 'localhost', - 'Cookie': cookie, + 'Cookie': cookie_header, 'Connection': 'close', }, )['status'] diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index 3ac62f71..aae89999 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -2,6 +2,7 @@ import re import subprocess import pytest + from unit.applications.lang.ruby import ApplicationRuby prerequisites = {'modules': {'ruby': 'all'}} diff --git a/test/test_settings.py b/test/test_settings.py index 0cdc6c0d..9d37d6ca 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -4,6 +4,7 @@ import subprocess import time import pytest + from unit.applications.lang.python import ApplicationPython prerequisites = {'modules': {'python': 'any'}} diff --git a/test/test_static.py b/test/test_static.py index 98f27c7f..e2fc2283 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -1,7 +1,9 @@ import os import socket +from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto from unit.utils import waitforfiles @@ -11,18 +13,13 @@ client = ApplicationProto() @pytest.fixture(autouse=True) def setup_method_fixture(temp_dir): - os.makedirs(f'{temp_dir}/assets/dir') assets_dir = f'{temp_dir}/assets' - with open(f'{assets_dir}/index.html', 'w') as index, open( - f'{assets_dir}/README', 'w' - ) as readme, open(f'{assets_dir}/log.log', 'w') as log, open( - f'{assets_dir}/dir/file', 'w' - ) as file: - index.write('0123456789') - readme.write('readme') - log.write('[debug]') - file.write('blah') + Path(f'{assets_dir}/dir').mkdir(parents=True) + Path(f'{assets_dir}/index.html').write_text('0123456789', encoding='utf-8') + Path(f'{assets_dir}/README').write_text('readme', encoding='utf-8') + Path(f'{assets_dir}/log.log').write_text('[debug]', encoding='utf-8') + Path(f'{assets_dir}/dir/file').write_text('blah', encoding='utf-8') assert 'success' in client.conf( { @@ -103,7 +100,7 @@ def test_static_etag(temp_dir): assert etag != etag_2, 'different ETag' assert etag == client.get(url='/')['headers']['ETag'], 'same ETag' - with open(f'{temp_dir}/assets/index.html', 'w') as f: + with open(f'{temp_dir}/assets/index.html', 'w', encoding='utf-8') as f: f.write('blah') assert etag != client.get(url='/')['headers']['ETag'], 'new ETag' @@ -119,18 +116,16 @@ def test_static_redirect(): def test_static_space_in_name(temp_dir): assets_dir = f'{temp_dir}/assets' - os.rename( - f'{assets_dir}/dir/file', - f'{assets_dir}/dir/fi le', - ) + Path(f'{assets_dir}/dir/file').rename(f'{assets_dir}/dir/fi le') + assert waitforfiles(f'{assets_dir}/dir/fi le') assert client.get(url='/dir/fi le')['body'] == 'blah', 'file name' - os.rename(f'{assets_dir}/dir', f'{assets_dir}/di r') + Path(f'{assets_dir}/dir').rename(f'{assets_dir}/di r') assert waitforfiles(f'{assets_dir}/di r/fi le') assert client.get(url='/di r/fi le')['body'] == 'blah', 'dir name' - os.rename(f'{assets_dir}/di r', f'{assets_dir}/ di r ') + Path(f'{assets_dir}/di r').rename(f'{assets_dir}/ di r ') assert waitforfiles(f'{assets_dir}/ di r /fi le') assert ( client.get(url='/ di r /fi le')['body'] == 'blah' @@ -149,17 +144,14 @@ def test_static_space_in_name(temp_dir): == 'blah' ), 'encoded 2' - os.rename( - f'{assets_dir}/ di r /fi le', - f'{assets_dir}/ di r / fi le ', - ) + Path(f'{assets_dir}/ di r /fi le').rename(f'{assets_dir}/ di r / fi le ') assert waitforfiles(f'{assets_dir}/ di r / fi le ') assert ( client.get(url='/%20di%20r%20/%20fi%20le%20')['body'] == 'blah' ), 'file name enclosing' try: - open(f'{temp_dir}/ф а', 'a').close() + Path(f'{temp_dir}/ф а').touch() utf8 = True except KeyboardInterrupt: @@ -169,17 +161,13 @@ def test_static_space_in_name(temp_dir): utf8 = False if utf8: - os.rename( - f'{assets_dir}/ di r / fi le ', - f'{assets_dir}/ di r /фа йл', + Path(f'{assets_dir}/ di r / fi le ').rename( + f'{assets_dir}/ di r /фа йл' ) assert waitforfiles(f'{assets_dir}/ di r /фа йл') assert client.get(url='/ di r /фа йл')['body'] == 'blah' - os.rename( - f'{assets_dir}/ di r ', - f'{assets_dir}/ди ректория', - ) + Path(f'{assets_dir}/ di r ').rename(f'{assets_dir}/ди ректория') assert waitforfiles(f'{assets_dir}/ди ректория/фа йл') assert ( client.get(url='/ди ректория/фа йл')['body'] == 'blah' diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index fb14d7ab..31e10b4e 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -2,21 +2,23 @@ import os from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto from unit.option import option prerequisites = {'features': {'chroot': True}} client = ApplicationProto() +test_path = f'/{os.path.relpath(Path(__file__))}' @pytest.fixture(autouse=True) def setup_method_fixture(temp_dir): - os.makedirs(f'{temp_dir}/assets/dir') - Path(f'{temp_dir}/assets/index.html').write_text('0123456789') - Path(f'{temp_dir}/assets/dir/file').write_text('blah') - - client.test_path = f'/{os.path.relpath(Path(__file__))}' + Path(f'{temp_dir}/assets/dir').mkdir(parents=True) + Path(f'{temp_dir}/assets/index.html').write_text( + '0123456789', encoding='utf-8' + ) + Path(f'{temp_dir}/assets/dir/file').write_text('blah', encoding='utf-8') assert 'success' in client.conf( { @@ -85,7 +87,7 @@ def test_static_chroot_empty(): assert client.get(url='/dir/file')['status'] == 200, 'empty absolute' assert 'success' in update_action("", ".$uri") - assert client.get(url=client.test_path)['status'] == 200, 'empty relative' + assert client.get(url=test_path)['status'] == 200, 'empty relative' def test_static_chroot_relative(require): @@ -95,10 +97,10 @@ def test_static_chroot_relative(require): assert client.get(url='/dir/file')['status'] == 403, 'relative chroot' assert 'success' in client.conf({"share": ".$uri"}, 'routes/0/action') - assert client.get(url=client.test_path)['status'] == 200, 'relative share' + assert client.get(url=test_path)['status'] == 200, 'relative share' assert 'success' in update_action(".", ".$uri") - assert client.get(url=client.test_path)['status'] == 200, 'relative' + assert client.get(url=test_path)['status'] == 200, 'relative' def test_static_chroot_variables(temp_dir): diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py index 25e466a3..9b5fcb53 100644 --- a/test/test_static_fallback.py +++ b/test/test_static_fallback.py @@ -2,6 +2,7 @@ import os from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() @@ -11,7 +12,7 @@ client = ApplicationProto() def setup_method_fixture(temp_dir): assets_dir = f'{temp_dir}/assets' os.makedirs(f'{assets_dir}/dir') - Path(f'{assets_dir}/index.html').write_text('0123456789') + Path(f'{assets_dir}/index.html').write_text('0123456789', encoding='utf-8') os.makedirs(f'{assets_dir}/403') os.chmod(f'{assets_dir}/403', 0o000) diff --git a/test/test_static_mount.py b/test/test_static_mount.py index d8d3b698..41b436e2 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -3,6 +3,7 @@ import subprocess from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto prerequisites = {'features': {'chroot': True}, 'privileged_user': True} @@ -15,9 +16,11 @@ def setup_method_fixture(temp_dir): os.makedirs(f'{temp_dir}/assets/dir/mount') os.makedirs(f'{temp_dir}/assets/dir/dir') os.makedirs(f'{temp_dir}/assets/mount') - Path(f'{temp_dir}/assets/index.html').write_text('index') - Path(f'{temp_dir}/assets/dir/dir/file').write_text('file') - Path(f'{temp_dir}/assets/mount/index.html').write_text('mount') + Path(f'{temp_dir}/assets/index.html').write_text('index', encoding='utf-8') + Path(f'{temp_dir}/assets/dir/dir/file').write_text('file', encoding='utf-8') + Path(f'{temp_dir}/assets/mount/index.html').write_text( + 'mount', encoding='utf-8' + ) try: subprocess.check_output( diff --git a/test/test_static_share.py b/test/test_static_share.py index fa16d267..ee53fe9b 100644 --- a/test/test_static_share.py +++ b/test/test_static_share.py @@ -2,6 +2,7 @@ import os from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() @@ -12,8 +13,8 @@ def setup_method_fixture(temp_dir): os.makedirs(f'{temp_dir}/assets/dir') os.makedirs(f'{temp_dir}/assets/dir2') - Path(f'{temp_dir}/assets/dir/file').write_text('1') - Path(f'{temp_dir}/assets/dir2/file2').write_text('2') + Path(f'{temp_dir}/assets/dir/file').write_text('1', encoding='utf-8') + Path(f'{temp_dir}/assets/dir2/file2').write_text('2', encoding='utf-8') assert 'success' in client.conf( { diff --git a/test/test_static_symlink.py b/test/test_static_symlink.py index 3b04d70c..2d402d48 100644 --- a/test/test_static_symlink.py +++ b/test/test_static_symlink.py @@ -2,6 +2,7 @@ import os from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto prerequisites = {'features': {'chroot': True}} @@ -12,8 +13,10 @@ client = ApplicationProto() @pytest.fixture(autouse=True) def setup_method_fixture(temp_dir): os.makedirs(f'{temp_dir}/assets/dir/dir') - Path(f'{temp_dir}/assets/index.html').write_text('0123456789') - Path(f'{temp_dir}/assets/dir/file').write_text('blah') + Path(f'{temp_dir}/assets/index.html').write_text( + '0123456789', encoding='utf-8' + ) + Path(f'{temp_dir}/assets/dir/file').write_text('blah', encoding='utf-8') assert 'success' in client.conf( { diff --git a/test/test_static_types.py b/test/test_static_types.py index a468319a..e931d949 100644 --- a/test/test_static_types.py +++ b/test/test_static_types.py @@ -1,6 +1,7 @@ from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() @@ -10,9 +11,9 @@ client = ApplicationProto() def setup_method_fixture(temp_dir): Path(f'{temp_dir}/assets').mkdir() for ext in ['.xml', '.mp4', '.php', '', '.txt', '.html', '.png']: - Path(f'{temp_dir}/assets/file{ext}').write_text(ext) + Path(f'{temp_dir}/assets/file{ext}').write_text(ext, encoding='utf-8') - Path(f'{temp_dir}/assets/index.html').write_text('index') + Path(f'{temp_dir}/assets/index.html').write_text('index', encoding='utf-8') assert 'success' in client.conf( { diff --git a/test/test_static_variables.py b/test/test_static_variables.py index 5afd0127..62753750 100644 --- a/test/test_static_variables.py +++ b/test/test_static_variables.py @@ -2,6 +2,7 @@ import os from pathlib import Path import pytest + from unit.applications.proto import ApplicationProto client = ApplicationProto() @@ -11,9 +12,11 @@ client = ApplicationProto() def setup_method_fixture(temp_dir): os.makedirs(f'{temp_dir}/assets/dir') os.makedirs(f'{temp_dir}/assets/d$r') - Path(f'{temp_dir}/assets/index.html').write_text('0123456789') - Path(f'{temp_dir}/assets/dir/file').write_text('file') - Path(f'{temp_dir}/assets/d$r/file').write_text('d$r') + Path(f'{temp_dir}/assets/index.html').write_text( + '0123456789', encoding='utf-8' + ) + Path(f'{temp_dir}/assets/dir/file').write_text('file', encoding='utf-8') + Path(f'{temp_dir}/assets/d$r/file').write_text('d$r', encoding='utf-8') assert 'success' in client.conf( { diff --git a/test/test_tls.py b/test/test_tls.py index a56d5428..09921773 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -2,8 +2,10 @@ import io import ssl import subprocess import time +from pathlib import Path import pytest + from unit.applications.tls import ApplicationTLS from unit.option import option @@ -53,9 +55,8 @@ def context_cert_req(cert='root'): def generate_ca_conf(): - with open(f'{option.temp_dir}/ca.conf', 'w') as f: - f.write( - f"""[ ca ] + Path(f'{option.temp_dir}/ca.conf').write_text( + f"""[ ca ] default_ca = myca [ myca ] @@ -72,17 +73,13 @@ copy_extensions = copy commonName = optional [ myca_extensions ] -basicConstraints = critical,CA:TRUE""" - ) - - with open(f'{option.temp_dir}/certserial', 'w') as f: - f.write('1000') - - with open(f'{option.temp_dir}/certindex', 'w') as f: - f.write('') +basicConstraints = critical,CA:TRUE""", + encoding='utf-8', + ) - with open(f'{option.temp_dir}/certindex.attr', 'w') as f: - f.write('') + Path(f'{option.temp_dir}/certserial').write_text('1000', encoding='utf-8') + Path(f'{option.temp_dir}/certindex').touch() + Path(f'{option.temp_dir}/certindex.attr').touch() def remove_tls(application='empty', port=8080): @@ -322,8 +319,8 @@ def test_tls_certificate_chain(temp_dir): with open(crt_path, 'wb') as crt, open(end_path, 'rb') as end, open( int_path, 'rb' - ) as int: - crt.write(end.read() + int.read()) + ) as inter: + crt.write(end.read() + inter.read()) # incomplete chain @@ -428,7 +425,9 @@ def test_tls_certificate_chain_long(temp_dir): else f'{temp_dir}/int{i}.crt' ) - with open(f'{temp_dir}/all.crt', 'a') as chain, open(path) as cert: + with open(f'{temp_dir}/all.crt', 'a', encoding='utf-8') as chain, open( + path, encoding='utf-8' + ) as cert: chain.write(cert.read()) assert 'success' in client.certificate_load( diff --git a/test/test_tls_conf_command.py b/test/test_tls_conf_command.py index 4d772c83..5a9a3f32 100644 --- a/test/test_tls_conf_command.py +++ b/test/test_tls_conf_command.py @@ -1,6 +1,7 @@ import ssl import pytest + from unit.applications.tls import ApplicationTLS prerequisites = {'modules': {'openssl': 'any'}} diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index aa7ed3c5..61d72125 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -2,6 +2,7 @@ import ssl import subprocess import pytest + from unit.applications.tls import ApplicationTLS from unit.option import option @@ -104,7 +105,7 @@ def config_bundles(bundles): def generate_ca_conf(): - with open(f'{option.temp_dir}/ca.conf', 'w') as f: + with open(f'{option.temp_dir}/ca.conf', 'w', encoding='utf-8') as f: f.write( f"""[ ca ] default_ca = myca @@ -126,10 +127,10 @@ commonName = optional basicConstraints = critical,CA:TRUE""" ) - with open(f'{option.temp_dir}/certserial', 'w') as f: + with open(f'{option.temp_dir}/certserial', 'w', encoding='utf-8') as f: f.write('1000') - with open(f'{option.temp_dir}/certindex', 'w') as f: + with open(f'{option.temp_dir}/certindex', 'w', encoding='utf-8') as f: f.write('') diff --git a/test/test_upstreams_rr.py b/test/test_upstreams_rr.py index ecf24add..a2dc5c68 100644 --- a/test/test_upstreams_rr.py +++ b/test/test_upstreams_rr.py @@ -2,6 +2,7 @@ import os import re import pytest + from unit.applications.lang.python import ApplicationPython from unit.option import option diff --git a/test/test_usr1.py b/test/test_usr1.py index ce756fc0..ecb4d8fd 100644 --- a/test/test_usr1.py +++ b/test/test_usr1.py @@ -1,5 +1,6 @@ import os import signal +from pathlib import Path from unit.applications.lang.python import ApplicationPython from unit.log import Log @@ -23,14 +24,14 @@ def test_usr1_access_log(search_in_file, temp_dir, unit_pid, wait_for_record): assert waitforfiles(log_path), 'open' - os.rename(log_path, f'{temp_dir}/{log_new}') + Path(log_path).rename(f'{temp_dir}/{log_new}') assert client.get()['status'] == 200 assert ( wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', log_new) is not None ), 'rename new' - assert not os.path.isfile(log_path), 'rename old' + assert not Path(log_path).is_file(), 'rename old' os.kill(unit_pid, signal.SIGUSR1) @@ -51,7 +52,7 @@ def test_usr1_unit_log(search_in_file, temp_dir, unit_pid, wait_for_record): log_path = f'{temp_dir}/unit.log' log_path_new = f'{temp_dir}/{log_new}' - os.rename(log_path, log_path_new) + Path(log_path).rename(log_path_new) Log.swap(log_new) @@ -60,7 +61,7 @@ def test_usr1_unit_log(search_in_file, temp_dir, unit_pid, wait_for_record): assert client.post(body=body)['status'] == 200 assert wait_for_record(body, log_new) is not None, 'rename new' - assert not os.path.isfile(log_path), 'rename old' + assert not Path(log_path).is_file(), 'rename old' os.kill(unit_pid, signal.SIGUSR1) @@ -75,13 +76,10 @@ def test_usr1_unit_log(search_in_file, temp_dir, unit_pid, wait_for_record): finally: # merge two log files into unit.log to check alerts - with open(log_path, 'r', errors='ignore') as unit_log: - log = unit_log.read() - - with open(log_path, 'w') as unit_log, open( - log_path_new, 'r', errors='ignore' - ) as unit_log_new: - unit_log.write(unit_log_new.read()) - unit_log.write(log) + path_log = Path(log_path) + log = path_log.read_text(encoding='utf-8', errors='ignore') + Path( + log_path_new + ).read_text(encoding='utf-8', errors='ignore') + path_log.write_text(log, encoding='utf-8', errors='ignore') Log.swap(log_new) diff --git a/test/test_variables.py b/test/test_variables.py index 0b7b9ea8..9aab8a62 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -1,11 +1,11 @@ -import os -from pathlib import Path import re import time +from pathlib import Path import pytest -from unit.applications.proto import ApplicationProto + from unit.applications.lang.python import ApplicationPython +from unit.applications.proto import ApplicationProto from unit.option import option client = ApplicationProto() @@ -22,11 +22,11 @@ def setup_method_fixture(): ), 'configure routes' -def set_format(format): +def set_format(log_format): assert 'success' in client.conf( { 'path': f'{option.temp_dir}/access.log', - 'format': format, + 'format': log_format, }, 'access_log', ), 'access_log format' @@ -127,8 +127,8 @@ def test_variables_uri(search_in_file, wait_for_record): def test_variables_uri_no_cache(temp_dir): - os.makedirs(f'{temp_dir}/foo/bar') - Path(f'{temp_dir}/foo/bar/index.html').write_text('index') + Path(f'{temp_dir}/foo/bar').mkdir(parents=True) + Path(f'{temp_dir}/foo/bar/index.html').write_text('index', encoding='utf-8') assert 'success' in client.conf( { @@ -443,7 +443,7 @@ def test_variables_response_header(temp_dir, wait_for_record): # share Path(f'{temp_dir}/foo').mkdir() - Path(f'{temp_dir}/foo/index.html').write_text('index') + Path(f'{temp_dir}/foo/index.html').write_text('index', encoding='utf-8') assert 'success' in client.conf( { @@ -514,11 +514,11 @@ def test_variables_response_header_application(require, wait_for_record): def test_variables_invalid(temp_dir): - def check_variables(format): + def check_variables(log_format): assert 'error' in client.conf( { 'path': f'{temp_dir}/access.log', - 'format': format, + 'format': log_format, }, 'access_log', ), 'access_log format' diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 5aca5048..2479d4f6 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -53,7 +53,7 @@ class ApplicationGo(ApplicationProto): replace_path = f'{option.current_dir}/build/go/src/unit.nginx.org/go' - with open(f'{temp_dir}go.mod', 'w') as f: + with open(f'{temp_dir}go.mod', 'w', encoding='utf-8') as f: f.write( f"""module test/app require unit.nginx.org/go v0.0.0 diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py index 2ab172b0..ac59ec1b 100644 --- a/test/unit/applications/lang/php.py +++ b/test/unit/applications/lang/php.py @@ -1,4 +1,4 @@ -import os +from pathlib import Path import shutil from unit.applications.proto import ApplicationProto @@ -15,10 +15,9 @@ class ApplicationPHP(ApplicationProto): if kwargs.get('isolation') and kwargs['isolation'].get('rootfs'): rootfs = kwargs['isolation']['rootfs'] - if not os.path.exists(f'{rootfs}/app/php/'): - os.makedirs(f'{rootfs}/app/php/') + Path(f'{rootfs}/app/php/').mkdir(parents=True, exist_ok=True) - if not os.path.exists(f'{rootfs}/app/php/{script}'): + if not Path(f'{rootfs}/app/php/{script}').exists(): shutil.copytree(script_path, f'{rootfs}/app/php/{script}') script_path = f'/app/php/{script}' diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py index 67304d12..67684b04 100644 --- a/test/unit/applications/lang/python.py +++ b/test/unit/applications/lang/python.py @@ -1,4 +1,4 @@ -import os +from pathlib import Path import shutil from urllib.parse import quote @@ -26,10 +26,9 @@ class ApplicationPython(ApplicationProto): if kwargs.get('isolation') and kwargs['isolation'].get('rootfs'): rootfs = kwargs['isolation']['rootfs'] - if not os.path.exists(f'{rootfs}/app/python/'): - os.makedirs(f'{rootfs}/app/python/') + Path(f'{rootfs}/app/python/').mkdir(parents=True, exist_ok=True) - if not os.path.exists(f'{rootfs}/app/python/{name}'): + if not Path(f'{rootfs}/app/python/{name}').exists(): shutil.copytree(script_path, f'{rootfs}/app/python/{name}') script_path = f'/app/python/{name}' diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py index 50a27348..75354dd9 100644 --- a/test/unit/applications/tls.py +++ b/test/unit/applications/tls.py @@ -79,7 +79,7 @@ subjectAltName = @alt_names {a_names}''' - with open(conf_path, 'w') as f: + with open(conf_path, 'w', encoding='utf-8') as f: f.write( f'''[ req ] default_bits = 2048 diff --git a/test/unit/applications/websockets.py b/test/unit/applications/websockets.py index 29725943..a8e563d0 100644 --- a/test/unit/applications/websockets.py +++ b/test/unit/applications/websockets.py @@ -6,6 +6,7 @@ import select import struct import pytest + from unit.applications.proto import ApplicationProto GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" @@ -69,7 +70,7 @@ class ApplicationWebsocket(ApplicationProto): return struct.pack('!H', code) + reason.encode('utf-8') def frame_read(self, sock, read_timeout=60): - def recv_bytes(sock, bytes): + def recv_bytes(sock, bytes_len): data = b'' while True: rlist = select.select([sock], [], [], read_timeout)[0] @@ -80,9 +81,9 @@ class ApplicationWebsocket(ApplicationProto): pytest.fail("Can't read response from server.") break - data += sock.recv(bytes - len(data)) + data += sock.recv(bytes_len - len(data)) - if len(data) == bytes: + if len(data) == bytes_len: break return data @@ -206,18 +207,18 @@ class ApplicationWebsocket(ApplicationProto): end = frame_len pos = end - def message(self, sock, type, message, fragmention_size=None, **kwargs): + def message(self, sock, mes_type, message, fragmention_size=None, **kwargs): message_len = len(message) if fragmention_size is None: fragmention_size = message_len if message_len <= fragmention_size: - self.frame_write(sock, type, message, **kwargs) + self.frame_write(sock, mes_type, message, **kwargs) return pos = 0 - op_code = type + op_code = mes_type while pos < message_len: end = min(pos + fragmention_size, message_len) fin = end == message_len diff --git a/test/unit/check/check_prerequisites.py b/test/unit/check/check_prerequisites.py index 44c3f10f..ea319346 100644 --- a/test/unit/check/check_prerequisites.py +++ b/test/unit/check/check_prerequisites.py @@ -1,4 +1,5 @@ import pytest + from unit.option import option diff --git a/test/unit/check/isolation.py b/test/unit/check/isolation.py index e31179e8..861c0818 100644 --- a/test/unit/check/isolation.py +++ b/test/unit/check/isolation.py @@ -1,5 +1,5 @@ import json -import os +from pathlib import Path from unit.applications.lang.go import ApplicationGo from unit.applications.lang.java import ApplicationJava @@ -145,11 +145,12 @@ def check_isolation(): isolation = {'user': userns} - unp_clone_path = '/proc/sys/kernel/unprivileged_userns_clone' - if os.path.exists(unp_clone_path): - with open(unp_clone_path, 'r') as f: - if str(f.read()).rstrip() == '1': - isolation['unprivileged_userns_clone'] = True + path_clone = Path('/proc/sys/kernel/unprivileged_userns_clone') + if ( + path_clone.exists() + and path_clone.read_text(encoding='utf-8').rstrip() == '1' + ): + isolation['unprivileged_userns_clone'] = True for ns in allns: ns_value = getns(ns) diff --git a/test/unit/check/node.py b/test/unit/check/node.py index 6a3d581f..b206e914 100644 --- a/test/unit/check/node.py +++ b/test/unit/check/node.py @@ -1,11 +1,11 @@ -import os import subprocess +from pathlib import Path from unit.option import option def check_node(): - if not os.path.exists(f'{option.current_dir}/node/node_modules'): + if not Path(f'{option.current_dir}/node/node_modules').exists(): return False try: diff --git a/test/unit/control.py b/test/unit/control.py index 164d0e60..8cdf1887 100644 --- a/test/unit/control.py +++ b/test/unit/control.py @@ -16,7 +16,7 @@ def args_handler(conf_func): elif argcount == 3: conf = args[0] - if isinstance(conf, dict) or isinstance(conf, list): + if isinstance(conf, (dict, list)): conf = json.dumps(conf) url = args[1] if len(args) == 2 else url_default diff --git a/test/unit/http.py b/test/unit/http.py index 5a6a1a1b..9401501b 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -7,6 +7,7 @@ import select import socket import pytest + from unit.option import option @@ -38,10 +39,7 @@ class HTTP1: if 'sock' not in kwargs: sock = socket.socket(sock_types[sock_type], socket.SOCK_STREAM) - if ( - sock_type == sock_types['ipv4'] - or sock_type == sock_types['ipv6'] - ): + if sock_type in (sock_types['ipv4'], sock_types['ipv6']): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if 'wrapper' in kwargs: @@ -202,7 +200,7 @@ class HTTP1: data += part - if not len(part): + if not part: break return data @@ -263,7 +261,7 @@ class HTTP1: size = int(chunks.pop(0), 16) except ValueError: - pytest.fail(f'Invalid chunk size {size}') + pytest.fail('Invalid chunk size') if size == 0: assert len(chunks) == 1, 'last zero size' diff --git a/test/unit/status.py b/test/unit/status.py index 84c958a3..95096a96 100644 --- a/test/unit/status.py +++ b/test/unit/status.py @@ -30,16 +30,16 @@ class Status: for k in d1 if k in d2 } - else: - return d1 - d2 + + return d1 - d2 return find_diffs(Status.control.conf_get('/status'), Status._status) def get(path='/'): - path = path.split('/')[1:] + path_lst = path.split('/')[1:] diff = Status.diff() - for p in path: - diff = diff[p] + for part in path_lst: + diff = diff[part] return diff -- cgit From a1e00b4e28d56365b4b5cc4aa44185c4b53f5c33 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 16 Jan 2024 15:37:07 +0000 Subject: White space formatting fixes Closes: --- auto/cc/deps | 4 ++-- pkg/rpm/Makefile | 2 +- src/java/nginx/unit/websocket/Util.java | 2 +- src/java/nginx/unit/websocket/server/WsSessionListener.java | 2 +- src/nodejs/unit-http/websocket_connection.js | 8 ++++---- src/nodejs/unit-http/websocket_request.js | 8 ++++---- src/nxt_clone.c | 8 ++++---- src/nxt_openssl.c | 2 +- src/nxt_router.c | 2 +- src/nxt_socket.c | 8 ++++---- tools/setup-unit | 10 +++++----- tools/unitc | 4 ++-- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/auto/cc/deps b/auto/cc/deps index 6e7df20f..11429788 100644 --- a/auto/cc/deps +++ b/auto/cc/deps @@ -3,7 +3,7 @@ case "$NXT_CC_NAME" in SunC): nxt_gen_dep_flags() { - $echo "-xMMD -xMF $NXT_BUILD_DIR/$nxt_dep.tmp" + $echo "-xMMD -xMF $NXT_BUILD_DIR/$nxt_dep.tmp" } nxt_gen_dep_post() { @@ -15,7 +15,7 @@ case "$NXT_CC_NAME" in *) nxt_gen_dep_flags() { - $echo "-MMD -MF $NXT_BUILD_DIR/$nxt_dep -MT $NXT_BUILD_DIR/$nxt_obj" + $echo "-MMD -MF $NXT_BUILD_DIR/$nxt_dep -MT $NXT_BUILD_DIR/$nxt_obj" } nxt_gen_dep_post() { diff --git a/pkg/rpm/Makefile b/pkg/rpm/Makefile index 355f8a59..7906fc24 100644 --- a/pkg/rpm/Makefile +++ b/pkg/rpm/Makefile @@ -254,7 +254,7 @@ rpmbuild/SPECS/unit-%.spec: unit.module.spec.in ../../docs/changes.xml | rpmbuil cat ../../build/unit-$(MODULE_SUFFIX_$*).rpm-changelog | sed -e \ "s/> - $(DEFAULT_VERSION)-$(DEFAULT_RELEASE)/> - $(MODULE_VERSION_$*)-$(MODULE_RELEASE_$*)/" \ >> $@.tmp - mv $@.tmp $@ + mv $@.tmp $@ unit-%: check-build-depends-% rpmbuild/SPECS/unit-%.spec rpmbuild/SOURCES/unit-$(VERSION).tar.gz @echo "===> Building $(subst _,-,$@) package" ; \ diff --git a/src/java/nginx/unit/websocket/Util.java b/src/java/nginx/unit/websocket/Util.java index 6acf3ade..5388431f 100644 --- a/src/java/nginx/unit/websocket/Util.java +++ b/src/java/nginx/unit/websocket/Util.java @@ -332,7 +332,7 @@ public class Util { public static List getDecoders( List> decoderClazzes) - throws DeploymentException{ + throws DeploymentException { List result = new ArrayList<>(); if (decoderClazzes != null) { diff --git a/src/java/nginx/unit/websocket/server/WsSessionListener.java b/src/java/nginx/unit/websocket/server/WsSessionListener.java index fc2bc9c5..2921bd45 100644 --- a/src/java/nginx/unit/websocket/server/WsSessionListener.java +++ b/src/java/nginx/unit/websocket/server/WsSessionListener.java @@ -19,7 +19,7 @@ package nginx.unit.websocket.server; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; -public class WsSessionListener implements HttpSessionListener{ +public class WsSessionListener implements HttpSessionListener { private final WsServerContainer wsServerContainer; diff --git a/src/nodejs/unit-http/websocket_connection.js b/src/nodejs/unit-http/websocket_connection.js index 4eccf6bf..c04075d7 100644 --- a/src/nodejs/unit-http/websocket_connection.js +++ b/src/nodejs/unit-http/websocket_connection.js @@ -36,11 +36,11 @@ var idCounter = 0; function WebSocketConnection(socket, extensions, protocol, maskOutgoingPackets, config) { this._debug = utils.BufferingLogger('websocket:connection', ++idCounter); this._debug('constructor'); - + if (this._debug.enabled) { instrumentSocketForDebugging(this, socket); } - + // Superclass Constructor EventEmitter.call(this); @@ -432,8 +432,8 @@ WebSocketConnection.prototype.processFrame = function(frame) { // logic to emit the ping frame: this is only done when a listener is known to exist // Expose a function allowing the user to override the default ping() behavior var cancelled = false; - var cancel = function() { - cancelled = true; + var cancel = function() { + cancelled = true; }; this.emit('ping', cancel, frame.binaryPayload); diff --git a/src/nodejs/unit-http/websocket_request.js b/src/nodejs/unit-http/websocket_request.js index d84e428b..450ab629 100644 --- a/src/nodejs/unit-http/websocket_request.js +++ b/src/nodejs/unit-http/websocket_request.js @@ -247,7 +247,7 @@ WebSocketRequest.prototype.parseCookies = function(str) { WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, cookies) { this._verifyResolution(); - + // TODO: Handle extensions var protocolFullCase; @@ -418,7 +418,7 @@ WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, co // if (negotiatedExtensions) { // response += 'Sec-WebSocket-Extensions: ' + negotiatedExtensions.join(', ') + '\r\n'; // } - + // Mark the request resolved now so that the user can't call accept or // reject a second time. this._resolved = true; @@ -447,12 +447,12 @@ WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, co WebSocketRequest.prototype.reject = function(status, reason, extraHeaders) { this._verifyResolution(); - + // Mark the request resolved now so that the user can't call accept or // reject a second time. this._resolved = true; this.emit('requestResolved', this); - + if (typeof(status) !== 'number') { status = 403; } diff --git a/src/nxt_clone.c b/src/nxt_clone.c index 1cd70f6c..305f4261 100644 --- a/src/nxt_clone.c +++ b/src/nxt_clone.c @@ -152,7 +152,7 @@ nxt_clone_credential_map_set(nxt_task_t *task, const char* mapfile, pid_t pid, return NXT_ERROR; } - if (i+1 < map->size) { + if (i + 1 < map->size) { *p++ = '\n'; } else { @@ -382,13 +382,13 @@ nxt_clone_vldt_credential_gidmap(nxt_task_t *task, m = map->map[j]; if (!base_ok && creds->base_gid >= (nxt_gid_t) m.container - && creds->base_gid < (nxt_gid_t) (m.container+m.size)) + && creds->base_gid < (nxt_gid_t) (m.container + m.size)) { base_ok = 1; } if (creds->gids[i] >= (nxt_gid_t) m.container - && creds->gids[i] < (nxt_gid_t) (m.container+m.size)) + && creds->gids[i] < (nxt_gid_t) (m.container + m.size)) { gid_ok = 1; break; @@ -405,7 +405,7 @@ nxt_clone_vldt_credential_gidmap(nxt_task_t *task, m = map->map[i]; if (creds->base_gid >= (nxt_gid_t) m.container - && creds->base_gid < (nxt_gid_t) (m.container+m.size)) + && creds->base_gid < (nxt_gid_t) (m.container + m.size)) { base_ok = 1; break; diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index f56135f3..8f66f45b 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -73,7 +73,7 @@ static nxt_int_t nxt_ssl_conf_commands(nxt_task_t *task, SSL_CTX *ctx, static nxt_int_t nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init, nxt_mp_t *mp); static int nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, - unsigned char *iv, EVP_CIPHER_CTX *ectx,HMAC_CTX *hctx, int enc); + unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); #endif static void nxt_ssl_session_cache(SSL_CTX *ctx, size_t cache_size, time_t timeout); diff --git a/src/nxt_router.c b/src/nxt_router.c index 4e3cb303..0b979575 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -2971,7 +2971,7 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, mp = tmcf->router_conf->mem_pool; - if (tls->socket_conf->tls == NULL){ + if (tls->socket_conf->tls == NULL) { tlscf = nxt_mp_zget(mp, sizeof(nxt_tls_conf_t)); if (nxt_slow_path(tlscf == NULL)) { goto fail; diff --git a/src/nxt_socket.c b/src/nxt_socket.c index a8e0d514..9ac8ecd2 100644 --- a/src/nxt_socket.c +++ b/src/nxt_socket.c @@ -322,15 +322,15 @@ nxt_socket_error(nxt_socket_t s) err = 0; len = sizeof(int); - /* - * Linux and BSDs return 0 and store a pending error in the err argument; + /* + * Linux and BSDs return 0 and store a pending error in the err argument; * Solaris returns -1 and sets the errno. - */ + */ ret = getsockopt(s, SOL_SOCKET, SO_ERROR, (void *) &err, &len); if (nxt_slow_path(ret == -1)) { err = nxt_errno; - } + } return err; } diff --git a/tools/setup-unit b/tools/setup-unit index 38592fe3..f40a767c 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -77,9 +77,9 @@ SYNOPSIS Subcommands ├── cmd [-h] ├── ctl [-h] [-s SOCK] SUBCOMMAND [ARGS] - │   ├── edit [-h] PATH - │   ├── http [-h] [-c CURLOPT] METHOD PATH - │   └── insert [-h] PATH INDEX + │ ├── edit [-h] PATH + │ ├── http [-h] [-c CURLOPT] METHOD PATH + │ └── insert [-h] PATH INDEX ├── freeport [-h] ├── json-ins [-hn] JSON INDEX ├── os-probe [-h] @@ -87,8 +87,8 @@ SYNOPSIS ├── repo-config [-hn] [PKG-MANAGER OS-NAME OS-VERSION] ├── restart [-hls] ├── sock [-h] SUBCOMMAND [ARGS] - │   ├── filter [-chs] - │   └── find [-h] + │ ├── filter [-chs] + │ └── find [-h] └── welcome [-hn] DESCRIPTION diff --git a/tools/unitc b/tools/unitc index 4ab5f663..22417266 100755 --- a/tools/unitc +++ b/tools/unitc @@ -1,6 +1,6 @@ #!/bin/bash # unitc - a curl wrapper for configuring NGINX Unit -# https://github.com/nginx/unit/tree/master/tools +# https://github.com/nginx/unit/tree/master/tools # NGINX, Inc. (c) 2023 # Defaults @@ -292,7 +292,7 @@ else exit 1 fi NEW_ELEMENT=$(cat ${CONF_FILES[@]}) - echo $NEW_ELEMENT | jq > /dev/null || exit $? # Test the input is valid JSON before proceeding + echo $NEW_ELEMENT | jq > /dev/null || exit $? # Test the input is valid JSON before proceeding OLD_ARRAY=$($RPC_CMD curl -s $UNIT_CTRL$URI) if [ "$(echo $OLD_ARRAY | jq -r type)" = "array" ]; then echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT -- cgit From 4e08f4954917ba8485823ab56619089a75c25129 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 15 Jan 2024 17:53:46 +0000 Subject: Tests: added Ruby tests with array in header values --- test/ruby/header_array/config.ru | 7 +++++++ test/ruby/header_array_empty/config.ru | 7 +++++++ test/ruby/header_array_nil/config.ru | 7 +++++++ test/test_ruby_application.py | 20 ++++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 test/ruby/header_array/config.ru create mode 100644 test/ruby/header_array_empty/config.ru create mode 100644 test/ruby/header_array_nil/config.ru diff --git a/test/ruby/header_array/config.ru b/test/ruby/header_array/config.ru new file mode 100644 index 00000000..6401ab4b --- /dev/null +++ b/test/ruby/header_array/config.ru @@ -0,0 +1,7 @@ +app = Proc.new do |env| + ['200', { + 'x-array' => ['name=value', '', 'value', 'av'], + }, []] +end + +run app diff --git a/test/ruby/header_array_empty/config.ru b/test/ruby/header_array_empty/config.ru new file mode 100644 index 00000000..df40ffdd --- /dev/null +++ b/test/ruby/header_array_empty/config.ru @@ -0,0 +1,7 @@ +app = Proc.new do |env| + ['200', { + 'x-array' => [], + }, []] +end + +run app diff --git a/test/ruby/header_array_nil/config.ru b/test/ruby/header_array_nil/config.ru new file mode 100644 index 00000000..04550c8d --- /dev/null +++ b/test/ruby/header_array_nil/config.ru @@ -0,0 +1,7 @@ +app = Proc.new do |env| + ['200', { + 'x-array' => [nil], + }, []] +end + +run app diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index aae89999..127b75b7 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -309,6 +309,26 @@ def test_ruby_application_header_status(): assert client.get()['status'] == 200, 'header status' +def test_ruby_application_header_array(): + client.load('header_array') + + assert client.get()['headers']['x-array'] == 'name=value; ; value; av' + + +def test_ruby_application_header_array_nil(): + client.load('header_array_nil') + + assert client.get()['status'] == 503 + + +def test_ruby_application_header_array_empty(): + client.load('header_array_empty') + + headers = client.get()['headers'] + assert 'x-array' in headers + assert headers['x-array'] == '' + + @pytest.mark.skip('not yet') def test_ruby_application_header_rack(): client.load('header_rack') -- cgit From 02d1984c912261a1274534a24a2d94ac7c7abfa7 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 17 Jan 2024 17:18:30 +0000 Subject: HTTP: Remove short read check in nxt_http_static_buf_completion() On GH, @tonychuuy reported an issue when using Units 'share' action they would get the following error in the unit log 2024/01/15 17:53:41 [error] 49#52 *103 file "/var/www/html/public/vendor/telescope/app.css" has changed while sending response to a client This would happen when trying to serve files over a certain size and the requested file would not be sent. This is due to a somewhat bogus check in nxt_http_static_buf_completion() I say bogus because it's not clear what the check is trying to accomplish and the error message is not entirely accurate either. The check in question goes like n = pread(file->fd, buf, size, offset); return n; ... if (n != size) { if (n >= 0) { /* log file changed error and finish */ /* >> Problem is here << */ } /* log general error and finish */ } If the number of bytes read is not what we asked for and is > -1 (i.e not an error) then it says the file has changed, but really it only checks if the file has _shrunk_ (we can't get back _more_ bytes than we asked for) since it was stat'd. This is what happens recvfrom(22, "GET /tfile HTTP/1.1\r\nHost: local"..., 2048, 0, NULL, NULL) = 82 openat(AT_FDCWD, "/mnt/9p/tfile", O_RDONLY|O_NONBLOCK) = 23 newfstatat(23, "", {st_mode=S_IFREG|0644, st_size=149922, ...}, AT_EMPTY_PATH) = 0 We get a request from a client, open the requested file and stat(2) it to get the file size. We would then go into a pread/writev loop reading the file data and sending it to the client until it's all been sent. However what was happening in this case was this (showing a dummy file of 149922 bytes) pread64(23, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072, 0) = 61440 write(2, "2024/01/17 15:30:50 [error] 1849"..., 109) = 109 We wanted to read 131072 bytes but only read 61440 bytes, the above check triggered and the file transfer was aborted and the above error message logged. Normally for a regular file you will only get less bytes than asked for if the read call is interrupted by a signal or you're near the end of file. There is however at least another situation where this may happen, if the file in question is being served from a network filesystem. It turns out that was indeed the case here, the files where being served over the 9P filesystem protocol. Unit was running in a docker container in an Ubuntu VM under Windows/WSL2 and the files where being passed through to the VM from Windows over 9P. Whatever the intention of this check, it is clearly causing issues in real world scenarios. If it was really desired to check if the had changed since it was opened/stat'd then it would require a different methodology and be a patch for another day. But as it stands this current check does more harm than good, so lets just remove it. With it removed we now get for the above test file recvfrom(22, "GET /tfile HTTP/1.1\r\nHost: local"..., 2048, 0, NULL, NULL) = 82 openat(AT_FDCWD, "/mnt/9p/tfile", O_RDONLY|O_NONBLOCK) = 23 newfstatat(23, "", {st_mode=S_IFREG|0644, st_size=149922, ...}, AT_EMPTY_PATH) = 0 mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f367817b000 pread64(23, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 131072, 0) = 61440 pread64(23, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 18850, 61440) = 18850 writev(22, [{iov_base="HTTP/1.1 200 OK\r\nLast-Modified: "..., iov_len=171}, {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=61440}, {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=18850}], 3) = 80461 pread64(23, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 69632, 80290) = 61440 pread64(23, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192, 141730) = 8192 close(23) = 0 writev(22, [{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=61440}, {iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=8192}], 2) = 69632 So we can see we do two pread(2)s's and a writev(2), then another two pread(2)s and another writev(2) and all the file data has been read and sent to the client. Reported-by: tonychuuy Link: Fixes: 08a8d1510 ("Basic support for serving static files.") Closes: https://github.com/nginx/unit/issues/1064 Reviewed-by: Zhidao Hong Reviewed-by: Andrei Zeliankou Signed-off-by: Andrew Clayton --- src/nxt_http_static.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index e51ba6b0..c4caab3c 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -879,12 +879,7 @@ complete_buf: n = nxt_file_read(fb->file, b->mem.start, size, fb->file_pos); - if (n != size) { - if (n >= 0) { - nxt_log(task, NXT_LOG_ERR, "file \"%FN\" has changed " - "while sending response to a client", fb->file->name); - } - + if (nxt_slow_path(n == NXT_ERROR)) { nxt_http_request_error_handler(task, r, r->proto.any); goto clean; } -- cgit From af6833a18272a0450037b929fef81f3ea43893f2 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Jan 2024 13:37:08 +0100 Subject: Tools: setup-unit: -hh: Add missing documentation for 'restart' Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/setup-unit b/tools/setup-unit index f40a767c..885a5df6 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -3,7 +3,8 @@ ##################################################################### # # Copyright (C) NGINX, Inc. -# Author: NGINX Unit Team, F5 Inc. +# Author: NGINX Unit Team, F5 Inc. +# Copyright 2024, Alejandro Colomar # ##################################################################### @@ -118,6 +119,9 @@ COMMANDS Configure your package manager with the NGINX Unit repository for later installation. + restart + Restart all running unitd(8) instances. + sock Print the control API socket address. welcome -- cgit From 034b6394a414d7336cc2450eaddd842e2e8c35cb Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Jan 2024 13:40:04 +0100 Subject: Tools: setup-unit: -hh: The advanced commands aren't experimental I've been using them for a long time, and they are quite useful and stable. Let's say they're advanced instead of experimental. Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/setup-unit b/tools/setup-unit index 885a5df6..bb5b2ba0 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -63,8 +63,7 @@ OPTIONS Print this help. --help-more - Print help for more commands. They are experimental. Using - these isn't recommended, unless you know what you're doing. + Print help for more (advanced) commands. __EOF__ } -- cgit From ba56e50ee77d11c45f569ba8fbc95e6dadb323ef Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Tue, 23 Jan 2024 13:42:14 +0100 Subject: Tools: setup-unit: -hh: Add short-cut for the advanced help I hate having to type so much just for the useful help. Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/setup-unit b/tools/setup-unit index bb5b2ba0..e9ad5896 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -37,7 +37,7 @@ help_unit() { cat <<__EOF__ ; SYNOPSIS - $0 [-h] COMMAND [ARGS] + $0 [-h[h]] COMMAND [ARGS] Subcommands ├── repo-config [-hn] [PKG-MANAGER OS-NAME OS-VERSION] @@ -62,7 +62,7 @@ OPTIONS -h, --help Print this help. - --help-more + -hh, --help-more Print help for more (advanced) commands. __EOF__ @@ -72,7 +72,7 @@ help_more_unit() { cat <<__EOF__ ; SYNOPSIS - $0 [-h] COMMAND [ARGS] + $0 [-h[h]] COMMAND [ARGS] Subcommands ├── cmd [-h] @@ -131,7 +131,7 @@ OPTIONS -h, --help Print basic help (some commands are hidden). - --help-more + -hh, --help-more Print the hidden help with more commands. __EOF__ @@ -1637,7 +1637,7 @@ while test $# -ge 1; do help_unit; exit 0; ;; - --help-more) + -hh | --help-more) help_more_unit; exit 0; ;; -- cgit From 6452ca111c71188ab2813c763e6a0e86b48fbd56 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 25 Jan 2024 12:49:47 +0000 Subject: Node.js: fixed "httpVersion" variable format According to the Node.js documenation this variable should only include numbering scheme. Thanks to @dbit-xia. Closes: https://github.com/nginx/unit/issues/1085 --- docs/changes.xml | 7 +++++++ src/nodejs/unit-http/unit.cpp | 8 +++++++- test/test_node_application.py | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index 6b1aaf71..f226e4f4 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -40,6 +40,13 @@ with Next.js. + + +ServerRequest.httpVersion variable format in Node.js module. + + + + diff --git a/src/nodejs/unit-http/unit.cpp b/src/nodejs/unit-http/unit.cpp index 7912d0ac..7d9395bb 100644 --- a/src/nodejs/unit-http/unit.cpp +++ b/src/nodejs/unit-http/unit.cpp @@ -581,6 +581,7 @@ Unit::get_server_object() void Unit::create_headers(nxt_unit_request_info_t *req, napi_value request) { + char *p; uint32_t i; napi_value headers, raw_headers; napi_status status; @@ -602,7 +603,12 @@ Unit::create_headers(nxt_unit_request_info_t *req, napi_value request) set_named_property(request, "headers", headers); set_named_property(request, "rawHeaders", raw_headers); - set_named_property(request, "httpVersion", r->version, r->version_length); + + // trim the "HTTP/" protocol prefix + p = (char *) nxt_unit_sptr_get(&r->version); + p += 5; + + set_named_property(request, "httpVersion", create_string_latin1(p, 3)); set_named_property(request, "method", r->method, r->method_length); set_named_property(request, "url", r->target, r->target_length); diff --git a/test/test_node_application.py b/test/test_node_application.py index aaad2bcf..cb775210 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -80,7 +80,7 @@ def test_node_application_variables(date_to_sec_epoch, sec_epoch): 'Request-Method': 'POST', 'Request-Uri': '/', 'Http-Host': 'localhost', - 'Server-Protocol': 'HTTP/1.1', + 'Server-Protocol': '1.1', 'Custom-Header': 'blah', }, 'headers' assert resp['body'] == body, 'body' -- cgit From 37abe2e4633d66241bf1766a740d2b2734c132fa Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 23 Jan 2024 18:45:27 +0800 Subject: HTTP: refactored out nxt_http_request_access_log(). This is in preparation for adding conditional access logging. No functional changes. --- src/nxt_http_request.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index e532baff..2e39e4e8 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -24,6 +24,8 @@ static void nxt_http_request_proto_info(nxt_task_t *task, static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data); +static void nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_conf_t *rtcf); static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); @@ -816,26 +818,23 @@ nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data) void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) { - nxt_tstr_t *log_format; nxt_http_proto_t proto; + nxt_router_conf_t *rtcf; nxt_http_request_t *r; nxt_http_protocol_t protocol; nxt_socket_conf_joint_t *conf; - nxt_router_access_log_t *access_log; r = obj; proto.any = data; conf = r->conf; + rtcf = conf->socket_conf->router_conf; if (!r->logged) { r->logged = 1; - access_log = conf->socket_conf->router_conf->access_log; - log_format = conf->socket_conf->router_conf->log_format; - - if (access_log != NULL) { - access_log->handler(task, r, access_log, log_format); + if (rtcf->access_log != NULL) { + nxt_http_request_access_log(task, r, rtcf); return; } } @@ -866,6 +865,18 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) } +static void +nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_conf_t *rtcf) +{ + nxt_router_access_log_t *access_log; + + access_log = rtcf->access_log; + + access_log->handler(task, r, access_log, rtcf->log_format); +} + + static u_char * nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format) -- cgit From 4c91bebb50d06b28e369d68b23022caa072cf62d Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 23 Jan 2024 18:57:30 +0800 Subject: HTTP: enhanced access log with conditional filtering. This feature allows users to specify conditions to control if access log should be recorded. The "if" option supports a string and JavaScript code. If its value is empty, 0, false, null, or undefined, the logs will not be recorded. And the '!' as a prefix inverses the condition. Example 1: Only log requests that sent a session cookie. { "access_log": { "if": "$cookie_session", "path": "..." } } Example 2: Do not log health check requests. { "access_log": { "if": "`${uri == '/health' ? false : true}`", "path": "..." } } Example 3: Only log requests when the time is before 22:00. { "access_log": { "if": "`${new Date().getHours() < 22}`", "path": "..." } } or { "access_log": { "if": "!`${new Date().getHours() >= 22}`", "path": "..." } } Closes: https://github.com/nginx/unit/issues/594 --- src/nxt_conf_validation.c | 37 +++++++++++++++++++++++++++++++ src/nxt_http_request.c | 54 ++++++++++++++++++++++++++++++++++++++++----- src/nxt_router.h | 2 ++ src/nxt_router_access_log.c | 25 +++++++++++++++++++++ 4 files changed, 112 insertions(+), 6 deletions(-) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 32ed4ffd..32124ee9 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -77,6 +77,8 @@ static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...); static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_str_t *value); +static nxt_int_t nxt_conf_vldt_if(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data) NXT_MAYBE_UNUSED; @@ -1369,6 +1371,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_access_log_members[] = { }, { .name = nxt_string("format"), .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("if"), + .type = NXT_CONF_VLDT_STRING, + .validator = nxt_conf_vldt_if, }, NXT_CONF_VLDT_END @@ -1538,6 +1544,37 @@ nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, } +static nxt_int_t +nxt_conf_vldt_if(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + nxt_str_t str; + + static nxt_str_t if_str = nxt_string("if"); + + if (nxt_conf_type(value) != NXT_CONF_STRING) { + return nxt_conf_vldt_error(vldt, "The \"if\" must be a string"); + } + + nxt_conf_get_string(value, &str); + + if (str.length == 0) { + return NXT_OK; + } + + if (str.start[0] == '!') { + str.start++; + str.length--; + } + + if (nxt_is_tstr(&str)) { + return nxt_conf_vldt_var(vldt, &if_str, &str); + } + + return NXT_OK; +} + + typedef struct { nxt_mp_t *pool; nxt_str_t *type; diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 2e39e4e8..f8d8d887 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -24,8 +24,8 @@ static void nxt_http_request_proto_info(nxt_task_t *task, static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data); -static void nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, - nxt_router_conf_t *rtcf); +static nxt_int_t nxt_http_request_access_log(nxt_task_t *task, + nxt_http_request_t *r, nxt_router_conf_t *rtcf); static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); @@ -818,6 +818,7 @@ nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data) void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) { + nxt_int_t ret; nxt_http_proto_t proto; nxt_router_conf_t *rtcf; nxt_http_request_t *r; @@ -834,8 +835,10 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) r->logged = 1; if (rtcf->access_log != NULL) { - nxt_http_request_access_log(task, r, rtcf); - return; + ret = nxt_http_request_access_log(task, r, rtcf); + if (ret == NXT_OK) { + return; + } } } @@ -865,15 +868,54 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) } -static void +static nxt_int_t nxt_http_request_access_log(nxt_task_t *task, nxt_http_request_t *r, nxt_router_conf_t *rtcf) { + nxt_int_t ret; + nxt_str_t str; + nxt_bool_t expr; nxt_router_access_log_t *access_log; access_log = rtcf->access_log; - access_log->handler(task, r, access_log, rtcf->log_format); + expr = 1; + + if (rtcf->log_expr != NULL) { + + if (nxt_tstr_is_const(rtcf->log_expr)) { + nxt_tstr_str(rtcf->log_expr, &str); + + } else { + ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, + &r->tstr_cache, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_DECLINED; + } + + nxt_tstr_query(task, r->tstr_query, rtcf->log_expr, &str); + + if (nxt_slow_path(nxt_tstr_query_failed(r->tstr_query))) { + return NXT_DECLINED; + } + } + + if (str.length == 0 + || nxt_str_eq(&str, "0", 1) + || nxt_str_eq(&str, "false", 5) + || nxt_str_eq(&str, "null", 4) + || nxt_str_eq(&str, "undefined", 9)) + { + expr = 0; + } + } + + if (rtcf->log_negate ^ expr) { + access_log->handler(task, r, access_log, rtcf->log_format); + return NXT_OK; + } + + return NXT_DECLINED; } diff --git a/src/nxt_router.h b/src/nxt_router.h index b14f8410..3e523001 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -54,6 +54,8 @@ typedef struct { nxt_router_access_log_t *access_log; nxt_tstr_t *log_format; + nxt_tstr_t *log_expr; + uint8_t log_negate; /* 1 bit */ } nxt_router_conf_t; diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c index ccbddb96..7fc59972 100644 --- a/src/nxt_router_access_log.c +++ b/src/nxt_router_access_log.c @@ -13,6 +13,7 @@ typedef struct { nxt_str_t path; nxt_str_t format; + nxt_conf_value_t *expr; } nxt_router_access_log_conf_t; @@ -53,6 +54,12 @@ static nxt_conf_map_t nxt_router_access_log_conf[] = { NXT_CONF_MAP_STR, offsetof(nxt_router_access_log_conf_t, format), }, + + { + nxt_string("if"), + NXT_CONF_MAP_PTR, + offsetof(nxt_router_access_log_conf_t, expr), + }, }; @@ -72,6 +79,8 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf, "[$time_local] \"$request_line\" $status $body_bytes_sent " "\"$header_referer\" \"$header_user_agent\""); + nxt_memzero(&alcf, sizeof(nxt_router_access_log_conf_t)); + alcf.format = log_format_str; if (nxt_conf_type(value) == NXT_CONF_STRING) { @@ -133,6 +142,22 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf, rtcf->access_log = access_log; rtcf->log_format = format; + if (alcf.expr != NULL) { + nxt_conf_get_string(alcf.expr, &str); + + if (str.length > 0 && str.start[0] == '!') { + rtcf->log_negate = 1; + + str.start++; + str.length--; + } + + rtcf->log_expr = nxt_tstr_compile(rtcf->tstr_state, &str, 0); + if (nxt_slow_path(rtcf->log_expr == NULL)) { + return NXT_ERROR; + } + } + return NXT_OK; } -- cgit From dcbff27d9bc88c9e2049c52a441fa67d36ca7efc Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 29 Jan 2024 20:07:53 +0800 Subject: Docs: Update changes.xml for conditional access logging --- docs/changes.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changes.xml b/docs/changes.xml index f226e4f4..50867856 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -26,6 +26,12 @@ NGINX Unit updated to 1.32.0. + + +conditional access logging. + + + $request_id variable contains a string that is formed using random data and -- cgit From ad3645074e368e7277fa2c25d8f87ebd1f522e87 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 24 Jan 2024 16:09:41 +0000 Subject: Tests: "if" option in access logging. Conditional access logging was introduced here: https://github.com/nginx/unit/commit/4c91bebb50d06b28e369d68b23022caa072cf62d --- test/test_access_log.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/test/test_access_log.py b/test/test_access_log.py index 873c941a..1b0ec8ad 100644 --- a/test/test_access_log.py +++ b/test/test_access_log.py @@ -28,6 +28,10 @@ def set_format(log_format): ), 'access_log format' +def set_if(condition): + assert 'success' in client.conf(f'"{condition}"', 'access_log/if') + + def test_access_log_keepalive(wait_for_record): load('mirror') @@ -308,6 +312,62 @@ def test_access_log_variables(wait_for_record): ), '$body_bytes_sent' +def test_access_log_if(search_in_file, wait_for_record): + load('empty') + set_format('$uri') + + def try_if(condition): + set_if(condition) + assert client.get(url=f'/{condition}')['status'] == 200 + + # const + + try_if('') + try_if('0') + try_if('false') + try_if('undefined') + try_if('!') + try_if('!null') + try_if('1') + + # variable + + set_if('$arg_foo') + assert client.get(url='/bar?bar')['status'] == 200 + assert client.get(url='/foo_empty?foo')['status'] == 200 + assert client.get(url='/foo?foo=1')['status'] == 200 + + # check results + + assert wait_for_record(r'^/foo$', 'access.log') is not None + + assert search_in_file(r'^/$', 'access.log') is None + assert search_in_file(r'^/0$', 'access.log') is None + assert search_in_file(r'^/false$', 'access.log') is None + assert search_in_file(r'^/undefined$', 'access.log') is None + assert search_in_file(r'^/!$', 'access.log') is not None + assert search_in_file(r'^/!null$', 'access.log') is not None + assert search_in_file(r'^/1$', 'access.log') is not None + + assert search_in_file(r'^/bar$', 'access.log') is None + assert search_in_file(r'^/foo_empty$', 'access.log') is None + + +def test_access_log_if_njs(require, search_in_file, wait_for_record): + require({'modules': {'njs': 'any'}}) + + load('empty') + set_format('$uri') + + set_if('`${args.foo == \'1\'}`') + + assert client.get(url='/foo_2?foo=2')['status'] == 200 + assert client.get(url='/foo_1?foo=1')['status'] == 200 + + assert wait_for_record(r'^/foo_1$', 'access.log') is not None + assert search_in_file(r'^/foo_2$', 'access.log') is None + + def test_access_log_incorrect(temp_dir, skip_alert): skip_alert(r'failed to apply new conf') @@ -323,3 +383,5 @@ def test_access_log_incorrect(temp_dir, skip_alert): }, 'access_log', ), 'access_log format incorrect' + + assert 'error' in client.conf('$arg_', 'access_log/if') -- cgit From 9919b50aecb196ff9e005ab3d13689bc011233a7 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 24 Jan 2024 17:21:53 +0000 Subject: Isolation: Add a new nxt_cred_t type This is a generic type to represent a uid_t/gid_t on Linux when user namespaces are in use. Technically this only needs to be an unsigned int, but we make it an int64_t so we can make use of the existing NXT_CONF_MAP_INT64 type. This will be used in subsequent commits. Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_clone.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nxt_clone.h b/src/nxt_clone.h index 6cea1bd7..1677dc77 100644 --- a/src/nxt_clone.h +++ b/src/nxt_clone.h @@ -9,6 +9,8 @@ #if (NXT_HAVE_CLONE_NEWUSER) +typedef int64_t nxt_cred_t; + typedef struct { nxt_int_t container; nxt_int_t host; -- cgit From f7c9d3a8b3dbe083007e73c8c7b7e50094bf3763 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 24 Jan 2024 18:01:49 +0000 Subject: Isolation: Use an appropriate type for storing uid/gids Andrei reported an issue on arm64 where he was seeing the following error message when running the tests 2024/01/17 18:32:31.109 [error] 54904#54904 "gidmap" field has an entry with "size": 1, but for unprivileged unit it must be 1. This error message is guarded by the following if statement if (nxt_slow_path(m.size > 1) Turns out size was indeed > 1, in this case it was 289356276058554369, m.size is defined as a nxt_int_t, which on arm64 is actually 8 bytes, but was being printed as a signed int (4 bytes) and by chance/undefined behaviour comes out as 1. But why is size so big? In this case it should have just been 1 with a config of 'gidmap': [{'container': 0, 'host': os.getegid(), 'size': 1}], This is due to nxt_int_t being 64bits on arm64 but using a conf type of NXT_CONF_MAP_INT which means in nxt_conf_map_object() we would do (using our m.size variable as an example) ptr = nxt_pointer_to(data, map[i].offset); ... ptr->i = num; Where ptr is a union pointer and is now pointing at our m.size Next we set m.size to the value of num (which is 1 in this case), via ptr->i where i is a member of that union of type int. So here we are setting a 64bit memory location (nxt_int_t on arm64) through a 32bit (int) union alias, this means we are only setting the lower half (4) of the bytes. Whatever happens to be in the upper 4 bytes will remain, giving us our exceptionally large value. This is demonstrated by this program #include #include int main(void) { int64_t num = -1; /* All 1's in two's complement */ union { int32_t i32; int64_t i64; } *ptr; ptr = (void *)# ptr->i32 = 1; printf("num : %lu / %ld\n", num, num); ptr->i64 = 1; printf("num : %ld\n", num); return 0; } $ make union-32-64-issue cc union-32-64-issue.c -o union-32-64-issue $ ./union-32-64-issue num : 18446744069414584321 / -4294967295 num : 1 However that is not the only issue, because the members of nxt_clone_map_entry_t were specified as nxt_int_t's on the likes of x86_64 this would be a 32bit signed integer. However uid/gids on Linux at least are defined as unsigned integers, so a nxt_int_t would not be big enough to hold all potential values. We could make the nxt_uint_t's but then we're back to the above union aliasing problem. We could just set the memory for these variables to 0 and that would work, however that's really just papering over the problem. The right thing is to use a large enough sized type to store these things, hence the previously introduced nxt_cred_t. This is an int64_t which is plenty large enough. So we switch the nxt_clone_map_entry_t structure members over to nxt_cred_t's and use NXT_CONF_MAP_INT64 as the conf type, which then uses the right sized union member in nxt_conf_map_object() to set these variables. Reported-by: Andrei Zeliankou Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_clone.c | 6 +++--- src/nxt_clone.h | 6 +++--- src/nxt_isolation.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nxt_clone.c b/src/nxt_clone.c index 305f4261..e78a7822 100644 --- a/src/nxt_clone.c +++ b/src/nxt_clone.c @@ -143,7 +143,7 @@ nxt_clone_credential_map_set(nxt_task_t *task, const char* mapfile, pid_t pid, end = mapinfo + len; for (i = 0; i < map->size; i++) { - p = nxt_sprintf(p, end, "%d %d %d", map->map[i].container, + p = nxt_sprintf(p, end, "%L %L %L", map->map[i].container, map->map[i].host, map->map[i].size); if (nxt_slow_path(p == end)) { @@ -332,7 +332,7 @@ nxt_clone_vldt_credential_gidmap(nxt_task_t *task, if (nxt_slow_path((nxt_gid_t) m.host != nxt_egid)) { nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has an entry for " - "host gid %d but unprivileged unit can only map itself " + "host gid %L but unprivileged unit can only map itself " "(gid %d) into child namespaces.", m.host, nxt_egid); return NXT_ERROR; @@ -340,7 +340,7 @@ nxt_clone_vldt_credential_gidmap(nxt_task_t *task, if (nxt_slow_path(m.size > 1)) { nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has an entry with " - "\"size\": %d, but for unprivileged unit it must be 1.", + "\"size\": %L, but for unprivileged unit it must be 1.", m.size); return NXT_ERROR; diff --git a/src/nxt_clone.h b/src/nxt_clone.h index 1677dc77..bf28322f 100644 --- a/src/nxt_clone.h +++ b/src/nxt_clone.h @@ -12,9 +12,9 @@ typedef int64_t nxt_cred_t; typedef struct { - nxt_int_t container; - nxt_int_t host; - nxt_int_t size; + nxt_cred_t container; + nxt_cred_t host; + nxt_cred_t size; } nxt_clone_map_entry_t; typedef struct { diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index cfa494a8..ed5e0d76 100644 --- a/src/nxt_isolation.c +++ b/src/nxt_isolation.c @@ -326,19 +326,19 @@ nxt_isolation_credential_map(nxt_task_t *task, nxt_mp_t *mp, static nxt_conf_map_t nxt_clone_map_entry_conf[] = { { nxt_string("container"), - NXT_CONF_MAP_INT, + NXT_CONF_MAP_INT64, offsetof(nxt_clone_map_entry_t, container), }, { nxt_string("host"), - NXT_CONF_MAP_INT, + NXT_CONF_MAP_INT64, offsetof(nxt_clone_map_entry_t, host), }, { nxt_string("size"), - NXT_CONF_MAP_INT, + NXT_CONF_MAP_INT64, offsetof(nxt_clone_map_entry_t, size), }, }; -- cgit From eba7378d4f8816799032a0c086ab54d3c15157b3 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 24 Jan 2024 22:03:12 +0000 Subject: Configuration: Use the NXT_CONF_VLDT_REQUIRED flag for procmap Use the NXT_CONF_VLDT_REQUIRED flag on the app_procmap members. These three settings are required. These are for the uidmap & gidmap settings in the config. Suggested-by: Zhidao HONG Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 32124ee9..eb7ef530 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1327,12 +1327,15 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_procmap_members[] = { { .name = nxt_string("container"), .type = NXT_CONF_VLDT_INTEGER, + .flags = NXT_CONF_VLDT_REQUIRED, }, { .name = nxt_string("host"), .type = NXT_CONF_VLDT_INTEGER, + .flags = NXT_CONF_VLDT_REQUIRED, }, { .name = nxt_string("size"), .type = NXT_CONF_VLDT_INTEGER, + .flags = NXT_CONF_VLDT_REQUIRED, }, NXT_CONF_VLDT_END -- cgit From 990fbe7010526bb97f2d414db866050ef5e8f244 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 24 Jan 2024 22:17:02 +0000 Subject: Configuration: Remove procmap validation code With the previous commit which introduced the use of the NXT_CONF_VLDT_REQUIRED flag, we no longer need to do this separate validation, it's only purpose was to check if the three uidmap/gidmap settings had been provided. Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 73 ++--------------------------------------------- 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index eb7ef530..c843b265 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -218,8 +218,6 @@ static nxt_int_t nxt_conf_vldt_clone_namespaces(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); #if (NXT_HAVE_CLONE_NEWUSER) -static nxt_int_t nxt_conf_vldt_clone_procmap(nxt_conf_validation_t *vldt, - const char* mapfile, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt, @@ -3091,73 +3089,6 @@ nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, #if (NXT_HAVE_CLONE_NEWUSER) -typedef struct { - nxt_int_t container; - nxt_int_t host; - nxt_int_t size; -} nxt_conf_vldt_clone_procmap_conf_t; - - -static nxt_conf_map_t nxt_conf_vldt_clone_procmap_conf_map[] = { - { - nxt_string("container"), - NXT_CONF_MAP_INT32, - offsetof(nxt_conf_vldt_clone_procmap_conf_t, container), - }, - - { - nxt_string("host"), - NXT_CONF_MAP_INT32, - offsetof(nxt_conf_vldt_clone_procmap_conf_t, host), - }, - - { - nxt_string("size"), - NXT_CONF_MAP_INT32, - offsetof(nxt_conf_vldt_clone_procmap_conf_t, size), - }, - -}; - - -static nxt_int_t -nxt_conf_vldt_clone_procmap(nxt_conf_validation_t *vldt, const char *mapfile, - nxt_conf_value_t *value) -{ - nxt_int_t ret; - nxt_conf_vldt_clone_procmap_conf_t procmap; - - procmap.container = -1; - procmap.host = -1; - procmap.size = -1; - - ret = nxt_conf_map_object(vldt->pool, value, - nxt_conf_vldt_clone_procmap_conf_map, - nxt_nitems(nxt_conf_vldt_clone_procmap_conf_map), - &procmap); - if (ret != NXT_OK) { - return ret; - } - - if (procmap.container == -1) { - return nxt_conf_vldt_error(vldt, "The %s requires the " - "\"container\" field set.", mapfile); - } - - if (procmap.host == -1) { - return nxt_conf_vldt_error(vldt, "The %s requires the " - "\"host\" field set.", mapfile); - } - - if (procmap.size == -1) { - return nxt_conf_vldt_error(vldt, "The %s requires the " - "\"size\" field set.", mapfile); - } - - return NXT_OK; -} - - static nxt_int_t nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value) { @@ -3174,7 +3105,7 @@ nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value) return ret; } - return nxt_conf_vldt_clone_procmap(vldt, "uid_map", value); + return NXT_OK; } @@ -3194,7 +3125,7 @@ nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value) return ret; } - return nxt_conf_vldt_clone_procmap(vldt, "gid_map", value); + return NXT_OK; } #endif -- cgit From ecd573924f5dc31e279f12249fb44e8d00e144a2 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 2 Feb 2024 23:29:48 +0100 Subject: Configuration: Add nxt_conf_get_string_dup() This function is like nxt_conf_get_string(), but creates a new copy, so that it can be modified without corrupting the configuration string. Reviewed-by: Andrew Clayton Cc: Zhidao Hong Signed-off-by: Alejandro Colomar --- src/nxt_conf.c | 11 +++++++++++ src/nxt_conf.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 664b5468..008cb968 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -3,6 +3,7 @@ * Copyright (C) Igor Sysoev * Copyright (C) Valentin V. Bartenev * Copyright (C) NGINX, Inc. + * Copyright 2024, Alejandro Colomar */ #include @@ -174,6 +175,16 @@ nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str) } +nxt_str_t * +nxt_conf_get_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str) +{ + nxt_str_t s; + + nxt_conf_get_string(value, &s); + return nxt_str_dup(mp, str, &s); +} + + void nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str) { diff --git a/src/nxt_conf.h b/src/nxt_conf.h index 1b13f5ae..626b6d4d 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -3,6 +3,7 @@ * Copyright (C) Igor Sysoev * Copyright (C) Valentin V. Bartenev * Copyright (C) NGINX, Inc. + * Copyright 2024, Alejandro Colomar */ #ifndef _NXT_CONF_INCLUDED_ @@ -116,6 +117,8 @@ void nxt_conf_json_position(u_char *start, const u_char *pos, nxt_uint_t *line, nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt); NXT_EXPORT void nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str); +NXT_EXPORT nxt_str_t *nxt_conf_get_string_dup(nxt_conf_value_t *value, + nxt_mp_t *mp, nxt_str_t *str); NXT_EXPORT void nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str); NXT_EXPORT nxt_int_t nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, const nxt_str_t *str); -- cgit From bb376c683877d2aec9ce4358536113ca5fd19d84 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 2 Feb 2024 23:43:13 +0100 Subject: Simplify, by calling nxt_conf_get_string_dup() Refactor. Reviewed-by: Andrew Clayton Cc: Zhidao Hong Signed-off-by: Alejandro Colomar --- src/nxt_http_static.c | 4 +--- src/nxt_router.c | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index c4caab3c..ee25015e 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -117,9 +117,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_str_set(&conf->index, "index.html"); } else { - nxt_conf_get_string(acf->index, &str); - - ret = nxt_str_dup(mp, &conf->index, &str); + ret = nxt_conf_get_string_dup(acf->index, mp, &conf->index); if (nxt_slow_path(ret == NULL)) { return NXT_ERROR; } diff --git a/src/nxt_router.c b/src/nxt_router.c index 0b979575..947836c8 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -2275,7 +2275,7 @@ nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, { uint32_t next, i; nxt_mp_t *mp; - nxt_str_t *type, exten, str; + nxt_str_t *type, exten, str, *s; nxt_int_t ret; nxt_uint_t exts; nxt_conf_value_t *mtypes_conf, *ext_conf, *value; @@ -2311,9 +2311,8 @@ nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, } if (nxt_conf_type(ext_conf) == NXT_CONF_STRING) { - nxt_conf_get_string(ext_conf, &str); - - if (nxt_slow_path(nxt_str_dup(mp, &exten, &str) == NULL)) { + s = nxt_conf_get_string_dup(ext_conf, mp, &exten); + if (nxt_slow_path(s == NULL)) { return NXT_ERROR; } @@ -2331,9 +2330,8 @@ nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, for (i = 0; i < exts; i++) { value = nxt_conf_get_array_element(ext_conf, i); - nxt_conf_get_string(value, &str); - - if (nxt_slow_path(nxt_str_dup(mp, &exten, &str) == NULL)) { + s = nxt_conf_get_string_dup(value, mp, &exten); + if (nxt_slow_path(s == NULL)) { return NXT_ERROR; } @@ -2425,14 +2423,11 @@ static nxt_int_t nxt_router_conf_forward_header(nxt_mp_t *mp, nxt_conf_value_t *conf, nxt_http_forward_header_t *fh) { - char c; - size_t i; - uint32_t hash; - nxt_str_t header; - - nxt_conf_get_string(conf, &header); + char c; + size_t i; + uint32_t hash; - fh->header = nxt_str_dup(mp, NULL, &header); + fh->header = nxt_conf_get_string_dup(conf, mp, NULL); if (nxt_slow_path(fh->header == NULL)) { return NXT_ERROR; } -- cgit From 46cef09f296d9a3d54b98331d25920fc6322bea8 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 31 Jan 2024 15:34:57 +0100 Subject: Configuration: Don't corrupt abstract socket names The commit that added support for Unix sockets accepts abstract sockets using '@' in the config, but we stored it internally using '\0'. We want to support abstract sockets transparently to the user, so that if the user configures unitd with '@', if we receive a query about the current configuration, the user should see the same exact thing that was configured. So, this commit avoids the transformation in the internal state file, storing user input pristine, and we only transform the '@' in temporary strings. This commit fixes another bug, where we try to connect to abstract sockets with a trailing '\0' in their name due to calling twice nxt_sockaddr_parse() on the same string. By calling that function only once with each copy of the string, we have fixed that bug. The following code was responsible for this bug, which the second time it was called, considered these sockets as file-backed (not abstract) Unix socket, and so appended a '\0' to the socket name. $ grepc -tfd nxt_sockaddr_unix_parse . | grep -A10 @ if (path[0] == '@') { path[0] = '\0'; socklen--; #if !(NXT_LINUX) nxt_thread_log_error(NXT_LOG_ERR, "abstract unix domain sockets are not supported"); return NULL; #endif } sa = nxt_sockaddr_alloc(mp, socklen, addr->length); This bug was found thanks to some experiment about using 'const' for some strings. And here's some history: - 9041d276fc6a ("nxt_sockaddr_parse() introducted.") This commit introduced support for abstract Unix sockets, but they only worked as "servers", and not as "listeners". We corrupted the JSON config file, and stored a \u0000. This also caused calling connect(2) with a bogus trailing null byte, which tried to connect to a different abstract socket. - d8e0768a5bae ("Fixed support for abstract Unix sockets.") This commit (partially) fixed support for abstract Unix sockets, so they they worked also as listeners. We still corrupted the JSON config file, and stored a \u0000. This caused calling connect(2) (and now bind(2) too) with a bogus trailing null byte. - e2aec6686a4d ("Storing abstract sockets with @ internally.") This commit fixed the problem by which we were corrupting the config file, but only for "listeners", not for "servers". (It also fixes the issue about the terminating '\0'.) We completely forgot about "servers", and other callers of the same function. To reproduce the problem, I used the following config: ```json { "listeners": { "*:80": { "pass": "routes/u" }, "unix:@abstract": { "pass": "routes/a" } }, "routes": { "u": [{ "action": { "pass": "upstreams/u" } }], "a": [{ "action": { "return": 302, "location": "/i/am/not/at/home/" } }] }, "upstreams": { "u": { "servers": { "unix:@abstract": {} } } } } ``` And then check the state file: $ sudo cat /opt/local/nginx/unit/master/var/lib/unit/conf.json \ | jq . \ | grep unix; "unix:@abstract": { "unix:\u0000abstract": {} After this patch, the state file has a '@' as expected: $ sudo cat /opt/local/nginx/unit/unix/var/lib/unit/conf.json \ | jq . \ | grep unix; "unix:@abstract": { "unix:@abstract": {} Regarding the trailing null byte, here are some tests: $ sudo strace -f -e 'bind,connect' /opt/local/nginx/unit/d8e0/sbin/unitd \ |& grep abstract; [pid 22406] bind(10, {sa_family=AF_UNIX, sun_path=@"abstract\0"}, 12) = 0 [pid 22410] connect(134, {sa_family=AF_UNIX, sun_path=@"abstract\0"}, 12) = 0 ^C $ sudo killall unitd $ sudo strace -f -e 'bind,connect' /opt/local/nginx/unit/master/sbin/unitd \ |& grep abstract; [pid 22449] bind(10, {sa_family=AF_UNIX, sun_path=@"abstract"}, 11) = 0 [pid 22453] connect(134, {sa_family=AF_UNIX, sun_path=@"abstract\0"}, 12) = -1 ECONNREFUSED (Connection refused) ^C $ sudo killall unitd $ sudo strace -f -e 'bind,connect' /opt/local/nginx/unit/unix/sbin/unitd \ |& grep abstract; [pid 22488] bind(10, {sa_family=AF_UNIX, sun_path=@"abstract"}, 11) = 0 [pid 22492] connect(134, {sa_family=AF_UNIX, sun_path=@"abstract"}, 11) = 0 ^C Fixes: 9041d276fc6a ("nxt_sockaddr_parse() introducted.") Fixes: d8e0768a5bae ("Fixed support for abstract Unix sockets.") Fixes: e2aec6686a4d ("Storing abstract sockets with @ internally.") Link: Reviewed-by: Andrew Clayton Cc: Liam Crilly Cc: Zhidao Hong Signed-off-by: Alejandro Colomar --- src/nxt_conf_validation.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index c843b265..bf18cd1a 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -2,6 +2,7 @@ /* * Copyright (C) Valentin V. Bartenev * Copyright (C) NGINX, Inc. + * Copyright 2024, Alejandro Colomar */ #include @@ -1936,10 +1937,13 @@ static nxt_int_t nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data) { - nxt_str_t name; + nxt_str_t name, *ret; nxt_sockaddr_t *sa; - nxt_conf_get_string(value, &name); + ret = nxt_conf_get_string_dup(value, vldt->pool, &name); + if (nxt_slow_path(ret == NULL)) { + return NXT_ERROR; + } if (nxt_str_start(&name, "http://", 7)) { name.length -= 7; @@ -2913,13 +2917,11 @@ nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt, for ( ;; ) { member = nxt_conf_next_object_member(value, &name, &index); - if (member == NULL) { return NXT_OK; } ret = validator(vldt, &name, member); - if (ret != NXT_OK) { return ret; } @@ -3268,16 +3270,19 @@ nxt_conf_vldt_server(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) { nxt_int_t ret; + nxt_str_t str; nxt_sockaddr_t *sa; ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_VLDT_OBJECT); - if (ret != NXT_OK) { return ret; } - sa = nxt_sockaddr_parse(vldt->pool, name); + if (nxt_slow_path(nxt_str_dup(vldt->pool, &str, name) == NULL)) { + return NXT_ERROR; + } + sa = nxt_sockaddr_parse(vldt->pool, &str); if (sa == NULL) { return nxt_conf_vldt_error(vldt, "The \"%V\" is not valid " "server address.", name); -- cgit From 9e986704480de0d6b74dafa5ebcf775eaa88333a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Thu, 8 Feb 2024 11:15:34 +0100 Subject: Configuration: Fix validation of "processes" It's an integer, not a floating number. Fixes: 68c6b67ffc84 ("Configuration: support for rational numbers.") Closes: https://github.com/nginx/unit/issues/1115 Link: Reviewed-by: Zhidao Hong Reviewed-by: Andrew Clayton Cc: Dan Callahan Cc: Valentin Bartenev Signed-off-by: Alejandro Colomar --- src/nxt_conf_validation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index bf18cd1a..caa068d2 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -2830,7 +2830,7 @@ nxt_conf_vldt_processes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, nxt_int_t ret; nxt_conf_vldt_processes_conf_t proc; - if (nxt_conf_type(value) == NXT_CONF_NUMBER) { + if (nxt_conf_type(value) == NXT_CONF_INTEGER) { int_value = nxt_conf_get_number(value); if (int_value < 1) { -- cgit From 3a2687bb714226ab13111cac2149afc660fa70e7 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Tue, 17 Oct 2023 16:22:44 -0700 Subject: Packages: added Ubuntu 23.10 "mantic" support. --- docs/changes.xml | 29 ++++++++- pkg/deb/Makefile | 17 ++++++ pkg/deb/Makefile.jsc21 | 71 ++++++++++++++++++++++ pkg/deb/Makefile.python312 | 46 ++++++++++++++ pkg/deb/debian.module/unit.example-jsc21-config | 15 +++++ .../debian.module/unit.example-python3.12-config | 16 +++++ 6 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 pkg/deb/Makefile.jsc21 create mode 100644 pkg/deb/Makefile.python312 create mode 100644 pkg/deb/debian.module/unit.example-jsc21-config create mode 100644 pkg/deb/debian.module/unit.example-python3.12-config diff --git a/docs/changes.xml b/docs/changes.xml index 50867856..428da0ba 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -5,16 +5,43 @@ + + + + +Initial release of Java 21 module for NGINX Unit. + + + + + + + + + + +Initial release of Python 3.12 module for NGINX Unit. + + + + + + Date: Fri, 20 Oct 2023 18:21:00 -0700 Subject: contrib: Bump libunit-wasm to 0.3.0. --- pkg/contrib/src/libunit-wasm/version | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/contrib/src/libunit-wasm/version b/pkg/contrib/src/libunit-wasm/version index 7ca15f98..60577d0e 100644 --- a/pkg/contrib/src/libunit-wasm/version +++ b/pkg/contrib/src/libunit-wasm/version @@ -1,2 +1,2 @@ -LIBUNIT_WASM_VERSION := 0.1.0 -LIBUNIT_WASM_GITHASH := d6ed6a219b31a58526721f96195c80061d41ce54 +LIBUNIT_WASM_VERSION := 0.3.0 +LIBUNIT_WASM_GITHASH := 01c43784ec53aa1ff22aca7e7ae6f18b4591b514 -- cgit From ca1bc0625a7c1c57f8f9fb9be66b29a96ac9d79d Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Wed, 25 Oct 2023 12:37:10 -0700 Subject: contrib: updated njs to 0.8.2. --- pkg/contrib/src/njs/SHA512SUMS | 2 +- pkg/contrib/src/njs/version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/contrib/src/njs/SHA512SUMS b/pkg/contrib/src/njs/SHA512SUMS index 3c3ce210..43766487 100644 --- a/pkg/contrib/src/njs/SHA512SUMS +++ b/pkg/contrib/src/njs/SHA512SUMS @@ -1 +1 @@ -5038b4cd9e18de89c9cf7fe7b25a0a8a03c51cfb20b6ee5085e68f885113b104092baf5ac8fe80e9d1611b2f75e47448753e6b327bef2e706ea46f2d6299f927 njs-0.8.1.tar.gz +cc3110a0c6866dfc03d19c58745e5b75aa9792999db45bc55a752f7b04db8ae51322bfe0156b873109c8477c6c1a030c851c770697cf6791c6e89fb2fed0a2c5 njs-0.8.2.tar.gz diff --git a/pkg/contrib/src/njs/version b/pkg/contrib/src/njs/version index 73c524fb..00453419 100644 --- a/pkg/contrib/src/njs/version +++ b/pkg/contrib/src/njs/version @@ -1 +1 @@ -NJS_VERSION := 0.8.1 +NJS_VERSION := 0.8.2 -- cgit From bad2c181e124cc93cd839fce019bc31dab1b7e1b Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Fri, 17 Nov 2023 16:29:18 -0800 Subject: Packages: Added Fedora 39 support. --- pkg/rpm/Makefile | 16 ++++++- pkg/rpm/Makefile.jsc-common | 5 +- pkg/rpm/Makefile.jsc17 | 13 ++++++ pkg/rpm/Makefile.python312 | 53 ++++++++++++++++++++++ .../rpmbuild/SOURCES/unit.example-python312-config | 16 +++++++ 5 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 pkg/rpm/Makefile.python312 create mode 100644 pkg/rpm/rpmbuild/SOURCES/unit.example-python312-config diff --git a/pkg/rpm/Makefile b/pkg/rpm/Makefile index 7906fc24..1f3bbd58 100644 --- a/pkg/rpm/Makefile +++ b/pkg/rpm/Makefile @@ -22,8 +22,10 @@ else ifeq ($(shell rpm --eval "%{?amzn}"), 2023) OSVER = amazonlinux2023 else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 35 -a 0%{?fedora} -le 36'`; echo $$?),0) OSVER = fedora -else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 37'`; echo $$?),0) +else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 37 -a 0%{?fedora} -le 38'`; echo $$?),0) OSVER = fedora37 +else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 39'`; echo $$?),0) +OSVER = fedora39 endif BUILD_DEPENDS_unit = gcc rpm-build rpmlint @@ -124,6 +126,18 @@ include Makefile.jsc11 include Makefile.wasm endif +ifeq ($(OSVER), fedora39) +include Makefile.php +include Makefile.python312 +include Makefile.go +include Makefile.perl +include Makefile.ruby +include Makefile.jsc-common +include Makefile.jsc17 +include Makefile.wasm +endif + + CONFIGURE_ARGS_COMMON=\ --prefix=/usr \ --statedir=%{_sharedstatedir}/unit \ diff --git a/pkg/rpm/Makefile.jsc-common b/pkg/rpm/Makefile.jsc-common index a3c3a3da..f77ca1e9 100644 --- a/pkg/rpm/Makefile.jsc-common +++ b/pkg/rpm/Makefile.jsc-common @@ -10,16 +10,19 @@ JAVA_ARCH_jsc_common= $(shell /usr/lib/jvm/java-1.8.0/bin/java -XshowSettings 2> ifeq ($(OSVER),amazonlinux2023) MODULE_CONFARGS_jsc_common= java --home=/usr/lib/jvm/java-17-amazon-corretto --lib-path=/usr/lib/jvm/java-17-amazon-corretto/lib --jars=/usr/share/unit-jsc-common/ +else ifeq ($(OSVER),fedora39) +MODULE_CONFARGS_jsc_common= java --home=/usr/lib/jvm/java-17-openjdk --lib-path=/usr/lib/jvm/java-17-openjdk/lib --jars=/usr/share/unit-jsc-common/ else MODULE_CONFARGS_jsc_common= java --home=/usr/lib/jvm/java-1.8.0 --lib-path=/usr/lib/jvm/jre-1.8.0/lib/$(JAVA_ARCH_jsc_common) --jars=/usr/share/unit-jsc-common/ endif -MODULE_MAKEARGS_jsc_common= java MODULE_INSTARGS_jsc_common= java-shared-install MODULE_SOURCES_jsc_common= COPYRIGHT.unit-jsc-common ifeq ($(OSVER),amazonlinux2023) BUILD_DEPENDS_jsc_common= java-17-amazon-corretto-devel curl +else ifeq ($(OSVER),fedora39) +BUILD_DEPENDS_jsc_common= java-17-openjdk-devel curl else BUILD_DEPENDS_jsc_common= java-1.8.0-openjdk-devel curl endif diff --git a/pkg/rpm/Makefile.jsc17 b/pkg/rpm/Makefile.jsc17 index 7efdafaa..9a42c5a1 100644 --- a/pkg/rpm/Makefile.jsc17 +++ b/pkg/rpm/Makefile.jsc17 @@ -6,19 +6,32 @@ MODULE_SUMMARY_jsc17= Java 17 module for NGINX Unit MODULE_VERSION_jsc17= $(VERSION) MODULE_RELEASE_jsc17= 1 +ifeq ($(OSVER),amazonlinux2023) MODULE_CONFARGS_jsc17= java --module=java17 --home=/usr/lib/jvm/java-17-amazon-corretto --lib-path=/usr/lib/jvm/java-17-amazon-corretto/lib --jars=/usr/share/unit-jsc-common/ +else ifeq ($(OSVER),fedora39) +MODULE_CONFARGS_jsc17= java --module=java17 --home=/usr/lib/jvm/java-17-openjdk --lib-path=/usr/lib/jvm/java-17-openjdk/lib --jars=/usr/share/unit-jsc-common/ +endif MODULE_MAKEARGS_jsc17= java17 MODULE_INSTARGS_jsc17= java17-install MODULE_SOURCES_jsc17= unit.example-jsc-app \ unit.example-jsc17-config +ifeq ($(OSVER),amazonlinux2023) BUILD_DEPENDS_jsc17= java-17-amazon-corretto-devel +else ifeq ($(OSVER),fedora39) +BUILD_DEPENDS_jsc17= java-17-openjdk-devel BUILD_DEPENDS+= $(BUILD_DEPENDS_jsc17) +endif define MODULE_DEFINITIONS_jsc17 Requires: unit-jsc-common == $(MODULE_VERSION_jsc_common)-$(MODULE_RELEASE_jsc_common)%{?dist}.ngx +%if (0%{?amzn} == 2023) Requires: java-17-amazon-corretto-headless +%endif +%if (0%{?fedora} >= 39) +Requires: java-17-openjdk-headless +%endif endef export MODULE_DEFINITIONS_jsc17 diff --git a/pkg/rpm/Makefile.python312 b/pkg/rpm/Makefile.python312 new file mode 100644 index 00000000..c37069eb --- /dev/null +++ b/pkg/rpm/Makefile.python312 @@ -0,0 +1,53 @@ +MODULES+= python312 +MODULE_SUFFIX_python312= python3.12 + +MODULE_SUMMARY_python312= Python 3.12 module for NGINX Unit + +MODULE_VERSION_python312= $(VERSION) +MODULE_RELEASE_python312= 1 + +MODULE_CONFARGS_python312= python --config=python3.12-config +MODULE_MAKEARGS_python312= python3.12 +MODULE_INSTARGS_python312= python3.12-install + +MODULE_SOURCES_python312= unit.example-python-app \ + unit.example-python312-config + +BUILD_DEPENDS_python312= python3-devel + +BUILD_DEPENDS+= $(BUILD_DEPENDS_python312) + +define MODULE_PREINSTALL_python312 +%{__mkdir} -p %{buildroot}%{_datadir}/doc/unit-python312/examples/python-app +%{__install} -m 644 -p %{SOURCE100} \ + %{buildroot}%{_datadir}/doc/unit-python312/examples/python-app/wsgi.py +%{__install} -m 644 -p %{SOURCE101} \ + %{buildroot}%{_datadir}/doc/unit-python312/examples/unit.config +endef +export MODULE_PREINSTALL_python312 + +define MODULE_FILES_python312 +%{_libdir}/unit/modules/* +%{_libdir}/unit/debug-modules/* +endef +export MODULE_FILES_python312 + +define MODULE_POST_python312 +cat < Date: Mon, 8 Jan 2024 16:15:15 +0100 Subject: Docker: added python3.12 to versions --- pkg/docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 237228a9..4a81f270 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -59,7 +59,7 @@ INSTALL_php ?= php-install RUN_php ?= ldconfig MODULE_PREBUILD_php ?= /bin/true -VERSIONS_python ?= 3.11 +VERSIONS_python ?= 3.11 3.12 VARIANT_python ?= $(VARIANT) $(foreach pythonversion, $(VERSIONS_python), $(eval CONTAINER_python$(pythonversion) = python:$(pythonversion)-$(VARIANT_python))) CONFIGURE_python ?= python --config=/usr/local/bin/python3-config -- cgit From 2b0d93d1a73703ca4c3f1892cfd922b1d2107fb4 Mon Sep 17 00:00:00 2001 From: tclesius Date: Mon, 8 Jan 2024 16:16:21 +0100 Subject: Docker: Generated Dockerfile for Unit 1.31.1. --- pkg/docker/Dockerfile.python3.12 | 89 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 pkg/docker/Dockerfile.python3.12 diff --git a/pkg/docker/Dockerfile.python3.12 b/pkg/docker/Dockerfile.python3.12 new file mode 100644 index 00000000..ad98519c --- /dev/null +++ b/pkg/docker/Dockerfile.python3.12 @@ -0,0 +1,89 @@ +FROM python:3.12-bullseye + +LABEL org.opencontainers.image.title="Unit (python3.12)" +LABEL org.opencontainers.image.description="Official build of Unit for Docker." +LABEL org.opencontainers.image.url="https://unit.nginx.org" +LABEL org.opencontainers.image.source="https://github.com/nginx/unit" +LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" +LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " +LABEL org.opencontainers.image.version="1.31.1" + +RUN set -ex \ + && savedAptMark="$(apt-mark showmanual)" \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && mkdir -p /usr/src/unit \ + && cd /usr/src/unit \ + && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && cd unit \ + && 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_MODULES="--prefix=/usr \ + --statedir=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --runstatedir=/var/run \ + --pid=/var/run/unit.pid \ + --logdir=/var/log \ + --log=/var/log/unit.log \ + --tmpdir=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ + --njs" \ + && make -j $NCPU -C pkg/contrib .njs \ + && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd \ + && make clean \ + && /bin/true \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && ./configure python --config=/usr/local/bin/python3-config \ + && make -j $NCPU python3-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ + && ./configure python --config=/usr/local/bin/python3-config \ + && make -j $NCPU python3-install \ + && cd \ + && rm -rf /usr/src/unit \ + && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ + ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ + done \ + && apt-mark showmanual | xargs apt-mark auto > /dev/null \ + && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ + && /bin/true \ + && mkdir -p /var/lib/unit/ \ + && mkdir -p /docker-entrypoint.d/ \ + && groupadd --gid 999 unit \ + && useradd \ + --uid 999 \ + --gid unit \ + --no-create-home \ + --home /nonexistent \ + --comment "unit user" \ + --shell /bin/false \ + unit \ + && apt-get update \ + && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get purge -y --auto-remove build-essential \ + && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stdout /var/log/unit.log + +COPY docker-entrypoint.sh /usr/local/bin/ +COPY welcome.* /usr/share/unit/welcome/ + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +EXPOSE 80 +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] -- cgit From fbeb2065b180e2376088387ee150d3975dc08cd5 Mon Sep 17 00:00:00 2001 From: Gabor Javorszky Date: Wed, 14 Feb 2024 18:16:01 +0000 Subject: fix: Take options as well as requestListener (#1091) * Take options as well as requestListener Unit-http have not kept up with the signature of nodejs's http package development. Nodejs allows an optional `options` object to be passed to the `createServer` function, we didn't. This resulted in function signature errors when user code that did make use of the options arg tried to call unit's replaced function. This change changes the signature to be more in line with how nodejs does it discarding it and printing a message to stdout. * Add test file to start node application with options * Add changes to docs/changes.xml Closes: https://github.com/nginx/unit/issues/1043 --- docs/changes.xml | 6 ++++++ src/nodejs/unit-http/http.js | 4 ++-- src/nodejs/unit-http/http_server.js | 10 +++++++++- test/node/options/app.js | 4 ++++ test/test_node_application.py | 6 ++++++ 5 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 test/node/options/app.js diff --git a/docs/changes.xml b/docs/changes.xml index 428da0ba..a3549697 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -53,6 +53,12 @@ NGINX Unit updated to 1.32.0. + + +http.createServer() now accepts "options" argument introduced in Node.js v9.6.0, v8.12.0. + + + conditional access logging. diff --git a/src/nodejs/unit-http/http.js b/src/nodejs/unit-http/http.js index d298a35f..60b8004f 100644 --- a/src/nodejs/unit-http/http.js +++ b/src/nodejs/unit-http/http.js @@ -11,8 +11,8 @@ const { ServerResponse, } = require('./http_server'); -function createServer (requestHandler) { - return new Server(requestHandler); +function createServer (options, requestHandler) { + return new Server(options, requestHandler); } const http = require("http") diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js index 8eb13d7f..b78f309a 100644 --- a/src/nodejs/unit-http/http_server.js +++ b/src/nodejs/unit-http/http_server.js @@ -5,6 +5,7 @@ 'use strict'; +const { stderr } = require('process'); const EventEmitter = require('events'); const http = require('http'); const util = require('util'); @@ -413,7 +414,14 @@ ServerRequest.prototype._read = function _read(n) { }; -function Server(requestListener) { +function Server(options, requestListener) { + if (typeof options === 'function') { + requestListener = options; + options = {}; + } else { + stderr.write("http.Server constructor was called with unsupported options, using default settings\n"); + } + EventEmitter.call(this); this.unit = new unit_lib.Unit(); diff --git a/test/node/options/app.js b/test/node/options/app.js new file mode 100644 index 00000000..bc538080 --- /dev/null +++ b/test/node/options/app.js @@ -0,0 +1,4 @@ +require('http').createServer({}, function (req, res) { + res.writeHead(200, {'Content-Length': 12, 'Content-Type': 'text/plain'}) + .end('Hello World\n'); +}).listen(8080); diff --git a/test/test_node_application.py b/test/test_node_application.py index cb775210..88ae3136 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -21,6 +21,12 @@ def test_node_application_basic(): assert_basic_application() +def test_node_application_options(wait_for_record): + client.load('options') + + assert_basic_application() + assert wait_for_record(r'constructor was called with unsupported') is not None + def test_node_application_loader_unit_http(): client.load('loader/unit_http') -- cgit From c3af21e970ca3c822004cfda7c5b56ec07d99da9 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 15 Feb 2024 21:43:58 -0800 Subject: Docker: Switch to github --- pkg/docker/Dockerfile.go1.20 | 4 ++-- pkg/docker/Dockerfile.go1.21 | 4 ++-- pkg/docker/Dockerfile.jsc11 | 4 ++-- pkg/docker/Dockerfile.minimal | 4 ++-- pkg/docker/Dockerfile.node18 | 4 ++-- pkg/docker/Dockerfile.node20 | 4 ++-- pkg/docker/Dockerfile.perl5.36 | 4 ++-- pkg/docker/Dockerfile.perl5.38 | 4 ++-- pkg/docker/Dockerfile.php8.2 | 4 ++-- pkg/docker/Dockerfile.python3.11 | 4 ++-- pkg/docker/Dockerfile.ruby3.2 | 4 ++-- pkg/docker/Dockerfile.wasm | 4 ++-- pkg/docker/template.Dockerfile | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/pkg/docker/Dockerfile.go1.20 b/pkg/docker/Dockerfile.go1.20 index 53379dd1..fcb449a7 100644 --- a/pkg/docker/Dockerfile.go1.20 +++ b/pkg/docker/Dockerfile.go1.20 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.go1.21 b/pkg/docker/Dockerfile.go1.21 index a90dc115..5aff94b6 100644 --- a/pkg/docker/Dockerfile.go1.21 +++ b/pkg/docker/Dockerfile.go1.21 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index 2844c813..33a40a47 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 4b585480..2ff15d7b 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.node18 b/pkg/docker/Dockerfile.node18 index 4ac18847..29eebdcf 100644 --- a/pkg/docker/Dockerfile.node18 +++ b/pkg/docker/Dockerfile.node18 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.node20 b/pkg/docker/Dockerfile.node20 index f783ba72..05a7bfab 100644 --- a/pkg/docker/Dockerfile.node20 +++ b/pkg/docker/Dockerfile.node20 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.perl5.36 b/pkg/docker/Dockerfile.perl5.36 index 8cc5d9e2..31be2388 100644 --- a/pkg/docker/Dockerfile.perl5.36 +++ b/pkg/docker/Dockerfile.perl5.36 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.perl5.38 b/pkg/docker/Dockerfile.perl5.38 index 531188fe..0097d638 100644 --- a/pkg/docker/Dockerfile.perl5.38 +++ b/pkg/docker/Dockerfile.perl5.38 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.php8.2 b/pkg/docker/Dockerfile.php8.2 index 5783bf6c..da0487e7 100644 --- a/pkg/docker/Dockerfile.php8.2 +++ b/pkg/docker/Dockerfile.php8.2 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.python3.11 b/pkg/docker/Dockerfile.python3.11 index b5e81b6c..b298b873 100644 --- a/pkg/docker/Dockerfile.python3.11 +++ b/pkg/docker/Dockerfile.python3.11 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.ruby3.2 b/pkg/docker/Dockerfile.ruby3.2 index c417a327..29c27116 100644 --- a/pkg/docker/Dockerfile.ruby3.2 +++ b/pkg/docker/Dockerfile.ruby3.2 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.wasm b/pkg/docker/Dockerfile.wasm index e45f020f..cf92d707 100644 --- a/pkg/docker/Dockerfile.wasm +++ b/pkg/docker/Dockerfile.wasm @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/template.Dockerfile b/pkg/docker/template.Dockerfile index 4d5cc101..f5efc3c8 100644 --- a/pkg/docker/template.Dockerfile +++ b/pkg/docker/template.Dockerfile @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="@@VERSION@@" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u @@VERSION@@-@@PATCHLEVEL@@ https://hg.nginx.org/unit \ + && git clone -b @@VERSION@@-@@PATCHLEVEL@@ https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ -- cgit From baff936be1b8bb9627deaef2af58d9aa398b7ca2 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 15 Feb 2024 22:12:03 -0800 Subject: Packages: Move dist target to git archive --- .gitattributes | 5 +++++ pkg/Makefile | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.gitattributes b/.gitattributes index 45ec5156..16af3a06 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,7 @@ *.c diff=cpp *.h diff=cpp + +.hg* export-ignore +pkg/** export-ignore +docs/*.* export-ignore +docs/Makefile export-ignore diff --git a/pkg/Makefile b/pkg/Makefile index c252969b..ad12efb7 100644 --- a/pkg/Makefile +++ b/pkg/Makefile @@ -11,10 +11,11 @@ default: dist: rm -f unit-$(VERSION).tar.gz - hg archive unit-$(VERSION).tar.gz \ - -r $(VERSION) \ - -p unit-$(VERSION) \ - -X "../.hg*" -X "../pkg/" -X "../docs/*.*" -X "../docs/Makefile" + cd .. && git archive \ + --output pkg/unit-$(VERSION).tar.gz \ + --prefix unit-$(VERSION)/ \ + --worktree-attributes \ + $(VERSION) ./ $(SHA512SUM) unit-$(VERSION).tar.gz > unit-$(VERSION).tar.gz.sha512 rpm: -- cgit From 34b3a812b110e8fba0669fc843aebffddf89ab17 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 6 Nov 2023 18:43:19 +0000 Subject: Add nxt_file_chown() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This wraps chown(2) but takes the user/owner and group as strings. It's a little long winded as it uses the thread safe versions of getpwnam()/getgrname() which require a little more work. This function will be used by the following commit that allows to set the permissions of the Unix domain control socket. We need to cast uid & gid to long in the call to nxt_thread_log_alert() to appease clang-ast as it's adamant that uid/gid are unsigned ints, but chown(2) takes -1 for these values to indicate don't change this item, and it'd be nice to show them in the error message. Note that getpwnam()/getgrname() don't define "not found" as an error as per their man page The formulation given above under "RETURN VALUE" is from POSIX.1-2001. It does not call "not found" an error, and hence does not specify what value errno might have in this situation. But that makes it impossible to recognize errors. One might argue that according to POSIX errno should be left unchanged if an entry is not found. Experiments on var‐ ious UNIX-like systems show that lots of different values occur in this situation: 0, ENOENT, EBADF, ESRCH, EWOULDBLOCK, EPERM, and probably others. Thus if we log an error from these functions we can end up with the slightly humorous error message 2024/02/12 15:15:12 [alert] 99404#99404 getpwnam_r("noddy", ...) failed (0: Success) (User not found) while creating listening socket on unix:/opt/unit/control.unit.sock Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_file.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nxt_file.h | 2 ++ 2 files changed, 84 insertions(+) diff --git a/src/nxt_file.c b/src/nxt_file.c index 6f1a93e4..4047d9d7 100644 --- a/src/nxt_file.c +++ b/src/nxt_file.c @@ -325,6 +325,88 @@ nxt_file_set_access(nxt_file_name_t *name, nxt_file_access_t access) } +nxt_int_t +nxt_file_chown(nxt_file_name_t *name, const char *owner, const char *group) +{ + int err; + char *buf; + long bufsize; + gid_t gid = ~0; + uid_t uid = ~0; + + if (owner == NULL && group == NULL) { + return NXT_OK; + } + + if (owner != NULL) { + struct passwd pwd, *result; + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) { + bufsize = 32768; + } + + buf = nxt_malloc(bufsize); + if (buf == NULL) { + return NXT_ERROR; + } + + err = getpwnam_r(owner, &pwd, buf, bufsize, &result); + if (result == NULL) { + nxt_thread_log_alert("getpwnam_r(\"%s\", ...) failed %E %s", + owner, nxt_errno, + err == 0 ? "(User not found)" : ""); + goto out_err_free; + } + + uid = pwd.pw_uid; + + nxt_free(buf); + } + + if (group != NULL) { + struct group grp, *result; + + bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); + if (bufsize == -1) { + bufsize = 32768; + } + + buf = nxt_malloc(bufsize); + if (buf == NULL) { + return NXT_ERROR; + } + + err = getgrnam_r(group, &grp, buf, bufsize, &result); + if (result == NULL) { + nxt_thread_log_alert("getgrnam_r(\"%s\", ...) failed %E %s", + group, nxt_errno, + err == 0 ? "(Group not found)" : ""); + goto out_err_free; + } + + gid = grp.gr_gid; + + nxt_free(buf); + } + + if (nxt_fast_path(chown((const char *) name, uid, gid) == 0)) { + return NXT_OK; + } + + nxt_thread_log_alert("chown(\"%FN\", %l, %l) failed %E", name, + owner != NULL ? (long) uid : -1, + group != NULL ? (long) gid : -1, nxt_errno); + + return NXT_ERROR; + +out_err_free: + nxt_free(buf); + + return NXT_ERROR; +} + + nxt_int_t nxt_file_rename(nxt_file_name_t *old_name, nxt_file_name_t *new_name) { diff --git a/src/nxt_file.h b/src/nxt_file.h index 97636db6..0c03a5f9 100644 --- a/src/nxt_file.h +++ b/src/nxt_file.h @@ -177,6 +177,8 @@ NXT_EXPORT nxt_int_t nxt_file_info(nxt_file_t *file, nxt_file_info_t *fi); NXT_EXPORT nxt_int_t nxt_file_delete(nxt_file_name_t *name); NXT_EXPORT nxt_int_t nxt_file_set_access(nxt_file_name_t *name, nxt_file_access_t access); +NXT_EXPORT nxt_int_t nxt_file_chown(nxt_file_name_t *name, const char *owner, + const char *group); NXT_EXPORT nxt_int_t nxt_file_rename(nxt_file_name_t *old_name, nxt_file_name_t *new_name); -- cgit From b500c36d2e808e123f11a243724f8fdeecd53f86 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 6 Nov 2023 18:48:51 +0000 Subject: Allow to set the permissions of the Unix domain control socket Several users in GitHub have asked for the ability to set the permissions of the unitd UNIX Domain control socket. This can of course be done externally, but can be done much cleaner by Unit itself. This commit adds three new options --control-mode Set the mode of the socket, e.g 644 --control-user Set the user/owner of the socket, e.g unit --control-group Set the group of the socket, e.g unit Of course these only have an affect when using a UNIX Domain Socket for the control socket. Requested-by: michaelkosir Requested-by: chopanovv Link: Link: Closes: https://github.com/nginx/unit/issues/840 Tested-by: Liam Crilly Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_listen_socket.c | 14 +++++++++++-- src/nxt_runtime.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ src/nxt_runtime.h | 6 +++++- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index d477eef1..047c1ef9 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -127,13 +127,23 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, #if (NXT_HAVE_UNIX_DOMAIN) if (family == AF_UNIX) { - name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; + const char *user; + const char *group; + nxt_runtime_t *rt = thr->runtime; - access = (S_IRUSR | S_IWUSR); + name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; + access = rt->control_mode > 0 ? rt->control_mode : S_IRUSR | S_IWUSR; if (nxt_file_set_access(name, access) != NXT_OK) { goto listen_fail; } + + user = rt->control_user; + group = rt->control_group; + + if (nxt_file_chown(name, user, group) != NXT_OK) { + goto listen_fail; + } } #endif diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index 9bfabc75..0e7f879e 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -956,6 +956,12 @@ nxt_runtime_conf_read_cmd(nxt_task_t *task, nxt_runtime_t *rt) static const char no_control[] = "option \"--control\" requires socket address\n"; + static const char no_control_mode[] = + "option \"--control-mode\" requires a mode\n"; + static const char no_control_user[] = + "option \"--control-user\" requires a username\n"; + static const char no_control_group[] = + "option \"--control-group\" requires a group name\n"; static const char no_user[] = "option \"--user\" requires username\n"; static const char no_group[] = "option \"--group\" requires group name\n"; static const char no_pid[] = "option \"--pid\" requires filename\n"; @@ -984,6 +990,13 @@ nxt_runtime_conf_read_cmd(nxt_task_t *task, nxt_runtime_t *rt) " --control ADDRESS set address of control API socket\n" " default: \"" NXT_CONTROL_SOCK "\"\n" "\n" + " --control-mode MODE set mode of the control API socket\n" + " default: 0600\n" + "\n" + " --control-user USER set the owner of the control API socket\n" + "\n" + " --control-group GROUP set the group of the control API socket\n" + "\n" " --pid FILE set pid filename\n" " default: \"" NXT_PID "\"\n" "\n" @@ -1032,6 +1045,48 @@ nxt_runtime_conf_read_cmd(nxt_task_t *task, nxt_runtime_t *rt) continue; } + if (nxt_strcmp(p, "--control-mode") == 0) { + if (*argv == NULL) { + write(STDERR_FILENO, no_control_mode, + nxt_length(no_control_mode)); + return NXT_ERROR; + } + + p = *argv++; + + rt->control_mode = strtoul(p, NULL, 8); + + continue; + } + + if (nxt_strcmp(p, "--control-user") == 0) { + if (*argv == NULL) { + write(STDERR_FILENO, no_control_user, + nxt_length(no_control_user)); + return NXT_ERROR; + } + + p = *argv++; + + rt->control_user = p; + + continue; + } + + if (nxt_strcmp(p, "--control-group") == 0) { + if (*argv == NULL) { + write(STDERR_FILENO, no_control_group, + nxt_length(no_control_group)); + return NXT_ERROR; + } + + p = *argv++; + + rt->control_group = p; + + continue; + } + if (nxt_strcmp(p, "--user") == 0) { if (*argv == NULL) { write(STDERR_FILENO, no_user, nxt_length(no_user)); diff --git a/src/nxt_runtime.h b/src/nxt_runtime.h index 66ec0106..7bd490d7 100644 --- a/src/nxt_runtime.h +++ b/src/nxt_runtime.h @@ -70,8 +70,12 @@ struct nxt_runtime_s { const char *ver_tmp; const char *conf; const char *conf_tmp; - const char *control; const char *tmp; + const char *control; + + mode_t control_mode; + const char *control_user; + const char *control_group; nxt_str_t certs; nxt_str_t scripts; -- cgit From 2bd3b41876151488b123ea8f5fe6195b97bdd9ce Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 6 Nov 2023 22:14:08 +0000 Subject: Docs: Update man page for new --control-* options Signed-off-by: Andrew Clayton --- docs/man/man8/unitd.8.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/man/man8/unitd.8.in b/docs/man/man8/unitd.8.in index 1c2093da..01bb4218 100644 --- a/docs/man/man8/unitd.8.in +++ b/docs/man/man8/unitd.8.in @@ -24,6 +24,9 @@ .Nm .Op Fl Fl no-daemon .Op Fl Fl control Ar socket +.Op Fl Fl control-mode Ar mode +.Op Fl Fl control-user Ar user +.Op Fl Fl control-group Ar group .Op Fl Fl group Ar name .Op Fl Fl user Ar name .Op Fl Fl log Ar file @@ -53,6 +56,12 @@ Runs Unit in non-daemon mode. .It Fl Fl control Ar socket Overrides the control API's socket address in IPv4, IPv6, or UNIX-domain format. +.It Fl Fl control-mode Ar mode +Sets the permission of the UNIX-domain control socket. +.It Fl Fl control-user Ar user +Sets the owner of the UNIX-domain control socket. +.It Fl Fl control-group Ar group +Sets the group of the UNIX-domain control socket. .It Fl Fl group Ar name , Fl Fl user Ar name Override group name and user name used to run Unit's non-privileged processes. .It Fl Fl log Ar file -- cgit From 1dca86028a1306655f513512f353a38e10b75d85 Mon Sep 17 00:00:00 2001 From: Liam Crilly Date: Wed, 8 Nov 2023 09:33:38 +0000 Subject: Tools: disambiguate unitc control socket detection Now that unitd has multiple --control* startup options, locating the address of the control socket requires additional precision. Signed-off-by: Liam Crilly Acked-by: Andrew Clayton Signed-off-by: Andrew Clayton --- tools/unitc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/unitc b/tools/unitc index 22417266..9b3557c5 100755 --- a/tools/unitc +++ b/tools/unitc @@ -186,9 +186,9 @@ if [ $REMOTE -eq 0 ]; then echo "${0##*/}: WARNING: unable to identify unitd command line parameters for PID $PID, assuming unitd defaults from \$PATH" PARAMS=unitd fi - CTRL_ADDR=$(echo "$PARAMS" | grep '\--control' | cut -f2 -d' ') + CTRL_ADDR=$(echo "$PARAMS" | grep '\--control ' | cut -f2 -d' ') if [ "$CTRL_ADDR" = "" ]; then - CTRL_ADDR=$($(echo "$PARAMS") --help | grep -A1 '\--control' | tail -1 | cut -f2 -d\") + CTRL_ADDR=$($(echo "$PARAMS") --help | grep -A1 '\--control ADDRESS' | tail -1 | cut -f2 -d\") fi if [ "$CTRL_ADDR" = "" ]; then echo "${0##*/}: ERROR: cannot detect control socket. Did you start unitd with a relative path? Try starting unitd with --control option." -- cgit From 756feafd541160e97edfb6faf13e9942271629ce Mon Sep 17 00:00:00 2001 From: Dan Callahan Date: Mon, 19 Feb 2024 12:22:05 +0000 Subject: Node.js: Use console.warn instead of stderr.write Functionally identical, but marginally more idiomatic. Refines: fbeb2065b180e2376088387ee150d3975dc08cd5 --- src/nodejs/unit-http/http_server.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js index b78f309a..4e1c190e 100644 --- a/src/nodejs/unit-http/http_server.js +++ b/src/nodejs/unit-http/http_server.js @@ -5,7 +5,6 @@ 'use strict'; -const { stderr } = require('process'); const EventEmitter = require('events'); const http = require('http'); const util = require('util'); @@ -419,7 +418,7 @@ function Server(options, requestListener) { requestListener = options; options = {}; } else { - stderr.write("http.Server constructor was called with unsupported options, using default settings\n"); + console.warn("http.Server constructor was called with unsupported options, using default settings"); } EventEmitter.call(this); -- cgit From ea239635beac396fb859d822474af76a7014c70d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 19 Feb 2024 14:41:28 +0000 Subject: Docker: Switch python3.12 to using github Forgotten in --- pkg/docker/Dockerfile.python3.12 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/docker/Dockerfile.python3.12 b/pkg/docker/Dockerfile.python3.12 index ad98519c..0fc64911 100644 --- a/pkg/docker/Dockerfile.python3.12 +++ b/pkg/docker/Dockerfile.python3.12 @@ -11,11 +11,11 @@ LABEL org.opencontainers.image.version="1.31.1" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && hg clone -u 1.31.1-1 https://hg.nginx.org/unit \ + && git clone -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ -- cgit From 0c98353091e6c95f6a70a461d0146b7872a8f14d Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 7 Nov 2023 19:38:28 +0000 Subject: Node.js: Build/install fix A user on GitHub reported an issue when trying to build/install the nodejs language module. Doing a $ ./configure nodejs --node=/usr/bin/node --npm=/usr/bin/npm --node-gyp=/usr/bin/node-gyp $ make install was throwing the following error mv build/src//usr/bin/node/unit-http-g/unit-http-1.31.1.tgz build//usr/bin/node-unit-http-g.tar.gz mv: cannot move 'build/src//usr/bin/node/unit-http-g/unit-http-1.31.1.tgz' to 'build//usr/bin/node-unit-http-g.tar.gz': No such file or directory make: *** [build/Makefile:2061: build//usr/bin/node-unit-http-g.tar.gz] Error 1 The fact that we're using the path given by --node= to then use as directory locations seems erroneous. But rather than risk breaking existing expectations the simple fix is to just use build/src in the destination path above to match that of the source. These paths were added in some previous commits, and the missing 'src/' component looks like an oversight. After this commit both the following work $ ./configure nodejs --node-gyp=/usr/lib/node_modules/bin/node-gyp-bin/node-gyp --local=/opt/unit/node $ ./configure nodejs --node=/usr/bin/node --node-gyp=/usr/lib/node_modules/npm/bin/node-gyp-bin/node-gyp --local=/opt/unit/node Reported-by: ruspaul013 Tested-by: ruspaul013 Fixes: 0ee8de554 ("Fixed Makefile target for NodeJS.") Fixes: c84948386 ("Node.js: fixing module global installation.") Reviewed-by: Timo Stark Signed-off-by: Andrew Clayton --- auto/modules/nodejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auto/modules/nodejs b/auto/modules/nodejs index 968f3fdf..472fb3be 100644 --- a/auto/modules/nodejs +++ b/auto/modules/nodejs @@ -123,8 +123,8 @@ fi NXT_NODE_TMP=${NXT_BUILD_DIR}/src/${NXT_NODE}/unit-http NXT_NODE_TMP_G=${NXT_BUILD_DIR}/src/${NXT_NODE}/unit-http-g -NXT_NODE_TARBALL=${NXT_BUILD_DIR}/${NXT_NODE}-unit-http.tar.gz -NXT_NODE_TARBALL_G=${NXT_BUILD_DIR}/${NXT_NODE}-unit-http-g.tar.gz +NXT_NODE_TARBALL=${NXT_BUILD_DIR}/src/${NXT_NODE}-unit-http.tar.gz +NXT_NODE_TARBALL_G=${NXT_BUILD_DIR}/src/${NXT_NODE}-unit-http-g.tar.gz NXT_NODE_VERSION_FILE=${NXT_BUILD_DIR}/src/${NXT_NODE}/version.h NXT_NODE_PACKAGE_FILE=${NXT_BUILD_DIR}/src/${NXT_NODE}/package.json NXT_NODE_EXPORTS="export UNIT_SRC_PATH=${PWD}/src \ -- cgit From 30b410e49098c5016b9295263a15c479aec77e86 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 19 Feb 2024 15:20:51 +0000 Subject: Avoid a segfault in nxt_conn_io_sendbuf() This is a simple temporary fix (doesn't address the underlying problem) for an issue reported by a user on GitHub whereby downloading of files from a PHP application would cause the router process to crash. This is actually a generic problem that will affect anything sending data via nxt_unit_response_write(). This is just a simple fix for the 1.32 release, after which the full correct fix will be worked out. Link: Reported-by: rustedsword Co-developed-by: rustedsword Tested-by: rustedsword Tested-by: Andrew Clayton Reviewed-by: Zhidao Hong Signed-off-by: Andrew Clayton --- src/nxt_conn_write.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/nxt_conn_write.c b/src/nxt_conn_write.c index 714a3e15..7d0a579f 100644 --- a/src/nxt_conn_write.c +++ b/src/nxt_conn_write.c @@ -172,6 +172,13 @@ nxt_conn_io_sendbuf(nxt_task_t *task, nxt_sendbuf_t *sb) return 0; } + /* + * XXX Temporary fix for + */ + if (niov == 0 && sb->buf == NULL) { + return 0; + } + if (niov == 0 && nxt_buf_is_file(sb->buf)) { return nxt_conn_io_sendfile(task, sb); } -- cgit From 62894ae77b806e84e7e2c16950850f62825869c2 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 31 Jan 2024 14:08:57 +0800 Subject: Var: Refactored nxt_var_ref_get() --- src/nxt_var.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/nxt_var.c b/src/nxt_var.c index 729de788..e45c4f14 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -132,18 +132,13 @@ nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) ref->index = state->var_refs->nelts - 1; - ref->name = nxt_str_dup(state->pool, NULL, name); - if (nxt_slow_path(ref->name == NULL)) { - return NULL; - } - decl = nxt_var_hash_find(name); if (decl != NULL) { ref->handler = decl->handler; ref->cacheable = decl->cacheable; - return ref; + goto done; } ret = nxt_http_unknown_var_ref(state, ref, name); @@ -151,6 +146,13 @@ nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) return NULL; } +done: + + ref->name = nxt_str_dup(state->pool, NULL, name); + if (nxt_slow_path(ref->name == NULL)) { + return NULL; + } + return ref; } -- cgit From 01fd121c4e442039662889bb54ce24f21af649f0 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 31 Jan 2024 14:11:29 +0800 Subject: Var: Refactored nxt_http_unknown_var_ref() --- src/nxt_http_variables.c | 13 ++++++------- src/nxt_var.c | 2 +- src/nxt_var.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index a4205eec..85ae6004 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -135,8 +135,7 @@ nxt_http_register_variables(void) nxt_int_t -nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, - nxt_str_t *name) +nxt_http_unknown_var_ref(nxt_mp_t *mp, nxt_var_ref_t *ref, nxt_str_t *name) { int64_t hash; nxt_str_t str, *lower; @@ -152,7 +151,7 @@ nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, return NXT_ERROR; } - lower = nxt_str_alloc(state->pool, str.length); + lower = nxt_str_alloc(mp, str.length); if (nxt_slow_path(lower == NULL)) { return NXT_ERROR; } @@ -175,7 +174,7 @@ nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, return NXT_ERROR; } - hash = nxt_http_header_hash(state->pool, &str); + hash = nxt_http_header_hash(mp, &str); if (nxt_slow_path(hash == -1)) { return NXT_ERROR; } @@ -191,7 +190,7 @@ nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, return NXT_ERROR; } - hash = nxt_http_argument_hash(state->pool, &str); + hash = nxt_http_argument_hash(mp, &str); if (nxt_slow_path(hash == -1)) { return NXT_ERROR; } @@ -207,7 +206,7 @@ nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, return NXT_ERROR; } - hash = nxt_http_cookie_hash(state->pool, &str); + hash = nxt_http_cookie_hash(mp, &str); if (nxt_slow_path(hash == -1)) { return NXT_ERROR; } @@ -216,7 +215,7 @@ nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, return NXT_ERROR; } - ref->data = nxt_var_field_new(state->pool, &str, (uint32_t) hash); + ref->data = nxt_var_field_new(mp, &str, (uint32_t) hash); if (nxt_slow_path(ref->data == NULL)) { return NXT_ERROR; } diff --git a/src/nxt_var.c b/src/nxt_var.c index e45c4f14..a297b5b3 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -141,7 +141,7 @@ nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) goto done; } - ret = nxt_http_unknown_var_ref(state, ref, name); + ret = nxt_http_unknown_var_ref(state->pool, ref, name); if (nxt_slow_path(ret != NXT_OK)) { return NULL; } diff --git a/src/nxt_var.h b/src/nxt_var.h index fde64f1e..d04ba48a 100644 --- a/src/nxt_var.h +++ b/src/nxt_var.h @@ -62,7 +62,7 @@ nxt_int_t nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, nxt_str_t *nxt_var_get(nxt_task_t *task, nxt_var_cache_t *cache, nxt_str_t *name, void *ctx); -nxt_int_t nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, +nxt_int_t nxt_http_unknown_var_ref(nxt_mp_t *mp, nxt_var_ref_t *ref, nxt_str_t *name); -- cgit From 63507c499e2ff3fa4af416c4d69dbaba2ac1c774 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 31 Jan 2024 14:14:28 +0800 Subject: Var: Make nxt_var_cache_value() more general This commit enhances nxt_var_cache_value() to enable variable access using string names, complementing the existing reference index method. The modification ensures future compatibility with njs variable access. --- src/nxt_var.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nxt_var.c b/src/nxt_var.c index a297b5b3..53700f40 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -54,7 +54,7 @@ static nxt_var_ref_t *nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name); static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, - nxt_var_cache_t *cache, uint32_t index, void *ctx); + nxt_var_cache_t *cache, nxt_var_ref_t *ref, void *ctx); static u_char *nxt_var_next_part(u_char *start, u_char *end, nxt_str_t *part); @@ -205,16 +205,12 @@ nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) static nxt_str_t * nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, - nxt_var_cache_t *cache, uint32_t index, void *ctx) + nxt_var_cache_t *cache, nxt_var_ref_t *ref, void *ctx) { nxt_int_t ret; nxt_str_t *value; - nxt_var_ref_t *ref; nxt_lvlhsh_query_t lhq; - ref = state->var_refs->elts; - ref = &ref[index]; - value = cache->spare; if (value == NULL) { @@ -230,10 +226,10 @@ nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, goto not_cached; } - lhq.key_hash = nxt_murmur_hash2_uint32(&index); + lhq.key_hash = nxt_murmur_hash2_uint32(&ref->index); lhq.replace = 0; lhq.key.length = sizeof(uint32_t); - lhq.key.start = (u_char *) &index; + lhq.key.start = (u_char *) &ref->index; lhq.value = value; lhq.proto = &nxt_var_cache_proto; lhq.pool = cache->pool; @@ -493,20 +489,24 @@ nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, { u_char *p, *src; size_t length, last, next; + uint32_t index; nxt_str_t *value, **part; nxt_uint_t i; nxt_array_t parts; + nxt_var_ref_t *ref; nxt_var_sub_t *subs; nxt_memzero(&parts, sizeof(nxt_array_t)); nxt_array_init(&parts, cache->pool, sizeof(nxt_str_t *)); + ref = state->var_refs->elts; subs = nxt_var_subs(var); length = var->length; for (i = 0; i < var->vars; i++) { - value = nxt_var_cache_value(task, state, cache, subs[i].index, ctx); + index = subs[i].index; + value = nxt_var_cache_value(task, state, cache, &ref[index], ctx); if (nxt_slow_path(value == NULL)) { return NXT_ERROR; } -- cgit From 465540157fe116db4082f52af4f3f67de33ed7c8 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 31 Jan 2024 14:32:08 +0800 Subject: Var: Introduced nxt_var_get() This commit is for subsequent commits that will support njs variable accessing. In this commit, nxt_var_get() is introduced to extend the variable handling capabilities. Concurrently, nxt_var_ref_get() has been refactored to use in both configuration and request phases. --- src/nxt_var.c | 48 +++++++++++++++++++++++++++++++++++++----------- src/nxt_var.h | 4 ++-- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/nxt_var.c b/src/nxt_var.c index 53700f40..2600371b 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -50,7 +50,8 @@ struct nxt_var_query_s { static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data); static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name); -static nxt_var_ref_t *nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name); +static nxt_var_ref_t *nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name, + nxt_mp_t *mp); static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, @@ -109,7 +110,7 @@ nxt_var_hash_find(nxt_str_t *name) static nxt_var_ref_t * -nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) +nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name, nxt_mp_t *mp) { nxt_int_t ret; nxt_uint_t i; @@ -125,12 +126,22 @@ nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) } } - ref = nxt_array_add(state->var_refs); - if (nxt_slow_path(ref == NULL)) { - return NULL; - } + if (mp != NULL) { + ref = nxt_mp_alloc(mp, sizeof(nxt_var_ref_t)); + if (nxt_slow_path(ref == NULL)) { + return NULL; + } - ref->index = state->var_refs->nelts - 1; + } else { + ref = nxt_array_add(state->var_refs); + if (nxt_slow_path(ref == NULL)) { + return NULL; + } + + ref->index = state->var_refs->nelts - 1; + + mp = state->pool; + } decl = nxt_var_hash_find(name); @@ -141,14 +152,14 @@ nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) goto done; } - ret = nxt_http_unknown_var_ref(state->pool, ref, name); + ret = nxt_http_unknown_var_ref(mp, ref, name); if (nxt_slow_path(ret != NXT_OK)) { return NULL; } done: - ref->name = nxt_str_dup(state->pool, NULL, name); + ref->name = nxt_str_dup(mp, NULL, name); if (nxt_slow_path(ref->name == NULL)) { return NULL; } @@ -355,7 +366,7 @@ nxt_var_compile(nxt_tstr_state_t *state, nxt_str_t *str) next = nxt_var_next_part(p, end, &part); if (part.start != NULL) { - ref = nxt_var_ref_get(state, &part); + ref = nxt_var_ref_get(state, &part, NULL); if (nxt_slow_path(ref == NULL)) { return NULL; } @@ -395,7 +406,7 @@ nxt_var_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) } if (part.start != NULL) { - ref = nxt_var_ref_get(state, &part); + ref = nxt_var_ref_get(state, &part, NULL); if (ref == NULL) { nxt_sprintf(error, error + NXT_MAX_ERROR_STR, @@ -560,3 +571,18 @@ nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, return NXT_OK; } + + +nxt_str_t * +nxt_var_get(nxt_task_t *task, nxt_tstr_state_t *state, nxt_var_cache_t *cache, + nxt_str_t *name, void *ctx) +{ + nxt_var_ref_t *ref; + + ref = nxt_var_ref_get(state, name, cache->pool); + if (nxt_slow_path(ref == NULL)) { + return NULL; + } + + return nxt_var_cache_value(task, state, cache, ref, ctx); +} diff --git a/src/nxt_var.h b/src/nxt_var.h index d04ba48a..08a92c08 100644 --- a/src/nxt_var.h +++ b/src/nxt_var.h @@ -59,8 +59,8 @@ nxt_int_t nxt_var_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error); nxt_int_t nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, nxt_var_cache_t *cache, nxt_var_t *var, nxt_str_t *str, void *ctx, nxt_bool_t logging); -nxt_str_t *nxt_var_get(nxt_task_t *task, nxt_var_cache_t *cache, - nxt_str_t *name, void *ctx); +nxt_str_t *nxt_var_get(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, nxt_str_t *name, void *ctx); nxt_int_t nxt_http_unknown_var_ref(nxt_mp_t *mp, nxt_var_ref_t *ref, nxt_str_t *name); -- cgit From 63ad4deb8a9a7955c5eec3098a2acc3e149831c7 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 31 Jan 2024 14:38:00 +0800 Subject: NJS: Simplified nxt_js_call() --- src/nxt_js.c | 57 +++++++++++++++++---------------------------------------- 1 file changed, 17 insertions(+), 40 deletions(-) diff --git a/src/nxt_js.c b/src/nxt_js.c index 74663660..0e1fe463 100644 --- a/src/nxt_js.c +++ b/src/nxt_js.c @@ -388,16 +388,19 @@ nxt_js_call(nxt_task_t *task, nxt_js_conf_t *jcf, nxt_js_cache_t *cache, njs_vm_t *vm; njs_int_t ret; njs_str_t res; + njs_uint_t i, n; njs_value_t *value; njs_function_t *func; njs_opaque_value_t retval, opaque_value, arguments[6]; - static const njs_str_t uri_str = njs_str("uri"); - static const njs_str_t host_str = njs_str("host"); - static const njs_str_t remote_addr_str = njs_str("remoteAddr"); - static const njs_str_t args_str = njs_str("args"); - static const njs_str_t headers_str = njs_str("headers"); - static const njs_str_t cookies_str = njs_str("cookies"); + static const njs_str_t js_args[] = { + njs_str("uri"), + njs_str("host"), + njs_str("remoteAddr"), + njs_str("args"), + njs_str("headers"), + njs_str("cookies"), + }; vm = cache->vm; @@ -424,43 +427,17 @@ nxt_js_call(nxt_task_t *task, nxt_js_conf_t *jcf, nxt_js_cache_t *cache, return NXT_ERROR; } - value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), &uri_str, - &arguments[0]); - if (nxt_slow_path(value == NULL)) { - return NXT_ERROR; - } - - value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), &host_str, - &arguments[1]); - if (nxt_slow_path(value == NULL)) { - return NXT_ERROR; - } - - value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), - &remote_addr_str, &arguments[2]); - if (nxt_slow_path(value == NULL)) { - return NXT_ERROR; - } - - value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), &args_str, - &arguments[3]); - if (nxt_slow_path(value == NULL)) { - return NXT_ERROR; - } - - value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), &headers_str, - &arguments[4]); - if (nxt_slow_path(value == NULL)) { - return NXT_ERROR; - } + n = nxt_nitems(js_args); - value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), &cookies_str, - &arguments[5]); - if (nxt_slow_path(value == NULL)) { - return NXT_ERROR; + for (i = 0; i < n; i++) { + value = njs_vm_object_prop(vm, njs_value_arg(&opaque_value), + &js_args[i], &arguments[i]); + if (nxt_slow_path(value == NULL)) { + return NXT_ERROR; + } } - ret = njs_vm_invoke(vm, func, njs_value_arg(&arguments), 6, + ret = njs_vm_invoke(vm, func, njs_value_arg(&arguments), n, njs_value_arg(&retval)); if (ret != NJS_OK) { -- cgit From 33c6c4d4c0e060a974791a472b739214366dead6 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Wed, 31 Jan 2024 14:51:21 +0800 Subject: NJS: variable access support This commit introduces the 'vars' JavaScript object to NJS, enabling direct access to native variables such as $uri and $arg_foo. The syntax is `${vars.var_name}` or `${'vars[var_name]'}`. For example: { "action": { "share": "`/www/html${vars.uri}`" } } --- docs/changes.xml | 6 ++++++ src/nxt_http_js.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/nxt_js.c | 5 +++-- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index a3549697..833ec20e 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -65,6 +65,12 @@ conditional access logging. + + +NJS variables access. + + + $request_id variable contains a string that is formed using random data and diff --git a/src/nxt_http_js.c b/src/nxt_http_js.c index 72ba761f..e3beb8b4 100644 --- a/src/nxt_http_js.c +++ b/src/nxt_http_js.c @@ -28,6 +28,8 @@ static njs_int_t nxt_http_js_ext_get_cookie(njs_vm_t *vm, njs_value_t *retval); static njs_int_t nxt_http_js_ext_keys_cookie(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); +static njs_int_t nxt_http_js_ext_get_var(njs_vm_t *vm, njs_object_prop_t *prop, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval); static njs_external_t nxt_http_js_proto[] = { @@ -88,6 +90,14 @@ static njs_external_t nxt_http_js_proto[] = { .keys = nxt_http_js_ext_keys_cookie, } }, + + { + .flags = NJS_EXTERN_OBJECT, + .name.string = njs_str("vars"), + .u.object = { + .prop_handler = nxt_http_js_ext_get_var, + } + }, }; @@ -338,3 +348,42 @@ nxt_http_js_ext_keys_cookie(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) return NJS_OK; } + + +static njs_int_t +nxt_http_js_ext_get_var(njs_vm_t *vm, njs_object_prop_t *prop, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) +{ + njs_int_t rc; + njs_str_t key; + nxt_str_t name, *vv; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + + r = njs_vm_external(vm, nxt_js_proto_id, value); + if (r == NULL) { + njs_value_undefined_set(retval); + return NJS_DECLINED; + } + + rc = njs_vm_prop_name(vm, prop, &key); + if (rc != NJS_OK) { + njs_value_undefined_set(retval); + return NJS_DECLINED; + } + + rtcf = r->conf->socket_conf->router_conf; + + name.start = key.start; + name.length = key.length; + + vv = nxt_var_get(&r->task, rtcf->tstr_state, &r->tstr_cache.var, &name, r); + + if (vv != NULL) { + return njs_vm_value_string_set(vm, retval, vv->start, vv->length); + } + + njs_value_undefined_set(retval); + + return NJS_DECLINED; +} diff --git a/src/nxt_js.c b/src/nxt_js.c index 0e1fe463..6885afb7 100644 --- a/src/nxt_js.c +++ b/src/nxt_js.c @@ -240,7 +240,7 @@ nxt_js_add_tpl(nxt_js_conf_t *jcf, nxt_str_t *str, nxt_bool_t strz) nxt_str_t *func; static nxt_str_t func_str = nxt_string("function(uri, host, remoteAddr, " - "args, headers, cookies) {" + "args, headers, cookies, vars) {" " return "); /* @@ -391,7 +391,7 @@ nxt_js_call(nxt_task_t *task, nxt_js_conf_t *jcf, nxt_js_cache_t *cache, njs_uint_t i, n; njs_value_t *value; njs_function_t *func; - njs_opaque_value_t retval, opaque_value, arguments[6]; + njs_opaque_value_t retval, opaque_value, arguments[7]; static const njs_str_t js_args[] = { njs_str("uri"), @@ -400,6 +400,7 @@ nxt_js_call(nxt_task_t *task, nxt_js_conf_t *jcf, nxt_js_cache_t *cache, njs_str("args"), njs_str("headers"), njs_str("cookies"), + njs_str("vars"), }; vm = cache->vm; -- cgit From 183a1e9d634ae2fb129ce98f1ca8a16cbfdeac99 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Tue, 13 Feb 2024 18:30:22 -0800 Subject: Docker: redirect logs to stderr This allows to use /dev/stdout as application logs if users choose to do so. Closes: https://github.com/nginx/unit/issues/982 --- pkg/docker/template.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/docker/template.Dockerfile b/pkg/docker/template.Dockerfile index f5efc3c8..70951747 100644 --- a/pkg/docker/template.Dockerfile +++ b/pkg/docker/template.Dockerfile @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ -- cgit From 5570d807d9917cf738e1737dba7e2b8005b8e389 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Tue, 13 Feb 2024 11:19:34 -0800 Subject: Packages: fixed a path to python 3.12 example app --- pkg/rpm/rpmbuild/SOURCES/unit.example-python312-config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rpm/rpmbuild/SOURCES/unit.example-python312-config b/pkg/rpm/rpmbuild/SOURCES/unit.example-python312-config index 37b65f1f..1de2eba6 100644 --- a/pkg/rpm/rpmbuild/SOURCES/unit.example-python312-config +++ b/pkg/rpm/rpmbuild/SOURCES/unit.example-python312-config @@ -3,7 +3,7 @@ "example_python": { "type": "python 3.12", "processes": 2, - "path": "/usr/share/doc/unit-python3.12/examples/python-app", + "path": "/usr/share/doc/unit-python312/examples/python-app", "module": "wsgi" } }, -- cgit From 53648ed56488c73aaed94c3258fc4136bc4cba6d Mon Sep 17 00:00:00 2001 From: Dan Callahan Date: Fri, 5 Jan 2024 12:09:36 +0000 Subject: Tools: Fix typo in tools/README.md As suggested by @lcrilly --- tools/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/README.md b/tools/README.md index 883bc107..e7caae34 100644 --- a/tools/README.md +++ b/tools/README.md @@ -33,7 +33,7 @@ web page with NGINX Unit. | Options | | |---------|-| -| filename … | Read configuration data consequently from the specified files instead of stdin. +| filename … | Read configuration data consecutively from the specified files instead of stdin. | _HTTP method_ | It is usually not required to specify a HTTP method. `GET` is used to read the configuration. `PUT` is used when making configuration changes unless a specific method is provided. | `edit` | Opens **URI** in the default editor for interactive configuration. The [jq](https://stedolan.github.io/jq/) tool is required for this option. | `INSERT` | A _virtual_ HTTP method that prepends data when the URI specifies an existing array. The [jq](https://stedolan.github.io/jq/) tool is required for this option. -- cgit From d24ae5a9a4b1140695e027087e72dcfdeb484ec0 Mon Sep 17 00:00:00 2001 From: Gabor Javorszky Date: Thu, 7 Dec 2023 15:07:24 +0000 Subject: Add additional replace rules for node:* modules In that particular issue the compiled nuxt files end up importing the http module as node:http rather than http only. This bypasses unit's custom loader implementation which only check for the http or unit-http modules, and their websocket counterparts. This changeset adds replace sources for both the node:http and node:websocket import signatures. Closes: https://github.com/nginx/unit/issues/1013 Reviewed-by: Andrew Clayton --- src/nodejs/unit-http/loader.js | 2 ++ src/nodejs/unit-http/loader.mjs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/nodejs/unit-http/loader.js b/src/nodejs/unit-http/loader.js index e5aa3558..849df3d1 100644 --- a/src/nodejs/unit-http/loader.js +++ b/src/nodejs/unit-http/loader.js @@ -11,10 +11,12 @@ if (module.parent && module.parent.id === "internal/preload") { Module.prototype.require = function (id) { switch(id) { case "http": + case "node:http": case "unit-http": return http case "websocket": + case "node:websocket": case "unit-http/websocket": return websocket } diff --git a/src/nodejs/unit-http/loader.mjs b/src/nodejs/unit-http/loader.mjs index 83985b0f..01fa2920 100644 --- a/src/nodejs/unit-http/loader.mjs +++ b/src/nodejs/unit-http/loader.mjs @@ -2,6 +2,7 @@ export async function resolve(specifier, context, defaultResolver) { switch (specifier) { case "websocket": + case "node:websocket": return { url: new URL("./websocket.js", import.meta.url).href, format: "commonjs", @@ -9,6 +10,7 @@ export async function resolve(specifier, context, defaultResolver) { } case "http": + case "node:http": return { url: new URL("./http.js", import.meta.url).href, format: "commonjs", -- cgit From bd0abdf0838f3dd8952825332fb7631d85f51a34 Mon Sep 17 00:00:00 2001 From: Dan Callahan Date: Mon, 19 Feb 2024 12:59:22 +0000 Subject: Docker: Shallow clone the Unit repo Saves on the order of 10 MBs of transfer for each build. We call `rm -rf /usr/src/unit` later in this step, so the full repo has never appeared in our published images anyway. --- pkg/docker/Dockerfile.go1.20 | 2 +- pkg/docker/Dockerfile.go1.21 | 2 +- pkg/docker/Dockerfile.jsc11 | 2 +- pkg/docker/Dockerfile.minimal | 2 +- pkg/docker/Dockerfile.node18 | 2 +- pkg/docker/Dockerfile.node20 | 2 +- pkg/docker/Dockerfile.perl5.36 | 2 +- pkg/docker/Dockerfile.perl5.38 | 2 +- pkg/docker/Dockerfile.php8.2 | 2 +- pkg/docker/Dockerfile.python3.11 | 2 +- pkg/docker/Dockerfile.python3.12 | 2 +- pkg/docker/Dockerfile.ruby3.2 | 2 +- pkg/docker/Dockerfile.wasm | 2 +- pkg/docker/template.Dockerfile | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/docker/Dockerfile.go1.20 b/pkg/docker/Dockerfile.go1.20 index fcb449a7..a390b2f6 100644 --- a/pkg/docker/Dockerfile.go1.20 +++ b/pkg/docker/Dockerfile.go1.20 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.go1.21 b/pkg/docker/Dockerfile.go1.21 index 5aff94b6..ba509900 100644 --- a/pkg/docker/Dockerfile.go1.21 +++ b/pkg/docker/Dockerfile.go1.21 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index 33a40a47..14481f79 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 2ff15d7b..44356254 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.node18 b/pkg/docker/Dockerfile.node18 index 29eebdcf..5cb73f2d 100644 --- a/pkg/docker/Dockerfile.node18 +++ b/pkg/docker/Dockerfile.node18 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.node20 b/pkg/docker/Dockerfile.node20 index 05a7bfab..d4da6a18 100644 --- a/pkg/docker/Dockerfile.node20 +++ b/pkg/docker/Dockerfile.node20 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.perl5.36 b/pkg/docker/Dockerfile.perl5.36 index 31be2388..94925b2c 100644 --- a/pkg/docker/Dockerfile.perl5.36 +++ b/pkg/docker/Dockerfile.perl5.36 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.perl5.38 b/pkg/docker/Dockerfile.perl5.38 index 0097d638..d2b3f06d 100644 --- a/pkg/docker/Dockerfile.perl5.38 +++ b/pkg/docker/Dockerfile.perl5.38 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.php8.2 b/pkg/docker/Dockerfile.php8.2 index da0487e7..d49edcdd 100644 --- a/pkg/docker/Dockerfile.php8.2 +++ b/pkg/docker/Dockerfile.php8.2 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.python3.11 b/pkg/docker/Dockerfile.python3.11 index b298b873..1d0322cc 100644 --- a/pkg/docker/Dockerfile.python3.11 +++ b/pkg/docker/Dockerfile.python3.11 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.python3.12 b/pkg/docker/Dockerfile.python3.12 index 0fc64911..ef1fba99 100644 --- a/pkg/docker/Dockerfile.python3.12 +++ b/pkg/docker/Dockerfile.python3.12 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.ruby3.2 b/pkg/docker/Dockerfile.ruby3.2 index 29c27116..e0ab47d4 100644 --- a/pkg/docker/Dockerfile.ruby3.2 +++ b/pkg/docker/Dockerfile.ruby3.2 @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.wasm b/pkg/docker/Dockerfile.wasm index cf92d707..f5aab32d 100644 --- a/pkg/docker/Dockerfile.wasm +++ b/pkg/docker/Dockerfile.wasm @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/template.Dockerfile b/pkg/docker/template.Dockerfile index 70951747..edf9ba75 100644 --- a/pkg/docker/template.Dockerfile +++ b/pkg/docker/template.Dockerfile @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone -b @@VERSION@@-@@PATCHLEVEL@@ https://github.com/nginx/unit \ + && git clone --depth 1 -b @@VERSION@@-@@PATCHLEVEL@@ https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ -- cgit From 914cd4e3547a8f1b3681a64375955d60edf55aed Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 20 Feb 2024 12:57:18 +0000 Subject: .mailmap: Map some more personal addresses Add more entries for Andrei and Konstantin and an entry for Dan. Reviewed-by: Dan Callahan Signed-off-by: Andrew Clayton --- .mailmap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index 21085d68..d1dc863a 100644 --- a/.mailmap +++ b/.mailmap @@ -2,11 +2,14 @@ Alejandro Colomar Alejandro Colomar Alejandro Colomar Andrei Zeliankou +Andrei Zeliankou Andrew Clayton Andrew Clayton Artem Konev <41629299+artemkonev@users.noreply.github.com> +Dan Callahan Danielle De Leo Konstantin Pavlov +Konstantin Pavlov Max Romanov OutOfFocus4 Sergey A. Osokin -- cgit From d52a9361a85ed7694815df5b707649dd6b31ead1 Mon Sep 17 00:00:00 2001 From: Dan Callahan Date: Tue, 20 Feb 2024 12:56:15 +0000 Subject: Docker: Update versions of Go, Node, PHP, Ruby - Go: Drop 1.20, Add 1.22 - Node: Drop 18, Add 21 - PHP: Add 8.3 - Ruby: Add 3.3 Perl and Python are still up-to-date with upstream releases Regenerating the Dockerfiles also picks up the logging change from 183a1e9d634ae2fb129ce98f1ca8a16cbfdeac99 --- pkg/docker/Dockerfile.go1.20 | 89 ---------------------------------------- pkg/docker/Dockerfile.go1.21 | 2 +- pkg/docker/Dockerfile.go1.22 | 89 ++++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.jsc11 | 2 +- pkg/docker/Dockerfile.minimal | 2 +- pkg/docker/Dockerfile.node18 | 89 ---------------------------------------- pkg/docker/Dockerfile.node20 | 2 +- pkg/docker/Dockerfile.node21 | 89 ++++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.perl5.36 | 2 +- pkg/docker/Dockerfile.perl5.38 | 2 +- pkg/docker/Dockerfile.php8.2 | 2 +- pkg/docker/Dockerfile.php8.3 | 89 ++++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.python3.11 | 2 +- pkg/docker/Dockerfile.python3.12 | 2 +- pkg/docker/Dockerfile.ruby3.2 | 2 +- pkg/docker/Dockerfile.ruby3.3 | 89 ++++++++++++++++++++++++++++++++++++++++ pkg/docker/Dockerfile.wasm | 2 +- pkg/docker/Makefile | 8 ++-- 18 files changed, 371 insertions(+), 193 deletions(-) delete mode 100644 pkg/docker/Dockerfile.go1.20 create mode 100644 pkg/docker/Dockerfile.go1.22 delete mode 100644 pkg/docker/Dockerfile.node18 create mode 100644 pkg/docker/Dockerfile.node21 create mode 100644 pkg/docker/Dockerfile.php8.3 create mode 100644 pkg/docker/Dockerfile.ruby3.3 diff --git a/pkg/docker/Dockerfile.go1.20 b/pkg/docker/Dockerfile.go1.20 deleted file mode 100644 index a390b2f6..00000000 --- a/pkg/docker/Dockerfile.go1.20 +++ /dev/null @@ -1,89 +0,0 @@ -FROM golang:1.20-bullseye - -LABEL org.opencontainers.image.title="Unit (go1.20)" -LABEL org.opencontainers.image.description="Official build of Unit for Docker." -LABEL org.opencontainers.image.url="https://unit.nginx.org" -LABEL org.opencontainers.image.source="https://github.com/nginx/unit" -LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" -LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" - -RUN set -ex \ - && savedAptMark="$(apt-mark showmanual)" \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ - && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ - && mkdir -p /usr/src/unit \ - && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ - && cd unit \ - && 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_MODULES="--prefix=/usr \ - --statedir=/var/lib/unit \ - --control=unix:/var/run/control.unit.sock \ - --runstatedir=/var/run \ - --pid=/var/run/unit.pid \ - --logdir=/var/log \ - --log=/var/log/unit.log \ - --tmpdir=/var/tmp \ - --user=unit \ - --group=unit \ - --openssl \ - --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ - && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ - --njs" \ - && make -j $NCPU -C pkg/contrib .njs \ - && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ - && make -j $NCPU unitd \ - && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ - && make -j $NCPU unitd \ - && install -pm755 build/sbin/unitd /usr/sbin/unitd \ - && make clean \ - && /bin/true \ - && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ - && ./configure go --go-path=$GOPATH \ - && make -j $NCPU go-install-src libunit-install \ - && make clean \ - && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ - && ./configure go --go-path=$GOPATH \ - && make -j $NCPU go-install-src libunit-install \ - && cd \ - && rm -rf /usr/src/unit \ - && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ - ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ - done \ - && apt-mark showmanual | xargs apt-mark auto > /dev/null \ - && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ - && /bin/true \ - && mkdir -p /var/lib/unit/ \ - && mkdir -p /docker-entrypoint.d/ \ - && groupadd --gid 999 unit \ - && useradd \ - --uid 999 \ - --gid unit \ - --no-create-home \ - --home /nonexistent \ - --comment "unit user" \ - --shell /bin/false \ - unit \ - && apt-get update \ - && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ - && apt-get purge -y --auto-remove build-essential \ - && rm -rf /var/lib/apt/lists/* \ - && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log - -COPY docker-entrypoint.sh /usr/local/bin/ -COPY welcome.* /usr/share/unit/welcome/ - -STOPSIGNAL SIGTERM - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] -EXPOSE 80 -CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.go1.21 b/pkg/docker/Dockerfile.go1.21 index ba509900..068a787f 100644 --- a/pkg/docker/Dockerfile.go1.21 +++ b/pkg/docker/Dockerfile.go1.21 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.go1.22 b/pkg/docker/Dockerfile.go1.22 new file mode 100644 index 00000000..567d607a --- /dev/null +++ b/pkg/docker/Dockerfile.go1.22 @@ -0,0 +1,89 @@ +FROM golang:1.22-bullseye + +LABEL org.opencontainers.image.title="Unit (go1.22)" +LABEL org.opencontainers.image.description="Official build of Unit for Docker." +LABEL org.opencontainers.image.url="https://unit.nginx.org" +LABEL org.opencontainers.image.source="https://github.com/nginx/unit" +LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" +LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " +LABEL org.opencontainers.image.version="1.31.1" + +RUN set -ex \ + && savedAptMark="$(apt-mark showmanual)" \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && mkdir -p /usr/src/unit \ + && cd /usr/src/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && cd unit \ + && 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_MODULES="--prefix=/usr \ + --statedir=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --runstatedir=/var/run \ + --pid=/var/run/unit.pid \ + --logdir=/var/log \ + --log=/var/log/unit.log \ + --tmpdir=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ + --njs" \ + && make -j $NCPU -C pkg/contrib .njs \ + && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd \ + && make clean \ + && /bin/true \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && ./configure go --go-path=$GOPATH \ + && make -j $NCPU go-install-src libunit-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ + && ./configure go --go-path=$GOPATH \ + && make -j $NCPU go-install-src libunit-install \ + && cd \ + && rm -rf /usr/src/unit \ + && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ + ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ + done \ + && apt-mark showmanual | xargs apt-mark auto > /dev/null \ + && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ + && /bin/true \ + && mkdir -p /var/lib/unit/ \ + && mkdir -p /docker-entrypoint.d/ \ + && groupadd --gid 999 unit \ + && useradd \ + --uid 999 \ + --gid unit \ + --no-create-home \ + --home /nonexistent \ + --comment "unit user" \ + --shell /bin/false \ + unit \ + && apt-get update \ + && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get purge -y --auto-remove build-essential \ + && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stderr /var/log/unit.log + +COPY docker-entrypoint.sh /usr/local/bin/ +COPY welcome.* /usr/share/unit/welcome/ + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +EXPOSE 80 +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index 14481f79..ff84edd5 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 44356254..667f3016 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.node18 b/pkg/docker/Dockerfile.node18 deleted file mode 100644 index 5cb73f2d..00000000 --- a/pkg/docker/Dockerfile.node18 +++ /dev/null @@ -1,89 +0,0 @@ -FROM node:18-bullseye - -LABEL org.opencontainers.image.title="Unit (node18)" -LABEL org.opencontainers.image.description="Official build of Unit for Docker." -LABEL org.opencontainers.image.url="https://unit.nginx.org" -LABEL org.opencontainers.image.source="https://github.com/nginx/unit" -LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" -LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" - -RUN set -ex \ - && savedAptMark="$(apt-mark showmanual)" \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ - && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ - && mkdir -p /usr/src/unit \ - && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ - && cd unit \ - && 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_MODULES="--prefix=/usr \ - --statedir=/var/lib/unit \ - --control=unix:/var/run/control.unit.sock \ - --runstatedir=/var/run \ - --pid=/var/run/unit.pid \ - --logdir=/var/log \ - --log=/var/log/unit.log \ - --tmpdir=/var/tmp \ - --user=unit \ - --group=unit \ - --openssl \ - --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ - && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ - --njs" \ - && make -j $NCPU -C pkg/contrib .njs \ - && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ - && make -j $NCPU unitd \ - && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ - && make clean \ - && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ - && make -j $NCPU unitd \ - && install -pm755 build/sbin/unitd /usr/sbin/unitd \ - && make clean \ - && npm -g install node-gyp \ - && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ - && ./configure nodejs --node-gyp=/usr/local/bin/node-gyp \ - && make -j $NCPU node node-install libunit-install \ - && make clean \ - && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ - && ./configure nodejs --node-gyp=/usr/local/bin/node-gyp \ - && make -j $NCPU node node-install libunit-install \ - && cd \ - && rm -rf /usr/src/unit \ - && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ - ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ - done \ - && apt-mark showmanual | xargs apt-mark auto > /dev/null \ - && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ - && rm -rf /root/.cache/ && rm -rf /root/.npm \ - && mkdir -p /var/lib/unit/ \ - && mkdir -p /docker-entrypoint.d/ \ - && groupadd --gid 999 unit \ - && useradd \ - --uid 999 \ - --gid unit \ - --no-create-home \ - --home /nonexistent \ - --comment "unit user" \ - --shell /bin/false \ - unit \ - && apt-get update \ - && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ - && apt-get purge -y --auto-remove build-essential \ - && rm -rf /var/lib/apt/lists/* \ - && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log - -COPY docker-entrypoint.sh /usr/local/bin/ -COPY welcome.* /usr/share/unit/welcome/ - -STOPSIGNAL SIGTERM - -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] -EXPOSE 80 -CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.node20 b/pkg/docker/Dockerfile.node20 index d4da6a18..dff88113 100644 --- a/pkg/docker/Dockerfile.node20 +++ b/pkg/docker/Dockerfile.node20 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.node21 b/pkg/docker/Dockerfile.node21 new file mode 100644 index 00000000..ab03d91a --- /dev/null +++ b/pkg/docker/Dockerfile.node21 @@ -0,0 +1,89 @@ +FROM node:21-bullseye + +LABEL org.opencontainers.image.title="Unit (node21)" +LABEL org.opencontainers.image.description="Official build of Unit for Docker." +LABEL org.opencontainers.image.url="https://unit.nginx.org" +LABEL org.opencontainers.image.source="https://github.com/nginx/unit" +LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" +LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " +LABEL org.opencontainers.image.version="1.31.1" + +RUN set -ex \ + && savedAptMark="$(apt-mark showmanual)" \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && mkdir -p /usr/src/unit \ + && cd /usr/src/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && cd unit \ + && 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_MODULES="--prefix=/usr \ + --statedir=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --runstatedir=/var/run \ + --pid=/var/run/unit.pid \ + --logdir=/var/log \ + --log=/var/log/unit.log \ + --tmpdir=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ + --njs" \ + && make -j $NCPU -C pkg/contrib .njs \ + && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd \ + && make clean \ + && npm -g install node-gyp \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && ./configure nodejs --node-gyp=/usr/local/bin/node-gyp \ + && make -j $NCPU node node-install libunit-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ + && ./configure nodejs --node-gyp=/usr/local/bin/node-gyp \ + && make -j $NCPU node node-install libunit-install \ + && cd \ + && rm -rf /usr/src/unit \ + && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ + ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ + done \ + && apt-mark showmanual | xargs apt-mark auto > /dev/null \ + && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ + && rm -rf /root/.cache/ && rm -rf /root/.npm \ + && mkdir -p /var/lib/unit/ \ + && mkdir -p /docker-entrypoint.d/ \ + && groupadd --gid 999 unit \ + && useradd \ + --uid 999 \ + --gid unit \ + --no-create-home \ + --home /nonexistent \ + --comment "unit user" \ + --shell /bin/false \ + unit \ + && apt-get update \ + && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get purge -y --auto-remove build-essential \ + && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stderr /var/log/unit.log + +COPY docker-entrypoint.sh /usr/local/bin/ +COPY welcome.* /usr/share/unit/welcome/ + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +EXPOSE 80 +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.perl5.36 b/pkg/docker/Dockerfile.perl5.36 index 94925b2c..696b0035 100644 --- a/pkg/docker/Dockerfile.perl5.36 +++ b/pkg/docker/Dockerfile.perl5.36 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.perl5.38 b/pkg/docker/Dockerfile.perl5.38 index d2b3f06d..1680f1e5 100644 --- a/pkg/docker/Dockerfile.perl5.38 +++ b/pkg/docker/Dockerfile.perl5.38 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.php8.2 b/pkg/docker/Dockerfile.php8.2 index d49edcdd..063ec28c 100644 --- a/pkg/docker/Dockerfile.php8.2 +++ b/pkg/docker/Dockerfile.php8.2 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.php8.3 b/pkg/docker/Dockerfile.php8.3 new file mode 100644 index 00000000..de946eb7 --- /dev/null +++ b/pkg/docker/Dockerfile.php8.3 @@ -0,0 +1,89 @@ +FROM php:8.3-cli-bullseye + +LABEL org.opencontainers.image.title="Unit (php8.3)" +LABEL org.opencontainers.image.description="Official build of Unit for Docker." +LABEL org.opencontainers.image.url="https://unit.nginx.org" +LABEL org.opencontainers.image.source="https://github.com/nginx/unit" +LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" +LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " +LABEL org.opencontainers.image.version="1.31.1" + +RUN set -ex \ + && savedAptMark="$(apt-mark showmanual)" \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && mkdir -p /usr/src/unit \ + && cd /usr/src/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && cd unit \ + && 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_MODULES="--prefix=/usr \ + --statedir=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --runstatedir=/var/run \ + --pid=/var/run/unit.pid \ + --logdir=/var/log \ + --log=/var/log/unit.log \ + --tmpdir=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ + --njs" \ + && make -j $NCPU -C pkg/contrib .njs \ + && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd \ + && make clean \ + && /bin/true \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && ./configure php \ + && make -j $NCPU php-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ + && ./configure php \ + && make -j $NCPU php-install \ + && cd \ + && rm -rf /usr/src/unit \ + && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ + ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ + done \ + && apt-mark showmanual | xargs apt-mark auto > /dev/null \ + && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ + && ldconfig \ + && mkdir -p /var/lib/unit/ \ + && mkdir -p /docker-entrypoint.d/ \ + && groupadd --gid 999 unit \ + && useradd \ + --uid 999 \ + --gid unit \ + --no-create-home \ + --home /nonexistent \ + --comment "unit user" \ + --shell /bin/false \ + unit \ + && apt-get update \ + && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get purge -y --auto-remove build-essential \ + && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stderr /var/log/unit.log + +COPY docker-entrypoint.sh /usr/local/bin/ +COPY welcome.* /usr/share/unit/welcome/ + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +EXPOSE 80 +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.python3.11 b/pkg/docker/Dockerfile.python3.11 index 1d0322cc..5fbeb1d7 100644 --- a/pkg/docker/Dockerfile.python3.11 +++ b/pkg/docker/Dockerfile.python3.11 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.python3.12 b/pkg/docker/Dockerfile.python3.12 index ef1fba99..3043502e 100644 --- a/pkg/docker/Dockerfile.python3.12 +++ b/pkg/docker/Dockerfile.python3.12 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.ruby3.2 b/pkg/docker/Dockerfile.ruby3.2 index e0ab47d4..03f99c20 100644 --- a/pkg/docker/Dockerfile.ruby3.2 +++ b/pkg/docker/Dockerfile.ruby3.2 @@ -77,7 +77,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Dockerfile.ruby3.3 b/pkg/docker/Dockerfile.ruby3.3 new file mode 100644 index 00000000..8d23499e --- /dev/null +++ b/pkg/docker/Dockerfile.ruby3.3 @@ -0,0 +1,89 @@ +FROM ruby:3.3-bullseye + +LABEL org.opencontainers.image.title="Unit (ruby3.3)" +LABEL org.opencontainers.image.description="Official build of Unit for Docker." +LABEL org.opencontainers.image.url="https://unit.nginx.org" +LABEL org.opencontainers.image.source="https://github.com/nginx/unit" +LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" +LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " +LABEL org.opencontainers.image.version="1.31.1" + +RUN set -ex \ + && savedAptMark="$(apt-mark showmanual)" \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates git build-essential libssl-dev libpcre2-dev curl pkg-config \ + && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ + && mkdir -p /usr/src/unit \ + && cd /usr/src/unit \ + && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && cd unit \ + && 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_MODULES="--prefix=/usr \ + --statedir=/var/lib/unit \ + --control=unix:/var/run/control.unit.sock \ + --runstatedir=/var/run \ + --pid=/var/run/unit.pid \ + --logdir=/var/log \ + --log=/var/log/unit.log \ + --tmpdir=/var/tmp \ + --user=unit \ + --group=unit \ + --openssl \ + --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \ + && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \ + --njs" \ + && make -j $NCPU -C pkg/contrib .njs \ + && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \ + && make clean \ + && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \ + && make -j $NCPU unitd \ + && install -pm755 build/sbin/unitd /usr/sbin/unitd \ + && make clean \ + && /bin/true \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ + && ./configure ruby \ + && make -j $NCPU ruby-install \ + && make clean \ + && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ + && ./configure ruby \ + && make -j $NCPU ruby-install \ + && cd \ + && rm -rf /usr/src/unit \ + && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ + ldd $f | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq >> /requirements.apt; \ + done \ + && apt-mark showmanual | xargs apt-mark auto > /dev/null \ + && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \ + && gem install rack && rm -rf /root/.local \ + && mkdir -p /var/lib/unit/ \ + && mkdir -p /docker-entrypoint.d/ \ + && groupadd --gid 999 unit \ + && useradd \ + --uid 999 \ + --gid unit \ + --no-create-home \ + --home /nonexistent \ + --comment "unit user" \ + --shell /bin/false \ + unit \ + && apt-get update \ + && apt-get --no-install-recommends --no-install-suggests -y install curl $(cat /requirements.apt) \ + && apt-get purge -y --auto-remove build-essential \ + && rm -rf /var/lib/apt/lists/* \ + && rm -f /requirements.apt \ + && ln -sf /dev/stderr /var/log/unit.log + +COPY docker-entrypoint.sh /usr/local/bin/ +COPY welcome.* /usr/share/unit/welcome/ + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +EXPOSE 80 +CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"] diff --git a/pkg/docker/Dockerfile.wasm b/pkg/docker/Dockerfile.wasm index f5aab32d..64742e88 100644 --- a/pkg/docker/Dockerfile.wasm +++ b/pkg/docker/Dockerfile.wasm @@ -97,7 +97,7 @@ RUN set -ex \ && apt-get purge -y --auto-remove build-essential \ && rm -rf /var/lib/apt/lists/* \ && rm -f /requirements.apt \ - && ln -sf /dev/stdout /var/log/unit.log + && ln -sf /dev/stderr /var/log/unit.log COPY docker-entrypoint.sh /usr/local/bin/ COPY welcome.* /usr/share/unit/welcome/ diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 4a81f270..102d0a05 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -19,7 +19,7 @@ INSTALL_minimal ?= version RUN_minimal ?= /bin/true MODULE_PREBUILD_minimal ?= /bin/true -VERSIONS_go ?= 1.20 1.21 +VERSIONS_go ?= 1.21 1.22 VARIANT_go ?= $(VARIANT) $(foreach goversion, $(VERSIONS_go), $(eval CONTAINER_go$(goversion) = golang:$(goversion)-$(VARIANT_go))) CONFIGURE_go ?= go --go-path=$$GOPATH @@ -35,7 +35,7 @@ INSTALL_jsc ?= java-shared-install java-install RUN_jsc ?= rm -rf /root/.m2 MODULE_PREBUILD_jsc ?= /bin/true -VERSIONS_node ?= 18 20 +VERSIONS_node ?= 20 21 VARIANT_node ?= $(VARIANT) $(foreach nodeversion, $(VERSIONS_node), $(eval CONTAINER_node$(nodeversion) = node:$(nodeversion)-$(VARIANT_node))) CONFIGURE_node ?= nodejs --node-gyp=/usr/local/bin/node-gyp @@ -51,7 +51,7 @@ INSTALL_perl ?= perl-install RUN_perl ?= /bin/true MODULE_PREBUILD_perl ?= /bin/true -VERSIONS_php ?= 8.2 +VERSIONS_php ?= 8.2 8.3 VARIANT_php ?= cli-$(VARIANT) $(foreach phpversion, $(VERSIONS_php), $(eval CONTAINER_php$(phpversion) = php:$(phpversion)-$(VARIANT_php))) CONFIGURE_php ?= php @@ -67,7 +67,7 @@ INSTALL_python ?= python3-install RUN_python ?= /bin/true MODULE_PREBUILD_python ?= /bin/true -VERSIONS_ruby ?= 3.2 +VERSIONS_ruby ?= 3.2 3.3 VARIANT_ruby ?= $(VARIANT) $(foreach rubyversion, $(VERSIONS_ruby), $(eval CONTAINER_ruby$(rubyversion) = ruby:$(rubyversion)-$(VARIANT_ruby))) CONFIGURE_ruby ?= ruby -- cgit From 2765522b94e748d01e449d5508f83ea4a5b46ea5 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 17 Jan 2024 14:36:36 +0000 Subject: Tests: NJS request variables --- test/test_njs.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/test/test_njs.py b/test/test_njs.py index aaaa23aa..8ef815fd 100644 --- a/test/test_njs.py +++ b/test/test_njs.py @@ -23,7 +23,7 @@ def setup_method_fixture(temp_dir): def create_files(*files): assets_dir = f'{option.temp_dir}/assets/' - Path(assets_dir).mkdir() + Path(assets_dir).mkdir(exist_ok=True) _ = [Path(assets_dir + f).touch() for f in files] waitforfiles(*[assets_dir + f for f in files]) @@ -83,6 +83,38 @@ def test_njs_variables(temp_dir): set_share(f'"`{temp_dir}/assets/${{args.foo}}`"') assert client.get(url='/?foo=str')['status'] == 200, 'args' + check_expression('/${vars.header_host}') + + set_share(f'"`{temp_dir}/assets/${{vars[\\"arg_foo\\"]}}`"') + assert client.get(url='/?foo=str')['status'] == 200, 'vars' + + set_share(f'"`{temp_dir}/assets/${{vars.non_exist}}`"') + assert client.get()['status'] == 404, 'undefined' + + create_files('undefined') + assert client.get()['status'] == 200, 'undefined 2' + + +def test_njs_variables_cacheable(temp_dir): + create_files('str') + + def check_rewrite(rewrite, uri): + assert 'success' in client.conf( + [ + { + "action": { + "rewrite": rewrite, + "share": f"`{temp_dir}/assets{uri}`", + }, + }, + ], + 'routes', + ) + assert client.get()['status'] == 200 + + check_rewrite('/str', '${uri}') + check_rewrite('/str', '${vars.uri}') + def test_njs_invalid(skip_alert): skip_alert(r'js exception:') @@ -93,6 +125,7 @@ def test_njs_invalid(skip_alert): check_invalid('"`a"') check_invalid('"`a``"') check_invalid('"`a`/"') + check_invalid('"`${vars.}`"') def check_invalid_resolve(template): assert 'success' in client.conf(template, 'routes/0/action/share') @@ -100,3 +133,4 @@ def test_njs_invalid(skip_alert): check_invalid_resolve('"`${a}`"') check_invalid_resolve('"`${uri.a.a}`"') + check_invalid_resolve('"`${vars.a.a}`"') -- cgit From cca2c46e4995497c091073d51d7148eac5cf140a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 9 Feb 2024 12:37:14 +0100 Subject: Tools: setup-unit: Use trap(1) to handle cleanup This allows listening to command exit statuses. Before this change, we had to ignore the exit status of curl(1) (and a few other commands), since otherwise the script would go kaboom and not cleanup the ssh(1) tunnels. Fixes: 543d478e1236 ("Tools: setup-unit: ctl: added "edit" subcommand.") Fixes: 3778877eb3be ("Tools: Added subcommands to setup-unit.") Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/tools/setup-unit b/tools/setup-unit index e9ad5896..5b5b3ccc 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -29,6 +29,7 @@ test -v BASH_VERSION \ test -v ZSH_VERSION \ && setopt sh_word_split; + export LC_ALL=C dry_run='no'; @@ -164,6 +165,18 @@ dry_run_eval() fi; } +run_trap() +{ + trap -p "$1" \ + | tr -d '\n' \ + | sed "s/[^']*'\(.*\)'[^']*/\1/" \ + | sed "s/'\\\\''/'/g" \ + | read -r trap_cmd; + + eval $trap_cmd; + trap - "$1"; +} + help_unit_cmd() { @@ -399,14 +412,16 @@ unit_ctl_edit() -o 'ExitOnForwardFailure yes' \ -L "$local_sock:$remote_sock" "$remote"; + trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; + unlink '$local_sock'" EXIT; + sock="unix:$local_sock"; fi; - local tmp="$(mktemp ||:)"; + local tmp="$(mktemp)"; unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \ - "$tmp" \ - ||:; + "$tmp"; $( ((test -v VISUAL && test -n "$VISUAL") && printf '%s\n' "$VISUAL") \ @@ -415,15 +430,12 @@ unit_ctl_edit() || command -v vi \ || command -v vim \ || echo ed; - ) "$tmp" \ - ||:; + ) "$tmp"; - unit_ctl_http ---s "$sock" PUT "$req_path" <"$tmp" \ - ||:; + unit_ctl_http ---s "$sock" PUT "$req_path" <"$tmp"; if test -v remote; then - ssh -S "$ssh_ctrl" -O exit "$remote" 2>/dev/null; - unlink "$local_sock"; + run_trap EXIT; fi; } @@ -519,16 +531,17 @@ unit_ctl_http() -o 'ExitOnForwardFailure yes' \ -L "$local_sock:$remote_sock" "$remote"; + trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; + unlink '$local_sock'" EXIT; + sock="unix:$local_sock"; fi; curl $curl_options -X $method -d@- \ - $(echo "$sock" | unit_sock_filter -c)${req_path} \ - ||:; + $(echo "$sock" | unit_sock_filter -c)${req_path}; if test -v remote; then - ssh -S "$ssh_ctrl" -O exit "$remote" 2>/dev/null; - unlink "$local_sock"; + run_trap EXIT; fi; } @@ -603,22 +616,22 @@ unit_ctl_insert() -o 'ExitOnForwardFailure yes' \ -L "$local_sock:$remote_sock" "$remote"; + trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; + unlink '$local_sock'" EXIT; + sock="unix:$local_sock"; fi; - local old="$(mktemp ||:)"; + local old="$(mktemp)"; unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \ - "$old" \ - ||:; + "$old"; unit_json_ins "$old" "$idx" \ - | unit_ctl_http ---s "$sock" PUT "$req_path" \ - ||:; + | unit_ctl_http ---s "$sock" PUT "$req_path"; if test -v remote; then - ssh -S "$ssh_ctrl" -O exit "$remote" 2>/dev/null; - unlink "$local_sock"; + run_trap EXIT; fi; } -- cgit From d6ed000316b4226ad73333ba294ac63096665a02 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 9 Feb 2024 12:51:28 +0100 Subject: Tools: setup-unit: De-duplicate code Centralize handling of the ssh(1) tunnel in the ctl command. This is possible now that we do the cleanup with trap(1). Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 100 ++++++++++++------------------------------------------- 1 file changed, 22 insertions(+), 78 deletions(-) diff --git a/tools/setup-unit b/tools/setup-unit index 5b5b3ccc..8466e882 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -315,25 +315,44 @@ unit_ctl() if echo $sock | grep '^ssh://' >/dev/null; then local remote="$(echo $sock | sed 's,\(ssh://[^/]*\).*,\1,')"; local sock="$(echo $sock | sed 's,ssh://[^/]*\(.*\),unix:\1,')"; + + local remote_sock="$(echo "$sock" | unit_sock_filter -s)"; + local local_sock="$(mktemp -u -p /var/run/unit/)"; + local ssh_ctrl="$(mktemp -u -p /var/run/unit/)"; + + mkdir -p /var/run/unit/; + + ssh -fMNnT -S "$ssh_ctrl" \ + -o 'ExitOnForwardFailure yes' \ + -L "$local_sock:$remote_sock" "$remote"; + + trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; + unlink '$local_sock';" EXIT; + + sock="unix:$local_sock"; fi; case $1 in edit) shift; - unit_ctl_edit ${remote:+ ---r $remote} ---s "$sock" $@; + unit_ctl_edit ---s "$sock" $@; ;; http) shift; - unit_ctl_http ${remote:+ ---r $remote} ---s "$sock" $@; + unit_ctl_http ---s "$sock" $@; ;; insert) shift; - unit_ctl_insert ${remote:+ ---r $remote} ---s "$sock" $@; + unit_ctl_insert ---s "$sock" $@; ;; *) err "ctl: $1: Unknown argument."; ;; esac; + + if test -v remote; then + run_trap EXIT; + fi; } @@ -378,10 +397,6 @@ unit_ctl_edit() help_unit_ctl_edit; exit 0; ;; - ---r | ----remote) - local remote="$2"; - shift; - ;; ---s | ----sock) local sock="$2"; shift; @@ -401,23 +416,6 @@ unit_ctl_edit() fi; local req_path="$1"; - if test -v remote; then - local remote_sock="$(echo "$sock" | unit_sock_filter -s)"; - local local_sock="$(mktemp -u -p /var/run/unit/)"; - local ssh_ctrl="$(mktemp -u -p /var/run/unit/)"; - - mkdir -p /var/run/unit/; - - ssh -fMNnT -S "$ssh_ctrl" \ - -o 'ExitOnForwardFailure yes' \ - -L "$local_sock:$remote_sock" "$remote"; - - trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; - unlink '$local_sock'" EXIT; - - sock="unix:$local_sock"; - fi; - local tmp="$(mktemp)"; unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \ @@ -433,10 +431,6 @@ unit_ctl_edit() ) "$tmp"; unit_ctl_http ---s "$sock" PUT "$req_path" <"$tmp"; - - if test -v remote; then - run_trap EXIT; - fi; } @@ -492,10 +486,6 @@ unit_ctl_http() help_unit_ctl_http; exit 0; ;; - ---r | ----remote) - local remote="$2"; - shift; - ;; ---s | ----sock) local sock="$2"; shift; @@ -520,29 +510,8 @@ unit_ctl_http() fi; local req_path="$2"; - if test -v remote; then - local remote_sock="$(echo "$sock" | unit_sock_filter -s)"; - local local_sock="$(mktemp -u -p /var/run/unit/)"; - local ssh_ctrl="$(mktemp -u -p /var/run/unit/)"; - - mkdir -p /var/run/unit/; - - ssh -fMNnT -S "$ssh_ctrl" \ - -o 'ExitOnForwardFailure yes' \ - -L "$local_sock:$remote_sock" "$remote"; - - trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; - unlink '$local_sock'" EXIT; - - sock="unix:$local_sock"; - fi; - curl $curl_options -X $method -d@- \ $(echo "$sock" | unit_sock_filter -c)${req_path}; - - if test -v remote; then - run_trap EXIT; - fi; } @@ -577,10 +546,6 @@ unit_ctl_insert() help_unit_ctl_insert; exit 0; ;; - ---r | ----remote) - local remote="$2"; - shift; - ;; ---s | ----sock) local sock="$2"; shift; @@ -605,23 +570,6 @@ unit_ctl_insert() fi; local idx="$2"; - if test -v remote; then - local remote_sock="$(echo "$sock" | unit_sock_filter -s)"; - local local_sock="$(mktemp -u -p /var/run/unit/)"; - local ssh_ctrl="$(mktemp -u -p /var/run/unit/)"; - - mkdir -p /var/run/unit/; - - ssh -fMNnT -S "$ssh_ctrl" \ - -o 'ExitOnForwardFailure yes' \ - -L "$local_sock:$remote_sock" "$remote"; - - trap "ssh -S '$ssh_ctrl' -O exit '$remote' 2>/dev/null; - unlink '$local_sock'" EXIT; - - sock="unix:$local_sock"; - fi; - local old="$(mktemp)"; unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \ @@ -629,10 +577,6 @@ unit_ctl_insert() unit_json_ins "$old" "$idx" \ | unit_ctl_http ---s "$sock" PUT "$req_path"; - - if test -v remote; then - run_trap EXIT; - fi; } -- cgit From e9a0c49dbca628d8bfa6dbc8819846881b16b8b0 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 9 Feb 2024 14:01:56 +0100 Subject: Tools: setup-unit: Pass --fail-with-body to curl(1) Suggested-by: Liam Crilly Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/setup-unit b/tools/setup-unit index 8466e882..48e5c998 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -510,7 +510,7 @@ unit_ctl_http() fi; local req_path="$2"; - curl $curl_options -X $method -d@- \ + curl --fail-with-body $curl_options -X $method -d@- \ $(echo "$sock" | unit_sock_filter -c)${req_path}; } -- cgit From 565a8ed0183718deb4e14b3b3d67417db4a8092a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 9 Feb 2024 00:26:47 +0100 Subject: Tools: setup-unit: ctl edit: Print file name on error When editing the configuration in-place, it's easy to make a mistake. If the configuration is wrong, it will be passed to the control socket, which will reject it, keeping the old configuration. Those manual edits would be lost, which can make it very uncomfortable to edit in-place. By printing the name of the temporary file, we allow the user to recover the changes. Cc: Liam Crilly Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/setup-unit b/tools/setup-unit index 48e5c998..0df19070 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -138,6 +138,11 @@ OPTIONS __EOF__ } +info() +{ + >&2 echo "$(basename "$0"): info: $*"; +} + warn() { >&2 echo "$(basename "$0"): error: $*"; @@ -430,7 +435,11 @@ unit_ctl_edit() || echo ed; ) "$tmp"; + trap "info 'ctl: edit: Invalid configuration saved in <$tmp>.'" ERR + unit_ctl_http ---s "$sock" PUT "$req_path" <"$tmp"; + + trap - ERR; } -- cgit From bc093ab3ee72ca9606fea821fe5c4af221737331 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 9 Feb 2024 00:28:51 +0100 Subject: Tools: setup-unit: Fix error message Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/setup-unit b/tools/setup-unit index 0df19070..5fb7218e 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -417,7 +417,7 @@ unit_ctl_edit() done; if ! test $# -ge 1; then - err 'ctl: insert: PATH: Missing argument.'; + err 'ctl: edit: PATH: Missing argument.'; fi; local req_path="$1"; -- cgit From 6aa5ef63ce52df598b73c496955f1c0fddd01fb4 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Fri, 9 Feb 2024 00:49:07 +0100 Subject: Tools: setup-unit: ctl edit: Append suffix to tmp file name This allows the editor(1) to enable syntax highlighting. See suffixes(7). Cc: Liam Crilly Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- tools/setup-unit | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/setup-unit b/tools/setup-unit index 5fb7218e..a0dafe10 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -421,7 +421,12 @@ unit_ctl_edit() fi; local req_path="$1"; - local tmp="$(mktemp)"; + echo "$req_path" \ + | sed 's%^/js_modules/.*%.js%' \ + | sed 's%^/config\>.*%.json%' \ + | sed 's%^/.*%.txt%' \ + | xargs mktemp --suffix \ + | read -r tmp; unit_ctl_http ---s "$sock" -c --no-progress-meter GET "$req_path" \ "$tmp"; -- cgit From f71ead5fa5b8bae378a0eca2bedb689cf08a8eff Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 30 Jan 2024 09:14:39 +0000 Subject: Updated copyright notice. --- NOTICE | 18 +++++++++----- auto/endian | 2 +- docs/man/man8/unitd.8.in | 36 ++++++++++++++++++--------- pkg/deb/debian.module/copyright.unit-jsc11 | 18 +++++++++----- pkg/deb/debian.module/copyright.unit-jsc8 | 18 +++++++++----- pkg/deb/debian/copyright | 18 +++++++++----- pkg/docker/welcome.html | 2 +- pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 | 18 +++++++++----- pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 | 18 +++++++++----- src/test/nxt_rbtree1.c | 2 +- src/test/nxt_rbtree1.h | 2 +- tools/setup-unit | 2 +- tools/unitc | 2 +- 13 files changed, 102 insertions(+), 54 deletions(-) diff --git a/NOTICE b/NOTICE index 42d51c92..257f478c 100644 --- a/NOTICE +++ b/NOTICE @@ -1,13 +1,19 @@ NGINX Unit. - Copyright 2017-2023 NGINX, Inc. - Copyright 2017-2023 Andrei Zeliankou - Copyright 2018-2023 Konstantin Pavlov - Copyright 2021-2023 Zhidao Hong + Copyright 2017-2024 NGINX, Inc. + Copyright 2017-2024 Andrei Zeliankou + Copyright 2018-2024 Konstantin Pavlov + Copyright 2021-2024 Zhidao Hong + Copyright 2022-2024 Andrew Clayton + Copyright 2022-2024 Liam Crilly + Copyright 2023-2024 Dan Callahan + Copyright 2023-2024 Danielle De Leo + Copyright 2023-2024 Dylan Arbour + Copyright 2023-2024 Gabor Javorszky + Copyright 2023-2024 Igor Ippolitov + Copyright 2023-2024 Taryn Musgrave Copyright 2021-2023 Alejandro Colomar - Copyright 2022-2023 Andrew Clayton - Copyright 2022-2023 Liam Crilly Copyright 2017-2022 Valentin V. Bartenev Copyright 2017-2022 Max Romanov Copyright 2021-2022 Oisín Canty diff --git a/auto/endian b/auto/endian index cb23639b..40b5ad28 100644 --- a/auto/endian +++ b/auto/endian @@ -1,6 +1,6 @@ # Copyright (C) Igor Sysoev # Copyright (C) Andrew Clayton -# Copyright (C) Nginx, Inc. +# Copyright (C) NGINX, Inc. nxt_feature="endianness" diff --git a/docs/man/man8/unitd.8.in b/docs/man/man8/unitd.8.in index 01bb4218..70371cdf 100644 --- a/docs/man/man8/unitd.8.in +++ b/docs/man/man8/unitd.8.in @@ -1,10 +1,16 @@ -.\" (C) 2017-2023, NGINX, Inc. -.\" (C) 2017-2023 Andrei Zeliankou -.\" (C) 2018-2023 Konstantin Pavlov -.\" (C) 2021-2023 Zhidao Hong +.\" (C) 2017-2024 NGINX, Inc. +.\" (C) 2017-2024 Andrei Zeliankou +.\" (C) 2018-2024 Konstantin Pavlov +.\" (C) 2021-2024 Zhidao Hong +.\" (C) 2022-2024 Andrew Clayton +.\" (C) 2022-2024 Liam Crilly +.\" (C) 2023-2024 Dan Callahan +.\" (C) 2023-2024 Danielle De Leo +.\" (C) 2023-2024 Dylan Arbour +.\" (C) 2023-2024 Gabor Javorszky +.\" (C) 2023-2024 Igor Ippolitov +.\" (C) 2023-2024 Taryn Musgrave .\" (C) 2021-2023 Alejandro Colomar -.\" (C) 2022-2023 Andrew Clayton -.\" (C) 2022-2023 Liam Crilly .\" (C) 2017-2022 Valentin V. Bartenev .\" (C) 2017-2022 Max Romanov .\" (C) 2021-2022 Oisín Canty @@ -91,13 +97,19 @@ The socket address of Unit's control API. .El .Sh Copyright .nf -(C) 2017-2023, NGINX, Inc. -(C) 2017-2023 Andrei Zeliankou -(C) 2018-2023 Konstantin Pavlov -(C) 2021-2023 Zhidao Hong +(C) 2017-2024 NGINX, Inc. +(C) 2017-2024 Andrei Zeliankou +(C) 2018-2024 Konstantin Pavlov +(C) 2021-2024 Zhidao Hong +(C) 2022-2024 Andrew Clayton +(C) 2022-2024 Liam Crilly +(C) 2023-2024 Dan Callahan +(C) 2023-2024 Danielle De Leo +(C) 2023-2024 Dylan Arbour +(C) 2023-2024 Gabor Javorszky +(C) 2023-2024 Igor Ippolitov +(C) 2023-2024 Taryn Musgrave (C) 2021-2023 Alejandro Colomar -(C) 2022-2023 Andrew Clayton -(C) 2022-2023 Liam Crilly (C) 2017-2022 Valentin V. Bartenev (C) 2017-2022 Max Romanov (C) 2021-2022 Oisín Canty diff --git a/pkg/deb/debian.module/copyright.unit-jsc11 b/pkg/deb/debian.module/copyright.unit-jsc11 index e11b64d3..6e512e86 100644 --- a/pkg/deb/debian.module/copyright.unit-jsc11 +++ b/pkg/deb/debian.module/copyright.unit-jsc11 @@ -1,13 +1,19 @@ NGINX Unit. - Copyright 2017-2023 NGINX, Inc. - Copyright 2017-2023 Andrei Zeliankou - Copyright 2018-2023 Konstantin Pavlov - Copyright 2021-2023 Zhidao Hong + Copyright 2017-2024 NGINX, Inc. + Copyright 2017-2024 Andrei Zeliankou + Copyright 2018-2024 Konstantin Pavlov + Copyright 2021-2024 Zhidao Hong + Copyright 2022-2024 Andrew Clayton + Copyright 2022-2024 Liam Crilly + Copyright 2023-2024 Dan Callahan + Copyright 2023-2024 Danielle De Leo + Copyright 2023-2024 Dylan Arbour + Copyright 2023-2024 Gabor Javorszky + Copyright 2023-2024 Igor Ippolitov + Copyright 2023-2024 Taryn Musgrave Copyright 2021-2023 Alejandro Colomar - Copyright 2022-2023 Andrew Clayton - Copyright 2022-2023 Liam Crilly Copyright 2017-2022 Valentin V. Bartenev Copyright 2017-2022 Max Romanov Copyright 2021-2022 Oisín Canty diff --git a/pkg/deb/debian.module/copyright.unit-jsc8 b/pkg/deb/debian.module/copyright.unit-jsc8 index 1d267021..60da2dfa 100644 --- a/pkg/deb/debian.module/copyright.unit-jsc8 +++ b/pkg/deb/debian.module/copyright.unit-jsc8 @@ -1,13 +1,19 @@ NGINX Unit. - Copyright 2017-2023 NGINX, Inc. - Copyright 2017-2023 Andrei Zeliankou - Copyright 2018-2023 Konstantin Pavlov - Copyright 2021-2023 Zhidao Hong + Copyright 2017-2024 NGINX, Inc. + Copyright 2017-2024 Andrei Zeliankou + Copyright 2018-2024 Konstantin Pavlov + Copyright 2021-2024 Zhidao Hong + Copyright 2022-2024 Andrew Clayton + Copyright 2022-2024 Liam Crilly + Copyright 2023-2024 Dan Callahan + Copyright 2023-2024 Danielle De Leo + Copyright 2023-2024 Dylan Arbour + Copyright 2023-2024 Gabor Javorszky + Copyright 2023-2024 Igor Ippolitov + Copyright 2023-2024 Taryn Musgrave Copyright 2021-2023 Alejandro Colomar - Copyright 2022-2023 Andrew Clayton - Copyright 2022-2023 Liam Crilly Copyright 2017-2022 Valentin V. Bartenev Copyright 2017-2022 Max Romanov Copyright 2021-2022 Oisín Canty diff --git a/pkg/deb/debian/copyright b/pkg/deb/debian/copyright index 692ae2e0..dbc37146 100644 --- a/pkg/deb/debian/copyright +++ b/pkg/deb/debian/copyright @@ -1,13 +1,19 @@ NGINX Unit. - Copyright 2017-2023 NGINX, Inc. - Copyright 2017-2023 Andrei Zeliankou - Copyright 2018-2023 Konstantin Pavlov - Copyright 2021-2023 Zhidao Hong + Copyright 2017-2024 NGINX, Inc. + Copyright 2017-2024 Andrei Zeliankou + Copyright 2018-2024 Konstantin Pavlov + Copyright 2021-2024 Zhidao Hong + Copyright 2022-2024 Andrew Clayton + Copyright 2022-2024 Liam Crilly + Copyright 2023-2024 Dan Callahan + Copyright 2023-2024 Danielle De Leo + Copyright 2023-2024 Dylan Arbour + Copyright 2023-2024 Gabor Javorszky + Copyright 2023-2024 Igor Ippolitov + Copyright 2023-2024 Taryn Musgrave Copyright 2021-2023 Alejandro Colomar - Copyright 2022-2023 Andrew Clayton - Copyright 2022-2023 Liam Crilly Copyright 2017-2022 Valentin V. Bartenev Copyright 2017-2022 Max Romanov Copyright 2021-2022 Oisín Canty diff --git a/pkg/docker/welcome.html b/pkg/docker/welcome.html index 89de39e1..7167ddb7 100644 --- a/pkg/docker/welcome.html +++ b/pkg/docker/welcome.html @@ -40,6 +40,6 @@

NGINX Unit — the universal web app server
- NGINX, Inc. © 2023

+ NGINX, Inc. © 2024

diff --git a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 index 4505b5b5..e6372b97 100644 --- a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 +++ b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc11 @@ -1,13 +1,19 @@ NGINX Unit. - Copyright 2017-2023 NGINX, Inc. - Copyright 2017-2023 Andrei Zeliankou - Copyright 2018-2023 Konstantin Pavlov - Copyright 2021-2023 Zhidao Hong + Copyright 2017-2024 NGINX, Inc. + Copyright 2017-2024 Andrei Zeliankou + Copyright 2018-2024 Konstantin Pavlov + Copyright 2021-2024 Zhidao Hong + Copyright 2022-2024 Andrew Clayton + Copyright 2022-2024 Liam Crilly + Copyright 2023-2024 Dan Callahan + Copyright 2023-2024 Danielle De Leo + Copyright 2023-2024 Dylan Arbour + Copyright 2023-2024 Gabor Javorszky + Copyright 2023-2024 Igor Ippolitov + Copyright 2023-2024 Taryn Musgrave Copyright 2021-2023 Alejandro Colomar - Copyright 2022-2023 Andrew Clayton - Copyright 2022-2023 Liam Crilly Copyright 2017-2022 Valentin V. Bartenev Copyright 2017-2022 Max Romanov Copyright 2021-2022 Oisín Canty diff --git a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 index 59891951..174f2309 100644 --- a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 +++ b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc8 @@ -1,13 +1,19 @@ NGINX Unit. - Copyright 2017-2023 NGINX, Inc. - Copyright 2017-2023 Andrei Zeliankou - Copyright 2018-2023 Konstantin Pavlov - Copyright 2021-2023 Zhidao Hong + Copyright 2017-2024 NGINX, Inc. + Copyright 2017-2024 Andrei Zeliankou + Copyright 2018-2024 Konstantin Pavlov + Copyright 2021-2024 Zhidao Hong + Copyright 2022-2024 Andrew Clayton + Copyright 2022-2024 Liam Crilly + Copyright 2023-2024 Dan Callahan + Copyright 2023-2024 Danielle De Leo + Copyright 2023-2024 Dylan Arbour + Copyright 2023-2024 Gabor Javorszky + Copyright 2023-2024 Igor Ippolitov + Copyright 2023-2024 Taryn Musgrave Copyright 2021-2023 Alejandro Colomar - Copyright 2022-2023 Andrew Clayton - Copyright 2022-2023 Liam Crilly Copyright 2017-2022 Valentin V. Bartenev Copyright 2017-2022 Max Romanov Copyright 2021-2022 Oisín Canty diff --git a/src/test/nxt_rbtree1.c b/src/test/nxt_rbtree1.c index 1ae059ab..ec024858 100644 --- a/src/test/nxt_rbtree1.c +++ b/src/test/nxt_rbtree1.c @@ -1,7 +1,7 @@ /* * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. + * Copyright (C) NGINX, Inc. */ diff --git a/src/test/nxt_rbtree1.h b/src/test/nxt_rbtree1.h index 60048dad..d6230ab0 100644 --- a/src/test/nxt_rbtree1.h +++ b/src/test/nxt_rbtree1.h @@ -1,7 +1,7 @@ /* * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. + * Copyright (C) NGINX, Inc. */ diff --git a/tools/setup-unit b/tools/setup-unit index a0dafe10..688e87a1 100755 --- a/tools/setup-unit +++ b/tools/setup-unit @@ -760,7 +760,7 @@ unit_ctl_welcome()

NGINX Unit — the universal web app server
- NGINX, Inc. © 2023

+ NGINX, Inc. © 2024

__EOF__'; diff --git a/tools/unitc b/tools/unitc index 9b3557c5..9fba4c6d 100755 --- a/tools/unitc +++ b/tools/unitc @@ -1,7 +1,7 @@ #!/bin/bash # unitc - a curl wrapper for configuring NGINX Unit # https://github.com/nginx/unit/tree/master/tools -# NGINX, Inc. (c) 2023 +# NGINX, Inc. (c) 2024 # Defaults # -- cgit From 697a58506235e89af1c8cc3cafc92b3d85a3467d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Fri, 26 Jan 2024 14:58:43 +0000 Subject: Python: bytearray body support for ASGI module. @filiphanes requested support for bytearray and memoryview in the request body here: This patch implements bytearray body support only. Memoryview body still need to be implemented. --- docs/changes.xml | 6 ++++++ src/python/nxt_python_asgi_http.c | 31 +++++++++++++++++++------------ test/python/body_bytearray/asgi.py | 20 ++++++++++++++++++++ test/test_asgi_application.py | 8 ++++++++ 4 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 test/python/body_bytearray/asgi.py diff --git a/docs/changes.xml b/docs/changes.xml index 833ec20e..ba41f00d 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -78,6 +78,12 @@ can be used as a unique request identifier.
+ + +bytearray in response body for ASGI applications. + + + ServerRequest.flushHeaders() implemented in Node.js module to make it compatible diff --git a/src/python/nxt_python_asgi_http.c b/src/python/nxt_python_asgi_http.c index 05c0da4f..cdd6357e 100644 --- a/src/python/nxt_python_asgi_http.c +++ b/src/python/nxt_python_asgi_http.c @@ -362,16 +362,6 @@ nxt_py_asgi_http_response_body(nxt_py_asgi_http_t *http, PyObject *dict) Py_ssize_t body_len, body_off; nxt_py_asgi_ctx_data_t *ctx_data; - body = PyDict_GetItem(dict, nxt_py_body_str); - if (nxt_slow_path(body != NULL && !PyBytes_Check(body))) { - return PyErr_Format(PyExc_TypeError, "'body' is not a byte string"); - } - - more_body = PyDict_GetItem(dict, nxt_py_more_body_str); - if (nxt_slow_path(more_body != NULL && !PyBool_Check(more_body))) { - return PyErr_Format(PyExc_TypeError, "'more_body' is not a bool"); - } - if (nxt_slow_path(http->complete)) { return PyErr_Format(PyExc_RuntimeError, "Unexpected ASGI message 'http.response.body' " @@ -382,9 +372,26 @@ nxt_py_asgi_http_response_body(nxt_py_asgi_http_t *http, PyObject *dict) return PyErr_Format(PyExc_RuntimeError, "Concurrent send"); } + more_body = PyDict_GetItem(dict, nxt_py_more_body_str); + if (nxt_slow_path(more_body != NULL && !PyBool_Check(more_body))) { + return PyErr_Format(PyExc_TypeError, "'more_body' is not a bool"); + } + + body = PyDict_GetItem(dict, nxt_py_body_str); + if (body != NULL) { - body_str = PyBytes_AS_STRING(body); - body_len = PyBytes_GET_SIZE(body); + if (PyBytes_Check(body)) { + body_str = PyBytes_AS_STRING(body); + body_len = PyBytes_GET_SIZE(body); + + } else if (PyByteArray_Check(body)) { + body_str = PyByteArray_AS_STRING(body); + body_len = PyByteArray_GET_SIZE(body); + + } else { + return PyErr_Format(PyExc_TypeError, + "'body' is not a byte string or bytearray"); + } nxt_unit_req_debug(http->req, "asgi_http_response_body: %d, %d", (int) body_len, (more_body == Py_True) ); diff --git a/test/python/body_bytearray/asgi.py b/test/python/body_bytearray/asgi.py new file mode 100644 index 00000000..6d2f402f --- /dev/null +++ b/test/python/body_bytearray/asgi.py @@ -0,0 +1,20 @@ +async def application(scope, receive, send): + assert scope['type'] == 'http' + + body = b'' + while True: + m = await receive() + body += m.get('body', b'') + if not m.get('more_body', False): + body = bytearray(body) + break + + await send( + { + 'type': 'http.response.start', + 'status': 200, + 'headers': [(b'content-length', str(len(body)).encode())], + } + ) + + await send({'type': 'http.response.body', 'body': body}) diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index e6668b2f..226a1ed7 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -218,6 +218,14 @@ def test_asgi_application_shm_ack_handle(): assert resp['body'] == body, 'keep-alive 1' +def test_asgi_application_body_bytearray(): + client.load('body_bytearray') + + body = '0123456789' + + assert client.post(body=body)['body'] == body + + def test_asgi_keepalive_body(): client.load('mirror') -- cgit From 56d3a1a72b3db74ac3bf8b7665428a3cd15056bd Mon Sep 17 00:00:00 2001 From: Dylan Arbour Date: Mon, 18 Dec 2023 18:09:32 -0500 Subject: Add GitHub Actions This commit adds GitHub Actions configuration, running tests on pull-requests and master push changes. This change is meant to be a first-pass at our evolving CI processes. - Tests run in parallel per language for speed and isolation - Test matrix is composed by a string list of languages and versions - `setup-${language}` actions are preferred over base (and changing) versions from `ubuntu-latest` operating system A few caveats with the current setup: - Only tests on Ubuntu (no FreeBSD or Alpine) - Unpriviledged tests only - No core dumps available on failure --- .github/workflows/ci.yml | 335 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..42ca7896 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,335 @@ +name: ci + +on: + pull_request: + push: + branches: + - master + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + # Core + - build: unit + os: ubuntu-latest + # Modules + - build: go-1.21 + os: ubuntu-latest + - build: go-1.22 + os: ubuntu-latest + - build: java-17 + os: ubuntu-latest + - build: java-18 + os: ubuntu-latest + - build: java-21 + os: ubuntu-latest + - build: node-20 + os: ubuntu-latest + - build: node-21 + os: ubuntu-latest + - build: perl + os: ubuntu-latest + - build: php-8.3 + os: ubuntu-latest + - build: python-3.11 + os: ubuntu-latest + - build: python-3.12 + os: ubuntu-latest + - build: ruby-3.2 + os: ubuntu-latest + - build: ruby-3.3 + os: ubuntu-latest + - build: wasm + os: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + # Creates and outputs directories used by tests (/usr/local is unfriendly) + - name: Configure directories + id: dir + run: | + PREFIX=${HOME}/.unit + BIN=${PREFIX}/bin + VAR=${PREFIX}/var + mkdir -p $BIN + mkdir -p $VAR + + echo "prefix=${PREFIX}" >> "$GITHUB_OUTPUT" + echo "bin=${BIN}" >> "$GITHUB_OUTPUT" + echo "bin=${BIN}" >> "$GITHUB_PATH" + echo "var=${VAR}" >> "$GITHUB_OUTPUT" + cat "$GITHUB_OUTPUT" + + # Provides module, language version and testpath from build name + - name: Output build metadata + id: metadata + run: | + # Split the build name by '-' into module and version + IFS='-' read -r module version <<< "${{ matrix.build }}" + + testpath="test/test_${module}*" + + # Run all tests for "unit" and "python" + # Python is the default module for tests + if [ "$module" = "unit" ] || [ "$module" = "python" ]; then + testpath="test" + fi + + echo "module=${module}" >> "$GITHUB_OUTPUT" + echo "version=${version}" >> "$GITHUB_OUTPUT" + echo "testpath=${testpath}" >> "$GITHUB_OUTPUT" + + NJS_VERSION=$(sed -n "s/NJS_VERSION := \(.*\)/\1/p" pkg/contrib/src/njs/version) + echo "njs_version=${NJS_VERSION}" >> "$GITHUB_OUTPUT" + + cat "$GITHUB_OUTPUT" + + # https://github.com/actions/runner-images/issues/2821 + - name: Kill mono process + run: | + sudo systemctl stop mono-xsp4.service + sudo systemctl mask mono-xsp4.service + sudo systemctl status mono-xsp4.service || true + PID=$(sudo lsof -t -i :8084) + echo "Killing PID $PID" + sudo kill -9 $PID + + ## + ## njs + ## + + - name: Clone njs repository + uses: actions/checkout@v4 + with: + repository: nginx/njs + ref: '${{ steps.metadata.outputs.njs_version }}' + path: njs + + - name: Make njs + run: | + ./configure --no-libxml2 --no-zlib + make -j4 -k + working-directory: njs + + ## + ## Unit + ## + + - name: Configure unit + run: | + ./configure \ + --prefix=${{ steps.dir.outputs.prefix }} \ + --sbindir=${{ steps.dir.outputs.bin }} \ + --logdir=${{ steps.dir.outputs.var }}/log \ + --log=${{ steps.dir.outputs.var }}/log/unit/unit.log \ + --runstatedir=${{ steps.dir.outputs.var }}/run \ + --pid=${{ steps.dir.outputs.var }}/run/unit/unit.pid \ + --control=unix:${{ steps.dir.outputs.var }}/run/unit/control.sock \ + --modules=${{ steps.dir.outputs.prefix }}/lib/unit/modules \ + --statedir=${{ steps.dir.outputs.var }}/state/unit \ + --tests \ + --openssl \ + --njs \ + --cc-opt="-I njs/src/ -I njs/build" \ + --ld-opt="-L njs/build" \ + --debug + + - name: Make unit + run: | + make -j4 -k || make + + ## + ## Go + ## + + - uses: actions/setup-go@v4 + with: + go-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'go' + + - name: Configure go + run: | + ./configure go --go-path= + if: steps.metadata.outputs.module == 'go' + + - name: Make go + run: | + make go + make go-install + if: steps.metadata.outputs.module == 'go' + + ## + ## Java + ## + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'java' + + - name: Configure java + run: | + ./configure java + if: steps.metadata.outputs.module == 'java' + + - name: Make java + run: | + make java + if: steps.metadata.outputs.module == 'java' + + ## + ## Node + ## + + - uses: actions/setup-node@v4 + with: + node-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'node' + + - name: Install node-gyp + run: | + npm install -g node-gyp + if: steps.metadata.outputs.module == 'node' + + - name: Configure node + run: | + ./configure nodejs + if: steps.metadata.outputs.module == 'node' + + - name: Make node + run: | + make node-local-install DESTDIR=node + if: steps.metadata.outputs.module == 'node' + + ## + ## Perl + ## + + # Uses default Actions VM Perl + # https://github.com/actions/runner-images#available-images + + - name: Install libperl-dev + run: | + sudo apt-get install libperl-dev + if: steps.metadata.outputs.module == 'perl' + + - name: Configure perl + run: | + ./configure perl + if: steps.metadata.outputs.module == 'perl' + + - name: Make perl + run: | + make perl + if: steps.metadata.outputs.module == 'perl' + + ## + ## PHP + ## + + - uses: shivammathur/setup-php@v2 + with: + php-version: '${{ steps.metadata.outputs.version }}' + extensions: none + env: + update: true + if: steps.metadata.outputs.module == 'php' + + - name: Configure php + run: | + ./configure php + if: steps.metadata.outputs.module == 'php' + + - name: Make php + run: | + make php + if: steps.metadata.outputs.module == 'php' + + ## + ## Python 3 + ## + + - uses: actions/setup-python@v5 + with: + python-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'python' + + - name: Configure python3 + run: | + ./configure python --config=python3-config + if: steps.metadata.outputs.module == 'python' + + - name: Make python3 + run: | + make python3 + if: steps.metadata.outputs.module == 'python' + + ## + ## Ruby + ## + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '${{ steps.metadata.outputs.version }}' + if: steps.metadata.outputs.module == 'ruby' + + - name: Install rack + run: | + gem install rack + if: steps.metadata.outputs.module == 'ruby' + + - name: Configure ruby + run: | + ./configure ruby + if: steps.metadata.outputs.module == 'ruby' + + - name: Make ruby + run: | + make ruby + if: steps.metadata.outputs.module == 'ruby' + + ## + ## Wasm + ## + + - name: Make wasmtime + run: | + make -C pkg/contrib .wasmtime + if: steps.metadata.outputs.module == 'wasm' + + - name: Configure wasm + run: | + ./configure wasm --include-path=pkg/contrib/wasmtime/crates/c-api/include --lib-path=pkg/contrib/wasmtime/target/release + if: steps.metadata.outputs.module == 'wasm' + + - name: Make wasm + run: | + make wasm + if: steps.metadata.outputs.module == 'wasm' + + ## + ## Tests + ## + + # Install python3 if not present + - uses: actions/setup-python@v5 + with: + python-version: '3' + if: steps.metadata.outputs.module != 'wasm' + + - name: Install pytest + run: | + pip install pytest + if: steps.metadata.outputs.module != 'wasm' + + - name: Run ${{ steps.metadata.outputs.module }} tests + run: | + pytest --print-log ${{ steps.metadata.outputs.testpath }} + # Skip pytest if wasm build, as there are no tests yet + if: steps.metadata.outputs.module != 'wasm' -- cgit From bca44630ed50da036da056f0f89c48f9a30a19cc Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 21 Feb 2024 16:06:42 +0000 Subject: .mailmap: Map Dylan's GitHub address Signed-off-by: Andrew Clayton --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index d1dc863a..23a492fa 100644 --- a/.mailmap +++ b/.mailmap @@ -8,6 +8,7 @@ Andrew Clayton Artem Konev <41629299+artemkonev@users.noreply.github.com> Dan Callahan Danielle De Leo +Dylan Arbour Konstantin Pavlov Konstantin Pavlov Max Romanov -- cgit From f2e6447567eef6eeafa833adae0ef155568ec20f Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 5 Feb 2024 21:32:00 +0000 Subject: Wasm-wc: Register a new Wasm component model language module type This is the first commit in adding WebAssembly Component Model language module support. This just adds a new NXT_APP_WASM_WC type, required by subsequent commits. The WC stands for WASI_COMPONENT This new module will have a type of 'wasm-wasi-component'. Link: Signed-off-by: Andrew Clayton --- src/nxt_application.h | 1 + src/nxt_router.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/nxt_application.h b/src/nxt_application.h index 64866db6..f526c20d 100644 --- a/src/nxt_application.h +++ b/src/nxt_application.h @@ -22,6 +22,7 @@ typedef enum { NXT_APP_RUBY, NXT_APP_JAVA, NXT_APP_WASM, + NXT_APP_WASM_WC, NXT_APP_UNKNOWN, } nxt_app_type_t; diff --git a/src/nxt_router.c b/src/nxt_router.c index 947836c8..1a1aca2b 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -281,6 +281,7 @@ static const nxt_str_t *nxt_app_msg_prefix[] = { [NXT_APP_RUBY] = &http_prefix, [NXT_APP_JAVA] = &empty_prefix, [NXT_APP_WASM] = &empty_prefix, + [NXT_APP_WASM_WC] = &empty_prefix, }; -- cgit From f0782722654158c38193183e4c9b74925a0c52ef Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 5 Feb 2024 21:43:14 +0000 Subject: Wasm-wc: Add core configuration data structure This is required to actually _build_ the 'wasm-wasi-componet' language module. The nxt_wasm_wc_app_conf_t structure consists of the component name, e.g my_component.wasm, this is required. It also consists of an object to store the directories that are allowed access to by the component, this is optional. The bulk of the configuration infrastructure will be added in a subsequent commit. Signed-off-by: Andrew Clayton --- src/nxt_application.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nxt_application.h b/src/nxt_application.h index f526c20d..f5d7a9df 100644 --- a/src/nxt_application.h +++ b/src/nxt_application.h @@ -105,6 +105,13 @@ typedef struct { } nxt_wasm_app_conf_t; +typedef struct { + const char *component; + + nxt_conf_value_t *access; +} nxt_wasm_wc_app_conf_t; + + struct nxt_common_app_conf_s { nxt_str_t name; nxt_str_t type; @@ -134,6 +141,7 @@ struct nxt_common_app_conf_s { nxt_ruby_app_conf_t ruby; nxt_java_app_conf_t java; nxt_wasm_app_conf_t wasm; + nxt_wasm_wc_app_conf_t wasm_wc; } u; nxt_conf_value_t *self; -- cgit From 20ada4b5c135862104ca724a6d9d17730286aa82 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 29 Oct 2023 15:13:56 -0700 Subject: Wasm-wc: Core of initial Wasm component model language module support This is the work of Alex Crichton. This is written in Rust. The problem is that there is currently no support on the C side of things for the component model, which is the point of this module. It talks to Unit via automatically generated bindings. I've (Andrew) just made some minor tweaks to src/lib.rs, build.rs & Cargo.toml to adjust some paths, adjust where we get the language module config from and the module name and where it's located in the source tree, I also removed and disabled the tracking of the Cargo.lock file, this is constantly changing and not tracking it seems right for 'libraries' and dropped the README's... Other than that I have tried to leave his work intact, subsequent commits will make some larger changes, but I didn't want to intermix them with Alex's work. One such commit will update the module to use wasmtime 17 which brings WASI 0.2.0 support. Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/.gitignore | 3 + src/wasm-wasi-component/Cargo.toml | 30 ++ src/wasm-wasi-component/build.rs | 33 +++ src/wasm-wasi-component/src/lib.rs | 549 +++++++++++++++++++++++++++++++++++++ src/wasm-wasi-component/wrapper.h | 5 + 5 files changed, 620 insertions(+) create mode 100644 src/wasm-wasi-component/.gitignore create mode 100644 src/wasm-wasi-component/Cargo.toml create mode 100644 src/wasm-wasi-component/build.rs create mode 100644 src/wasm-wasi-component/src/lib.rs create mode 100644 src/wasm-wasi-component/wrapper.h diff --git a/src/wasm-wasi-component/.gitignore b/src/wasm-wasi-component/.gitignore new file mode 100644 index 00000000..159e3885 --- /dev/null +++ b/src/wasm-wasi-component/.gitignore @@ -0,0 +1,3 @@ +Cargo.lock + +target diff --git a/src/wasm-wasi-component/Cargo.toml b/src/wasm-wasi-component/Cargo.toml new file mode 100644 index 00000000..8f42d128 --- /dev/null +++ b/src/wasm-wasi-component/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "wasm-wasi-component" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +anyhow = "1.0.75" +bytes = "1.5.0" +futures-util = { version = "0.3.29", default-features = false } +http = "0.2.9" +http-body = { version = "1.0.0-rc.2", default-features = false } +http-body-util = "0.1.0-rc.2" +tokio = { version = "1.33.0", default-features = false } +wasmtime = "14.0.2" +wasmtime-wasi = "14.0.2" +wasmtime-wasi-http = "14.0.2" + +[build-dependencies] +bindgen = "0.68.1" +cc = "1.0.83" + +[profile.dev] +panic = 'abort' + +[profile.release] +panic = 'abort' diff --git a/src/wasm-wasi-component/build.rs b/src/wasm-wasi-component/build.rs new file mode 100644 index 00000000..5ea74f17 --- /dev/null +++ b/src/wasm-wasi-component/build.rs @@ -0,0 +1,33 @@ +use std::env; +use std::path::PathBuf; + +fn main() { + // Tell cargo to invalidate the built crate whenever the wrapper changes + println!("cargo:rerun-if-changed=wrapper.h"); + + let bindings = bindgen::Builder::default() + .clang_args(["-I", "../"]) + .clang_args(["-I", "../../build/include"]) + .header("./wrapper.h") + // only generate bindings for `nxt_*` header files + .allowlist_file(".*nxt_.*.h") + // generates an "improper_ctypes" warning and we don't need it anyway + .blocklist_function("nxt_vsprintf") + // Tell cargo to invalidate the built crate whenever any of the + // included header files changed. + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + // disable some features which aren't necessary + .layout_tests(false) + .derive_debug(false) + .generate() + .expect("Unable to generate bindings"); + + cc::Build::new() + .object("../../build/src/nxt_unit.o") + .compile("nxt-unit"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs new file mode 100644 index 00000000..54d99616 --- /dev/null +++ b/src/wasm-wasi-component/src/lib.rs @@ -0,0 +1,549 @@ +use anyhow::{bail, Context, Result}; +use bytes::{Bytes, BytesMut}; +use http_body_util::combinators::BoxBody; +use http_body_util::{BodyExt, Full}; +use std::ffi::{CStr, CString}; +use std::mem::MaybeUninit; +use std::ptr; +use std::sync::OnceLock; +use tokio::sync::mpsc; +use wasmtime::component::{Component, InstancePre, Linker}; +use wasmtime::{Config, Engine, Store}; +use wasmtime_wasi::preview2::{DirPerms, FilePerms, Table, WasiCtx, WasiCtxBuilder, WasiView}; +use wasmtime_wasi::{ambient_authority, Dir}; +use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; + +#[allow( + non_camel_case_types, + non_upper_case_globals, + non_snake_case, + dead_code +)] +mod bindings { + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + + pub const fn nxt_string(s: &'static str) -> nxt_str_t { + nxt_str_t { + start: s.as_ptr().cast_mut(), + length: s.len(), + } + } + + pub unsafe fn nxt_unit_sptr_get(sptr: &nxt_unit_sptr_t) -> *const u8 { + sptr.base.as_ptr().offset(sptr.offset as isize) + } +} + +#[no_mangle] +pub static mut nxt_app_module: bindings::nxt_app_module_t = { + const COMPAT: [u32; 2] = [bindings::NXT_VERNUM, bindings::NXT_DEBUG]; + let version = "0.1\0"; + bindings::nxt_app_module_t { + compat: COMPAT.as_ptr().cast_mut(), + compat_length: COMPAT.len() * 4, + mounts: ptr::null(), + nmounts: 0, + type_: bindings::nxt_string("wasm-wasi-component"), + version: version.as_ptr().cast(), + setup: Some(setup), + start: Some(start), + } +}; + +static GLOBAL_CONFIG: OnceLock = OnceLock::new(); +static GLOBAL_STATE: OnceLock = OnceLock::new(); + +unsafe extern "C" fn setup( + task: *mut bindings::nxt_task_t, + // TODO: should this get used? + _process: *mut bindings::nxt_process_t, + conf: *mut bindings::nxt_common_app_conf_t, +) -> bindings::nxt_int_t { + handle_result(task, || { + let wasm_conf = &(*conf).u.wasm_wc; + let component = CStr::from_ptr(wasm_conf.component).to_str()?; + let mut dirs = Vec::new(); + if !wasm_conf.access.is_null() { + let dirs_ptr = bindings::nxt_conf_get_object_member( + wasm_conf.access, + &mut bindings::nxt_string("filesystem"), + ptr::null_mut(), + ); + for i in 0..bindings::nxt_conf_object_members_count(dirs_ptr) { + let value = bindings::nxt_conf_get_array_element(dirs_ptr, i.try_into().unwrap()); + let mut s = bindings::nxt_string(""); + bindings::nxt_conf_get_string(value, &mut s); + dirs.push( + std::str::from_utf8(std::slice::from_raw_parts(s.start, s.length))?.to_string(), + ); + } + } + + let result = GLOBAL_CONFIG.set(GlobalConfig { + component: component.to_string(), + dirs, + }); + assert!(result.is_ok()); + Ok(()) + }) +} + +unsafe extern "C" fn start( + task: *mut bindings::nxt_task_t, + data: *mut bindings::nxt_process_data_t, +) -> bindings::nxt_int_t { + handle_result(task, || { + let config = GLOBAL_CONFIG.get().unwrap(); + let state = GlobalState::new(&config).context("failed to create initial state")?; + let res = GLOBAL_STATE.set(state); + assert!(res.is_ok()); + + let conf = (*data).app; + let mut wasm_init = MaybeUninit::uninit(); + let ret = bindings::nxt_unit_default_init(task, wasm_init.as_mut_ptr(), conf); + if ret != bindings::NXT_OK as bindings::nxt_int_t { + bail!("nxt_unit_default_init() failed"); + } + let mut wasm_init = wasm_init.assume_init(); + wasm_init.callbacks.request_handler = Some(request_handler); + + let unit_ctx = bindings::nxt_unit_init(&mut wasm_init); + if unit_ctx.is_null() { + bail!("nxt_unit_init() failed"); + } + + bindings::nxt_unit_run(unit_ctx); + bindings::nxt_unit_done(unit_ctx); + + Ok(()) + }) +} + +unsafe fn handle_result( + task: *mut bindings::nxt_task_t, + func: impl FnOnce() -> Result<()>, +) -> bindings::nxt_int_t { + let rc = match func() { + Ok(()) => bindings::NXT_OK as bindings::nxt_int_t, + Err(e) => { + alert(task, &format!("{e:?}")); + bindings::NXT_ERROR as bindings::nxt_int_t + } + }; + return rc; + + unsafe fn alert(task: *mut bindings::nxt_task_t, msg: &str) { + let log = (*task).log; + let msg = CString::new(msg).unwrap(); + ((*log).handler).unwrap()( + bindings::NXT_LOG_ALERT as bindings::nxt_uint_t, + log, + "%s\0".as_ptr().cast(), + msg.as_ptr(), + ); + } +} + +unsafe extern "C" fn request_handler(info: *mut bindings::nxt_unit_request_info_t) { + // Enqueue this request to get processed by the Tokio event loop, and + // otherwise immediately return. + let state = GLOBAL_STATE.get().unwrap(); + state.sender.blocking_send(NxtRequestInfo { info }).unwrap(); +} + +struct GlobalConfig { + component: String, + dirs: Vec, +} + +struct GlobalState { + engine: Engine, + component: InstancePre, + global_config: &'static GlobalConfig, + sender: mpsc::Sender, +} + +impl GlobalState { + fn new(global_config: &'static GlobalConfig) -> Result { + // Configure Wasmtime, e.g. the component model and async support are + // enabled here. Other configuration can include: + // + // * Epochs/fuel - enables async yielding to prevent any one request + // starving others. + // * Pooling allocator - accelerates instantiation at the cost of a + // large virtual memory reservation. + // * Memory limits/etc. + let mut config = Config::new(); + config.wasm_component_model(true); + config.async_support(true); + let engine = Engine::new(&config)?; + + // Compile the binary component on disk in Wasmtime. This is then + // pre-instantiated with host APIs defined by WASI. The result of + // this is a "pre-instantiated instance" which can be used to + // repeatedly instantiate later on. This will frontload + // compilation/linking/type-checking/etc to happen once rather than on + // each request. + let component = Component::from_file(&engine, &global_config.component) + .context("failed to compile component")?; + let mut linker = Linker::::new(&engine); + wasmtime_wasi_http::proxy::add_to_linker(&mut linker)?; + let component = linker + .instantiate_pre(&component) + .context("failed to pre-instantiate the provided component")?; + + // Spin up the Tokio async runtime in a separate thread with a + // communication channel into it. This thread will send requests to + // Tokio and the results will be calculated there. + let (sender, receiver) = mpsc::channel(10); + std::thread::spawn(|| GlobalState::run(receiver)); + + Ok(GlobalState { + engine, + component, + sender, + global_config, + }) + } + + /// Worker thread that executes the Tokio runtime, infinitely receiving + /// messages from the provided `receiver` and handling those requests. + /// + /// Each request is handled in a separate subtask so processing can all + /// happen concurrently. + fn run(mut receiver: mpsc::Receiver) { + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + while let Some(msg) = receiver.recv().await { + let state = GLOBAL_STATE.get().unwrap(); + tokio::task::spawn(async move { + state.handle(msg).await.expect("failed to handle request") + }); + } + }); + } + + async fn handle(&'static self, mut info: NxtRequestInfo) -> Result<()> { + // Create a "Store" which is the unit of per-request isolation in + // Wasmtime. + let data = StoreState { + ctx: { + let mut cx = WasiCtxBuilder::new(); + // NB: while useful for debugging untrusted code probably + // shouldn't get raw access to stdout/stderr. + cx.inherit_stdout(); + cx.inherit_stderr(); + for dir in self.global_config.dirs.iter() { + let fd = Dir::open_ambient_dir(dir, ambient_authority()) + .with_context(|| format!("failed to open directory '{dir}'"))?; + cx.preopened_dir(fd, DirPerms::all(), FilePerms::all(), dir); + } + cx.build() + }, + table: Table::default(), + http: WasiHttpCtx, + }; + let mut store = Store::new(&self.engine, data); + + // Convert the `nxt_*` representation into the representation required + // by Wasmtime's `wasi-http` implementation using the Rust `http` + // crate. + let request = self.to_request_builder(&info)?; + let body = self.to_request_body(&mut info); + let request = request.body(body)?; + + let (sender, receiver) = tokio::sync::oneshot::channel(); + + // Instantiate the WebAssembly component and invoke its `handle` + // function which receives a request and where to put a response. + // + // Note that this is done in a sub-task to work concurrently with + // writing the response when it's available. This enables wasm to + // generate headers, write those below, and then compute the body + // afterwards. + let task = tokio::spawn(async move { + let (proxy, _) = + wasmtime_wasi_http::proxy::Proxy::instantiate_pre(&mut store, &self.component) + .await + .context("failed to instantiate")?; + let req = store.data_mut().new_incoming_request(request)?; + let out = store.data_mut().new_response_outparam(sender)?; + proxy + .wasi_http_incoming_handler() + .call_handle(&mut store, req, out) + .await + .context("failed to invoke wasm `handle`")?; + Ok::<_, anyhow::Error>(()) + }); + + // Wait for the wasm to produce the initial response. If this succeeds + // then propagate that failure. If this fails then wait for the above + // task to complete to see if it failed, otherwise panic since that's + // unexpected. + let response = match receiver.await { + Ok(response) => response.context("response generation failed")?, + Err(_) => { + task.await.unwrap()?; + panic!("sender of response disappeared"); + } + }; + + // Send the headers/status which will extract the body for the next + // phase. + let body = self.send_response(&mut info, response); + + // Send the body, a blocking operation, over time as it becomes + // available. + self.send_response_body(&mut info, body) + .await + .context("failed to write response body")?; + + // Join on completion of the wasm task which should be done by this + // point. + task.await.unwrap()?; + + // And finally signal that we're done. + info.request_done(); + + Ok(()) + } + + fn to_request_builder(&self, info: &NxtRequestInfo) -> Result { + let mut request = http::Request::builder(); + + request = request.method(info.method()); + request = match info.version() { + "HTTP/0.9" => request.version(http::Version::HTTP_09), + "HTTP/1.0" => request.version(http::Version::HTTP_10), + "HTTP/1.1" => request.version(http::Version::HTTP_11), + "HTTP/2.0" => request.version(http::Version::HTTP_2), + "HTTP/3.0" => request.version(http::Version::HTTP_3), + version => { + println!("unknown version: {version}"); + request + } + }; + + let uri = http::Uri::builder() + .scheme(if info.tls() { "https" } else { "http" }) + .authority(info.server_name()) + .path_and_query(info.target()) + .build() + .context("failed to build URI")?; + request = request.uri(uri); + + for (name, value) in info.fields() { + request = request.header(name, value); + } + Ok(request) + } + + fn to_request_body(&self, info: &mut NxtRequestInfo) -> BoxBody { + // TODO: should convert the body into a form of `Stream` to become an async + // stream of frames. The return value can represent that here but for now + // this slurps up the entire body into memory and puts it all in a single + // `BytesMut` which is then converted to `Bytes`. + let mut body = BytesMut::with_capacity(info.content_length().try_into().unwrap()); + + // TODO: can this perform a partial read? + // TODO: how to make this async at the nxt level? + info.request_read(&mut body); + + Full::new(body.freeze()).map_err(|e| match e {}).boxed() + } + + fn send_response(&self, info: &mut NxtRequestInfo, response: http::Response) -> T { + info.init_response( + response.status().as_u16(), + response.headers().len().try_into().unwrap(), + response + .headers() + .iter() + .map(|(k, v)| k.as_str().len() + v.len()) + .sum::() + .try_into() + .unwrap(), + ); + for (k, v) in response.headers() { + info.add_field(k.as_str().as_bytes(), v.as_bytes()); + } + info.send_response(); + + response.into_body() + } + + async fn send_response_body( + &self, + info: &mut NxtRequestInfo, + mut body: BoxBody, + ) -> Result<()> { + loop { + // Acquire the next frame, and because nothing is actually async at the + // moment this should never block meaning that the `Pending` case + // should not happen. + let frame = match body.frame().await { + Some(Ok(frame)) => frame, + Some(Err(e)) => break Err(e), + None => break Ok(()), + }; + match frame.data_ref() { + Some(data) => { + info.response_write(&data); + } + None => { + // TODO: what to do with trailers? + } + } + } + } +} + +struct NxtRequestInfo { + info: *mut bindings::nxt_unit_request_info_t, +} + +// TODO: is this actually safe? +unsafe impl Send for NxtRequestInfo {} +unsafe impl Sync for NxtRequestInfo {} + +impl NxtRequestInfo { + fn method(&self) -> &str { + unsafe { + let raw = (*self.info).request; + self.get_str(&(*raw).method, (*raw).method_length.into()) + } + } + + fn tls(&self) -> bool { + unsafe { (*(*self.info).request).tls != 0 } + } + + fn version(&self) -> &str { + unsafe { + let raw = (*self.info).request; + self.get_str(&(*raw).version, (*raw).version_length.into()) + } + } + + fn server_name(&self) -> &str { + unsafe { + let raw = (*self.info).request; + self.get_str(&(*raw).server_name, (*raw).server_name_length.into()) + } + } + + fn target(&self) -> &str { + unsafe { + let raw = (*self.info).request; + self.get_str(&(*raw).target, (*raw).target_length.into()) + } + } + + fn content_length(&self) -> u64 { + unsafe { + let raw_request = (*self.info).request; + (*raw_request).content_length + } + } + + fn fields(&self) -> impl Iterator { + unsafe { + let raw = (*self.info).request; + (0..(*raw).fields_count).map(move |i| { + let field = (*raw).fields.as_ptr().add(i as usize); + let name = self.get_str(&(*field).name, (*field).name_length.into()); + let value = self.get_str(&(*field).value, (*field).value_length.into()); + (name, value) + }) + } + } + + fn request_read(&mut self, dst: &mut BytesMut) { + unsafe { + let rest = dst.spare_capacity_mut(); + let amt = + bindings::nxt_unit_request_read(self.info, rest.as_mut_ptr().cast(), rest.len()); + // TODO: handle failure when `amt` is negative + let amt: usize = amt.try_into().unwrap(); + dst.set_len(dst.len() + amt); + } + } + + fn response_write(&mut self, data: &[u8]) { + unsafe { + let rc = bindings::nxt_unit_response_write(self.info, data.as_ptr().cast(), data.len()); + assert_eq!(rc, 0); + } + } + + fn init_response(&mut self, status: u16, headers: u32, headers_size: u32) { + unsafe { + let rc = bindings::nxt_unit_response_init(self.info, status, headers, headers_size); + assert_eq!(rc, 0); + } + } + + fn add_field(&mut self, key: &[u8], val: &[u8]) { + unsafe { + let rc = bindings::nxt_unit_response_add_field( + self.info, + key.as_ptr().cast(), + key.len().try_into().unwrap(), + val.as_ptr().cast(), + val.len().try_into().unwrap(), + ); + assert_eq!(rc, 0); + } + } + + fn send_response(&mut self) { + unsafe { + let rc = bindings::nxt_unit_response_send(self.info); + assert_eq!(rc, 0); + } + } + + fn request_done(self) { + unsafe { + bindings::nxt_unit_request_done(self.info, bindings::NXT_UNIT_OK as i32); + } + } + + unsafe fn get_str(&self, ptr: &bindings::nxt_unit_sptr_t, len: u32) -> &str { + let ptr = bindings::nxt_unit_sptr_get(ptr); + let slice = std::slice::from_raw_parts(ptr, len.try_into().unwrap()); + std::str::from_utf8(slice).unwrap() + } +} + +struct StoreState { + ctx: WasiCtx, + http: WasiHttpCtx, + table: Table, +} + +impl WasiView for StoreState { + fn table(&self) -> &Table { + &self.table + } + fn table_mut(&mut self) -> &mut Table { + &mut self.table + } + fn ctx(&self) -> &WasiCtx { + &self.ctx + } + fn ctx_mut(&mut self) -> &mut WasiCtx { + &mut self.ctx + } +} + +impl WasiHttpView for StoreState { + fn ctx(&mut self) -> &mut WasiHttpCtx { + &mut self.http + } + fn table(&mut self) -> &mut Table { + &mut self.table + } +} + +impl StoreState {} diff --git a/src/wasm-wasi-component/wrapper.h b/src/wasm-wasi-component/wrapper.h new file mode 100644 index 00000000..93f3014a --- /dev/null +++ b/src/wasm-wasi-component/wrapper.h @@ -0,0 +1,5 @@ +#include +#include +#include +#include +#include -- cgit From a9345dd46e44a5294340ace1bced48fd6d6225d3 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 6 Feb 2024 16:19:41 +0000 Subject: Add a .rustfmt.toml file This is used by the rustfmt program to format Rust code according to the rules contained in this file. Currently we just set the line width limit to 80 characters to match our C code. Signed-off-by: Andrew Clayton --- .rustfmt.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .rustfmt.toml diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 00000000..df99c691 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +max_width = 80 -- cgit From 79c817724799a3c6ce88693b188926b4e626807f Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 6 Feb 2024 16:33:59 +0000 Subject: Wasm-wc: Run src/lib.rs through rustfmt Run from the repository root like $ rustfmt --edition 2021 src/wasm-wasi-component/src/lib.rs Also manually fix up some overly long comments. Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/src/lib.rs | 115 +++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 31 deletions(-) diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index 54d99616..da78ea6e 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -9,7 +9,9 @@ use std::sync::OnceLock; use tokio::sync::mpsc; use wasmtime::component::{Component, InstancePre, Linker}; use wasmtime::{Config, Engine, Store}; -use wasmtime_wasi::preview2::{DirPerms, FilePerms, Table, WasiCtx, WasiCtxBuilder, WasiView}; +use wasmtime_wasi::preview2::{ + DirPerms, FilePerms, Table, WasiCtx, WasiCtxBuilder, WasiView, +}; use wasmtime_wasi::{ambient_authority, Dir}; use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; @@ -70,11 +72,17 @@ unsafe extern "C" fn setup( ptr::null_mut(), ); for i in 0..bindings::nxt_conf_object_members_count(dirs_ptr) { - let value = bindings::nxt_conf_get_array_element(dirs_ptr, i.try_into().unwrap()); + let value = bindings::nxt_conf_get_array_element( + dirs_ptr, + i.try_into().unwrap(), + ); let mut s = bindings::nxt_string(""); bindings::nxt_conf_get_string(value, &mut s); dirs.push( - std::str::from_utf8(std::slice::from_raw_parts(s.start, s.length))?.to_string(), + std::str::from_utf8(std::slice::from_raw_parts( + s.start, s.length, + ))? + .to_string(), ); } } @@ -94,13 +102,15 @@ unsafe extern "C" fn start( ) -> bindings::nxt_int_t { handle_result(task, || { let config = GLOBAL_CONFIG.get().unwrap(); - let state = GlobalState::new(&config).context("failed to create initial state")?; + let state = GlobalState::new(&config) + .context("failed to create initial state")?; let res = GLOBAL_STATE.set(state); assert!(res.is_ok()); let conf = (*data).app; let mut wasm_init = MaybeUninit::uninit(); - let ret = bindings::nxt_unit_default_init(task, wasm_init.as_mut_ptr(), conf); + let ret = + bindings::nxt_unit_default_init(task, wasm_init.as_mut_ptr(), conf); if ret != bindings::NXT_OK as bindings::nxt_int_t { bail!("nxt_unit_default_init() failed"); } @@ -144,7 +154,9 @@ unsafe fn handle_result( } } -unsafe extern "C" fn request_handler(info: *mut bindings::nxt_unit_request_info_t) { +unsafe extern "C" fn request_handler( + info: *mut bindings::nxt_unit_request_info_t, +) { // Enqueue this request to get processed by the Tokio event loop, and // otherwise immediately return. let state = GLOBAL_STATE.get().unwrap(); @@ -235,8 +247,15 @@ impl GlobalState { cx.inherit_stderr(); for dir in self.global_config.dirs.iter() { let fd = Dir::open_ambient_dir(dir, ambient_authority()) - .with_context(|| format!("failed to open directory '{dir}'"))?; - cx.preopened_dir(fd, DirPerms::all(), FilePerms::all(), dir); + .with_context(|| { + format!("failed to open directory '{dir}'") + })?; + cx.preopened_dir( + fd, + DirPerms::all(), + FilePerms::all(), + dir, + ); } cx.build() }, @@ -262,10 +281,12 @@ impl GlobalState { // generate headers, write those below, and then compute the body // afterwards. let task = tokio::spawn(async move { - let (proxy, _) = - wasmtime_wasi_http::proxy::Proxy::instantiate_pre(&mut store, &self.component) - .await - .context("failed to instantiate")?; + let (proxy, _) = wasmtime_wasi_http::proxy::Proxy::instantiate_pre( + &mut store, + &self.component, + ) + .await + .context("failed to instantiate")?; let req = store.data_mut().new_incoming_request(request)?; let out = store.data_mut().new_response_outparam(sender)?; proxy @@ -308,7 +329,10 @@ impl GlobalState { Ok(()) } - fn to_request_builder(&self, info: &NxtRequestInfo) -> Result { + fn to_request_builder( + &self, + info: &NxtRequestInfo, + ) -> Result { let mut request = http::Request::builder(); request = request.method(info.method()); @@ -338,12 +362,16 @@ impl GlobalState { Ok(request) } - fn to_request_body(&self, info: &mut NxtRequestInfo) -> BoxBody { - // TODO: should convert the body into a form of `Stream` to become an async - // stream of frames. The return value can represent that here but for now - // this slurps up the entire body into memory and puts it all in a single - // `BytesMut` which is then converted to `Bytes`. - let mut body = BytesMut::with_capacity(info.content_length().try_into().unwrap()); + fn to_request_body( + &self, + info: &mut NxtRequestInfo, + ) -> BoxBody { + // TODO: should convert the body into a form of `Stream` to become an + // async stream of frames. The return value can represent that here + // but for now this slurps up the entire body into memory and puts it + // all in a single `BytesMut` which is then converted to `Bytes`. + let mut body = + BytesMut::with_capacity(info.content_length().try_into().unwrap()); // TODO: can this perform a partial read? // TODO: how to make this async at the nxt level? @@ -352,7 +380,11 @@ impl GlobalState { Full::new(body.freeze()).map_err(|e| match e {}).boxed() } - fn send_response(&self, info: &mut NxtRequestInfo, response: http::Response) -> T { + fn send_response( + &self, + info: &mut NxtRequestInfo, + response: http::Response, + ) -> T { info.init_response( response.status().as_u16(), response.headers().len().try_into().unwrap(), @@ -378,9 +410,9 @@ impl GlobalState { mut body: BoxBody, ) -> Result<()> { loop { - // Acquire the next frame, and because nothing is actually async at the - // moment this should never block meaning that the `Pending` case - // should not happen. + // Acquire the next frame, and because nothing is actually async + // at the moment this should never block meaning that the + // `Pending` case should not happen. let frame = match body.frame().await { Some(Ok(frame)) => frame, Some(Err(e)) => break Err(e), @@ -451,8 +483,10 @@ impl NxtRequestInfo { let raw = (*self.info).request; (0..(*raw).fields_count).map(move |i| { let field = (*raw).fields.as_ptr().add(i as usize); - let name = self.get_str(&(*field).name, (*field).name_length.into()); - let value = self.get_str(&(*field).value, (*field).value_length.into()); + let name = + self.get_str(&(*field).name, (*field).name_length.into()); + let value = + self.get_str(&(*field).value, (*field).value_length.into()); (name, value) }) } @@ -461,8 +495,11 @@ impl NxtRequestInfo { fn request_read(&mut self, dst: &mut BytesMut) { unsafe { let rest = dst.spare_capacity_mut(); - let amt = - bindings::nxt_unit_request_read(self.info, rest.as_mut_ptr().cast(), rest.len()); + let amt = bindings::nxt_unit_request_read( + self.info, + rest.as_mut_ptr().cast(), + rest.len(), + ); // TODO: handle failure when `amt` is negative let amt: usize = amt.try_into().unwrap(); dst.set_len(dst.len() + amt); @@ -471,14 +508,23 @@ impl NxtRequestInfo { fn response_write(&mut self, data: &[u8]) { unsafe { - let rc = bindings::nxt_unit_response_write(self.info, data.as_ptr().cast(), data.len()); + let rc = bindings::nxt_unit_response_write( + self.info, + data.as_ptr().cast(), + data.len(), + ); assert_eq!(rc, 0); } } fn init_response(&mut self, status: u16, headers: u32, headers_size: u32) { unsafe { - let rc = bindings::nxt_unit_response_init(self.info, status, headers, headers_size); + let rc = bindings::nxt_unit_response_init( + self.info, + status, + headers, + headers_size, + ); assert_eq!(rc, 0); } } @@ -505,11 +551,18 @@ impl NxtRequestInfo { fn request_done(self) { unsafe { - bindings::nxt_unit_request_done(self.info, bindings::NXT_UNIT_OK as i32); + bindings::nxt_unit_request_done( + self.info, + bindings::NXT_UNIT_OK as i32, + ); } } - unsafe fn get_str(&self, ptr: &bindings::nxt_unit_sptr_t, len: u32) -> &str { + unsafe fn get_str( + &self, + ptr: &bindings::nxt_unit_sptr_t, + len: u32, + ) -> &str { let ptr = bindings::nxt_unit_sptr_get(ptr); let slice = std::slice::from_raw_parts(ptr, len.try_into().unwrap()); std::str::from_utf8(slice).unwrap() -- cgit From ac3a54d67181bb8bfbe6753058941c91dd200c63 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 29 Jan 2024 11:35:13 +0000 Subject: Wasm-wc: Improve request buffer handling When Unit receives a request, if the body of that request is greater than a certain amount (16KiB by default) then it is written to a temporary file. When a language module goes to read the request body in such situations it will end up using read(2). The wasm-wasi-component language module was failing to properly read request bodies of around 2GiB or more. This is because (on Linux at least) read(2) (and other related system calls) will only read (or write) at most 0x7ffff000 (2,147,479,552) bytes, this is the case for both 32 and 64-bit systems. Regardless, it's probably not a good idea doing IO in such large chunks anyway. This patch changes the wasm-wasi-component language module to read the request buffer in 32MiB chunks (this matches the original 'wasm' language module). We are still limited to a 4GiB address space and can only upload files a little under 4GiB. Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/src/lib.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index da78ea6e..032878f5 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -495,14 +495,21 @@ impl NxtRequestInfo { fn request_read(&mut self, dst: &mut BytesMut) { unsafe { let rest = dst.spare_capacity_mut(); - let amt = bindings::nxt_unit_request_read( - self.info, - rest.as_mut_ptr().cast(), - rest.len(), - ); + let mut total_bytes_read = 0; + loop { + let amt = bindings::nxt_unit_request_read( + self.info, + rest.as_mut_ptr().wrapping_add(total_bytes_read).cast(), + 32 * 1024 * 1024, + ); + total_bytes_read += amt as usize; + if total_bytes_read >= rest.len() { + break; + } + } // TODO: handle failure when `amt` is negative - let amt: usize = amt.try_into().unwrap(); - dst.set_len(dst.len() + amt); + let total_bytes_read: usize = total_bytes_read.try_into().unwrap(); + dst.set_len(dst.len() + total_bytes_read); } } -- cgit From 98f808af2c23966e49abc7b2556e40adddbb51b9 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 30 Jan 2024 14:44:11 +0000 Subject: Wasm-wc: Upgrade to wasmtime 17 This brings WASI 0.2.0 support. Link: Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/Cargo.toml | 12 ++++++------ src/wasm-wasi-component/src/lib.rs | 21 +++++++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/wasm-wasi-component/Cargo.toml b/src/wasm-wasi-component/Cargo.toml index 8f42d128..feb7f53c 100644 --- a/src/wasm-wasi-component/Cargo.toml +++ b/src/wasm-wasi-component/Cargo.toml @@ -11,13 +11,13 @@ crate-type = ["cdylib"] anyhow = "1.0.75" bytes = "1.5.0" futures-util = { version = "0.3.29", default-features = false } -http = "0.2.9" -http-body = { version = "1.0.0-rc.2", default-features = false } -http-body-util = "0.1.0-rc.2" +http = "1.0.0" +http-body = { version = "1.0.0", default-features = false } +http-body-util = "0.1.0" tokio = { version = "1.33.0", default-features = false } -wasmtime = "14.0.2" -wasmtime-wasi = "14.0.2" -wasmtime-wasi-http = "14.0.2" +wasmtime = { version = "17.0.0", default-features = false, features = ['component-model', 'cranelift'] } +wasmtime-wasi = "17.0.0" +wasmtime-wasi-http = "17.0.0" [build-dependencies] bindgen = "0.68.1" diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index 032878f5..888074ab 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -7,12 +7,13 @@ use std::mem::MaybeUninit; use std::ptr; use std::sync::OnceLock; use tokio::sync::mpsc; -use wasmtime::component::{Component, InstancePre, Linker}; +use wasmtime::component::{Component, InstancePre, Linker, ResourceTable}; use wasmtime::{Config, Engine, Store}; use wasmtime_wasi::preview2::{ - DirPerms, FilePerms, Table, WasiCtx, WasiCtxBuilder, WasiView, + DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView, }; use wasmtime_wasi::{ambient_authority, Dir}; +use wasmtime_wasi_http::bindings::http::types::ErrorCode; use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; #[allow( @@ -259,7 +260,7 @@ impl GlobalState { } cx.build() }, - table: Table::default(), + table: ResourceTable::default(), http: WasiHttpCtx, }; let mut store = Store::new(&self.engine, data); @@ -365,7 +366,7 @@ impl GlobalState { fn to_request_body( &self, info: &mut NxtRequestInfo, - ) -> BoxBody { + ) -> BoxBody { // TODO: should convert the body into a form of `Stream` to become an // async stream of frames. The return value can represent that here // but for now this slurps up the entire body into memory and puts it @@ -407,7 +408,7 @@ impl GlobalState { async fn send_response_body( &self, info: &mut NxtRequestInfo, - mut body: BoxBody, + mut body: BoxBody, ) -> Result<()> { loop { // Acquire the next frame, and because nothing is actually async @@ -415,7 +416,7 @@ impl GlobalState { // `Pending` case should not happen. let frame = match body.frame().await { Some(Ok(frame)) => frame, - Some(Err(e)) => break Err(e), + Some(Err(e)) => break Err(e.into()), None => break Ok(()), }; match frame.data_ref() { @@ -579,14 +580,14 @@ impl NxtRequestInfo { struct StoreState { ctx: WasiCtx, http: WasiHttpCtx, - table: Table, + table: ResourceTable, } impl WasiView for StoreState { - fn table(&self) -> &Table { + fn table(&self) -> &ResourceTable { &self.table } - fn table_mut(&mut self) -> &mut Table { + fn table_mut(&mut self) -> &mut ResourceTable { &mut self.table } fn ctx(&self) -> &WasiCtx { @@ -601,7 +602,7 @@ impl WasiHttpView for StoreState { fn ctx(&mut self) -> &mut WasiHttpCtx { &mut self.http } - fn table(&mut self) -> &mut Table { + fn table(&mut self) -> &mut ResourceTable { &mut self.table } } -- cgit From 60eb6c43a71fb0f6cf21759917e0247bdb88b892 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 13 Feb 2024 16:21:49 +0000 Subject: Wasm-wc: Allow to use the 'reactor' adaptor again With the initial port to wasmtime 17 we could no longer use the 'reactor' adaptor but had to switch to the more restrictive 'proxy' adaptor. This meant amongst other things (probably) we could no longer access the filesystem. Thanks to Joel Dice for pointing out the fix. With this we can go back to using the 'reactor' adaptor again and things are back to working as before. It's worth noting that you can use either the 'proxy' or 'reactor' adaptor depending on your requirements. Cc: Joel Dice Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wasm-wasi-component/src/lib.rs b/src/wasm-wasi-component/src/lib.rs index 888074ab..3ee40c4f 100644 --- a/src/wasm-wasi-component/src/lib.rs +++ b/src/wasm-wasi-component/src/lib.rs @@ -200,7 +200,8 @@ impl GlobalState { let component = Component::from_file(&engine, &global_config.component) .context("failed to compile component")?; let mut linker = Linker::::new(&engine); - wasmtime_wasi_http::proxy::add_to_linker(&mut linker)?; + wasmtime_wasi::preview2::command::add_to_linker(&mut linker)?; + wasmtime_wasi_http::proxy::add_only_http_to_linker(&mut linker)?; let component = linker .instantiate_pre(&component) .context("failed to pre-instantiate the provided component")?; -- cgit From 8d030139a1bde3ee640852d1348eb595cb376d05 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 20 Feb 2024 14:43:59 +0000 Subject: Wasm-wc: Add Cargo.lock It seems we do want to track this thing. This is just the latest version that cargo had generated for me. Cc: Dan Callahan Signed-off-by: Andrew Clayton --- src/wasm-wasi-component/.gitignore | 2 - src/wasm-wasi-component/Cargo.lock | 2293 ++++++++++++++++++++++++++++++++++++ 2 files changed, 2293 insertions(+), 2 deletions(-) create mode 100644 src/wasm-wasi-component/Cargo.lock diff --git a/src/wasm-wasi-component/.gitignore b/src/wasm-wasi-component/.gitignore index 159e3885..eb5a316c 100644 --- a/src/wasm-wasi-component/.gitignore +++ b/src/wasm-wasi-component/.gitignore @@ -1,3 +1 @@ -Cargo.lock - target diff --git a/src/wasm-wasi-component/Cargo.lock b/src/wasm-wasi-component/Cargo.lock new file mode 100644 index 00000000..bc09e96a --- /dev/null +++ b/src/wasm-wasi-component/Cargo.lock @@ -0,0 +1,2293 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "ambient-authority" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.68.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +dependencies = [ + "bitflags 2.4.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cap-fs-ext" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88e341d15ac1029aadce600be764a1a1edafe40e03cde23285bc1d261b3a4866" +dependencies = [ + "cap-primitives", + "cap-std", + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "cap-net-ext" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434168fe6533055f0f4204039abe3ff6d7db338ef46872a5fa39e9d5ad5ab7a9" +dependencies = [ + "cap-primitives", + "cap-std", + "rustix", + "smallvec", +] + +[[package]] +name = "cap-primitives" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe16767ed8eee6d3f1f00d6a7576b81c226ab917eb54b96e5f77a5216ef67abb" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes", + "ipnet", + "maybe-owned", + "rustix", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "cap-rand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e5695565f0cd7106bc3c7170323597540e772bb73e0be2cd2c662a0f8fa4ca" +dependencies = [ + "ambient-authority", + "rand", +] + +[[package]] +name = "cap-std" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "593db20e4c51f62d3284bae7ee718849c3214f93a3b94ea1899ad85ba119d330" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes", + "rustix", +] + +[[package]] +name = "cap-time-ext" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03261630f291f425430a36f38c847828265bc928f517cdd2004c56f4b02f002b" +dependencies = [ + "ambient-authority", + "cap-primitives", + "iana-time-zone", + "once_cell", + "rustix", + "winx", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cranelift-bforest" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d819feeda4c420a18f1e28236ca0ce1177b22bf7c8a44ddee92dfe40de15bcf0" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b8d03d5bdbca7e5f72b0e0a0f69933ed1f09e24be6c075aa6fe3f802b0cc0c" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.14.3", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3fd3664e38e51649b17dc30cfdd561273fe2f590dcd013fb75d9eabc6272dfb" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b031ec5e605828975952622b5a77d49126f20ffe88d33719a0af66b23a0fc36" + +[[package]] +name = "cranelift-control" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fada054d017cf2ed8f7ed2336e0517fc1b19e6825be1790de9eb00c94788362b" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177b6f94ae8de6348eb45bf977c79ab9e3c40fc3ac8cb7ed8109560ea39bee7d" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-frontend" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebebd23a69a23e3ddea78e98ff3a2de222e88c8e045d81ef4a72f042e0d79dbd" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1571bfc14df8966d12c6121b5325026591a4b4009e22fea0fe3765ab7cd33b96" + +[[package]] +name = "cranelift-native" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a69c37e0c10b46fe5527f2397ac821046efbf5f7ec112c8b84df25712f465b" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3fef8bbceb8cb56d3f1778b0418d75c5cf12ec571a35fc01eb41abb0227a25" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools", + "log", + "smallvec", + "wasmparser 0.118.1", + "wasmtime-types", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fd-lock" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs-set-times" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" +dependencies = [ + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "h2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "want", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "io-extras" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c301e73fb90e8a29e600a9f402d095765f74310d582916a952f618836a1bd1ed" +dependencies = [ + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "io-lifetimes" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "crc32fast", + "hashbrown 0.14.3", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "itoa", + "libc", + "linux-raw-sys", + "once_cell", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-interface" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0682e006dd35771e392a6623ac180999a9a854b1d4a6c12fb2e804941c2b1f58" +dependencies = [ + "bitflags 2.4.2", + "cap-fs-ext", + "cap-std", + "fd-lock", + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "target-lexicon" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi-cap-std-sync" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db014d2ced91f17d1f1a8f2b76d6ea8d731bc1dbc8c2bbaec689d6a242568e5d" +dependencies = [ + "anyhow", + "async-trait", + "cap-fs-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "io-extras", + "io-lifetimes", + "once_cell", + "rustix", + "system-interface", + "tracing", + "wasi-common", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasi-common" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449d17849e3c83a931374442fe2deee4d6bd1ebf469719ef44192e9e82e19c89" +dependencies = [ + "anyhow", + "bitflags 2.4.2", + "cap-rand", + "cap-std", + "io-extras", + "log", + "rustix", + "thiserror", + "tracing", + "wasmtime", + "wiggle", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "wasm-encoder" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-wasi-component" +version = "0.1.0" +dependencies = [ + "anyhow", + "bindgen", + "bytes", + "cc", + "futures-util", + "http", + "http-body", + "http-body-util", + "tokio", + "wasmtime", + "wasmtime-wasi", + "wasmtime-wasi-http", +] + +[[package]] +name = "wasmparser" +version = "0.118.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" +dependencies = [ + "indexmap", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.121.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953cf6a7606ab31382cb1caa5ae403e77ba70c7f8e12eeda167e7040d42bfda8" +dependencies = [ + "bitflags 2.4.2", + "indexmap", + "semver", +] + +[[package]] +name = "wasmprinter" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e32c13c59fdc64d3f6998a1d52eb1d362b6904a88b754190ccb85661ad577a" +dependencies = [ + "anyhow", + "wasmparser 0.121.0", +] + +[[package]] +name = "wasmtime" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "910fabce77e660f0e0e41cfd5f69fc8bf020a025f059718846e918db7177f469" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bumpalo", + "cfg-if", + "encoding_rs", + "indexmap", + "libc", + "log", + "object", + "once_cell", + "paste", + "serde", + "serde_derive", + "serde_json", + "target-lexicon", + "wasmparser 0.118.1", + "wasmtime-component-macro", + "wasmtime-component-util", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit", + "wasmtime-runtime", + "wasmtime-winch", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37288142e9b4a61655a3bcbdc7316c2e4bb9e776b10ce3dd758f8186b4469572" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-component-macro" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad63de18eb42e586386b6091f787c82707cbd5ac5e9343216dba1976190cd03a" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0a160c0c44369aa4bee6d311a8e4366943bab1651040cc8b0fcec2c9eb8906" + +[[package]] +name = "wasmtime-cranelift" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3734cc01b7cd37bc62fdbcd9529ca9547440052d4b3886cfdec3b8081a5d3647" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli", + "log", + "object", + "target-lexicon", + "thiserror", + "wasmparser 0.118.1", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0eb33cd30c47844aa228d4d0030587e65c1108343f311fe9f7248b5bd9cb65c" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-native", + "gimli", + "object", + "target-lexicon", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-environ" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a056b041fdea604f0972e2fae97958e7748d629a55180228348baefdfc217" +dependencies = [ + "anyhow", + "cranelift-entity", + "gimli", + "indexmap", + "log", + "object", + "serde", + "serde_derive", + "target-lexicon", + "thiserror", + "wasm-encoder", + "wasmparser 0.118.1", + "wasmprinter", + "wasmtime-component-util", + "wasmtime-types", +] + +[[package]] +name = "wasmtime-fiber" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43987d0977c07f15c3608c2f255870c127ffd19e35eeedb1ac1dccedf9932a42" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "rustix", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-jit" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3e48395ac672b386ed588d97a9612aa13a345008f26466f0dfb2a91628aa9f" +dependencies = [ + "anyhow", + "bincode", + "cfg-if", + "gimli", + "log", + "object", + "rustix", + "serde", + "serde_derive", + "target-lexicon", + "wasmtime-environ", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdc26415bb89e9ccd3bdc498fef63aabf665c4c0dd710c107691deb9694955da" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-runtime" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0abddaf17912aabaf39be0802d5eba9a002e956e902d1ebd438a2fe1c88769a2" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "encoding_rs", + "indexmap", + "libc", + "log", + "mach", + "memfd", + "memoffset", + "paste", + "psm", + "rustix", + "sptr", + "wasm-encoder", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-versioned-export-macros", + "wasmtime-wmemcheck", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-types" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35a95cdc1433729085beab42c0a5c742b431f25b17c40d7718e46df63d5ffc7" +dependencies = [ + "cranelift-entity", + "serde", + "serde_derive", + "thiserror", + "wasmparser 0.118.1", +] + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad322733fe67e45743784d8b1df452bcb54f581572a4f1a646a4332deecbcc2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasmtime-wasi" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "902cc299b73655c36679b77efdfce4bb5971992f1a4a8a436dd3809a6848ff0e" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.4.2", + "bytes", + "cap-fs-ext", + "cap-net-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "futures", + "io-extras", + "io-lifetimes", + "libc", + "log", + "once_cell", + "rustix", + "system-interface", + "thiserror", + "tokio", + "tracing", + "url", + "wasi-cap-std-sync", + "wasi-common", + "wasmtime", + "wiggle", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-wasi-http" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151fc711fad35034b8a6df00a5bcd5a7b1acb89ca12c2407f564a36ebd382e26" +dependencies = [ + "anyhow", + "async-trait", + "bytes", + "futures", + "http", + "http-body", + "http-body-util", + "hyper", + "rustls", + "tokio", + "tokio-rustls", + "tracing", + "wasmtime", + "wasmtime-wasi", + "webpki-roots", +] + +[[package]] +name = "wasmtime-winch" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e63aeca929f84560eec52c5af43bf5d623b92683b0195d9fb06da8ed860e092" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "object", + "target-lexicon", + "wasmparser 0.118.1", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "winch-codegen", +] + +[[package]] +name = "wasmtime-wit-bindgen" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e5675998fdc74495afdd90ad2bd221206a258075b23048af0535a969b07893" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wit-parser", +] + +[[package]] +name = "wasmtime-wmemcheck" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b20a19e10d8cb50b45412fb21192982b7ce85c0122dc33bb71f1813e25dc6e52" + +[[package]] +name = "wast" +version = "35.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" +dependencies = [ + "leb128", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "wiggle" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "737728db69a7657a5f6a7bac445c02d8564d603d62c46c95edf928554e67d072" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.4.2", + "thiserror", + "tracing", + "wasmtime", + "wiggle-macro", +] + +[[package]] +name = "wiggle-generate" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2460c7163b79ffefd9a564eaeab0a5b0e84bb91afdfeeb84d36f304ddbe08982" +dependencies = [ + "anyhow", + "heck", + "proc-macro2", + "quote", + "shellexpand", + "syn", + "witx", +] + +[[package]] +name = "wiggle-macro" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8d8412375ba8325d61fbae56dead51dabfaec85d620ce36427922fb9cece83" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wiggle-generate", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winch-codegen" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2b346bad5397b219b4ff0a8fa7230936061ff07c61f05d589d8d81e06fb7b2" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser 0.118.1", + "wasmtime-environ", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winx" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" +dependencies = [ + "bitflags 2.4.2", + "windows-sys 0.52.0", +] + +[[package]] +name = "wit-parser" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df4913a2219096373fd6512adead1fb77ecdaa59d7fc517972a7d30b12f625be" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", +] + +[[package]] +name = "witx" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b" +dependencies = [ + "anyhow", + "log", + "thiserror", + "wast", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] -- cgit From 07a0c9a34817d6faedff67505507cd4f54752a22 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 5 Feb 2024 21:50:52 +0000 Subject: Wasm-wc: Wire up the language module to the config system This exposes the various WebAssembly Component Model language module specific options. The application type is "wasm-wasi-component". There is a "component" option that is required, this specifies the full path to the WebAssembly component to be run. This component should be in binary format, i.e a .wasm file. There is also currently one optional option "access" Due to the sandboxed nature of WebAssembly, by default Wasm modules/components don't have any access to the underlying filesystem. There is however a capabilities based mechanism[0] for allowing such access. This adds a config option to the 'wasm-wasi-component' application type (same as for 'wasm'); 'access.filesystem' which takes an array of directory paths that are then made available to the wasm module/component. This access works recursively, i.e everything under a specific path is allowed access to. Example config might look like "applications": { "my-wasm-component": { "type": "wasm-wasi-component", "component": "/path/to/component.wasm", "access" { "filesystem": [ "/tmp", "/var/tmp" ] } } } The actual mechanism used allows directories to be mapped differently in the guest. But at the moment we don't support that and just map say /tmp to /tmp. This can be revisited if it's something users clamour for. [0]: Signed-off-by: Andrew Clayton --- src/nxt_application.c | 3 +++ src/nxt_conf_validation.c | 17 +++++++++++++++++ src/nxt_main_process.c | 15 +++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/nxt_application.c b/src/nxt_application.c index 872e387a..e0247bf0 100644 --- a/src/nxt_application.c +++ b/src/nxt_application.c @@ -1100,6 +1100,9 @@ nxt_app_parse_type(u_char *p, size_t length) } else if (nxt_str_eq(&str, "java", 4)) { return NXT_APP_JAVA; + } else if (nxt_str_eq(&str, "wasm-wasi-component", 19)) { + return NXT_APP_WASM_WC; + } else if (nxt_str_eq(&str, "wasm", 4)) { return NXT_APP_WASM; } diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index caa068d2..2099f887 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1095,6 +1095,22 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_wasm_members[] = { }; +static nxt_conf_vldt_object_t nxt_conf_vldt_wasm_wc_members[] = { + { + .name = nxt_string("component"), + .type = NXT_CONF_VLDT_STRING, + .flags = NXT_CONF_VLDT_REQUIRED, + }, { + .name = nxt_string("access"), + .type = NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_object, + .u.members = nxt_conf_vldt_wasm_access_members, + }, + + NXT_CONF_VLDT_NEXT(nxt_conf_vldt_common_members) +}; + + static nxt_conf_vldt_object_t nxt_conf_vldt_wasm_access_members[] = { { .name = nxt_string("filesystem"), @@ -2660,6 +2676,7 @@ nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, { nxt_conf_vldt_object, nxt_conf_vldt_ruby_members }, { nxt_conf_vldt_object, nxt_conf_vldt_java_members }, { nxt_conf_vldt_object, nxt_conf_vldt_wasm_members }, + { nxt_conf_vldt_object, nxt_conf_vldt_wasm_wc_members }, }; ret = nxt_conf_vldt_type(vldt, name, value, NXT_CONF_VLDT_OBJECT); diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 3f317d5e..060ead41 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -377,6 +377,20 @@ static nxt_conf_map_t nxt_wasm_app_conf[] = { }; +static nxt_conf_map_t nxt_wasm_wc_app_conf[] = { + { + nxt_string("component"), + NXT_CONF_MAP_CSTRZ, + offsetof(nxt_common_app_conf_t, u.wasm_wc.component), + }, + { + nxt_string("access"), + NXT_CONF_MAP_PTR, + offsetof(nxt_common_app_conf_t, u.wasm_wc.access), + }, +}; + + static nxt_conf_app_map_t nxt_app_maps[] = { { nxt_nitems(nxt_external_app_conf), nxt_external_app_conf }, { nxt_nitems(nxt_python_app_conf), nxt_python_app_conf }, @@ -385,6 +399,7 @@ static nxt_conf_app_map_t nxt_app_maps[] = { { nxt_nitems(nxt_ruby_app_conf), nxt_ruby_app_conf }, { nxt_nitems(nxt_java_app_conf), nxt_java_app_conf }, { nxt_nitems(nxt_wasm_app_conf), nxt_wasm_app_conf }, + { nxt_nitems(nxt_wasm_wc_app_conf), nxt_wasm_wc_app_conf }, }; -- cgit From da44dc00dcb64c8bc04aedb685ac081087e2582c Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 6 Feb 2024 04:15:32 +0000 Subject: Fix alignment of wasm options text in auto/help The indentation uses spaces and not TABs. Signed-off-by: Andrew Clayton --- auto/help | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auto/help b/auto/help index b6d9919f..6aff4bba 100644 --- a/auto/help +++ b/auto/help @@ -76,7 +76,7 @@ cat << END java OPTIONS configure Java module run "./configure java --help" to see available options - wasm OPTIONS configure WebAssembly module - run "./configure wasm --help" to see available options + wasm OPTIONS configure WebAssembly module + run "./configure wasm --help" to see available options END -- cgit From 4e6d7e87685c30a62a654fc91e271d34dd642202 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 6 Feb 2024 04:20:16 +0000 Subject: Wasm-wc: Wire it up to the build system Et voila... $ ./configure wasm-wasi-component configuring wasm-wasi-component module Looking for rust compiler ... found. Looking for cargo ... found. + wasm-wasi-component module: wasm_wasi_component.unit.so $ make install test -d /opt/unit/sbin || install -d /opt/unit/sbin install -p build/sbin/unitd /opt/unit/sbin/ test -d /opt/unit/state || install -d /opt/unit/state test -d /opt/unit || install -d /opt/unit test -d /opt/unit || install -d /opt/unit test -d /opt/unit/share/man/man8 || install -d /opt/unit/sh man/man8 install -p -m644 build/share/man/man8/unitd.8 /opt/unit/share/ma n8/ make build/src/nxt_unit.o make[1]: Entering directory '/home/andrew/src/unit' make[1]: 'build/src/nxt_unit.o' is up to date. make[1]: Leaving directory '/home/andrew/src/unit' cargo build --release --manifest-path src/wasm-wasi-component/Cargo.toml Finished release [optimized] target(s) in 0.55s install -d /opt/unit/modules install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \ /opt/unit/modules/wasm_wasi_component.unit.so Signed-off-by: Andrew Clayton --- auto/help | 5 ++ auto/modules/conf | 4 ++ auto/modules/wasm-wasi-component | 119 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 auto/modules/wasm-wasi-component diff --git a/auto/help b/auto/help index 6aff4bba..d23c67ed 100644 --- a/auto/help +++ b/auto/help @@ -79,4 +79,9 @@ cat << END wasm OPTIONS configure WebAssembly module run "./configure wasm --help" to see available options + wasm-wasi-component OPTIONS + configure WebAssembly Component Model module + run "./configure wasm-wasi-component --help" to see + available options + END diff --git a/auto/modules/conf b/auto/modules/conf index 31be751f..ab4ed351 100644 --- a/auto/modules/conf +++ b/auto/modules/conf @@ -37,6 +37,10 @@ case "$nxt_module" in . auto/modules/wasm ;; + wasm-wasi-component) + . auto/modules/wasm-wasi-component + ;; + *) echo echo $0: error: invalid module \"$nxt_module\". diff --git a/auto/modules/wasm-wasi-component b/auto/modules/wasm-wasi-component new file mode 100644 index 00000000..1ec5841c --- /dev/null +++ b/auto/modules/wasm-wasi-component @@ -0,0 +1,119 @@ +# Copyright (C) Andrew Clayton +# Copyright (C) F5, Inc. + + +NXT_WCM_MODULE=wasm-wasi-component +NXT_WCM_MOD_NAME=`echo $NXT_WCM_MODULE | tr '-' '_'`.unit.so + + +shift + +for nxt_option; do + + case "$nxt_option" in + -*=*) value=`echo "$nxt_option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) value="" ;; + esac + + case "$nxt_option" in + + --help) + cat << END + +END + exit 0 + ;; + + *) + echo + echo $0: error: invalid $NXT_WCM_MODULE option \"$nxt_option\" + echo + exit 1 + ;; + esac + +done + + +if [ ! -f $NXT_AUTOCONF_DATA ]; then + echo + echo Please run common $0 before configuring module \"$nxt_module\". + echo + exit 1 +fi + +. $NXT_AUTOCONF_DATA + +NXT_WCM_WASM_TOOLS_BIN=${NXT_WCM_WASM_TOOLS_BIN=} + + +$echo "configuring $NXT_WCM_MODULE module" +$echo "configuring $NXT_WCM_MODULE module ..." >> $NXT_AUTOCONF_ERR + +$echo -n "looking for rust compiler ... " + +if [ -z `which rustc 2>/dev/null` ]; then + $echo "not found." + exit 1; +fi + +$echo "found." + +$echo -n "looking for cargo ... " + +if [ -z `which cargo 2>/dev/null` ]; then + $echo "not found." + exit 1; +fi + +$echo "found." + + +if grep ^$NXT_WCM_MODULE: $NXT_MAKEFILE 2>&1 > /dev/null; then + $echo + $echo $0: error: duplicate \"$NXT_WCM_MODULE\" module configured. + $echo + exit 1; +fi + + +$echo " + $NXT_WCM_MODULE module: $NXT_WCM_MOD_NAME" + + +NXT_OS=$(uname -o) + +if [ $NXT_OS = "Darwin" ]; then + NXT_CARGO_CMD="cargo rustc --release --manifest-path src/wasm-wasi-component/Cargo.toml -- --emit link=target/release/libwasm_wasi_component.so -C link-args='-undefined dynamic_lookup'" +else + NXT_CARGO_CMD="cargo build --release --manifest-path src/wasm-wasi-component/Cargo.toml" +fi + + +cat << END >> $NXT_MAKEFILE + +.PHONY: ${NXT_WCM_MODULE} +.PHONY: ${NXT_WCM_MODULE}-install +.PHONY: ${NXT_WCM_MODULE}-uninstall + +all: ${NXT_WCM_MODULE} + +${NXT_WCM_MODULE}: $NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME + +$NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME: + make build/src/nxt_unit.o + $NXT_CARGO_CMD + +install: ${NXT_WCM_MODULE}-install + +${NXT_WCM_MODULE}-install: ${NXT_WCM_MODULE} install-check + install -d \$(DESTDIR)$NXT_MODULESDIR + install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \\ + \$(DESTDIR)$NXT_MODULESDIR/$NXT_WCM_MOD_NAME + +uninstall: ${NXT_WCM_MODULE}-uninstall + +${NXT_WCM_MODULE}-uninstall: + rm -f \$(DESTDIR)$NXT_MODULESDIR/$NXT_WCM_MOD_NAME + @rmdir -p \$(DESTDIR)$NXT_MODULESDIR 2>/dev/null || true + +END -- cgit From 7702293dda8ed73cd2cc616f9a339212b4386707 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 21 Feb 2024 12:49:48 +0000 Subject: Docker: Bump rust version to 1.76.0 The minimum version required to build wasmtime 17 which is required by wasm-wasi-component is 1.73.0 But no point not using the latest version. This also now needs the libclang-dev package installed, we install this via MODULE_PREBUILD_wasm. Signed-off-by: Andrew Clayton --- pkg/docker/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 102d0a05..c7a5f1ee 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -81,7 +81,8 @@ CONFIGURE_wasm ?= wasm --include-path=\`pwd\`/pkg/contrib/wasmtime/crates/c-api/ INSTALL_wasm ?= wasm-install RUN_wasm ?= /bin/true define MODULE_PREBUILD_wasm -export RUST_VERSION=1.71.0 \\\n \ +apt-get install --no-install-recommends --no-install-suggests -y libclang-dev \\\n \ +\ \ \ \&\& export RUST_VERSION=1.76.0 \\\n \ \ \ \ \&\& export RUSTUP_HOME=/usr/src/unit/rustup \\\n \ \ \ \ \&\& export CARGO_HOME=/usr/src/unit/cargo \\\n \ \ \ \ \&\& export PATH=/usr/src/unit/cargo/bin:\$$PATH \\\n \ -- cgit From 1297f6f0f4e538b5d068657be66ae416ea095ce6 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 21 Feb 2024 12:59:38 +0000 Subject: Docker: Add wasm-wasi-component to the wasm target Thus $ make build-wasm will build _both_ the 'wasm' & 'wasm-wasi-component' modules. Signed-off-by: Andrew Clayton --- pkg/docker/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index c7a5f1ee..d8c53021 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -77,9 +77,10 @@ MODULE_PREBUILD_ruby ?= /bin/true VERSIONS_wasm ?= CONTAINER_wasm ?= debian:$(VARIANT)-slim -CONFIGURE_wasm ?= wasm --include-path=\`pwd\`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=/usr/lib/\$$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ -INSTALL_wasm ?= wasm-install -RUN_wasm ?= /bin/true +CONFIGURE_wasm ?= wasm --include-path=\`pwd\`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=/usr/lib/\$$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ \&\& ./configure wasm-wasi-component +INSTALL_wasm ?= wasm-install wasm-wasi-component-install +RUN_wasm ?= /bin/true + define MODULE_PREBUILD_wasm apt-get install --no-install-recommends --no-install-suggests -y libclang-dev \\\n \ \ \ \ \&\& export RUST_VERSION=1.76.0 \\\n \ -- cgit From 4c558697bb7375aaca01314dd3667df923d32bfb Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 21 Feb 2024 13:10:06 +0000 Subject: Docker: Re-generate Dockerfile.wasm This now includes support for the 'wasm-wasi-component' module. This targets the upcoming 1.32.0 release which is required by wasm-wasi-component. However of course the 1.32.0 tag doesn't exist yet, so there will be a small window where this image won't build. Signed-off-by: Andrew Clayton --- pkg/docker/Dockerfile.wasm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/docker/Dockerfile.wasm b/pkg/docker/Dockerfile.wasm index 64742e88..7c107b4c 100644 --- a/pkg/docker/Dockerfile.wasm +++ b/pkg/docker/Dockerfile.wasm @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ @@ -45,7 +45,8 @@ RUN set -ex \ && make -j $NCPU unitd \ && install -pm755 build/sbin/unitd /usr/sbin/unitd \ && make clean \ - && export RUST_VERSION=1.71.0 \ + && apt-get install --no-install-recommends --no-install-suggests -y libclang-dev \ + && export RUST_VERSION=1.76.0 \ && export RUSTUP_HOME=/usr/src/unit/rustup \ && export CARGO_HOME=/usr/src/unit/cargo \ && export PATH=/usr/src/unit/cargo/bin:$PATH \ @@ -67,12 +68,12 @@ RUN set -ex \ && make -C pkg/contrib .wasmtime \ && install -pm 755 pkg/contrib/wasmtime/target/release/libwasmtime.so /usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ \ && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \ - && ./configure wasm --include-path=`pwd`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=/usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ \ - && make -j $NCPU wasm-install \ + && ./configure wasm --include-path=`pwd`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=/usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ && ./configure wasm-wasi-component \ + && make -j $NCPU wasm-install wasm-wasi-component-install \ && make clean \ && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \ - && ./configure wasm --include-path=`pwd`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=/usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ \ - && make -j $NCPU wasm-install \ + && ./configure wasm --include-path=`pwd`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=/usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)/ && ./configure wasm-wasi-component \ + && make -j $NCPU wasm-install wasm-wasi-component-install \ && cd \ && rm -rf /usr/src/unit \ && for f in /usr/sbin/unitd /usr/lib/unit/modules/*.unit.so; do \ -- cgit From 7883acc62df64023dc8900298d65218b96d36ec7 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 7 Feb 2024 16:19:13 +0000 Subject: Tests: Ruby hook tests unstable for version older 3.0 It can fail with reporting following alert: [alert] 137462#137462 mount("none", "/tmp/unit-test-636e0uh8/proc", "proc", 2097162, "") (16: Device or resource busy) --- test/test_ruby_hooks.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/test_ruby_hooks.py b/test/test_ruby_hooks.py index 38893e47..dd9e0fca 100644 --- a/test/test_ruby_hooks.py +++ b/test/test_ruby_hooks.py @@ -1,8 +1,11 @@ from unit.applications.lang.ruby import ApplicationRuby from unit.option import option from unit.utils import waitforglob +from packaging import version -prerequisites = {'modules': {'ruby': 'all'}} +prerequisites = { + 'modules': {'ruby': lambda v: version.parse(v) >= version.parse('3.0')} +} client = ApplicationRuby() -- cgit From 99da2f3c8e689341a83c9432e0692160c1d8316d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 7 Feb 2024 16:22:18 +0000 Subject: Tests: check for the AddressSanitizer flag during discovery This flag is necessary to either run or skip certain tests that have specific behavior depending on whether AddressSanitizer is enabled. For instance, some tests may fail only when the binary is compiled with AddressSanitizer. --- test/unit/check/discover_available.py | 2 ++ test/unit/option.py | 1 + 2 files changed, 3 insertions(+) diff --git a/test/unit/check/discover_available.py b/test/unit/check/discover_available.py index 0942581b..1383a0c3 100644 --- a/test/unit/check/discover_available.py +++ b/test/unit/check/discover_available.py @@ -18,6 +18,8 @@ def discover_available(unit): [unit['unitd'], '--version'], stderr=subprocess.STDOUT ).decode() + option.configure_flag['asan'] = '-fsanitize=address' in output_version + # wait for controller start if Log.wait_for_record(r'controller started') is None: diff --git a/test/unit/option.py b/test/unit/option.py index ee1f46dd..7c66c619 100644 --- a/test/unit/option.py +++ b/test/unit/option.py @@ -6,6 +6,7 @@ class Options: _options = { 'architecture': platform.architecture()[0], 'available': {'modules': {}, 'features': {}}, + 'configure_flag': {}, 'is_privileged': os.geteuid() == 0, 'skip_alerts': [], 'skip_sanitizer': False, -- cgit From dbd9d25f17f4e5f248f6fb2071a5b20a43e27b24 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 7 Feb 2024 16:23:45 +0000 Subject: Tests: skip some of TLS reconfiguration tests under AddressSanitizer These tests cause router crash when run with AddressSanitizer: ================================================================= ==77196==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000079340 at pc 0x55d56b132d4b bp 0x7f8cc7f346b0 sp 0x7f8cc7f346a0 READ of size 1 at 0x60c000079340 thread T1 #0 0x55d56b132d4a in nxt_openssl_conn_io_shutdown src/nxt_openssl.c:1466 #1 0x55d56b0f6a25 in nxt_h1p_closing src/nxt_h1proto.c:2069 #2 0x55d56b1009a6 in nxt_h1p_shutdown src/nxt_h1proto.c:2038 #3 0x55d56b1014c3 in nxt_h1p_request_close src/nxt_h1proto.c:1718 #4 0x55d56b1045c0 in nxt_http_request_close_handler src/nxt_http_request.c:864 #5 0x55d56b104988 in nxt_http_request_done src/nxt_http_request.c:795 #6 0x55d56b0ba0c3 in nxt_event_engine_start src/nxt_event_engine.c:542 #7 0x55d56b0dcac2 in nxt_router_thread_start src/nxt_router.c:3645 #8 0x55d56b0b421b in nxt_thread_trampoline src/nxt_thread.c:126 #9 0x7f8ccab95ac2 (/lib/x86_64-linux-gnu/libc.so.6+0x94ac2) #10 0x7f8ccac2784f (/lib/x86_64-linux-gnu/libc.so.6+0x12684f) --- test/test_reconfigure_tls.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test_reconfigure_tls.py b/test/test_reconfigure_tls.py index 3cd01b13..4f7d344a 100644 --- a/test/test_reconfigure_tls.py +++ b/test/test_reconfigure_tls.py @@ -5,6 +5,7 @@ import time import pytest from unit.applications.tls import ApplicationTLS +from unit.option import option prerequisites = {'modules': {'openssl': 'any'}} @@ -70,6 +71,9 @@ def test_reconfigure_tls_switch(): def test_reconfigure_tls(): + if option.configure_flag['asan']: + pytest.skip('not yet, router crash') + ssl_sock = create_socket() ssl_sock.sendall("""GET / HTTP/1.1\r\n""".encode()) @@ -107,6 +111,9 @@ def test_reconfigure_tls_2(): def test_reconfigure_tls_3(): + if option.configure_flag['asan']: + pytest.skip('not yet, router crash') + ssl_sock = create_socket() ssl_sock.do_handshake() -- cgit From cabea47de7287ea421317c92bc868c2d451cb757 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 7 Feb 2024 16:29:11 +0000 Subject: Tests: renamed test_python_procman.py since it's not Python-specific Python applications are used only to generate responses here and can be replaced by applications written in any other language. While the "_python" prefix is used to indicate that the file contains tests specific to the Python module. --- test/test_procman.py | 303 ++++++++++++++++++++++++++++++++++++++++++++ test/test_python_procman.py | 303 -------------------------------------------- 2 files changed, 303 insertions(+), 303 deletions(-) create mode 100644 test/test_procman.py delete mode 100644 test/test_python_procman.py diff --git a/test/test_procman.py b/test/test_procman.py new file mode 100644 index 00000000..b4378c4f --- /dev/null +++ b/test/test_procman.py @@ -0,0 +1,303 @@ +import re +import shutil +import subprocess +import time + +import pytest + +from unit.applications.lang.python import ApplicationPython +from unit.option import option + +prerequisites = {'modules': {'python': 'any'}} + +client = ApplicationPython() + + +@pytest.fixture(autouse=True) +def setup_method_fixture(temp_dir): + client.app_name = f'app-{temp_dir.split("/")[-1]}' + client.app_proc = f'applications/{client.app_name}/processes' + client.load('empty', client.app_name) + + +def pids_for_process(): + time.sleep(0.2) + + output = subprocess.check_output(['ps', 'ax']) + + pids = set() + for m in re.findall( + fr'.*unit: "{client.app_name}" application', output.decode() + ): + pids.add(re.search(r'^\s*(\d+)', m).group(1)) + + return pids + + +def conf_proc(conf, path=None): + if path is None: + path = client.app_proc + + assert 'success' in client.conf(conf, path), 'configure processes' + + +def stop_all(): + assert 'success' in client.conf({"listeners": {}, "applications": {}}) + + assert len(pids_for_process()) == 0, 'stop all' + + +@pytest.mark.skip('not yet') +def test_python_processes_idle_timeout_zero(): + conf_proc({"spare": 0, "max": 2, "idle_timeout": 0}) + + client.get() + assert len(pids_for_process()) == 0, 'idle timeout 0' + + +def test_python_prefork(): + conf_proc('2') + + pids = pids_for_process() + assert len(pids) == 2, 'prefork 2' + + client.get() + assert pids_for_process() == pids, 'prefork still 2' + + conf_proc('4') + + pids = pids_for_process() + assert len(pids) == 4, 'prefork 4' + + client.get() + assert pids_for_process() == pids, 'prefork still 4' + + stop_all() + + +@pytest.mark.skip('not yet') +def test_python_prefork_same_processes(): + conf_proc('2') + pids = pids_for_process() + + conf_proc('4') + pids_new = pids_for_process() + + assert pids.issubset(pids_new), 'prefork same processes' + + +def test_python_ondemand(): + conf_proc({"spare": 0, "max": 8, "idle_timeout": 1}) + + assert len(pids_for_process()) == 0, 'on-demand 0' + + client.get() + pids = pids_for_process() + assert len(pids) == 1, 'on-demand 1' + + client.get() + assert pids_for_process() == pids, 'on-demand still 1' + + time.sleep(1) + + assert len(pids_for_process()) == 0, 'on-demand stop idle' + + stop_all() + + +def test_python_scale_updown(): + conf_proc({"spare": 2, "max": 8, "idle_timeout": 1}) + + pids = pids_for_process() + assert len(pids) == 2, 'updown 2' + + client.get() + pids_new = pids_for_process() + assert len(pids_new) == 3, 'updown 3' + assert pids.issubset(pids_new), 'updown 3 only 1 new' + + client.get() + assert pids_for_process() == pids_new, 'updown still 3' + + time.sleep(1) + + pids = pids_for_process() + assert len(pids) == 2, 'updown stop idle' + + client.get() + pids_new = pids_for_process() + assert len(pids_new) == 3, 'updown again 3' + assert pids.issubset(pids_new), 'updown again 3 only 1 new' + + stop_all() + + +def test_python_reconfigure(): + conf_proc({"spare": 2, "max": 6, "idle_timeout": 1}) + + pids = pids_for_process() + assert len(pids) == 2, 'reconf 2' + + client.get() + pids_new = pids_for_process() + assert len(pids_new) == 3, 'reconf 3' + assert pids.issubset(pids_new), 'reconf 3 only 1 new' + + conf_proc('6', f'{client.app_proc}/spare') + + pids = pids_for_process() + assert len(pids) == 6, 'reconf 6' + + client.get() + assert pids_for_process() == pids, 'reconf still 6' + + stop_all() + + +def test_python_idle_timeout(): + conf_proc({"spare": 0, "max": 6, "idle_timeout": 2}) + + client.get() + pids = pids_for_process() + assert len(pids) == 1, 'idle timeout 1' + + time.sleep(1) + + client.get() + + time.sleep(1) + + pids_new = pids_for_process() + assert len(pids_new) == 1, 'idle timeout still 1' + assert pids_for_process() == pids, 'idle timeout still 1 same pid' + + time.sleep(1) + + assert len(pids_for_process()) == 0, 'idle timed out' + + +def test_python_processes_connection_keepalive(): + conf_proc({"spare": 0, "max": 6, "idle_timeout": 2}) + + (_, sock) = client.get( + headers={'Host': 'localhost', 'Connection': 'keep-alive'}, + start=True, + read_timeout=1, + ) + assert len(pids_for_process()) == 1, 'keepalive connection 1' + + time.sleep(2) + + assert len(pids_for_process()) == 0, 'keepalive connection 0' + + sock.close() + + +def test_python_processes_access(): + conf_proc('1') + + path = f'/{client.app_proc}' + assert 'error' in client.conf_get(f'{path}/max') + assert 'error' in client.conf_get(f'{path}/spare') + assert 'error' in client.conf_get(f'{path}/idle_timeout') + + +def test_python_processes_invalid(): + assert 'error' in client.conf( + {"spare": -1}, client.app_proc + ), 'negative spare' + assert 'error' in client.conf({"max": -1}, client.app_proc), 'negative max' + assert 'error' in client.conf( + {"idle_timeout": -1}, client.app_proc + ), 'negative idle_timeout' + assert 'error' in client.conf( + {"spare": 2}, client.app_proc + ), 'spare gt max default' + assert 'error' in client.conf( + {"spare": 2, "max": 1}, client.app_proc + ), 'spare gt max' + assert 'error' in client.conf( + {"spare": 0, "max": 0}, client.app_proc + ), 'max zero' + + +def test_python_restart(temp_dir): + shutil.copyfile( + f'{option.test_dir}/python/restart/v1.py', f'{temp_dir}/wsgi.py' + ) + + client.load( + temp_dir, + name=client.app_name, + processes=1, + environment={'PYTHONDONTWRITEBYTECODE': '1'}, + ) + + b = client.get()['body'] + assert b == "v1", 'process started' + + shutil.copyfile( + f'{option.test_dir}/python/restart/v2.py', f'{temp_dir}/wsgi.py' + ) + + b = client.get()['body'] + assert b == "v1", 'still old process' + + assert 'success' in client.conf_get( + f'/control/applications/{client.app_name}/restart' + ), 'restart processes' + + b = client.get()['body'] + assert b == "v2", 'new process started' + + assert 'error' in client.conf_get( + '/control/applications/blah/restart' + ), 'application incorrect' + + assert 'error' in client.conf_delete( + f'/control/applications/{client.app_name}/restart' + ), 'method incorrect' + + +def test_python_restart_multi(): + conf_proc('2') + + pids = pids_for_process() + assert len(pids) == 2, 'restart 2 started' + + assert 'success' in client.conf_get( + f'/control/applications/{client.app_name}/restart' + ), 'restart processes' + + new_pids = pids_for_process() + assert len(new_pids) == 2, 'restart still 2' + + assert len(new_pids.intersection(pids)) == 0, 'restart all new' + + +def test_python_restart_longstart(): + client.load( + 'restart', + name=client.app_name, + module="longstart", + processes={"spare": 1, "max": 2, "idle_timeout": 5}, + ) + + assert len(pids_for_process()) == 1, 'longstarts == 1' + + client.get() + + pids = pids_for_process() + assert len(pids) == 2, 'longstarts == 2' + + assert 'success' in client.conf_get( + f'/control/applications/{client.app_name}/restart' + ), 'restart processes' + + # wait for longstarted app + time.sleep(2) + + new_pids = pids_for_process() + assert len(new_pids) == 1, 'restart 1' + + assert len(new_pids.intersection(pids)) == 0, 'restart all new' diff --git a/test/test_python_procman.py b/test/test_python_procman.py deleted file mode 100644 index b4378c4f..00000000 --- a/test/test_python_procman.py +++ /dev/null @@ -1,303 +0,0 @@ -import re -import shutil -import subprocess -import time - -import pytest - -from unit.applications.lang.python import ApplicationPython -from unit.option import option - -prerequisites = {'modules': {'python': 'any'}} - -client = ApplicationPython() - - -@pytest.fixture(autouse=True) -def setup_method_fixture(temp_dir): - client.app_name = f'app-{temp_dir.split("/")[-1]}' - client.app_proc = f'applications/{client.app_name}/processes' - client.load('empty', client.app_name) - - -def pids_for_process(): - time.sleep(0.2) - - output = subprocess.check_output(['ps', 'ax']) - - pids = set() - for m in re.findall( - fr'.*unit: "{client.app_name}" application', output.decode() - ): - pids.add(re.search(r'^\s*(\d+)', m).group(1)) - - return pids - - -def conf_proc(conf, path=None): - if path is None: - path = client.app_proc - - assert 'success' in client.conf(conf, path), 'configure processes' - - -def stop_all(): - assert 'success' in client.conf({"listeners": {}, "applications": {}}) - - assert len(pids_for_process()) == 0, 'stop all' - - -@pytest.mark.skip('not yet') -def test_python_processes_idle_timeout_zero(): - conf_proc({"spare": 0, "max": 2, "idle_timeout": 0}) - - client.get() - assert len(pids_for_process()) == 0, 'idle timeout 0' - - -def test_python_prefork(): - conf_proc('2') - - pids = pids_for_process() - assert len(pids) == 2, 'prefork 2' - - client.get() - assert pids_for_process() == pids, 'prefork still 2' - - conf_proc('4') - - pids = pids_for_process() - assert len(pids) == 4, 'prefork 4' - - client.get() - assert pids_for_process() == pids, 'prefork still 4' - - stop_all() - - -@pytest.mark.skip('not yet') -def test_python_prefork_same_processes(): - conf_proc('2') - pids = pids_for_process() - - conf_proc('4') - pids_new = pids_for_process() - - assert pids.issubset(pids_new), 'prefork same processes' - - -def test_python_ondemand(): - conf_proc({"spare": 0, "max": 8, "idle_timeout": 1}) - - assert len(pids_for_process()) == 0, 'on-demand 0' - - client.get() - pids = pids_for_process() - assert len(pids) == 1, 'on-demand 1' - - client.get() - assert pids_for_process() == pids, 'on-demand still 1' - - time.sleep(1) - - assert len(pids_for_process()) == 0, 'on-demand stop idle' - - stop_all() - - -def test_python_scale_updown(): - conf_proc({"spare": 2, "max": 8, "idle_timeout": 1}) - - pids = pids_for_process() - assert len(pids) == 2, 'updown 2' - - client.get() - pids_new = pids_for_process() - assert len(pids_new) == 3, 'updown 3' - assert pids.issubset(pids_new), 'updown 3 only 1 new' - - client.get() - assert pids_for_process() == pids_new, 'updown still 3' - - time.sleep(1) - - pids = pids_for_process() - assert len(pids) == 2, 'updown stop idle' - - client.get() - pids_new = pids_for_process() - assert len(pids_new) == 3, 'updown again 3' - assert pids.issubset(pids_new), 'updown again 3 only 1 new' - - stop_all() - - -def test_python_reconfigure(): - conf_proc({"spare": 2, "max": 6, "idle_timeout": 1}) - - pids = pids_for_process() - assert len(pids) == 2, 'reconf 2' - - client.get() - pids_new = pids_for_process() - assert len(pids_new) == 3, 'reconf 3' - assert pids.issubset(pids_new), 'reconf 3 only 1 new' - - conf_proc('6', f'{client.app_proc}/spare') - - pids = pids_for_process() - assert len(pids) == 6, 'reconf 6' - - client.get() - assert pids_for_process() == pids, 'reconf still 6' - - stop_all() - - -def test_python_idle_timeout(): - conf_proc({"spare": 0, "max": 6, "idle_timeout": 2}) - - client.get() - pids = pids_for_process() - assert len(pids) == 1, 'idle timeout 1' - - time.sleep(1) - - client.get() - - time.sleep(1) - - pids_new = pids_for_process() - assert len(pids_new) == 1, 'idle timeout still 1' - assert pids_for_process() == pids, 'idle timeout still 1 same pid' - - time.sleep(1) - - assert len(pids_for_process()) == 0, 'idle timed out' - - -def test_python_processes_connection_keepalive(): - conf_proc({"spare": 0, "max": 6, "idle_timeout": 2}) - - (_, sock) = client.get( - headers={'Host': 'localhost', 'Connection': 'keep-alive'}, - start=True, - read_timeout=1, - ) - assert len(pids_for_process()) == 1, 'keepalive connection 1' - - time.sleep(2) - - assert len(pids_for_process()) == 0, 'keepalive connection 0' - - sock.close() - - -def test_python_processes_access(): - conf_proc('1') - - path = f'/{client.app_proc}' - assert 'error' in client.conf_get(f'{path}/max') - assert 'error' in client.conf_get(f'{path}/spare') - assert 'error' in client.conf_get(f'{path}/idle_timeout') - - -def test_python_processes_invalid(): - assert 'error' in client.conf( - {"spare": -1}, client.app_proc - ), 'negative spare' - assert 'error' in client.conf({"max": -1}, client.app_proc), 'negative max' - assert 'error' in client.conf( - {"idle_timeout": -1}, client.app_proc - ), 'negative idle_timeout' - assert 'error' in client.conf( - {"spare": 2}, client.app_proc - ), 'spare gt max default' - assert 'error' in client.conf( - {"spare": 2, "max": 1}, client.app_proc - ), 'spare gt max' - assert 'error' in client.conf( - {"spare": 0, "max": 0}, client.app_proc - ), 'max zero' - - -def test_python_restart(temp_dir): - shutil.copyfile( - f'{option.test_dir}/python/restart/v1.py', f'{temp_dir}/wsgi.py' - ) - - client.load( - temp_dir, - name=client.app_name, - processes=1, - environment={'PYTHONDONTWRITEBYTECODE': '1'}, - ) - - b = client.get()['body'] - assert b == "v1", 'process started' - - shutil.copyfile( - f'{option.test_dir}/python/restart/v2.py', f'{temp_dir}/wsgi.py' - ) - - b = client.get()['body'] - assert b == "v1", 'still old process' - - assert 'success' in client.conf_get( - f'/control/applications/{client.app_name}/restart' - ), 'restart processes' - - b = client.get()['body'] - assert b == "v2", 'new process started' - - assert 'error' in client.conf_get( - '/control/applications/blah/restart' - ), 'application incorrect' - - assert 'error' in client.conf_delete( - f'/control/applications/{client.app_name}/restart' - ), 'method incorrect' - - -def test_python_restart_multi(): - conf_proc('2') - - pids = pids_for_process() - assert len(pids) == 2, 'restart 2 started' - - assert 'success' in client.conf_get( - f'/control/applications/{client.app_name}/restart' - ), 'restart processes' - - new_pids = pids_for_process() - assert len(new_pids) == 2, 'restart still 2' - - assert len(new_pids.intersection(pids)) == 0, 'restart all new' - - -def test_python_restart_longstart(): - client.load( - 'restart', - name=client.app_name, - module="longstart", - processes={"spare": 1, "max": 2, "idle_timeout": 5}, - ) - - assert len(pids_for_process()) == 1, 'longstarts == 1' - - client.get() - - pids = pids_for_process() - assert len(pids) == 2, 'longstarts == 2' - - assert 'success' in client.conf_get( - f'/control/applications/{client.app_name}/restart' - ), 'restart processes' - - # wait for longstarted app - time.sleep(2) - - new_pids = pids_for_process() - assert len(new_pids) == 1, 'restart 1' - - assert len(new_pids.intersection(pids)) == 0, 'restart all new' -- cgit From 3f805bc64e287e8fa06d82c0e3c0904f0173dafe Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Wed, 21 Feb 2024 16:40:43 -0800 Subject: Packages: added wasm-wasi-component module packaging for deb-based distros We need to redefine CFLAGS to drop missing-prototypes as warning since third-party code such as wasmtime fails to build from source when building a debian package. This happens only for packages because we use DPKG_EXPORT_BUILDFLAGS=1 propagating build flags to the environment, so cargo build picks it up as well. Since we have no control over third-party code, the easiest solution is to disable this warning. --- pkg/deb/Makefile.wasm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/deb/Makefile.wasm b/pkg/deb/Makefile.wasm index da028f19..9e408fda 100644 --- a/pkg/deb/Makefile.wasm +++ b/pkg/deb/Makefile.wasm @@ -6,9 +6,9 @@ MODULE_SUMMARY_wasm= WASM module for NGINX Unit MODULE_VERSION_wasm= $(VERSION) MODULE_RELEASE_wasm= 1 -MODULE_CONFARGS_wasm= wasm --include-path=\$$(CURDIR)/pkg/contrib/wasmtime/crates/c-api/include --lib-path=\$$(CURDIR)/pkg/contrib/wasmtime/target/release -MODULE_MAKEARGS_wasm= wasm -MODULE_INSTARGS_wasm= wasm-install +MODULE_CONFARGS_wasm= wasm --include-path=\$$(CURDIR)/pkg/contrib/wasmtime/crates/c-api/include --lib-path=\$$(CURDIR)/pkg/contrib/wasmtime/target/release \&\& ./configure wasm-wasi-component +MODULE_MAKEARGS_wasm= wasm wasm-wasi-component CFLAGS='\$$(CFLAGS) -Wno-missing-prototypes' +MODULE_INSTARGS_wasm= wasm-install wasm-wasi-component-install CFLAGS='\$$(CFLAGS) -Wno-missing-prototypes' MODULE_SOURCES_wasm= -- cgit From 7a6405566c0e15990fa6487a6dc4654389ce5601 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Wed, 21 Feb 2024 16:46:16 -0800 Subject: Packages: added wasm-wasi-component module packaging for rpm-based distros --- pkg/rpm/Makefile.wasm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/rpm/Makefile.wasm b/pkg/rpm/Makefile.wasm index c638071b..fbf64d11 100644 --- a/pkg/rpm/Makefile.wasm +++ b/pkg/rpm/Makefile.wasm @@ -6,9 +6,9 @@ MODULE_SUMMARY_wasm= WASM module for NGINX Unit MODULE_VERSION_wasm= $(VERSION) MODULE_RELEASE_wasm= 1 -MODULE_CONFARGS_wasm= wasm --include-path=\`pwd\`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=\`pwd\`/pkg/contrib/wasmtime/target/release -MODULE_MAKEARGS_wasm= wasm -MODULE_INSTARGS_wasm= wasm-install +MODULE_CONFARGS_wasm= wasm --include-path=\`pwd\`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=\`pwd\`/pkg/contrib/wasmtime/target/release \&\& ./configure wasm-wasi-component +MODULE_MAKEARGS_wasm= wasm wasm-wasi-component +MODULE_INSTARGS_wasm= wasm-install wasm-wasi-component-install MODULE_SOURCES_wasm= -- cgit From 7b13c30604952059c337b8c6afa588fdb5b8895a Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 22 Feb 2024 01:24:11 +0000 Subject: Wasm-wc: Add nxt_unit.o as a dependency in the auto script Rather than calling make itself to build nxt_unit.o make nxt_unit.o a dependency of the main module build target. Reported-by: Konstantin Pavlov Signed-off-by: Andrew Clayton --- auto/modules/wasm-wasi-component | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/auto/modules/wasm-wasi-component b/auto/modules/wasm-wasi-component index 1ec5841c..52ea3428 100644 --- a/auto/modules/wasm-wasi-component +++ b/auto/modules/wasm-wasi-component @@ -99,8 +99,7 @@ all: ${NXT_WCM_MODULE} ${NXT_WCM_MODULE}: $NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME -$NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME: - make build/src/nxt_unit.o +$NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME: build/src/nxt_unit.o $NXT_CARGO_CMD install: ${NXT_WCM_MODULE}-install -- cgit From d54af163c46bffd1bea0c2b544e412b5d628ec80 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 22 Feb 2024 02:24:36 +0000 Subject: Wasm-wc: Use the cargo build output as the make target dependency cargo build creates the language module under src/wasm-wasi-component/target/release/libwasm_wasi_component.so and not build/lib/unit/modules/wasm_wasi_component.unit.so which is what we were using as a target dependency in the Makefile which doesn't exist so this resulted in the following $ make wasm-wasi-component-install cargo build --release --manifest-path src/wasm-wasi-component/Cargo.toml Finished release [optimized] target(s) in 0.17s install -d /opt/unit/modules install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \ /opt/unit/modules/wasm_wasi_component.unit.so I.e it wanted to rebuild the module, after this patch we get the more correct $ make wasm-wasi-component-install install -d /opt/unit/modules install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \ /opt/unit/modules/wasm_wasi_component.unit.so This is all a little ugly because we're fighting against cargo wanting to do its own thing and this wasm-wasi-component language module build process is likely going to get some re-working anyway, so this will do for now. Reported-by: Konstantin Pavlov Signed-off-by: Andrew Clayton --- auto/modules/wasm-wasi-component | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/auto/modules/wasm-wasi-component b/auto/modules/wasm-wasi-component index 52ea3428..bfb6ffcb 100644 --- a/auto/modules/wasm-wasi-component +++ b/auto/modules/wasm-wasi-component @@ -5,6 +5,8 @@ NXT_WCM_MODULE=wasm-wasi-component NXT_WCM_MOD_NAME=`echo $NXT_WCM_MODULE | tr '-' '_'`.unit.so +NXT_WCM_MOD_CARGO="src/wasm-wasi-component/target/release/libwasm_wasi_component.so" + shift @@ -97,16 +99,16 @@ cat << END >> $NXT_MAKEFILE all: ${NXT_WCM_MODULE} -${NXT_WCM_MODULE}: $NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME +${NXT_WCM_MODULE}: ${NXT_WCM_MOD_CARGO} -$NXT_BUILD_DIR/lib/unit/modules/$NXT_WCM_MOD_NAME: build/src/nxt_unit.o +${NXT_WCM_MOD_CARGO}: build/src/nxt_unit.o $NXT_CARGO_CMD install: ${NXT_WCM_MODULE}-install ${NXT_WCM_MODULE}-install: ${NXT_WCM_MODULE} install-check install -d \$(DESTDIR)$NXT_MODULESDIR - install -p src/wasm-wasi-component/target/release/libwasm_wasi_component.so \\ + install -p ${NXT_WCM_MOD_CARGO} \\ \$(DESTDIR)$NXT_MODULESDIR/$NXT_WCM_MOD_NAME uninstall: ${NXT_WCM_MODULE}-uninstall -- cgit From 2f3c7c2c074cd91196d2793deb379ea92e13f885 Mon Sep 17 00:00:00 2001 From: "Sergey A. Osokin" Date: Mon, 19 Feb 2024 12:08:12 -0500 Subject: Update third-party java components to their recent versions Acked-by: Timo Stark [ Remove trailing '.' from subject line - Andrew ] Signed-off-by: Andrew Clayton --- auto/modules/java | 4 ++-- auto/modules/java_jar.sha512 | 24 ++++++++++++------------ test/unit/applications/lang/java.py | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/auto/modules/java b/auto/modules/java index 3727a111..b5c8d70a 100644 --- a/auto/modules/java +++ b/auto/modules/java @@ -238,7 +238,7 @@ cat << END > $NXT_JAVA_JARS static const char *nxt_java_system_jars[] = { END -NXT_TOMCAT_VERSION=9.0.83 +NXT_TOMCAT_VERSION=9.0.86 NXT_JAR_VERSION=$NXT_TOMCAT_VERSION @@ -284,7 +284,7 @@ static const char *nxt_java_unit_jars[] = { "$NXT_UNIT_JAR", END -NXT_JAR_VERSION=9.4.53.v20231009 +NXT_JAR_VERSION=9.4.54.v20240208 NXT_JAR_NAMESPACE=org/eclipse/jetty/ NXT_JAR_NAME=jetty-util diff --git a/auto/modules/java_jar.sha512 b/auto/modules/java_jar.sha512 index 13a7357c..a689b901 100644 --- a/auto/modules/java_jar.sha512 +++ b/auto/modules/java_jar.sha512 @@ -1,14 +1,14 @@ d0c17607eee55e181baa03f1abb2cf77f50e5114c471c2031607206768d8549c74ebb0a276d87dd3f8ea44db5e54e56087311c229ba18ad6013c388fc861beed classgraph-4.8.165.jar ab441acf5551a7dc81c353eaccb3b3df9e89a48987294d19e39acdb83a5b640fcdff7414cee29f5b96eaa8826647f1d5323e185018fe33a64c402d69c73c9158 ecj-3.26.0.jar -867afb0e69ab225a3d57c0eda4e773ca2f41dcc6eb294e14aef4d69441314bee88221081f9edc6289b9e4a99184804b60c32f4443c8ff96eb34d6508b348b755 jetty-http-9.4.53.v20231009.jar -aca14debabc0cc40e154d4de4de404c383c4611e9f2482911e17d9072f0941cef8a88511d5d49d70946e65872e1bc8d395b9401b2ec91132553d782d99140ce3 jetty-server-9.4.53.v20231009.jar -429b269e21c6e7bf86ba8a8b71569e3abf61b06ace9dd064a9c80af4282227e910a8d20be86ef6581895ff283a5aa4711bbb238de45dc7628f494624879c4d49 jetty-util-9.4.53.v20231009.jar -96af9145dfe3a9566af2a1c93085ed48d80fde0587db7e951b07ec32f1654aa17977b37d011589e2eec6f1f9b3ff52937d429a86d68febb23fde9572fda3b246 tomcat-api-9.0.83.jar -1b8a5de6e75664fdc1e8c1c1fd58694e0b4057ac33508c24fc95662f44fd177bc20c36d134926f68b93978fa659d3c9874e70a6f0e2ac8dd2dd9c7a7643d4ba3 tomcat-el-api-9.0.83.jar -71a560be521bb71366541ddac79b1a412e40e635165c18e9bd05dac59e4417557fe836109687181d4799c6089a375bc05d9fa86a14cd60b19e54e8828d00cf47 tomcat-jasper-9.0.83.jar -7a42a590f6af52e34aef323766295bb2b8ae87ac48b5bba0de6ac1240e262c0f37ef9ef4d185d4ec08249faff6125863d01256587810a3d9131bb20bf57159d1 tomcat-jasper-el-9.0.83.jar -4051eb6b13a7e59f64ffc99c6dad176e1908a4eb6936765f69c1df63048d3f28f94b93164ec7c9579ea8b37dff26a7f2e66354ddbcb594596839e9068fd8c18e tomcat-jsp-api-9.0.83.jar -2e1d417495b08cf3bf9d7f2806aee8fc96f42ad8152489497cb539dcb4d6668f3d6f6f7a6ae10df06abe7c9db3e11c7b03c9d46c35ec1074c8f7d6788a6cfc80 tomcat-juli-9.0.83.jar -96032c24db4336498d1b0328a48a6eae35010c840ceefd140c7c79a6fcdf5319ad5a16c4fc21de4ae1494c5b5eadcedca3da01a4584b27deb25dc80ac21ae4a9 tomcat-servlet-api-9.0.83.jar -ab0c1868ce50ec0d45c0d541921fd3e33b5b3bc314a97230467380461e8d80c54d08ba8ef94b0a28493ed3ffde3333623170850f3ad630485fc332dbceb2745b tomcat-util-9.0.83.jar -acc12ed11fce573003b4bd973a7dce311704a1c317811a8fd4086b9eb73296cc5f1e291f81c065869f578091cb508f49cbfbec32aba747b9367a504898bb4d04 tomcat-util-scan-9.0.83.jar +6e1d6fdffcb2acf8daa9ce5b3ad973526a30b3556dc8e950254c68c64cd70e101b28a8acac41b3bd74de6b9c8eac10676afdc3c58ccb1f61a74323721592e0b5 jetty-http-9.4.54.v20240208.jar +780ee47a8722bdfb4b159f440acbfb69afdb73cc329906392b10eba8d30c564aa6377fab129e61b85a56945f01c4403913c80b6ce3158d108d88a3ad64527f06 jetty-server-9.4.54.v20240208.jar +fbe9cf7efeba9f29297f75de3f1c2d98f0e02816a1dc9e6eaddcabb84c3a699a9332218c532017a3707ec57f4f99066bc671708bde4ec84dd873b8403422d7e9 jetty-util-9.4.54.v20240208.jar +1aa9024f49f74b44252f7c90d00bbfdd6aae4e96866708a0c2325def0314c8b7e5ad2fd17bb6b4b135eb2c513fe74b5b591d4b0fe3d1921192cfecadf140b7fa tomcat-api-9.0.86.jar +60a9991ff7b95ef4edfac57cd7c18b6c5177d9aee4f775b5794b5833246b928e1a685b80785babd2f450e3cd18383c58b843b0b5e742252a37044494bc90d608 tomcat-el-api-9.0.86.jar +b09cbfb834564cc7025ffad7bf069569989d3efa3bd176696045aea08bfb53622aa1aece5c84ea4371f0193d4fd477b9179999399e75d04205b219a3ab19bb66 tomcat-jasper-9.0.86.jar +1431469e91debc0ffcf820df2973782221be955dac0739a77d9030ac619cde96320970cb27eb2ff9de1e6bde3227a70b1645d1934da8e10fe2b32c069d33afec tomcat-jasper-el-9.0.86.jar +1ad9ebc1c49beb243c18ab2c459dbd54cab9514223c44b5c7e05d53d290c64c49990fc0fe276c66b1f6f6625acca651fdcb4b7df9e23fb0cc43bc05ad3900798 tomcat-jsp-api-9.0.86.jar +d30055aabf5d45ad350e01702ed0ff4bfbcdd14bee40e1e8a9a7690719816aff019ca961b7970234eaba673c3c13f5cea5dbf1bc0612ce4e8f7de795af2f170d tomcat-juli-9.0.86.jar +d7fa7d7bf35b35b7bb925cce6284e2f750e8e94ee54057daff4e369a32b361e6044e9011048a9dff54b12371ee785d34e82306b60ffae8add76602071e5fc9c5 tomcat-servlet-api-9.0.86.jar +b4a268b79fbfcd610ea5d14446ef71ad5f2ad3da247ae148669e3082ff5fd7f7256a2ecdf2529e4280ed393f53c3a7f6d09a5c38d5653b30b25ab3c4b74ed732 tomcat-util-9.0.86.jar +f2086356c8eca5cfe890232056ce30378422d3994c499845f52ec8641453af02041ae31ffdcb567bb998f0f24465d1ab65456b23e8f781058efdc01658c7252d tomcat-util-scan-9.0.86.jar diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py index 37dd1155..351d04ce 100644 --- a/test/unit/applications/lang/java.py +++ b/test/unit/applications/lang/java.py @@ -53,7 +53,7 @@ class ApplicationJava(ApplicationProto): os.makedirs(classes_path) classpath = ( - f'{option.current_dir}/build/tomcat-servlet-api-9.0.83.jar' + f'{option.current_dir}/build/tomcat-servlet-api-9.0.86.jar' ) ws_jars = glob.glob( -- cgit From e2cab032341f4a41d02107ac742cc44a04205038 Mon Sep 17 00:00:00 2001 From: Dylan Arbour Date: Thu, 22 Feb 2024 12:59:27 -0500 Subject: Remove debug from builds and tests The info and above errors should be more than enough for debugging failures in GitHuB Actions CI. --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42ca7896..8599b34c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,8 +136,7 @@ jobs: --openssl \ --njs \ --cc-opt="-I njs/src/ -I njs/build" \ - --ld-opt="-L njs/build" \ - --debug + --ld-opt="-L njs/build" - name: Make unit run: | -- cgit From faa7e792428265a7c72ff0c692f31c04932d7dc0 Mon Sep 17 00:00:00 2001 From: Konstantin Pavlov Date: Thu, 22 Feb 2024 14:12:51 -0800 Subject: Packages: Pass CFLAGS to compile wasm modules on all packaging targets This extends the approach used for debian-based packages in 3f805bc64e28 to rpm as well. Notable change for both deb and rpm packaging is to use CFLAGS as defined in the build/Makefile, and not pass them from the environment which might not be there (as is the case for rpm). While at it, stop passing CFLAGS in the install phase, as it should no longer invoke builds (see d54af163c46b). The rpm part was overlooked in 7a6405566c0, since testing was not done on the platforms where problem manifested itself, notably Amazon Linux 2023 and Fedora 38+. --- pkg/deb/Makefile.wasm | 4 ++-- pkg/rpm/Makefile.wasm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/deb/Makefile.wasm b/pkg/deb/Makefile.wasm index 9e408fda..8f3fdc67 100644 --- a/pkg/deb/Makefile.wasm +++ b/pkg/deb/Makefile.wasm @@ -7,8 +7,8 @@ MODULE_VERSION_wasm= $(VERSION) MODULE_RELEASE_wasm= 1 MODULE_CONFARGS_wasm= wasm --include-path=\$$(CURDIR)/pkg/contrib/wasmtime/crates/c-api/include --lib-path=\$$(CURDIR)/pkg/contrib/wasmtime/target/release \&\& ./configure wasm-wasi-component -MODULE_MAKEARGS_wasm= wasm wasm-wasi-component CFLAGS='\$$(CFLAGS) -Wno-missing-prototypes' -MODULE_INSTARGS_wasm= wasm-install wasm-wasi-component-install CFLAGS='\$$(CFLAGS) -Wno-missing-prototypes' +MODULE_MAKEARGS_wasm= wasm wasm-wasi-component CFLAGS=\"\$$(shell grep ^CFLAGS \$$(BUILDDIR_\$$*)/build/Makefile | cut -d' ' -f 3-) -Wno-missing-prototypes\" +MODULE_INSTARGS_wasm= wasm-install wasm-wasi-component-install MODULE_SOURCES_wasm= diff --git a/pkg/rpm/Makefile.wasm b/pkg/rpm/Makefile.wasm index fbf64d11..cb2ad35a 100644 --- a/pkg/rpm/Makefile.wasm +++ b/pkg/rpm/Makefile.wasm @@ -7,7 +7,7 @@ MODULE_VERSION_wasm= $(VERSION) MODULE_RELEASE_wasm= 1 MODULE_CONFARGS_wasm= wasm --include-path=\`pwd\`/pkg/contrib/wasmtime/crates/c-api/include --lib-path=\`pwd\`/pkg/contrib/wasmtime/target/release \&\& ./configure wasm-wasi-component -MODULE_MAKEARGS_wasm= wasm wasm-wasi-component +MODULE_MAKEARGS_wasm= wasm wasm-wasi-component CFLAGS=\"\$$(grep ^CFLAGS build/Makefile | cut -d' ' -f 3-) -Wno-missing-prototypes\" MODULE_INSTARGS_wasm= wasm-install wasm-wasi-component-install MODULE_SOURCES_wasm= -- cgit From 9d02b906a5e54000d8ae8f22c0a2fac930cfeea3 Mon Sep 17 00:00:00 2001 From: Dylan Arbour Date: Thu, 22 Feb 2024 13:55:32 -0500 Subject: Add PHP 8.2 and 8.1 to test matrix `setup-php` action was fixed to add embed SAPI for older versions of PHP --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8599b34c..65820c58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,10 @@ jobs: os: ubuntu-latest - build: perl os: ubuntu-latest + - build: php-8.1 + os: ubuntu-latest + - build: php-8.2 + os: ubuntu-latest - build: php-8.3 os: ubuntu-latest - build: python-3.11 -- cgit From d5665f49a486e8aff27d8f7ee65cfbb187401f20 Mon Sep 17 00:00:00 2001 From: Dylan Arbour Date: Fri, 23 Feb 2024 18:08:23 -0500 Subject: Update setup-go to v5 Removes deprecation notices on actions builds. v5 updates the version of node and `cache: false` disables the errors related to not finding a go.sum --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65820c58..b5368ae9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -150,9 +150,10 @@ jobs: ## Go ## - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: '${{ steps.metadata.outputs.version }}' + cache: false if: steps.metadata.outputs.module == 'go' - name: Configure go -- cgit From 4d25c612247643329beb9e924d1feded3cf578ab Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 15 Feb 2024 18:28:51 +0000 Subject: Edited changes.xml for the 1.32.0 release --- docs/changes.xml | 90 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 10 deletions(-) diff --git a/docs/changes.xml b/docs/changes.xml index ba41f00d..ccc87ef7 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -53,9 +53,17 @@ NGINX Unit updated to 1.32.0. - + + + + + + + -http.createServer() now accepts "options" argument introduced in Node.js v9.6.0, v8.12.0. +WebAssembly Components using WASI interfaces defined in wasi:http/proxy@0.2.0. @@ -80,12 +88,62 @@ can be used as a unique request identifier. -bytearray in response body for ASGI applications. +options to set control socket permissions. + + + + + +Ruby arrays in response headers, improving compatibility with Rack v3.0. +Python bytearray response bodies for ASGI applications. + + + + + +router could crash while sending large files. Thanks to rustedsword. + + + + + +serving static files from a network filesystem could lead to error. + + + + + +"uidmap" and "gidmap" isolation options validation. + + + + + +abstract UNIX socket name could be corrupted during configuration validation. +Thanks to Alejandro Colomar. + + + + + +HTTP header field value encoding could be misinterpreted in Python module. + + + + + +Node.js http.createServer() accepts and ignores the "options" argument, +improving compatibility with strapi applications, among others. + + + + + ServerRequest.flushHeaders() implemented in Node.js module to make it compatible with Next.js. @@ -97,13 +155,25 @@ ServerRequest.httpVersion variable format in Node.js module. + + +Node.js module handles standard library imports prefixed with "node:", making it +possible to run newer Nuxt applications, among others. + + - - + + +Node.js tarball location changed to avoid build/install errors. + + - + + +Go module sets environment variables necessary for building on macOS/arm64 +systems. + + @@ -182,8 +252,8 @@ compatibility with Node.js 15.0.0 and above. -Node.JS unit-http NPM module now has appropriate default paths for -macOS/arm64 systems. +Node.JS unit-http NPM module now has appropriate default paths for macOS/arm64 +systems. -- cgit From ace553dca47da60a14e10c29de0c59ec73cc3ad7 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 15 Feb 2024 19:56:06 +0000 Subject: Generated Dockerfiles for Unit 1.32.0 --- pkg/docker/Dockerfile.go1.21 | 4 ++-- pkg/docker/Dockerfile.go1.22 | 4 ++-- pkg/docker/Dockerfile.jsc11 | 4 ++-- pkg/docker/Dockerfile.minimal | 4 ++-- pkg/docker/Dockerfile.node20 | 4 ++-- pkg/docker/Dockerfile.node21 | 4 ++-- pkg/docker/Dockerfile.perl5.36 | 4 ++-- pkg/docker/Dockerfile.perl5.38 | 4 ++-- pkg/docker/Dockerfile.php8.2 | 4 ++-- pkg/docker/Dockerfile.php8.3 | 4 ++-- pkg/docker/Dockerfile.python3.11 | 4 ++-- pkg/docker/Dockerfile.python3.12 | 4 ++-- pkg/docker/Dockerfile.ruby3.2 | 4 ++-- pkg/docker/Dockerfile.ruby3.3 | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pkg/docker/Dockerfile.go1.21 b/pkg/docker/Dockerfile.go1.21 index 068a787f..f0caf402 100644 --- a/pkg/docker/Dockerfile.go1.21 +++ b/pkg/docker/Dockerfile.go1.21 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.go1.22 b/pkg/docker/Dockerfile.go1.22 index 567d607a..ccd19bda 100644 --- a/pkg/docker/Dockerfile.go1.22 +++ b/pkg/docker/Dockerfile.go1.22 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index ff84edd5..b056c0d9 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 667f3016..59849ed0 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.node20 b/pkg/docker/Dockerfile.node20 index dff88113..6174fd62 100644 --- a/pkg/docker/Dockerfile.node20 +++ b/pkg/docker/Dockerfile.node20 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.node21 b/pkg/docker/Dockerfile.node21 index ab03d91a..a2c1e419 100644 --- a/pkg/docker/Dockerfile.node21 +++ b/pkg/docker/Dockerfile.node21 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.perl5.36 b/pkg/docker/Dockerfile.perl5.36 index 696b0035..5d7564c8 100644 --- a/pkg/docker/Dockerfile.perl5.36 +++ b/pkg/docker/Dockerfile.perl5.36 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.perl5.38 b/pkg/docker/Dockerfile.perl5.38 index 1680f1e5..6af576d1 100644 --- a/pkg/docker/Dockerfile.perl5.38 +++ b/pkg/docker/Dockerfile.perl5.38 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.php8.2 b/pkg/docker/Dockerfile.php8.2 index 063ec28c..4348cfed 100644 --- a/pkg/docker/Dockerfile.php8.2 +++ b/pkg/docker/Dockerfile.php8.2 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.php8.3 b/pkg/docker/Dockerfile.php8.3 index de946eb7..31fe2335 100644 --- a/pkg/docker/Dockerfile.php8.3 +++ b/pkg/docker/Dockerfile.php8.3 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.python3.11 b/pkg/docker/Dockerfile.python3.11 index 5fbeb1d7..699fa426 100644 --- a/pkg/docker/Dockerfile.python3.11 +++ b/pkg/docker/Dockerfile.python3.11 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.python3.12 b/pkg/docker/Dockerfile.python3.12 index 3043502e..d3fb3c01 100644 --- a/pkg/docker/Dockerfile.python3.12 +++ b/pkg/docker/Dockerfile.python3.12 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.ruby3.2 b/pkg/docker/Dockerfile.ruby3.2 index 03f99c20..b6263e5d 100644 --- a/pkg/docker/Dockerfile.ruby3.2 +++ b/pkg/docker/Dockerfile.ruby3.2 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ diff --git a/pkg/docker/Dockerfile.ruby3.3 b/pkg/docker/Dockerfile.ruby3.3 index 8d23499e..132bbb9c 100644 --- a/pkg/docker/Dockerfile.ruby3.3 +++ b/pkg/docker/Dockerfile.ruby3.3 @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org" LABEL org.opencontainers.image.source="https://github.com/nginx/unit" LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images" LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers " -LABEL org.opencontainers.image.version="1.31.1" +LABEL org.opencontainers.image.version="1.32.0" RUN set -ex \ && savedAptMark="$(apt-mark showmanual)" \ @@ -15,7 +15,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && mkdir -p /usr/src/unit \ && cd /usr/src/unit \ - && git clone --depth 1 -b 1.31.1-1 https://github.com/nginx/unit \ + && git clone --depth 1 -b 1.32.0-1 https://github.com/nginx/unit \ && cd unit \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ -- cgit From 088117008c9e8f397a58cc8d8070ce047beff12f Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 15 Feb 2024 19:20:23 +0000 Subject: Added version 1.32.0 CHANGES --- CHANGES | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ docs/changes.xml | 4 ++-- docs/unit-openapi.yaml | 2 +- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index b16751ae..5204a2a1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,57 @@ +Changes with Unit 1.32.0 27 Feb 2024 + + *) Feature: WebAssembly Components using WASI interfaces defined in + wasi:http/proxy@0.2.0. + + *) Feature: conditional access logging. + + *) Feature: NJS variables access. + + *) Feature: $request_id variable contains a string that is formed using + random data and can be used as a unique request identifier. + + *) Feature: options to set control socket permissions. + + *) Feature: Ruby arrays in response headers, improving compatibility + with Rack v3.0. + + *) Feature: Python bytearray response bodies for ASGI applications. + + *) Bugfix: router could crash while sending large files. Thanks to + rustedsword. + + *) Bugfix: serving static files from a network filesystem could lead to + error. + + *) Bugfix: "uidmap" and "gidmap" isolation options validation. + + *) Bugfix: abstract UNIX socket name could be corrupted during + configuration validation. Thanks to Alejandro Colomar. + + *) Bugfix: HTTP header field value encoding could be misinterpreted in + Python module. + + *) Bugfix: Node.js http.createServer() accepts and ignores the "options" + argument, improving compatibility with strapi applications, among + others. + + *) Bugfix: ServerRequest.flushHeaders() implemented in Node.js module to + make it compatible with Next.js. + + *) Bugfix: ServerRequest.httpVersion variable format in Node.js module. + + *) Bugfix: Node.js module handles standard library imports prefixed with + "node:", making it possible to run newer Nuxt applications, among + others. + + *) Bugfix: Node.js tarball location changed to avoid build/install + errors. + + *) Bugfix: Go module sets environment variables necessary for building + on macOS/arm64 systems. + + Changes with Unit 1.31.1 19 Oct 2023 *) Feature: allow to set the HTTP response status in Wasm module. diff --git a/docs/changes.xml b/docs/changes.xml index ccc87ef7..4d64a16d 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -44,7 +44,7 @@ Initial release of Python 3.12 module for NGINX Unit. unit-jsc19 unit-jsc20 unit-jsc21 unit-wasm" ver="1.32.0" rev="1" - date="" time="" + date="2024-02-27" time="18:00:00 +0000" packager="Nginx Packaging <nginx-packaging@f5.com>"> @@ -58,7 +58,7 @@ NGINX Unit updated to 1.32.0. diff --git a/docs/unit-openapi.yaml b/docs/unit-openapi.yaml index 4ce26fa0..b2e02e89 100644 --- a/docs/unit-openapi.yaml +++ b/docs/unit-openapi.yaml @@ -1,6 +1,6 @@ openapi: 3.0.0 info: - title: "NGINX Unit 1.31.1" + title: "NGINX Unit 1.32.0" description: "NGINX Unit is a lightweight and versatile application runtime that provides the essential components for your web application as a single open-source server: running application code, serving static assets, -- cgit