summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIppolitov Igor <iippolitov@nginx.com>2023-10-19 12:50:39 +0100
committerIppolitov Igor <iippolitov@nginx.com>2023-10-19 12:50:39 +0100
commitc43629880472bba8d389dfb0b7ae6d883b0ba499 (patch)
treeacecdcb36cfb85fac3d8cdbfbe473c26ac2e2686
parent8c4425ccb9a413e8d0506e0254f0e84bd89a32a6 (diff)
parentfb33ec86a3b6ca6a844dfa6980bb9e083094abec (diff)
downloadunit-c43629880472bba8d389dfb0b7ae6d883b0ba499.tar.gz
unit-c43629880472bba8d389dfb0b7ae6d883b0ba499.tar.bz2
Merged with the default branch.1.31.1-1
-rw-r--r--.hgtags1
-rw-r--r--CHANGES27
-rw-r--r--auto/modules/java6
-rw-r--r--auto/modules/java_jar.sha51226
-rw-r--r--docs/changes.xml89
-rw-r--r--docs/unit-openapi.yaml57
-rw-r--r--pkg/contrib/src/njs/SHA512SUMS2
-rw-r--r--pkg/contrib/src/njs/version2
-rw-r--r--pkg/docker/Dockerfile.go1.204
-rw-r--r--pkg/docker/Dockerfile.go1.214
-rw-r--r--pkg/docker/Dockerfile.jsc114
-rw-r--r--pkg/docker/Dockerfile.minimal4
-rw-r--r--pkg/docker/Dockerfile.node184
-rw-r--r--pkg/docker/Dockerfile.node204
-rw-r--r--pkg/docker/Dockerfile.perl5.364
-rw-r--r--pkg/docker/Dockerfile.perl5.384
-rw-r--r--pkg/docker/Dockerfile.php8.24
-rw-r--r--pkg/docker/Dockerfile.python3.114
-rw-r--r--pkg/docker/Dockerfile.ruby3.24
-rw-r--r--pkg/docker/Dockerfile.wasm4
-rw-r--r--pkg/docker/welcome.html2
-rw-r--r--src/java/nxt_jni_Response.c7
-rw-r--r--src/nodejs/unit-http/binding_pub.gyp25
-rw-r--r--src/nodejs/unit-http/http_server.js16
-rw-r--r--src/nxt_conn_write.c2
-rw-r--r--src/nxt_controller.c5
-rw-r--r--src/nxt_http_rewrite.c1
-rw-r--r--src/nxt_main_process.c4
-rw-r--r--src/nxt_signal_handlers.c2
-rw-r--r--src/nxt_socket_msg.h18
-rw-r--r--src/nxt_sprintf.c17
-rw-r--r--src/nxt_unit.c3
-rw-r--r--src/wasm/nxt_rt_wasmtime.c23
-rw-r--r--src/wasm/nxt_wasm.c31
-rw-r--r--src/wasm/nxt_wasm.h12
-rw-r--r--test/node/write_array/app.js4
-rw-r--r--test/node/write_buffer/app.js2
-rw-r--r--test/test_java_application.py17
-rw-r--r--test/test_node_application.py4
-rw-r--r--test/test_php_application.py30
-rw-r--r--test/test_response_headers.py173
-rw-r--r--test/unit/applications/lang/java.py2
-rw-r--r--tools/README.md22
-rwxr-xr-xtools/unitc104
-rw-r--r--version4
45 files changed, 675 insertions, 113 deletions
diff --git a/.hgtags b/.hgtags
index 60aecf10..f5ecba72 100644
--- a/.hgtags
+++ b/.hgtags
@@ -73,3 +73,4 @@ e7b7f2bb04e8c6f4cbe6374fd6960d4465654215 1.29.1-1
8a0b4338a15648792bcad47edb53f1b1c0badeb4 1.30.0-1
3a9046dca2a6c51ee2df2cabdf69cb9a83e7a1e6 1.31.0
ef8ddca63f2c1a3e1758968740837b921dd953dc 1.31.0-1
+25aafe2ff61e0424b3245f4e3d40eb1fa7611063 1.31.1
diff --git a/CHANGES b/CHANGES
index a0e4410e..b16751ae 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,31 @@
+Changes with Unit 1.31.1 19 Oct 2023
+
+ *) Feature: allow to set the HTTP response status in Wasm module.
+
+ *) Feature: allow uploads larger than 4GiB in Wasm module.
+
+ *) Bugfix: application process could crash while rewriting URLs with
+ query strings.
+
+ *) Bugfix: requests larger than about 64MiB could cause error in Wasm
+ module.
+
+ *) Bugfix: when using many headers in Java module some of them could be
+ corrupted due to memory realocation issue.
+
+ *) Bugfix: ServerRequest.destroy() implemented in Node.js module to make
+ it compatible with some frameworks that might use it.
+
+ *) Bugfix: chunk argument of ServerResponse.write() can now be a
+ Uint8Array to improve compatibility with Node.js 15.0.0 and above.
+
+ *) Bugfix: Node.JS unit-http NPM module now has appropriate default
+ paths for macOS/arm64 systems.
+
+ *) Bugfix: build on musl libc with clang.
+
+
Changes with Unit 1.31.0 31 Aug 2023
*) Change: if building with njs, version 0.8.0 or later is now required.
diff --git a/auto/modules/java b/auto/modules/java
index 7c39eb37..53f99f7e 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.75
+NXT_TOMCAT_VERSION=9.0.82
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.51.v20230217
+NXT_JAR_VERSION=9.4.53.v20231009
NXT_JAR_NAMESPACE=org/eclipse/jetty/
NXT_JAR_NAME=jetty-util
@@ -297,7 +297,7 @@ NXT_JAR_NAME=jetty-http
. auto/modules/java_get_jar
NXT_JAR_NAME=classgraph
-NXT_JAR_VERSION=4.8.158
+NXT_JAR_VERSION=4.8.162
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 da08f786..e0a648af 100644
--- a/auto/modules/java_jar.sha512
+++ b/auto/modules/java_jar.sha512
@@ -1,14 +1,14 @@
-00dc1aedae7cb6600b4b27ac7ec0234981a23a8c6f03dc1881304b7d999d94f0fdaa51e0008288740d9890b34f41462e8ed82c76f36a18bd45eabbb8084ec8d4 classgraph-4.8.158.jar
+a117092f4ab77ef89b3b83a45b9e33c0360cb18098df17da77e5d765a6b5cea1fae6190399217236c0d970f2b3603bc8f408c2471cf8854de1282dba7525c335 classgraph-4.8.162.jar
ab441acf5551a7dc81c353eaccb3b3df9e89a48987294d19e39acdb83a5b640fcdff7414cee29f5b96eaa8826647f1d5323e185018fe33a64c402d69c73c9158 ecj-3.26.0.jar
-606d0446a948c7a349cba5415d079bd054e43a8a09727c8300865f38678c5101642ecafa777d5f979bde1bd520543a4cf83348fcd9a444e6681cf773eb3c5824 jetty-http-9.4.51.v20230217.jar
-e9d3f7104214a16435d077eb53d943130b3a85bf9e8a48b9e40a7ad063ca3cca69324e03f21202e66fc5fd864c3cb09cd1857eff8d682c69398b4d75c1a430c6 jetty-server-9.4.51.v20230217.jar
-12725e106000d6ef672c474e467d7c976c3913b2d39a92e7304cc30d0e0d1f92575227d2c2201b97ca50f39cba81ac8b79bccb2b32b63d758ac4e192173c3f62 jetty-util-9.4.51.v20230217.jar
-b802b595d796285653c3c1b3d870295767afc6d4f857d439d579b7261dc8d015c948cd900e93ebc0ad706d1c74600645d3a18caef4f040a7085ff0e9f6cb4e44 tomcat-api-9.0.75.jar
-90cc3c2847782b6854bc0549e7bdfda2e92feac726285718aa4083baef597e472e7f3712257790107fa9306263f645fcc17344a8209415d10a75f4f4cfa30b04 tomcat-el-api-9.0.75.jar
-c23a0db30c5d77a518c7cd0afebe6c59600b45e03651409788acb91fa652752960f6e21ac15a233b433dbe290028d00ac72c4cd2856880f4d4ba9ef227692d7a tomcat-jasper-9.0.75.jar
-06fb8c0d49945437900be1cc8fd8d8123a7bf6599e7755aa6c7963a65d46aea444661de532ce0e6c0573ecd12def2d5d1e7942ecace9c7c3a39e232373f3fd6b tomcat-jasper-el-9.0.75.jar
-7dbaacd7f0490c8f0062eb12cd244acc9c51ee72d1c60ad841ac61905cd46b5d477b01c97019ba6e93a6b27de3e3438c620fb156cec3d6ece36f37918a6ee5bd tomcat-jsp-api-9.0.75.jar
-05c15c5c6877b39aed4457e5ea7992819c28dc148a2442a149a8d5ee294a62042eebd2f3846acdd70b08d531d95cdcc8cfcd7b64fb8b046aa5639e7901505131 tomcat-juli-9.0.75.jar
-92a44f8970746976a63351d45f84c7963127bd21db0af834a7d38dcfb3c29450398cb4b466636dfb3d8e764093c612eb2938af22ac2098171bac201ad6bcc320 tomcat-servlet-api-9.0.75.jar
-6794c0d6d5780ca09fdbaf801c1475f227b799c809a46195c0fd1f9792303fb6d0aa6e49ac049337863bdb512c390334470210294364b7af25d86355f7fd0605 tomcat-util-9.0.75.jar
-e97c90c857a5c814518f3da10d8c09c900417421d81ad500ad338ac10c6b7dc8338b486d2338f5cebea6fa33c9803fd2c06cf35c44b1b5b720331943f2e22de3 tomcat-util-scan-9.0.75.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
diff --git a/docs/changes.xml b/docs/changes.xml
index fca9ebcd..60f259ad 100644
--- a/docs/changes.xml
+++ b/docs/changes.xml
@@ -16,6 +16,95 @@
unit-jsc14 unit-jsc15 unit-jsc16 unit-jsc17 unit-jsc18
unit-jsc19 unit-jsc20
unit-wasm"
+ ver="1.31.1" rev="1"
+ date="2023-10-19" time="18:00:00 +0300"
+ packager="Nginx Packaging &lt;nginx-packaging@f5.com&gt;">
+
+<change>
+<para>
+NGINX Unit updated to 1.31.1.
+</para>
+</change>
+
+</changes>
+
+
+<changes apply="unit" ver="1.31.1" rev="1"
+ date="2023-10-19" time="18:00:00 +0300"
+ packager="Nginx Packaging &lt;nginx-packaging@f5.com&gt;">
+
+<change type="feature">
+<para>
+allow to set the HTTP response status in Wasm module.
+</para>
+</change>
+
+<change type="feature">
+<para>
+allow uploads larger than 4GiB in Wasm module.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+application process could crash while rewriting URLs with query strings.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+requests larger than about 64MiB could cause error in Wasm module.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+when using many headers in Java module some of them could be
+corrupted due to memory realocation issue.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+ServerRequest.destroy() implemented in Node.js module to make it compatible
+with some frameworks that might use it.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+chunk argument of ServerResponse.write() can now be a Uint8Array to improve
+compatibility with Node.js 15.0.0 and above.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+Node.JS unit-http NPM module now has appropriate default paths for
+macOS/arm64 systems.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+build on musl libc with clang.
+</para>
+</change>
+
+</changes>
+
+
+<changes apply="unit-php
+ unit-python unit-python2.7
+ unit-python3.4 unit-python3.5 unit-python3.6 unit-python3.7
+ unit-python3.8 unit-python3.9 unit-python3.10 unit-python3.11
+ unit-go
+ unit-perl
+ unit-ruby
+ unit-jsc-common unit-jsc8 unit-jsc10 unit-jsc11 unit-jsc13
+ unit-jsc14 unit-jsc15 unit-jsc16 unit-jsc17 unit-jsc18
+ unit-jsc19 unit-jsc20
+ unit-wasm"
ver="1.31.0" rev="1"
date="2023-08-31" time="18:00:00 +0300"
packager="Nginx Packaging &lt;nginx-packaging@f5.com&gt;">
diff --git a/docs/unit-openapi.yaml b/docs/unit-openapi.yaml
index 0301326d..4ce26fa0 100644
--- a/docs/unit-openapi.yaml
+++ b/docs/unit-openapi.yaml
@@ -1,6 +1,6 @@
openapi: 3.0.0
info:
- title: "NGINX Unit 1.30.0"
+ title: "NGINX Unit 1.31.1"
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,
@@ -5887,6 +5887,7 @@ components:
description: "An object whose options define a step's action."
oneOf:
- $ref: "#/components/schemas/configRouteStepActionPass"
+ - $ref: "#/components/schemas/configRouteStepActionProxy"
- $ref: "#/components/schemas/configRouteStepActionReturn"
- $ref: "#/components/schemas/configRouteStepActionShare"
@@ -5903,6 +5904,32 @@ components:
description: "Destination to which the action passes
incoming requests."
+ rewrite:
+ $ref: "#/components/schemas/configRouteStepActionRewrite"
+
+ response_headers:
+ $ref: "#/components/schemas/configRouteStepActionResponseHeaders"
+
+ #/config/routes/{stepIndex}/action/proxy
+ #/config/routes/{routeName}/{stepIndex}/action/proxy
+ configRouteStepActionProxy:
+ type: object
+ description: "An object whose single option defines a step's proxy
+ action."
+ required:
+ - proxy
+ properties:
+ proxy:
+ type: string
+ description: "Socket address of an HTTP server to where the request
+ is proxied."
+
+ rewrite:
+ $ref: "#/components/schemas/configRouteStepActionRewrite"
+
+ response_headers:
+ $ref: "#/components/schemas/configRouteStepActionResponseHeaders"
+
#/config/routes/{stepIndex}/action/return
#/config/routes/{routeName}/{stepIndex}/action/return
configRouteStepActionReturn:
@@ -5922,6 +5949,12 @@ components:
type: string
description: "URI; used if the return value implies redirection."
+ rewrite:
+ $ref: "#/components/schemas/configRouteStepActionRewrite"
+
+ response_headers:
+ $ref: "#/components/schemas/configRouteStepActionResponseHeaders"
+
#/config/routes/{stepIndex}/action/share
#/config/routes/{routeName}/{stepIndex}/action/share
configRouteStepActionShare:
@@ -5964,6 +5997,28 @@ components:
description: "Turns on and off mount point resolution."
default: true
+ rewrite:
+ $ref: "#/components/schemas/configRouteStepActionRewrite"
+
+ response_headers:
+ $ref: "#/components/schemas/configRouteStepActionResponseHeaders"
+
+ #/config/routes/{stepIndex}/action/rewrite
+ #/config/routes/{routeName}/{stepIndex}/action/rewrite
+ configRouteStepActionRewrite:
+ type: string
+ description: "Updates the URI of the incoming request before the action
+ is applied."
+
+ #/config/routes/{stepIndex}/action/response_headers
+ #/config/routes/{routeName}/{stepIndex}/action/response_headers
+ configRouteStepActionResponseHeaders:
+ type: object
+ description: "Updates the header fields of Unit’s response before the
+ action is taken."
+ additionalProperties:
+ type: string
+
# /config/listeners/
configListeners:
type: object
diff --git a/pkg/contrib/src/njs/SHA512SUMS b/pkg/contrib/src/njs/SHA512SUMS
index ad8e180c..3c3ce210 100644
--- a/pkg/contrib/src/njs/SHA512SUMS
+++ b/pkg/contrib/src/njs/SHA512SUMS
@@ -1 +1 @@
-200f3ae1e1909f0d8086e2fbfbd6b8654e596f3ad2e4cf4d863e201cfcb2f86a419fa9061067cbededf6a8c792c1a5ecf60c3a4c983af044c179bb9fe619eea5 njs-0.8.0.tar.gz
+5038b4cd9e18de89c9cf7fe7b25a0a8a03c51cfb20b6ee5085e68f885113b104092baf5ac8fe80e9d1611b2f75e47448753e6b327bef2e706ea46f2d6299f927 njs-0.8.1.tar.gz
diff --git a/pkg/contrib/src/njs/version b/pkg/contrib/src/njs/version
index 8c9ee6ba..73c524fb 100644
--- a/pkg/contrib/src/njs/version
+++ b/pkg/contrib/src/njs/version
@@ -1 +1 @@
-NJS_VERSION := 0.8.0
+NJS_VERSION := 0.8.1
diff --git a/pkg/docker/Dockerfile.go1.20 b/pkg/docker/Dockerfile.go1.20
index 98f6d92f..53379dd1 100644
--- a/pkg/docker/Dockerfile.go1.20
+++ b/pkg/docker/Dockerfile.go1.20
@@ -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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.go1.21 b/pkg/docker/Dockerfile.go1.21
index 18d3cc7b..a90dc115 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11
index e7a057bd..2844c813 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal
index 8c5ce0d5..4b585480 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.node18 b/pkg/docker/Dockerfile.node18
index 735342dd..4ac18847 100644
--- a/pkg/docker/Dockerfile.node18
+++ b/pkg/docker/Dockerfile.node18
@@ -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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.node20 b/pkg/docker/Dockerfile.node20
index f291ccfc..f783ba72 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.perl5.36 b/pkg/docker/Dockerfile.perl5.36
index 2db7506d..8cc5d9e2 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.perl5.38 b/pkg/docker/Dockerfile.perl5.38
index bd653cb1..531188fe 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.php8.2 b/pkg/docker/Dockerfile.php8.2
index bd27a4dd..5783bf6c 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.python3.11 b/pkg/docker/Dockerfile.python3.11
index cdc96434..b5e81b6c 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.ruby3.2 b/pkg/docker/Dockerfile.ruby3.2
index 8b870756..c417a327 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/Dockerfile.wasm b/pkg/docker/Dockerfile.wasm
index 852bc5d0..e45f020f 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 <docker-maint@nginx.com>"
-LABEL org.opencontainers.image.version="1.31.0"
+LABEL org.opencontainers.image.version="1.31.1"
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 \
- && hg clone -u 1.31.0-1 https://hg.nginx.org/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)" \
diff --git a/pkg/docker/welcome.html b/pkg/docker/welcome.html
index 9c4f8281..89de39e1 100644
--- a/pkg/docker/welcome.html
+++ b/pkg/docker/welcome.html
@@ -35,7 +35,7 @@
on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
<b>/var/run/control.unit.sock</b> inside the container.<br>
To see the current configuration run:</p>
- <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+ <pre>docker exec -ti &lt;containerID&gt; curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
</div>
<hr>
diff --git a/src/java/nxt_jni_Response.c b/src/java/nxt_jni_Response.c
index 2ccfd854..fa698ee8 100644
--- a/src/java/nxt_jni_Response.c
+++ b/src/java/nxt_jni_Response.c
@@ -334,7 +334,8 @@ nxt_java_get_response_info(jlong req_info_ptr, uint32_t extra_fields,
- req->response->fields_count
|| extra_data > (uint32_t) (buf->end - buf->free))
{
- p = buf->start + req->response_max_fields * sizeof(nxt_unit_field_t);
+ p = buf->start + sizeof(nxt_unit_response_t)
+ + req->response_max_fields * sizeof(nxt_unit_field_t);
max_size = 2 * (buf->end - p);
if (max_size > nxt_unit_buf_max()) {
@@ -936,8 +937,8 @@ nxt_java_Response_reset(JNIEnv *env, jclass cls, jlong req_info_ptr)
buf = req->response_buf;
- buf->free = buf->start + req->response_max_fields
- * sizeof(nxt_unit_field_t);
+ buf->free = buf->start + sizeof(nxt_unit_response_t)
+ + req->response_max_fields * sizeof(nxt_unit_field_t);
}
}
diff --git a/src/nodejs/unit-http/binding_pub.gyp b/src/nodejs/unit-http/binding_pub.gyp
index 3c39933a..3dadf4a5 100644
--- a/src/nodejs/unit-http/binding_pub.gyp
+++ b/src/nodejs/unit-http/binding_pub.gyp
@@ -7,9 +7,28 @@
['OS=="mac"', {
'xcode_settings': {
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
- }
- }]
- ],
+ },
+ 'conditions': [
+ [ 'target_arch=="arm64"', {
+ 'include_dirs': [
+ '/opt/homebrew/include'
+ ],
+ 'libraries' : [
+ '-L/opt/homebrew/lib',
+ '-lunit'
+ ],
+ }],
+ ['target_arch=="x64"', {
+ 'include_dirs': [
+ '/usr/local/include',
+ ],
+ 'libraries' : [
+ '-L/usr/local/lib',
+ '-lunit'
+ ],
+ }]
+ ]}
+ ]],
'sources': ["unit.cpp", "addon.cpp"],
'libraries': ["-lunit"]
}]
diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js
index 89964ec3..0f00b47f 100644
--- a/src/nodejs/unit-http/http_server.js
+++ b/src/nodejs/unit-http/http_server.js
@@ -33,8 +33,17 @@ ServerResponse.prototype.statusMessage = undefined;
ServerResponse.prototype.headers_len = 0;
ServerResponse.prototype.headers_count = 0;
ServerResponse.prototype.headersSent = false;
+ServerResponse.prototype.destroyed = false;
ServerResponse.prototype.finished = false;
+ServerResponse.prototype.destroy = function destroy(error) {
+ if (!this.destroyed) {
+ this.destroyed = true;
+ }
+
+ return this;
+};
+
ServerResponse.prototype._finish = function _finish() {
this.headers = {};
this.headers_len = 0;
@@ -243,8 +252,11 @@ ServerResponse.prototype._writeBody = function(chunk, encoding, callback) {
}
if (chunk) {
- if (typeof chunk !== 'string' && !(chunk instanceof Buffer)) {
- throw new TypeError('First argument must be a string or Buffer');
+ if (typeof chunk !== 'string' && !(chunk instanceof Buffer ||
+ chunk instanceof Uint8Array)) {
+ throw new TypeError(
+ 'First argument must be a string, Buffer, ' +
+ 'or Uint8Array');
}
if (typeof chunk === 'string') {
diff --git a/src/nxt_conn_write.c b/src/nxt_conn_write.c
index bcf9e8fa..714a3e15 100644
--- a/src/nxt_conn_write.c
+++ b/src/nxt_conn_write.c
@@ -97,7 +97,7 @@ nxt_conn_io_write(nxt_task_t *task, void *obj, void *data)
if (sb.limit == 0) {
/*
* Postpone writing until next event poll to allow to
- * process other recevied events and to get new events.
+ * process other received events and to get new events.
*/
c->write_timer.handler = nxt_conn_write_timer_handler;
nxt_timer_add(engine, &c->write_timer, 0);
diff --git a/src/nxt_controller.c b/src/nxt_controller.c
index 4e2e3749..eb814321 100644
--- a/src/nxt_controller.c
+++ b/src/nxt_controller.c
@@ -510,8 +510,9 @@ nxt_controller_conf_default(void)
nxt_mp_t *mp;
nxt_conf_value_t *conf;
- static const nxt_str_t json
- = nxt_string("{ \"listeners\": {}, \"applications\": {} }");
+ static const nxt_str_t json = nxt_string(
+ "{ \"listeners\": {}, \"routes\": [], \"applications\": {} }"
+ );
mp = nxt_mp_create(1024, 128, 256, 32);
diff --git a/src/nxt_http_rewrite.c b/src/nxt_http_rewrite.c
index ae5c865a..fb216eeb 100644
--- a/src/nxt_http_rewrite.c
+++ b/src/nxt_http_rewrite.c
@@ -93,6 +93,7 @@ nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r)
nxt_memcpy(p, r->args->start, r->args->length);
r->target = target;
+ r->args->start = p;
}
r->path = nxt_mp_alloc(r->mem_pool, sizeof(nxt_str_t));
diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c
index 6622f67e..3f317d5e 100644
--- a/src/nxt_main_process.c
+++ b/src/nxt_main_process.c
@@ -856,7 +856,7 @@ nxt_main_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data)
nxt_array_t *new_files;
nxt_runtime_t *rt;
- nxt_log(task, NXT_LOG_NOTICE, "signal %d (%s) recevied, %s",
+ nxt_log(task, NXT_LOG_NOTICE, "signal %d (%s) received, %s",
(int) (uintptr_t) obj, data, "log files rotation");
rt = task->thread->runtime;
@@ -1073,7 +1073,7 @@ nxt_main_process_sigchld_handler(nxt_task_t *task, void *obj, void *data)
static void
nxt_main_process_signal_handler(nxt_task_t *task, void *obj, void *data)
{
- nxt_trace(task, "signal signo:%d (%s) recevied, ignored",
+ nxt_trace(task, "signal signo:%d (%s) received, ignored",
(int) (uintptr_t) obj, data);
}
diff --git a/src/nxt_signal_handlers.c b/src/nxt_signal_handlers.c
index 69ae2bc4..63b38fab 100644
--- a/src/nxt_signal_handlers.c
+++ b/src/nxt_signal_handlers.c
@@ -31,7 +31,7 @@ const nxt_sig_event_t nxt_process_signals[] = {
static void
nxt_signal_handler(nxt_task_t *task, void *obj, void *data)
{
- nxt_trace(task, "signal signo:%d (%s) recevied, ignored",
+ nxt_trace(task, "signal signo:%d (%s) received, ignored",
(int) (uintptr_t) obj, data);
}
diff --git a/src/nxt_socket_msg.h b/src/nxt_socket_msg.h
index 04de1761..81617bd6 100644
--- a/src/nxt_socket_msg.h
+++ b/src/nxt_socket_msg.h
@@ -69,6 +69,20 @@ NXT_EXPORT ssize_t nxt_recvmsg(nxt_socket_t s,
nxt_iobuf_t *iob, nxt_uint_t niob, nxt_recv_oob_t *oob);
+nxt_inline struct cmsghdr *
+NXT_CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr *cmsg)
+{
+#if !defined(__GLIBC__) && defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wsign-compare"
+#endif
+ return CMSG_NXTHDR(msgh, cmsg);
+#if !defined(__GLIBC__) && defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+}
+
+
nxt_inline void
nxt_socket_msg_oob_init(nxt_send_oob_t *oob, int *fds)
{
@@ -135,7 +149,7 @@ nxt_socket_msg_oob_get_fds(nxt_recv_oob_t *oob, nxt_fd_t *fd)
for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg, cmsg))
+ cmsg = NXT_CMSG_NXTHDR(&msg, cmsg))
{
size = cmsg->cmsg_len - CMSG_LEN(0);
@@ -174,7 +188,7 @@ nxt_socket_msg_oob_get(nxt_recv_oob_t *oob, nxt_fd_t *fd, nxt_pid_t *pid)
for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg, cmsg))
+ cmsg = NXT_CMSG_NXTHDR(&msg, cmsg))
{
size = cmsg->cmsg_len - CMSG_LEN(0);
diff --git a/src/nxt_sprintf.c b/src/nxt_sprintf.c
index 9c8e27ed..875f43a5 100644
--- a/src/nxt_sprintf.c
+++ b/src/nxt_sprintf.c
@@ -156,7 +156,8 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
p = va_arg(args, const u_char *);
if (nxt_slow_path(p == NULL)) {
- goto copy;
+ buf = nxt_cpymem(buf, null, nxt_length(null));
+ continue;
}
while (*p != '\0' && buf < end) {
@@ -174,6 +175,11 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
fmt++;
p = va_arg(args, const u_char *);
+ if (nxt_slow_path(p == NULL)) {
+ buf = nxt_cpymem(buf, null, nxt_length(null));
+ continue;
+ }
+
goto copy;
}
@@ -556,14 +562,7 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
copy:
- if (nxt_slow_path(p == NULL)) {
- p = null;
- length = nxt_length(null);
-
- } else {
- length = nxt_min((size_t) (end - buf), length);
- }
-
+ length = nxt_min((size_t) (end - buf), length);
buf = nxt_cpymem(buf, p, length);
continue;
}
diff --git a/src/nxt_unit.c b/src/nxt_unit.c
index e1b1897a..b6291b2d 100644
--- a/src/nxt_unit.c
+++ b/src/nxt_unit.c
@@ -2148,7 +2148,8 @@ nxt_unit_response_realloc(nxt_unit_request_info_t *req,
resp->status = req->response->status;
resp->content_length = req->response->content_length;
- p = buf->start + max_fields_count * sizeof(nxt_unit_field_t);
+ p = buf->start + sizeof(nxt_unit_response_t)
+ + max_fields_count * sizeof(nxt_unit_field_t);
f = resp->fields;
for (i = 0; i < req->response->fields_count; i++) {
diff --git a/src/wasm/nxt_rt_wasmtime.c b/src/wasm/nxt_rt_wasmtime.c
index 99786b89..bf0b0a0f 100644
--- a/src/wasm/nxt_rt_wasmtime.c
+++ b/src/wasm/nxt_rt_wasmtime.c
@@ -102,6 +102,19 @@ nxt_wasm_send_headers(void *env, wasmtime_caller_t *caller,
}
+static wasm_trap_t *
+nxt_wasm_set_resp_status(void *env, wasmtime_caller_t *caller,
+ const wasmtime_val_t *args, size_t nargs,
+ wasmtime_val_t *results, size_t nresults)
+{
+ nxt_wasm_ctx_t *ctx = env;
+
+ ctx->status = args[0].of.i32;
+
+ return NULL;
+}
+
+
static void
nxt_wasmtime_execute_hook(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook)
{
@@ -123,7 +136,7 @@ nxt_wasmtime_execute_hook(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook)
}
-static void
+static int
nxt_wasmtime_execute_request(const nxt_wasm_ctx_t *ctx)
{
int i = 0;
@@ -142,7 +155,10 @@ nxt_wasmtime_execute_request(const nxt_wasm_ctx_t *ctx)
nxt_wasmtime_err_msg(error, trap,
"failed to call function [->wasm_request_handler]"
);
+ return -1;
}
+
+ return results[0].of.i32;
}
@@ -183,6 +199,11 @@ nxt_wasmtime_set_function_imports(nxt_wasm_ctx_t *ctx)
.func = nxt_wasm_send_headers,
.params = { WASM_I32 },
.ft = NXT_WASM_FT_1_0
+ }, {
+ .func_name = "nxt_wasm_set_resp_status",
+ .func = nxt_wasm_set_resp_status,
+ .params = { WASM_I32 },
+ .ft = NXT_WASM_FT_1_0
},
{ }
diff --git a/src/wasm/nxt_wasm.c b/src/wasm/nxt_wasm.c
index 45a40b4b..92ed57ab 100644
--- a/src/wasm/nxt_wasm.c
+++ b/src/wasm/nxt_wasm.c
@@ -24,6 +24,11 @@ static nxt_wasm_ctx_t nxt_wasm_ctx;
static const nxt_wasm_operations_t *nxt_wops;
+enum {
+ NXT_WASM_HTTP_OK = 200,
+ NXT_WASM_HTTP_ERROR = 500
+};
+
void
nxt_wasm_do_response_end(nxt_wasm_ctx_t *ctx)
@@ -48,7 +53,7 @@ nxt_wasm_do_send_headers(nxt_wasm_ctx_t *ctx, uint32_t offset)
fields_len += rh->fields[i].name_len + rh->fields[i].value_len;
}
- nxt_unit_response_init(ctx->req, 200, rh->nfields, fields_len);
+ nxt_unit_response_init(ctx->req, ctx->status, rh->nfields, fields_len);
for (i = 0; i < rh->nfields; i++) {
const char *name;
@@ -72,7 +77,7 @@ nxt_wasm_do_send_response(nxt_wasm_ctx_t *ctx, uint32_t offset)
nxt_unit_request_info_t *req = ctx->req;
if (!nxt_unit_response_is_init(req)) {
- nxt_unit_response_init(req, 200, 0, 0);
+ nxt_unit_response_init(req, ctx->status, 0, 0);
}
resp = (nxt_wasm_response_t *)(nxt_wasm_ctx.baddr + offset);
@@ -84,6 +89,7 @@ nxt_wasm_do_send_response(nxt_wasm_ctx_t *ctx, uint32_t offset)
static void
nxt_wasm_request_handler(nxt_unit_request_info_t *req)
{
+ int err;
size_t offset, read_bytes, content_sent, content_len;
ssize_t bytes_read;
nxt_unit_field_t *sf, *sf_end;
@@ -149,15 +155,18 @@ nxt_wasm_request_handler(nxt_unit_request_info_t *req)
wr->request_size = offset + bytes_read;
+ nxt_wasm_ctx.status = NXT_WASM_HTTP_OK;
nxt_wasm_ctx.req = req;
- nxt_wops->exec_request(&nxt_wasm_ctx);
+ err = nxt_wops->exec_request(&nxt_wasm_ctx);
+ if (err) {
+ goto out_err_500;
+ }
if (content_len == content_sent) {
goto request_done;
}
- wr->nfields = 0;
- wr->content_off = offset = sizeof(nxt_wasm_request_t);
+ offset = sizeof(nxt_wasm_request_t);
do {
read_bytes = nxt_min(content_len - content_sent,
NXT_WASM_MEM_SIZE - offset);
@@ -167,10 +176,20 @@ nxt_wasm_request_handler(nxt_unit_request_info_t *req)
content_sent += bytes_read;
wr->request_size = wr->content_sent = bytes_read;
wr->total_content_sent = content_sent;
+ wr->content_off = offset;
- nxt_wops->exec_request(&nxt_wasm_ctx);
+ err = nxt_wops->exec_request(&nxt_wasm_ctx);
+ if (err) {
+ goto out_err_500;
+ }
} while (content_sent < content_len);
+ goto request_done;
+
+out_err_500:
+ nxt_unit_response_init(req, NXT_WASM_HTTP_ERROR, 0, 0);
+ nxt_unit_request_done(req, NXT_UNIT_OK);
+
request_done:
NXT_WASM_DO_HOOK(NXT_WASM_FH_REQUEST_END);
}
diff --git a/src/wasm/nxt_wasm.h b/src/wasm/nxt_wasm.h
index cb9dbdfe..6bc3ae35 100644
--- a/src/wasm/nxt_wasm.h
+++ b/src/wasm/nxt_wasm.h
@@ -59,10 +59,10 @@ struct nxt_wasm_request_s {
uint32_t server_name_off;
uint32_t server_name_len;
- uint32_t content_off;
- uint32_t content_len;
+ uint64_t content_len;
+ uint64_t total_content_sent;
uint32_t content_sent;
- uint32_t total_content_sent;
+ uint32_t content_off;
uint32_t request_size;
@@ -70,6 +70,8 @@ struct nxt_wasm_request_s {
uint32_t tls;
+ char __pad[4];
+
nxt_wasm_http_field_t fields[];
};
@@ -118,12 +120,14 @@ struct nxt_wasm_ctx_s {
size_t baddr_off;
size_t response_off;
+
+ uint16_t status;
};
struct nxt_wasm_operations_s {
int (*init)(nxt_wasm_ctx_t *ctx);
void (*destroy)(const nxt_wasm_ctx_t *ctx);
- void (*exec_request)(const nxt_wasm_ctx_t *ctx);
+ int (*exec_request)(const nxt_wasm_ctx_t *ctx);
void (*exec_hook)(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook);
};
diff --git a/test/node/write_array/app.js b/test/node/write_array/app.js
new file mode 100644
index 00000000..b7abb3fc
--- /dev/null
+++ b/test/node/write_array/app.js
@@ -0,0 +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);
diff --git a/test/node/write_buffer/app.js b/test/node/write_buffer/app.js
index 506e8613..72e9c600 100644
--- a/test/node/write_buffer/app.js
+++ b/test/node/write_buffer/app.js
@@ -1,5 +1,5 @@
require('http').createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'})
- .end(new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]));
+ .end(Buffer.from('buffer', 'utf8'));
}).listen(7080);
diff --git a/test/test_java_application.py b/test/test_java_application.py
index a8814583..eefc5c79 100644
--- a/test/test_java_application.py
+++ b/test/test_java_application.py
@@ -875,6 +875,23 @@ 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')
+
+ value = '0123456789' * 10
+
+ headers = client.get(
+ headers={
+ 'X-Header': [value] * 100,
+ 'Content-Type': 'text/html',
+ 'Host': 'localhost',
+ 'Connection': 'close',
+ }
+ )['headers']
+
+ for i in range(0, 99):
+ assert headers[f'X-Reply-{i}'] == value, 'many headers'
+
def test_java_application_get_headers_empty():
client.load('get_headers')
diff --git a/test/test_node_application.py b/test/test_node_application.py
index e4226535..ab8aa8f8 100644
--- a/test/test_node_application.py
+++ b/test/test_node_application.py
@@ -149,6 +149,10 @@ 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')
diff --git a/test/test_php_application.py b/test/test_php_application.py
index 6c1f227b..17440909 100644
--- a/test/test_php_application.py
+++ b/test/test_php_application.py
@@ -171,6 +171,36 @@ def test_php_application_query_string_empty():
assert resp['headers']['Query-String'] == '', 'query string empty'
+def test_php_application_query_string_rewrite():
+ assert 'success' in client.conf(
+ {
+ "listeners": {"*:7080": {"pass": "routes"}},
+ "routes": [
+ {
+ "action": {
+ "rewrite": "/new",
+ "pass": "applications/query_string",
+ },
+ },
+ ],
+ "applications": {
+ "query_string": {
+ "type": client.get_application_type(),
+ "processes": {"spare": 0},
+ "root": f"{option.test_dir}/php/query_string",
+ "script": "index.php",
+ }
+ },
+ },
+ )
+
+ assert client.get(url='/old')['status'] == 200
+
+ resp = client.get(url='/old?arg=val')
+ assert resp['status'] == 200
+ assert resp['headers']['Query-String'] == 'arg=val'
+
+
def test_php_application_fastcgi_finish_request(findall, unit_pid):
client.load('fastcgi_finish_request')
diff --git a/test/test_response_headers.py b/test/test_response_headers.py
new file mode 100644
index 00000000..50f47d9a
--- /dev/null
+++ b/test/test_response_headers.py
@@ -0,0 +1,173 @@
+from pathlib import Path
+
+import pytest
+from unit.applications.proto import ApplicationProto
+from unit.applications.lang.python import ApplicationPython
+from unit.option import option
+
+client = ApplicationProto()
+client_python = ApplicationPython()
+
+
+@pytest.fixture(autouse=True)
+def setup_method_fixture(temp_dir):
+ path = Path(f'{temp_dir}/index.html')
+ path.write_text('0123456789')
+
+ assert 'success' in client.conf(
+ {
+ "listeners": {
+ "*:7080": {"pass": "routes"},
+ },
+ "routes": [
+ {
+ "action": {
+ "share": str(path),
+ "response_headers": {
+ "X-Foo": "foo",
+ },
+ }
+ }
+ ],
+ }
+ )
+
+
+def action_update(conf):
+ assert 'success' in client.conf(conf, 'routes/0/action')
+
+
+def test_response_headers(temp_dir):
+ resp = client.get()
+ assert resp['status'] == 200, 'status 200'
+ assert resp['headers']['X-Foo'] == 'foo', 'header 200'
+
+ assert 'success' in client.conf(f'"{temp_dir}"', 'routes/0/action/share')
+
+ resp = client.get()
+ assert resp['status'] == 301, 'status 301'
+ assert resp['headers']['X-Foo'] == 'foo', 'header 301'
+
+ assert 'success' in client.conf('"/blah"', 'routes/0/action/share')
+
+ resp = client.get()
+ assert resp['status'] == 404, 'status 404'
+ assert 'X-Foo' not in client.get()['headers'], 'header 404'
+
+
+def test_response_last_action():
+ assert 'success' in client.conf(
+ {
+ "listeners": {
+ "*:7080": {"pass": "routes/first"},
+ },
+ "routes": {
+ "first": [
+ {
+ "action": {
+ "pass": "routes/second",
+ "response_headers": {
+ "X-Foo": "foo",
+ },
+ }
+ }
+ ],
+ "second": [
+ {
+ "action": {"return": 200},
+ }
+ ],
+ },
+ "applications": {},
+ }
+ )
+
+ assert 'X-Foo' not in client.get()['headers']
+
+
+def test_response_pass(require):
+ require({'modules': {'python': 'any'}})
+
+ assert 'success' in client_python.conf(
+ {
+ "listeners": {
+ "*:7080": {"pass": "routes"},
+ },
+ "routes": [
+ {
+ "action": {
+ "pass": "applications/empty",
+ "response_headers": {
+ "X-Foo": "foo",
+ },
+ }
+ },
+ ],
+ "applications": {
+ "empty": {
+ "type": client_python.get_application_type(),
+ "processes": {"spare": 0},
+ "path": f'{option.test_dir}/python/empty',
+ "working_directory": f'{option.test_dir}/python/empty',
+ "module": "wsgi",
+ }
+ },
+ }
+ )
+
+ assert client.get()['headers']['X-Foo'] == 'foo'
+
+
+def test_response_fallback():
+ assert 'success' in client.conf(
+ {
+ "listeners": {"*:7080": {"pass": "routes"}},
+ "routes": [
+ {
+ "action": {
+ "share": "/blah",
+ "fallback": {
+ "return": 200,
+ "response_headers": {
+ "X-Foo": "foo",
+ },
+ },
+ }
+ }
+ ],
+ }
+ )
+
+ assert client.get()['headers']['X-Foo'] == 'foo'
+
+
+def test_response_headers_var():
+ assert 'success' in client.conf(
+ {
+ "X-Foo": "$uri",
+ },
+ 'routes/0/action/response_headers',
+ )
+
+ assert client.get()['headers']['X-Foo'] == '/'
+
+
+def test_response_headers_remove():
+ assert 'success' in client.conf(
+ {"etag": None},
+ 'routes/0/action/response_headers',
+ )
+
+ assert 'ETag' not in client.get()['headers']
+
+
+def test_response_headers_invalid(skip_alert):
+ skip_alert(r'failed to apply new conf')
+
+ def check_invalid(conf):
+ assert 'error' in client.conf(
+ conf,
+ 'routes/0/action/response_headers',
+ )
+
+ check_invalid({"X-Foo": "$u"})
diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py
index a253aea5..dc6d2bfc 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.75.jar'
+ f'{option.current_dir}/build/tomcat-servlet-api-9.0.82.jar'
)
ws_jars = glob.glob(
diff --git a/tools/README.md b/tools/README.md
index 1a631e10..883bc107 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -37,12 +37,16 @@ web page with NGINX Unit.
| _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.
+| `-f` \| `--format YAML` | Convert configuration data to/from YAML format. The [yq](https://github.com/mikefarah/yq) tool is required for this option.
| `-q` \| `--quiet` | No output to stdout.
Options are case insensitive and can appear in any order. For example, a
redundant part of the configuration can be identified by its URI, and
followed by `delete` in a subsequent command.
+Options may be combined. For example, `edit -f yaml` will open the
+configuration URI in a text editor, in YAML format.
+
### Local Configuration
For local instances of Unit, the control socket is automatically detected.
The error log is monitored; when changes occur, new log entries are shown.
@@ -51,10 +55,9 @@ The error log is monitored; when changes occur, new log entries are shown.
|---------|-|
| `-l` \| `--nolog` | Do not monitor the error log after configuration changes.
-#### Examples
+#### Local Examples
```shell
unitc /config
-unitc /control/applications/my_app/restart
unitc /config < unitconf.json
echo '{"*:8080": {"pass": "routes"}}' | unitc /config/listeners
unitc /config/applications/my_app DELETE
@@ -64,10 +67,12 @@ unitc /certificates/bundle cert.pem key.pem
### Remote Configuration
For remote instances of NGINX Unit, the control socket on the remote host can
be set with the `$UNIT_CTRL` environment variable. The remote control socket
-can be accessed over TCP or SSH, depending on the type of control socket:
+can be accessed over TCP, SSH, or Docker containers on the host, depending on
+the type of control socket:
* `ssh://[user@]remote_host[:ssh_port]/path/to/control.socket`
* `http://remote_host:unit_control_port`
+ * `docker://container_ID[/path/to/control.socket]`
> **Note:** SSH is recommended for remote confguration. Consider the
> [security implications](https://unit.nginx.org/howto/security/#secure-socket-and-state)
@@ -77,8 +82,9 @@ can be accessed over TCP or SSH, depending on the type of control socket:
|---------|-|
| `ssh://…` | Specify the remote Unix control socket on the command line.
| `http://…`*URI* | For remote TCP control sockets, the URI may include the protocol, hostname, and port.
+| `docker://…` | Specify the local container ID/name. The default Unix control socket can be overridden.
-#### Examples
+#### Remote Examples
```shell
unitc http://192.168.0.1:8080/status
UNIT_CTRL=http://192.168.0.1:8080 unitc /status
@@ -89,4 +95,12 @@ cat catchall_route.json | unitc POST /config/routes
echo '{"match":{"uri":"/wp-admin/*"},"action":{"return":403}}' | unitc INSERT /config/routes
```
+#### Docker Examples
+```shell
+unitc docker://d43251184c54 /config
+echo '{"http": {"log_route": true}}' | unitc docker://d43251184c54 /settings
+unitc docker://f4f3d9e918e6/root/unit.sock /control/applications/my_app/restart
+UNIT_CTRL=docker://4d0431488982 unitc /status/requests/total
+```
+
---
diff --git a/tools/unitc b/tools/unitc
index 877e11d4..4ab5f663 100755
--- a/tools/unitc
+++ b/tools/unitc
@@ -10,14 +10,39 @@ REMOTE=0
SHOW_LOG=1
NOLOG=0
QUIET=0
+CONVERT=0
URI=""
-SSH_CMD=""
+RPC_CMD=""
METHOD=PUT
CONF_FILES=()
while [ $# -gt 0 ]; do
OPTION=$(echo $1 | tr '[a-z]' '[A-Z]')
case $OPTION in
+ "-F" | "--FORMAT")
+ case $(echo $2 | tr '[a-z]' '[A-Z]') in
+ "YAML")
+ CONVERT=1
+ if hash yq 2> /dev/null; then
+ CONVERT_TO_JSON="yq eval -P --output-format=json"
+ CONVERT_FROM_JSON="yq eval -P --output-format=yaml"
+ else
+ echo "${0##*/}: ERROR: yq(1) is required to use YAML format; install at <https://github.com/mikefarah/yq#install>"
+ exit 1
+ fi
+ ;;
+ "")
+ echo "${0##*/}: ERROR: Must specify configuration format"
+ exit 1
+ ;;
+ *)
+ echo "${0##*/}: ERROR: Invalid format ($2)"
+ exit 1
+ ;;
+ esac
+ shift; shift
+ ;;
+
"-H" | "--HELP")
shift
;;
@@ -45,15 +70,25 @@ while [ $# -gt 0 ]; do
*)
if [ -f $1 ] && [ -r $1 ]; then
CONF_FILES+=($1)
+ if [ "${1##*.}" = "yaml" ]; then
+ echo "${0##*/}: INFO: converting $1 to JSON"
+ shift; set -- "--format" "yaml" "$@" # Apply the command line option
+ else
+ shift
+ fi
elif [ "${1:0:1}" = "/" ] || [ "${1:0:4}" = "http" ] && [ "$URI" = "" ]; then
URI=$1
+ shift
elif [ "${1:0:6}" = "ssh://" ]; then
UNIT_CTRL=$1
+ shift
+ elif [ "${1:0:9}" = "docker://" ]; then
+ UNIT_CTRL=$1
+ shift
else
echo "${0##*/}: ERROR: Invalid option ($1)"
exit 1
fi
- shift
;;
esac
done
@@ -67,23 +102,26 @@ USAGE: ${0##*/} [options] URI
• URI is for Unit's control API target, e.g. /config
• A local Unit control socket is detected unless a remote one is specified.
• Configuration data is read from stdin.
+• All options are case-insensitive (excluding filenames and URIs).
General options
- filename … # Read configuration data from files instead of stdin
- HTTP method # Default=GET, or PUT with config data (case-insensitive)
- EDIT # Opens the URI contents in \$EDITOR
- INSERT # Virtual HTTP method to prepend data to an existing array
- -q | --quiet # No output to stdout
+ filename … # Read configuration data from files instead of stdin
+ HTTP method # Default=GET, or PUT when config data is present
+ EDIT # Opens the URI contents in \$EDITOR
+ INSERT # Virtual HTTP method; prepend data to an array
+ -f | --format YAML # Convert configuration data to/from YAML format
+ -q | --quiet # No output to stdout
Local options
- -l | --nolog # Do not monitor the error log after applying config changes
+ -l | --nolog # Do not monitor the Unit log file after config changes
Remote options
ssh://[user@]remote_host[:port]/path/to/control.socket # Remote Unix socket
http://remote_host:port/URI # Remote TCP socket
+ docker://container_ID[/non-default/control.socket] # Container on host
- A remote Unit control socket may also be defined with the \$UNIT_CTRL
- environment variable as http://remote_host:port -OR- ssh://… (as above)
+ A remote Unit instance may also be defined with the \$UNIT_CTRL environment
+ variable as http://remote_host:port or ssh://… or docker://… (as above).
__EOF__
exit 1
@@ -99,8 +137,16 @@ if [ "$UNIT_CTRL" = "" ]; then
fi
elif [ "${UNIT_CTRL:0:6}" = "ssh://" ]; then
REMOTE=1
- SSH_CMD="ssh $(echo $UNIT_CTRL | cut -f1-3 -d/)"
+ RPC_CMD="ssh $(echo $UNIT_CTRL | cut -f1-3 -d/)"
UNIT_CTRL="--unix-socket /$(echo $UNIT_CTRL | cut -f4- -d/) _"
+elif [ "${UNIT_CTRL:0:9}" = "docker://" ]; then
+ RPC_CMD="docker exec -i $(echo $UNIT_CTRL | cut -f3 -d/)"
+ DOCKSOCK=/$(echo "$UNIT_CTRL" | cut -f4- -d/)
+ if [ "$DOCKSOCK" = "/" ]; then
+ DOCKSOCK="/var/run/control.unit.sock" # Use default location if no path
+ fi
+ UNIT_CTRL="--unix-socket $DOCKSOCK _"
+ REMOTE=1
elif [ "${URI:0:1}" = "/" ]; then
REMOTE=1
fi
@@ -186,7 +232,9 @@ fi
# Choose presentation style
#
if [ $QUIET -eq 1 ]; then
- OUTPUT="head -c 0" # Equivalent to >/dev/null
+ OUTPUT="tail -c 0" # Equivalent to >/dev/null
+elif [ $CONVERT -eq 1 ]; then
+ OUTPUT=$CONVERT_FROM_JSON
elif hash jq 2> /dev/null; then
OUTPUT="jq"
else
@@ -205,11 +253,11 @@ fi
#
if [ -t 0 ] && [ ${#CONF_FILES[@]} -eq 0 ]; then
if [ "$METHOD" = "DELETE" ]; then
- $SSH_CMD curl -X $METHOD $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ $RPC_CMD curl -X $METHOD $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
elif [ "$METHOD" = "EDIT" ]; then
EDITOR=$(test "$EDITOR" && printf '%s' "$EDITOR" || command -v editor || command -v vim || echo vi)
EDIT_FILENAME=/tmp/${0##*/}.$$${URI//\//_}
- $SSH_CMD curl -fsS $UNIT_CTRL$URI > $EDIT_FILENAME || exit 2
+ $RPC_CMD curl -fsS $UNIT_CTRL$URI > $EDIT_FILENAME || exit 2
if [ "${URI:0:12}" = "/js_modules/" ]; then
if ! hash jq 2> /dev/null; then
echo "${0##*/}: ERROR: jq(1) is required to edit JavaScript modules; install at <https://stedolan.github.io/jq/>"
@@ -219,19 +267,23 @@ if [ -t 0 ] && [ ${#CONF_FILES[@]} -eq 0 ]; then
EDIT_FILE=$EDIT_FILENAME.js
$EDITOR $EDIT_FILENAME.js || exit 2
# Remove the references, delete old config, push new config+reference
- $SSH_CMD curl -fsS $UNIT_CTRL/config/settings/js_module > /tmp/${0##*/}.$$_js_module && \
- $SSH_CMD curl -X DELETE $UNIT_CTRL/config/settings/js_module && \
- $SSH_CMD curl -fsSX DELETE $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
- printf "%s" "$(< $EDIT_FILENAME.js)" | $SSH_CMD curl -fX PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
- $SSH_CMD curl -X PUT --data-binary @/tmp/${0##*/}.$$_js_module $UNIT_CTRL/config/settings/js_module 2> /tmp/${0##*/}.$$
+ $RPC_CMD curl -fsS $UNIT_CTRL/config/settings/js_module > /tmp/${0##*/}.$$_js_module && \
+ $RPC_CMD curl -X DELETE $UNIT_CTRL/config/settings/js_module && \
+ $RPC_CMD curl -fsSX DELETE $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
+ printf "%s" "$(< $EDIT_FILENAME.js)" | $RPC_CMD curl -fX PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ && \
+ cat /tmp/${0##*/}.$$_js_module | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL/config/settings/js_module 2> /tmp/${0##*/}.$$
+ elif [ $CONVERT -eq 1 ]; then
+ $CONVERT_FROM_JSON < $EDIT_FILENAME > $EDIT_FILENAME.yaml
+ $EDITOR $EDIT_FILENAME.yaml || exit 2
+ $CONVERT_TO_JSON < $EDIT_FILENAME.yaml | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
else
tr -d '\r' < $EDIT_FILENAME > $EDIT_FILENAME.json # Remove carriage-return from newlines
$EDITOR $EDIT_FILENAME.json || exit 2
- $SSH_CMD curl -X PUT --data-binary @$EDIT_FILENAME.json $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ cat $EDIT_FILENAME.json | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
fi
else
SHOW_LOG=$(echo $URI | grep -c ^/control/)
- $SSH_CMD curl $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ $RPC_CMD curl $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
fi
else
if [ "$METHOD" = "INSERT" ]; then
@@ -241,15 +293,19 @@ else
fi
NEW_ELEMENT=$(cat ${CONF_FILES[@]})
echo $NEW_ELEMENT | jq > /dev/null || exit $? # Test the input is valid JSON before proceeding
- OLD_ARRAY=$($SSH_CMD curl -s $UNIT_CTRL$URI)
+ OLD_ARRAY=$($RPC_CMD curl -s $UNIT_CTRL$URI)
if [ "$(echo $OLD_ARRAY | jq -r type)" = "array" ]; then
- echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $SSH_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ echo $OLD_ARRAY | jq ". |= [$NEW_ELEMENT] + ." | $RPC_CMD curl -X PUT --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
else
echo "${0##*/}: ERROR: the INSERT method expects an array"
exit 3
fi
else
- cat ${CONF_FILES[@]} | $SSH_CMD curl -X $METHOD --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
+ if [ $CONVERT -eq 1 ]; then
+ cat ${CONF_FILES[@]} | $CONVERT_TO_JSON > /tmp/${0##*/}.$$_json
+ CONF_FILES=(/tmp/${0##*/}.$$_json)
+ fi
+ cat ${CONF_FILES[@]} | $RPC_CMD curl -X $METHOD --data-binary @- $UNIT_CTRL$URI 2> /tmp/${0##*/}.$$ | $OUTPUT
fi
fi
diff --git a/version b/version
index c08b9fd5..3de0f8d3 100644
--- a/version
+++ b/version
@@ -1,5 +1,5 @@
# Copyright (C) NGINX, Inc.
-NXT_VERSION=1.31.0
-NXT_VERNUM=13100
+NXT_VERSION=1.31.1
+NXT_VERNUM=13101