summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKonstantin Pavlov <thresh@nginx.com>2018-11-15 16:23:35 +0300
committerKonstantin Pavlov <thresh@nginx.com>2018-11-15 16:23:35 +0300
commit6ccba253f8d415337a09fb935606447791ce308c (patch)
treee0f9a8c5e8ede8cef1500c316d7534dd8de7b972
parentbdde42999b36af85f2f04c0872fdd3e30af52027 (diff)
parenta4b02e17382ccbfc19410c644004c4615b2c2c29 (diff)
downloadunit-6ccba253f8d415337a09fb935606447791ce308c.tar.gz
unit-6ccba253f8d415337a09fb935606447791ce308c.tar.bz2
Merged with the default branch.1.6-1
-rw-r--r--.hgtags1
-rw-r--r--CHANGES22
-rw-r--r--auto/help3
-rw-r--r--auto/modules/nodejs58
-rw-r--r--docs/changes.xml68
-rw-r--r--pkg/docker/Dockerfile.full4
-rw-r--r--pkg/docker/Dockerfile.go1.7-dev4
-rw-r--r--pkg/docker/Dockerfile.go1.8-dev4
-rw-r--r--pkg/docker/Dockerfile.minimal4
-rw-r--r--pkg/docker/Dockerfile.perl5.244
-rw-r--r--pkg/docker/Dockerfile.php7.04
-rw-r--r--pkg/docker/Dockerfile.python2.74
-rw-r--r--pkg/docker/Dockerfile.python3.54
-rw-r--r--pkg/docker/Dockerfile.ruby2.34
-rw-r--r--pkg/docker/Dockerfile.tmpl2
-rw-r--r--src/nodejs/unit-http/README.md20
-rwxr-xr-xsrc/nodejs/unit-http/http_server.js35
-rwxr-xr-xsrc/nodejs/unit-http/socket.js38
-rw-r--r--src/nodejs/unit-http/unit.cpp291
-rw-r--r--src/nodejs/unit-http/unit.h9
-rw-r--r--src/nxt_conf.c2
-rw-r--r--src/nxt_conn_read.c4
-rw-r--r--src/nxt_main.h4
-rw-r--r--src/nxt_mp.c10
-rw-r--r--src/nxt_openssl.c44
-rw-r--r--src/nxt_unit.c3
-rw-r--r--src/nxt_unit.h2
-rw-r--r--src/test/nxt_lvlhsh_test.c2
-rw-r--r--test/unit.py39
29 files changed, 509 insertions, 184 deletions
diff --git a/.hgtags b/.hgtags
index 1ef36b17..083196c7 100644
--- a/.hgtags
+++ b/.hgtags
@@ -13,3 +13,4 @@ b3cf22b8a17e0e35ca80decb03ed2cceb662c3de 1.3
99d69d59aa5edee3405d304886d9319291e392ba 1.4-2
b3dee0cc5a4edd046345511769b5cfec49044f1c 1.5
e507438883ef0044c278f1accfc7bc7f90c0ffb6 1.5-1
+d411e7fdee9e03036adb652f8d9f4c45a420bdd5 1.6
diff --git a/CHANGES b/CHANGES
index b1047284..69761f50 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,26 @@
+Changes with Unit 1.6 15 Nov 2018
+
+ *) Change: "make install" now installs Node.js module as well if it was
+ configured.
+
+ *) Feature: "--local" ./configure option to install Node.js module
+ locally.
+
+ *) Bugfix: Node.js module might have crashed due to broken reference
+ counting.
+
+ *) Bugfix: asynchronous operations in Node.js might not have worked.
+
+ *) Bugfix: various compatibility issues with Node.js applications.
+
+ *) Bugfix: "freed pointer is out of pool" alerts might have appeared in
+ log.
+
+ *) Bugfix: module discovery didn't work on 64-bit big-endian systems
+ like IBM/S390x.
+
+
Changes with Unit 1.5 25 Oct 2018
*) Change: the "type" of application object for Go was changed to
diff --git a/auto/help b/auto/help
index 91be220f..f22362d5 100644
--- a/auto/help
+++ b/auto/help
@@ -55,4 +55,7 @@ cat << END
ruby OPTIONS configure Ruby module
run "./configure ruby --help" to see available options
+ nodejs OPTIONS configure Node.js module
+ run "./configure nodejs --help" to see available options
+
END
diff --git a/auto/modules/nodejs b/auto/modules/nodejs
index 56f84876..443ee9d5 100644
--- a/auto/modules/nodejs
+++ b/auto/modules/nodejs
@@ -15,13 +15,15 @@ for nxt_option; do
--node=*) NXT_NODE="$value" ;;
--npm=*) NXT_NPM="$value" ;;
--node-gyp=*) NXT_NODE_GYP="$value" ;;
+ --local=*) NXT_NODE_LOCAL="$value" ;;
--help)
cat << END
- --node=NAME set node executable
- --npm=NAME set npm executable
- --node-gyp=NAME set node-gyp executable
+ --node=FILE set node executable
+ --npm=FILE set npm executable
+ --node-gyp=FILE set node-gyp executable
+ --local=DIRECTORY set directory path for local installation
END
exit 0
@@ -49,12 +51,14 @@ fi
. $NXT_AUTOCONF_DATA
-$echo "configuring nodejs module"
-$echo "configuring nodejs module..." >> $NXT_AUTOCONF_ERR
-
NXT_NODE=${NXT_NODE=node}
NXT_NPM=${NXT_NPM=npm}
NXT_NODE_GYP=${NXT_NODE_GYP=node-gyp}
+NXT_NODE_LOCAL=${NXT_NODE_LOCAL=}
+
+
+$echo "configuring nodejs module"
+$echo "configuring nodejs module..." >> $NXT_AUTOCONF_ERR
$echo -n "checking for node ..."
$echo "checking for node ..." >> $NXT_AUTOCONF_ERR
@@ -73,6 +77,7 @@ else
exit 1;
fi
+
$echo -n "checking for npm ..."
$echo "checking for npm ..." >> $NXT_AUTOCONF_ERR
@@ -90,6 +95,7 @@ else
exit 1;
fi
+
$echo -n "checking for node-gyp ..."
$echo "checking for node-gyp ..." >> $NXT_AUTOCONF_ERR
@@ -114,19 +120,29 @@ if grep ^$NXT_NODE: $NXT_MAKEFILE 2>&1 > /dev/null; then
exit 1;
fi
+
NXT_NODE_TMP=${NXT_BUILD_DIR}/src/${NXT_NODE}/unit-http
NXT_NODE_TARBALL=${NXT_BUILD_DIR}/${NXT_NODE}-unit-http.tar.gz
NXT_NODE_EXPORTS="export UNIT_SRC_PATH=${PWD}/src && \
export UNIT_LIB_STATIC_PATH=${PWD}/${NXT_BUILD_DIR}/libunit.a"
+if [ -n "$NXT_NODE_LOCAL" ]; then
+ NXT_NODE_INSTALL=local-install
+else
+ NXT_NODE_INSTALL=install
+fi
+
cat << END >> $NXT_MAKEFILE
.PHONY: ${NXT_NODE}
.PHONY: ${NXT_NODE}-copy
.PHONY: ${NXT_NODE}-install
.PHONY: ${NXT_NODE}-uninstall
+.PHONY: ${NXT_NODE}-local-check
+.PHONY: ${NXT_NODE}-local-install
+.PHONY: ${NXT_NODE}-build
+.PHONY: ${NXT_NODE}-publish
-all:
${NXT_NODE}: ${NXT_NODE}-copy $NXT_BUILD_DIR/$NXT_LIB_UNIT_STATIC
${NXT_NODE_EXPORTS} && \\
@@ -139,23 +155,37 @@ ${NXT_NODE}-copy:
${NXT_NODE_TARBALL}: ${NXT_NODE}-copy
tar -zcvf ${NXT_NODE_TARBALL} -C ${NXT_NODE_TMP} .
+
+install: ${NXT_NODE}-$NXT_NODE_INSTALL
+
${NXT_NODE}-install: ${NXT_NODE_TARBALL} \
$NXT_BUILD_DIR/$NXT_LIB_UNIT_STATIC
${NXT_NODE_EXPORTS} && \\
- ${NXT_NPM} install -g ${PWD}/${NXT_NODE_TARBALL} --unsafe-perm=true
+ ${NXT_NPM} install -g ${PWD}/${NXT_NODE_TARBALL}
+
+${NXT_NODE}-uninstall:
+ ${NXT_NPM} uninstall -g unit-http
-${NXT_NODE}-local-install: ${NXT_NODE_TARBALL} \
+${NXT_NODE}-local-check:
+ @test -n "\$(DESTDIR)$NXT_NODE_LOCAL" \\
+ || (echo; \\
+ echo "error: to make ${NXT_NODE}-local-install you need either"; \\
+ echo " to configure --local option"; \\
+ echo " or to set DESTDIR environment variable."; \\
+ echo; \\
+ exit 1)
+
+${NXT_NODE}-local-install: ${NXT_NODE_TARBALL} ${NXT_NODE}-local-check \
$NXT_BUILD_DIR/$NXT_LIB_UNIT_STATIC
${NXT_NODE_EXPORTS} && \\
- mkdir -p \$(DESTDIR) && \\
- cd \$(DESTDIR) && ${NXT_NPM} install ${PWD}/${NXT_NODE_TARBALL}
+ mkdir -p \$(DESTDIR)${NXT_NODE_LOCAL} && \\
+ cd \$(DESTDIR)${NXT_NODE_LOCAL} && \\
+ ${NXT_NPM} install ${PWD}/${NXT_NODE_TARBALL}
+
${NXT_NODE}-build: ${NXT_NODE}
${NXT_NODE}-publish: ${NXT_NODE}
cd ${NXT_NODE_TMP} && ${NXT_NPM} publish
-${NXT_NODE}-uninstall:
- ${NXT_NPM} uninstall -g unit-http
-
END
diff --git a/docs/changes.xml b/docs/changes.xml
index 5be0a94e..b3bc33ee 100644
--- a/docs/changes.xml
+++ b/docs/changes.xml
@@ -11,6 +11,74 @@
unit-go unit-go1.7 unit-go1.8 unit-go1.9 unit-go1.10
unit-perl
unit-ruby"
+ ver="1.6" rev="1"
+ date="2018-11-15" time="18:00:00 +0300"
+ packager="Konstantin Pavlov &lt;thresh@nginx.com&gt;">
+
+<change>
+<para>
+NGINX Unit updated to 1.6.
+</para>
+</change>
+
+</changes>
+
+
+<changes apply="unit" ver="1.6" rev="1"
+ date="2018-11-15" time="18:00:00 +0300"
+ packager="Konstantin Pavlov &lt;thresh@nginx.com&gt;">
+
+<change type="change">
+<para>
+"make install" now installs Node.js module as well if it was configured.
+</para>
+</change>
+
+<change type="feature">
+<para>
+"--local" ./configure option to install Node.js module locally.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+Node.js module might have crashed due to broken reference counting.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+asynchronous operations in Node.js might not have worked.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+various compatibility issues with Node.js applications.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+"freed pointer is out of pool" alerts might have appeared in log.
+</para>
+</change>
+
+<change type="bugfix">
+<para>
+module discovery didn't work on 64-bit big-endian systems like IBM/S390x.
+</para>
+</change>
+
+</changes>
+
+
+<changes apply="unit-php
+ unit-python unit-python2.7
+ unit-python3.4 unit-python3.5 unit-python3.6
+ unit-go unit-go1.7 unit-go1.8 unit-go1.9 unit-go1.10
+ unit-perl
+ unit-ruby"
ver="1.5" rev="1"
date="2018-10-25" time="18:00:00 +0300"
packager="Andrei Belov &lt;defan@nginx.com&gt;">
diff --git a/pkg/docker/Dockerfile.full b/pkg/docker/Dockerfile.full
index 2ccfc16c..f3663eb4 100644
--- a/pkg/docker/Dockerfile.full
+++ b/pkg/docker/Dockerfile.full
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.go1.7-dev b/pkg/docker/Dockerfile.go1.7-dev
index aa915518..2c6975e2 100644
--- a/pkg/docker/Dockerfile.go1.7-dev
+++ b/pkg/docker/Dockerfile.go1.7-dev
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.go1.8-dev b/pkg/docker/Dockerfile.go1.8-dev
index e623182b..1cd1acfc 100644
--- a/pkg/docker/Dockerfile.go1.8-dev
+++ b/pkg/docker/Dockerfile.go1.8-dev
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal
index 0ff59411..0ffff5c9 100644
--- a/pkg/docker/Dockerfile.minimal
+++ b/pkg/docker/Dockerfile.minimal
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.perl5.24 b/pkg/docker/Dockerfile.perl5.24
index 06067fc7..9cbbc645 100644
--- a/pkg/docker/Dockerfile.perl5.24
+++ b/pkg/docker/Dockerfile.perl5.24
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.php7.0 b/pkg/docker/Dockerfile.php7.0
index a6b816bf..70ea8bbc 100644
--- a/pkg/docker/Dockerfile.php7.0
+++ b/pkg/docker/Dockerfile.php7.0
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.python2.7 b/pkg/docker/Dockerfile.python2.7
index b02fe194..4cb4d5f3 100644
--- a/pkg/docker/Dockerfile.python2.7
+++ b/pkg/docker/Dockerfile.python2.7
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.python3.5 b/pkg/docker/Dockerfile.python3.5
index 32ecfcf5..26c54174 100644
--- a/pkg/docker/Dockerfile.python3.5
+++ b/pkg/docker/Dockerfile.python3.5
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.ruby2.3 b/pkg/docker/Dockerfile.ruby2.3
index ce5fefda..b0d9de49 100644
--- a/pkg/docker/Dockerfile.ruby2.3
+++ b/pkg/docker/Dockerfile.ruby2.3
@@ -2,7 +2,7 @@ FROM debian:stretch-slim
LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
-ENV UNIT_VERSION 1.5-1~stretch
+ENV UNIT_VERSION 1.6-1~stretch
RUN set -x \
&& apt-get update \
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/pkg/docker/Dockerfile.tmpl b/pkg/docker/Dockerfile.tmpl
index 76722f88..18d6d34e 100644
--- a/pkg/docker/Dockerfile.tmpl
+++ b/pkg/docker/Dockerfile.tmpl
@@ -73,7 +73,7 @@ RUN set -x \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$unitPackages \
curl \
- && apt-get remove --purge --auto-remove -y apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
+ && apt-get remove --purge --auto-remove -y apt-transport-https && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/unit.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
diff --git a/src/nodejs/unit-http/README.md b/src/nodejs/unit-http/README.md
index 71a4067a..b6b975e4 100644
--- a/src/nodejs/unit-http/README.md
+++ b/src/nodejs/unit-http/README.md
@@ -1,21 +1,5 @@
+[<img src="https://unit.nginx.org/_static/logo.svg" width="40%">](https://unit.nginx.org)
+
# Node.js Package for NGINX Unit
-[<img src="https://unit.nginx.org/_static/logo.svg" width=150px>](https://unit.nginx.org)
-Node.js support package for NGINX Unit.
For details, see [NGINX Unit documentation](https://unit.nginx.org).
-
-## Installation
-
-```bash
-npm i unit-http
-```
-
-## Usage
-
-```javascript
-var http = require('unit-http');
-```
-
-## License
-
-Apache 2.0
diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js
index fa7b8e9b..57163c0b 100755
--- a/src/nodejs/unit-http/http_server.js
+++ b/src/nodejs/unit-http/http_server.js
@@ -78,7 +78,7 @@ ServerResponse.prototype.setHeader = function setHeader(key, value) {
this.removeHeader(key);
- this.headers[key] = value + "";
+ this.headers[key] = value;
this.headers_len += header_len + (header_key_len * header_count);
this.headers_count += header_count;
};
@@ -227,12 +227,11 @@ ServerResponse.prototype._writeBody = function(chunk, encoding, callback) {
ServerResponse.prototype.write = function write(chunk, encoding, callback) {
this._writeBody(chunk, encoding, callback);
- return this;
+ return true;
};
ServerResponse.prototype.end = function end(chunk, encoding, callback) {
this._writeBody(chunk, encoding, callback);
- unit_lib.unit_response_end(this)
this.finished = true;
@@ -290,10 +289,10 @@ function Server(requestListener) {
EventEmitter.call(this);
this.unit = new unit_lib.Unit();
- this.unit.createServer();
-
this.unit.server = this;
+ this.unit.createServer();
+
this.socket = Socket;
this.request = ServerRequest;
this.response = ServerResponse;
@@ -318,10 +317,34 @@ Server.prototype.listen = function () {
this.unit.listen();
};
+Server.prototype.run_events = function (server, req, res) {
+ /* Important!!! setImmediate starts the next iteration in Node.js loop. */
+ setImmediate(function () {
+ server.emit("request", req, res);
+
+ Promise.resolve().then(() => {
+ let buf = server.unit._read(req.socket.req_pointer);
+
+ if (buf.length != 0) {
+ req.emit("data", buf);
+ }
+
+ req.emit("end");
+ });
+
+ Promise.resolve().then(() => {
+ req.emit("finish");
+
+ if (res.finished) {
+ unit_lib.unit_response_end(res);
+ }
+ });
+ });
+};
+
function connectionListener(socket) {
}
-
module.exports = {
STATUS_CODES: http.STATUS_CODES,
Server,
diff --git a/src/nodejs/unit-http/socket.js b/src/nodejs/unit-http/socket.js
index 89702834..aef065bf 100755
--- a/src/nodejs/unit-http/socket.js
+++ b/src/nodejs/unit-http/socket.js
@@ -12,15 +12,16 @@ const unit_lib = require('unit-http/build/Release/unit-http.node');
function Socket(options) {
EventEmitter.call(this);
- if (typeof options === 'number') {
- options = { fd: options };
+ options = options || {};
- } else if (options === undefined) {
- options = {};
+ if (typeof options !== 'object') {
+ throw new TypeError('Options must be object');
}
- this.readable = options.readable !== false;
- this.writable = options.writable !== false;
+ this.readable = (typeof options.readable === 'boolean' ? options.readable
+ : false);
+ this.writable = (typeof options.writable === 'boolean' ? options.writable
+ : false);
}
util.inherits(Socket, EventEmitter);
@@ -38,25 +39,24 @@ Socket.prototype.remotePort = 0;
Socket.prototype.address = function address() {
};
-Socket.prototype.connect = function connect(options, callback) {
- if (callback !== null) {
- this.once('connect', cb);
- }
+Socket.prototype.connect = function connect(options, connectListener) {
+ this.once('connect', connectListener);
this.connecting = true;
this.writable = true;
-};
-Socket.prototype.address = function address() {
+ return this;
};
Socket.prototype.destroy = function destroy(exception) {
this.connecting = false;
this.readable = false;
this.writable = false;
+
+ return this;
};
-Socket.prototype.end = function end(data, encoding) {
+Socket.prototype.end = function end(data, encoding, callback) {
};
Socket.prototype.pause = function pause() {
@@ -77,13 +77,15 @@ Socket.prototype.setKeepAlive = function setKeepAlive(enable, initialDelay) {
Socket.prototype.setNoDelay = function setNoDelay(noDelay) {
};
-Socket.prototype.setTimeout = function setTimeout(msecs, callback) {
- this.timeout = msecs;
-
- if (callback) {
- this.on('timeout', callback);
+Socket.prototype.setTimeout = function setTimeout(timeout, callback) {
+ if (typeof timeout !== 'number') {
+ throw new TypeError('Timeout must be number');
}
+ this.timeout = timeout;
+
+ this.on('timeout', callback);
+
return this;
};
diff --git a/src/nodejs/unit-http/unit.cpp b/src/nodejs/unit-http/unit.cpp
index 40f641a6..be64a59b 100644
--- a/src/nodejs/unit-http/unit.cpp
+++ b/src/nodejs/unit-http/unit.cpp
@@ -5,10 +5,21 @@
#include "unit.h"
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <uv.h>
+
napi_ref Unit::constructor_;
+struct nxt_nodejs_ctx_t {
+ nxt_unit_port_id_t port_id;
+ uv_poll_t poll;
+};
+
+
Unit::Unit(napi_env env):
env_(env),
wrapper_(nullptr),
@@ -31,11 +42,12 @@ Unit::init(napi_env env, napi_value exports)
napi_property_descriptor properties[] = {
{ "createServer", 0, create_server, 0, 0, 0, napi_default, 0 },
- { "listen", 0, listen, 0, 0, 0, napi_default, 0 }
+ { "listen", 0, listen, 0, 0, 0, napi_default, 0 },
+ { "_read", 0, _read, 0, 0, 0, napi_default, 0 }
};
status = napi_define_class(env, "Unit", NAPI_AUTO_LENGTH, create, nullptr,
- 2, properties, &cons);
+ 3, properties, &cons);
if (status != napi_ok) {
goto failed;
}
@@ -105,6 +117,7 @@ napi_value
Unit::create(napi_env env, napi_callback_info info)
{
Unit *obj;
+ napi_ref ref;
napi_value target, cons, instance, jsthis;
napi_status status;
@@ -129,6 +142,11 @@ Unit::create(napi_env env, napi_callback_info info)
goto failed;
}
+ status = napi_create_reference(env, jsthis, 1, &ref);
+ if (status != napi_ok) {
+ goto failed;
+ }
+
return jsthis;
}
@@ -143,6 +161,11 @@ Unit::create(napi_env env, napi_callback_info info)
goto failed;
}
+ status = napi_create_reference(env, instance, 1, &ref);
+ if (status != napi_ok) {
+ goto failed;
+ }
+
return instance;
failed:
@@ -158,14 +181,13 @@ Unit::create_server(napi_env env, napi_callback_info info)
{
Unit *obj;
size_t argc;
- napi_value jsthis;
+ napi_value jsthis, argv;
napi_status status;
- napi_value argv[1];
nxt_unit_init_t unit_init;
argc = 1;
- status = napi_get_cb_info(env, info, &argc, argv, &jsthis, nullptr);
+ status = napi_get_cb_info(env, info, &argc, &argv, &jsthis, nullptr);
if (status != napi_ok) {
goto failed;
}
@@ -179,6 +201,9 @@ Unit::create_server(napi_env env, napi_callback_info info)
unit_init.data = obj;
unit_init.callbacks.request_handler = request_handler;
+ unit_init.callbacks.add_port = add_port;
+ unit_init.callbacks.remove_port = remove_port;
+ unit_init.callbacks.quit = quit;
obj->unit_ctx_ = nxt_unit_init(&unit_init);
if (obj->unit_ctx_ == NULL) {
@@ -198,41 +223,53 @@ failed:
napi_value
Unit::listen(napi_env env, napi_callback_info info)
{
- int ret;
- Unit *obj;
- napi_value jsthis;
- napi_status status;
+ return nullptr;
+}
+
- status = napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr);
+napi_value
+Unit::_read(napi_env env, napi_callback_info info)
+{
+ Unit *obj;
+ void *data;
+ size_t argc;
+ int64_t req_pointer;
+ napi_value jsthis, buffer, argv;
+ napi_status status;
+ nxt_unit_request_info_t *req;
+
+ argc = 1;
+
+ status = napi_get_cb_info(env, info, &argc, &argv, &jsthis, nullptr);
if (status != napi_ok) {
- goto failed;
+ napi_throw_error(env, NULL, "Failed to get arguments from js");
+ return nullptr;
}
status = napi_unwrap(env, jsthis, reinterpret_cast<void **>(&obj));
if (status != napi_ok) {
- goto failed;
- }
-
- if (obj->unit_ctx_ == NULL) {
- napi_throw_error(env, NULL, "Unit context was not created");
+ napi_throw_error(env, NULL, "Failed to get Unit object form js");
return nullptr;
}
- ret = nxt_unit_run(obj->unit_ctx_);
- if (ret != NXT_UNIT_OK) {
- napi_throw_error(env, NULL, "Failed to run Unit");
+ status = napi_get_value_int64(env, argv, &req_pointer);
+ if (status != napi_ok) {
+ napi_throw_error(env, NULL, "Failed to get request pointer");
return nullptr;
}
- nxt_unit_done(obj->unit_ctx_);
-
- return nullptr;
+ req = (nxt_unit_request_info_t *) (uintptr_t) req_pointer;
-failed:
+ status = napi_create_buffer(env, (size_t) req->content_length,
+ &data, &buffer);
+ if (status != napi_ok) {
+ napi_throw_error(env, NULL, "Failed to create request buffer");
+ return nullptr;
+ }
- napi_throw_error(env, NULL, "Failed to listen Unit socket");
+ nxt_unit_request_read(req, data, req->content_length);
- return nullptr;
+ return buffer;
}
@@ -242,8 +279,9 @@ Unit::request_handler(nxt_unit_request_info_t *req)
Unit *obj;
napi_value socket, request, response;
napi_value global, server_obj;
- napi_value req_argv[3];
+ napi_value run_events, events_res;
napi_status status;
+ napi_value events_args[3];
obj = reinterpret_cast<Unit *>(req->unit->data);
@@ -284,73 +322,143 @@ Unit::request_handler(nxt_unit_request_info_t *req)
return;
}
- req_argv[1] = request;
- req_argv[2] = response;
-
status = obj->create_headers(req, request);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to create headers");
return;
}
- obj->emit(server_obj, "request", sizeof("request") - 1, 3, req_argv);
- obj->emit_post_data(request, req);
+ status = napi_get_named_property(obj->env_, server_obj, "run_events",
+ &run_events);
+ if (status != napi_ok) {
+ napi_throw_error(obj->env_, NULL, "Failed to get"
+ " 'run_events' function");
+ return;
+ }
+
+ events_args[0] = server_obj;
+ events_args[1] = request;
+ events_args[2] = response;
+
+ status = napi_call_function(obj->env_, server_obj, run_events, 3,
+ events_args, &events_res);
+ if (status != napi_ok) {
+ napi_throw_error(obj->env_, NULL, "Failed to call"
+ " 'run_events' function");
+ return;
+ }
napi_close_handle_scope(obj->env_, scope);
}
-napi_value
-Unit::get_server_object()
+void
+nxt_uv_read_callback(uv_poll_t *handle, int status, int events)
{
- napi_value unit_obj, server_obj;
- napi_status status;
+ nxt_unit_run_once((nxt_unit_ctx_t *) handle->data);
+}
- status = napi_get_reference_value(env_, wrapper_, &unit_obj);
- if (status != napi_ok) {
- return nullptr;
+
+int
+Unit::add_port(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port)
+{
+ int err;
+ Unit *obj;
+ uv_loop_t *loop;
+ napi_status status;
+ nxt_nodejs_ctx_t *node_ctx;
+
+ if (port->in_fd != -1) {
+ obj = reinterpret_cast<Unit *>(ctx->unit->data);
+
+ if (fcntl(port->in_fd, F_SETFL, O_NONBLOCK) == -1) {
+ napi_throw_error(obj->env_, NULL, "Failed to upgrade read"
+ " file descriptor to O_NONBLOCK");
+ return -1;
+ }
+
+ status = napi_get_uv_event_loop(obj->env_, &loop);
+ if (status != napi_ok) {
+ napi_throw_error(obj->env_, NULL, "Failed to get uv.loop");
+ return NXT_UNIT_ERROR;
+ }
+
+ node_ctx = new nxt_nodejs_ctx_t;
+
+ err = uv_poll_init(loop, &node_ctx->poll, port->in_fd);
+ if (err < 0) {
+ napi_throw_error(obj->env_, NULL, "Failed to init uv.poll");
+ return NXT_UNIT_ERROR;
+ }
+
+ err = uv_poll_start(&node_ctx->poll, UV_READABLE, nxt_uv_read_callback);
+ if (err < 0) {
+ napi_throw_error(obj->env_, NULL, "Failed to start uv.poll");
+ return NXT_UNIT_ERROR;
+ }
+
+ ctx->data = node_ctx;
+
+ node_ctx->port_id = port->id;
+ node_ctx->poll.data = ctx;
}
- status = napi_get_named_property(env_, unit_obj, "server", &server_obj);
- if (status != napi_ok) {
- return nullptr;
+ return nxt_unit_add_port(ctx, port);
+}
+
+
+inline bool
+operator == (const nxt_unit_port_id_t &p1, const nxt_unit_port_id_t &p2)
+{
+ return p1.pid == p2.pid && p1.id == p2.id;
+}
+
+
+void
+Unit::remove_port(nxt_unit_ctx_t *ctx, nxt_unit_port_id_t *port_id)
+{
+ nxt_nodejs_ctx_t *node_ctx;
+
+ if (ctx->data != NULL) {
+ node_ctx = (nxt_nodejs_ctx_t *) ctx->data;
+
+ if (node_ctx->port_id == *port_id) {
+ uv_poll_stop(&node_ctx->poll);
+
+ delete node_ctx;
+
+ ctx->data = NULL;
+ }
}
- return server_obj;
+ nxt_unit_remove_port(ctx, port_id);
+}
+
+
+void
+Unit::quit(nxt_unit_ctx_t *ctx)
+{
+ nxt_unit_done(ctx);
}
napi_value
-Unit::emit(napi_value obj, const char *name, size_t name_len, size_t argc,
- napi_value *argv)
+Unit::get_server_object()
{
- napi_value emitter, return_val, str;
+ napi_value unit_obj, server_obj;
napi_status status;
- status = napi_get_named_property(env_, obj, "emit", &emitter);
- if (status != napi_ok) {
- return nullptr;
- }
-
- status = napi_create_string_latin1(env_, name, name_len, &str);
+ status = napi_get_reference_value(env_, wrapper_, &unit_obj);
if (status != napi_ok) {
return nullptr;
}
- if (argc != 0) {
- argv[0] = str;
-
- } else {
- argc = 1;
- argv = &str;
- }
-
- status = napi_call_function(env_, obj, emitter, argc, argv, &return_val);
+ status = napi_get_named_property(env_, unit_obj, "server", &server_obj);
if (status != napi_ok) {
return nullptr;
}
- return return_val;
+ return server_obj;
}
@@ -391,7 +499,7 @@ Unit::create_headers(nxt_unit_request_info_t *req, napi_value request)
return status;
}
- status = napi_set_named_property(env_, request, "raw_headers", raw_headers);
+ status = napi_set_named_property(env_, request, "rawHeaders", raw_headers);
if (status != napi_ok) {
return status;
}
@@ -480,7 +588,7 @@ Unit::append_header(nxt_unit_field_t *f, napi_value headers,
napi_value
Unit::create_socket(napi_value server_obj, nxt_unit_request_info_t *req)
{
- napi_value constructor, return_val;
+ napi_value constructor, return_val, req_pointer;
napi_status status;
status = napi_get_named_property(env_, server_obj, "socket",
@@ -494,6 +602,17 @@ Unit::create_socket(napi_value server_obj, nxt_unit_request_info_t *req)
return nullptr;
}
+ status = napi_create_int64(env_, (uintptr_t) req, &req_pointer);
+ if (status != napi_ok) {
+ return nullptr;
+ }
+
+ status = napi_set_named_property(env_, return_val, "req_pointer",
+ req_pointer);
+ if (status != napi_ok) {
+ return nullptr;
+ }
+
return return_val;
}
@@ -563,27 +682,6 @@ Unit::create_response(napi_value server_obj, napi_value socket,
}
-void
-Unit::emit_post_data(napi_value request, nxt_unit_request_info_t *req)
-{
- void *data;
- napi_value req_argv[2];
- napi_status status;
-
- status = napi_create_buffer(env_, (size_t) req->content_length,
- &data, &req_argv[1]);
- if (status != napi_ok) {
- napi_throw_error(env_, NULL, "Failed to create request buffer");
- return;
- }
-
- nxt_unit_request_read(req, data, req->content_length);
-
- emit(request, "data", sizeof("data") - 1, 2, req_argv);
- emit(request, "end", sizeof("end") - 1, 0, nullptr);
-}
-
-
napi_value
Unit::response_send_headers(napi_env env, napi_callback_info info)
{
@@ -598,6 +696,7 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
napi_value this_arg, headers, keys, name, value, array_val;
napi_value req_num;
napi_status status;
+ napi_valuetype val_type;
nxt_unit_field_t *f;
nxt_unit_request_info_t *req;
napi_value argv[5];
@@ -707,6 +806,18 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
goto failed;
}
+ napi_typeof(env, array_val, &val_type);
+ if (status != napi_ok) {
+ goto failed;
+ }
+
+ if (val_type != napi_string) {
+ status = napi_coerce_to_string(env, array_val, &array_val);
+ if (status != napi_ok) {
+ goto failed;
+ }
+ }
+
status = napi_get_value_string_latin1(env, array_val, ptr,
header_len,
&value_len);
@@ -732,6 +843,18 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
}
} else {
+ napi_typeof(env, value, &val_type);
+ if (status != napi_ok) {
+ goto failed;
+ }
+
+ if (val_type != napi_string) {
+ status = napi_coerce_to_string(env, value, &value);
+ if (status != napi_ok) {
+ goto failed;
+ }
+ }
+
status = napi_get_value_string_latin1(env, value, ptr, header_len,
&value_len);
if (status != napi_ok) {
diff --git a/src/nodejs/unit-http/unit.h b/src/nodejs/unit-http/unit.h
index 753a14d8..5f541cc4 100644
--- a/src/nodejs/unit-http/unit.h
+++ b/src/nodejs/unit-http/unit.h
@@ -36,13 +36,14 @@ private:
static napi_value create_server(napi_env env, napi_callback_info info);
static napi_value listen(napi_env env, napi_callback_info info);
+ static napi_value _read(napi_env env, napi_callback_info info);
static void request_handler(nxt_unit_request_info_t *req);
+ static int add_port(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port);
+ static void remove_port(nxt_unit_ctx_t *ctx, nxt_unit_port_id_t *port_id);
+ static void quit(nxt_unit_ctx_t *ctx);
napi_value get_server_object();
- napi_value emit(napi_value obj, const char *name, size_t name_len,
- size_t argc, napi_value *argv);
-
napi_value create_socket(napi_value server_obj,
nxt_unit_request_info_t *req);
@@ -52,8 +53,6 @@ private:
napi_value request,
nxt_unit_request_info_t *req, Unit *obj);
- void emit_post_data(napi_value request, nxt_unit_request_info_t *req);
-
static napi_value response_send_headers(napi_env env,
napi_callback_info info);
diff --git a/src/nxt_conf.c b/src/nxt_conf.c
index 1aeafc06..2255e12f 100644
--- a/src/nxt_conf.c
+++ b/src/nxt_conf.c
@@ -525,7 +525,7 @@ nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value, nxt_conf_map_t *map,
uint8_t ui8;
int32_t i32;
int64_t i64;
- nxt_int_t i;
+ int i;
ssize_t size;
off_t off;
nxt_msec_t msec;
diff --git a/src/nxt_conn_read.c b/src/nxt_conn_read.c
index e458bf81..8228326b 100644
--- a/src/nxt_conn_read.c
+++ b/src/nxt_conn_read.c
@@ -48,6 +48,10 @@ nxt_conn_io_read(nxt_task_t *task, void *obj, void *data)
nxt_debug(task, "conn read fd:%d rdy:%d cl:%d",
c->socket.fd, c->socket.read_ready, c->socket.closed);
+ if (c->socket.error != 0) {
+ return;
+ }
+
engine = task->thread->engine;
/*
diff --git a/src/nxt_main.h b/src/nxt_main.h
index 670010f8..12c0ce6d 100644
--- a/src/nxt_main.h
+++ b/src/nxt_main.h
@@ -11,8 +11,8 @@
#include <nxt_auto_config.h>
-#define NXT_VERSION "1.5"
-#define NXT_VERNUM 10500
+#define NXT_VERSION "1.6"
+#define NXT_VERNUM 10600
#define NXT_SERVER "Unit/" NXT_VERSION
diff --git a/src/nxt_mp.c b/src/nxt_mp.c
index a0f19ac2..5c1a4d00 100644
--- a/src/nxt_mp.c
+++ b/src/nxt_mp.c
@@ -768,7 +768,15 @@ nxt_mp_rbtree_compare(nxt_rbtree_node_t *node1, nxt_rbtree_node_t *node2)
block1 = (nxt_mp_block_t *) node1;
block2 = (nxt_mp_block_t *) node2;
- return (uintptr_t) block1->start - (uintptr_t) block2->start;
+ /*
+ * Shifting is necessary to prevent overflow of intptr_t when block1->start
+ * is much greater than block2->start or vice versa.
+ *
+ * It is safe to drop one bit since there cannot be adjacent addresses
+ * because of alignments and allocation sizes. Effectively this reduces
+ * the absolute values to fit into the magnitude of intptr_t.
+ */
+ return ((uintptr_t) block1->start >> 1) - ((uintptr_t) block2->start >> 1);
}
diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c
index 441da54b..99dd2077 100644
--- a/src/nxt_openssl.c
+++ b/src/nxt_openssl.c
@@ -40,7 +40,7 @@ static void nxt_openssl_locks_free(void);
#endif
static nxt_int_t nxt_openssl_server_init(nxt_task_t *task,
nxt_tls_conf_t *conf);
-static nxt_uint_t nxt_openssl_chain_file(SSL_CTX *ctx, nxt_fd_t fd);
+static nxt_int_t nxt_openssl_chain_file(SSL_CTX *ctx, nxt_fd_t fd);
static void nxt_openssl_server_free(nxt_task_t *task, nxt_tls_conf_t *conf);
static void nxt_openssl_conn_init(nxt_task_t *task, nxt_tls_conf_t *conf,
nxt_conn_t *c);
@@ -359,14 +359,14 @@ fail:
}
-static nxt_uint_t
+static nxt_int_t
nxt_openssl_chain_file(SSL_CTX *ctx, nxt_fd_t fd)
{
BIO *bio;
X509 *cert, *ca;
long reason;
EVP_PKEY *key;
- nxt_uint_t ret;
+ nxt_int_t ret;
bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
@@ -503,13 +503,19 @@ fail:
nxt_inline void
-nxt_openssl_conn_free(nxt_task_t *task, nxt_openssl_conn_t *tls)
+nxt_openssl_conn_free(nxt_task_t *task, nxt_conn_t *c)
{
+ nxt_openssl_conn_t *tls;
+
nxt_debug(task, "openssl conn free");
- nxt_free(tls->buffer.start);
+ tls = c->u.tls;
- SSL_free(tls->session);
+ if (tls != NULL) {
+ c->u.tls = NULL;
+ nxt_free(tls->buffer.start);
+ SSL_free(tls->session);
+ }
}
@@ -526,9 +532,20 @@ nxt_openssl_conn_handshake(nxt_task_t *task, void *obj, void *data)
const nxt_conn_state_t *state;
c = obj;
+
+ nxt_debug(task, "openssl conn handshake fd:%d", c->socket.fd);
+
+ if (c->socket.error != 0) {
+ return;
+ }
+
tls = c->u.tls;
- nxt_debug(task, "openssl conn handshake: %d", tls->times);
+ if (tls == NULL) {
+ return;
+ }
+
+ nxt_debug(task, "openssl conn handshake: %d times", tls->times);
/* "tls->times == 1" is suitable to run SSL_do_handshake() in job. */
@@ -715,10 +732,19 @@ nxt_openssl_conn_io_shutdown(nxt_task_t *task, void *obj, void *data)
c = obj;
- nxt_debug(task, "openssl conn shutdown");
+ nxt_debug(task, "openssl conn shutdown fd:%d", c->socket.fd);
+
+ if (c->socket.error != 0) {
+ return;
+ }
c->read_state = NULL;
tls = c->u.tls;
+
+ if (tls == NULL) {
+ return;
+ }
+
s = tls->session;
if (s == NULL || !tls->handshake) {
@@ -807,7 +833,7 @@ nxt_openssl_conn_io_shutdown(nxt_task_t *task, void *obj, void *data)
done:
- nxt_openssl_conn_free(task, tls);
+ nxt_openssl_conn_free(task, c);
nxt_work_queue_add(c->write_work_queue, handler, task, c, data);
}
diff --git a/src/nxt_unit.c b/src/nxt_unit.c
index 0d1be557..24e51075 100644
--- a/src/nxt_unit.c
+++ b/src/nxt_unit.c
@@ -74,7 +74,6 @@ static nxt_unit_process_t *nxt_unit_process_get(nxt_unit_ctx_t *ctx,
static nxt_unit_process_t *nxt_unit_process_find(nxt_unit_ctx_t *ctx,
pid_t pid, int remove);
static nxt_unit_process_t *nxt_unit_process_pop_first(nxt_unit_impl_t *lib);
-static int nxt_unit_run_once(nxt_unit_ctx_t *ctx);
static int nxt_unit_create_port(nxt_unit_ctx_t *ctx,
nxt_unit_port_id_t *port_id, int *fd);
@@ -2697,7 +2696,7 @@ nxt_unit_run(nxt_unit_ctx_t *ctx)
}
-static int
+int
nxt_unit_run_once(nxt_unit_ctx_t *ctx)
{
int rc;
diff --git a/src/nxt_unit.h b/src/nxt_unit.h
index 1b4923a2..2806d035 100644
--- a/src/nxt_unit.h
+++ b/src/nxt_unit.h
@@ -196,6 +196,8 @@ int nxt_unit_process_msg(nxt_unit_ctx_t *, nxt_unit_port_id_t *port_id,
*/
int nxt_unit_run(nxt_unit_ctx_t *);
+int nxt_unit_run_once(nxt_unit_ctx_t *ctx);
+
/* Destroy application library object. */
void nxt_unit_done(nxt_unit_ctx_t *);
diff --git a/src/test/nxt_lvlhsh_test.c b/src/test/nxt_lvlhsh_test.c
index 3dc56076..2e1e0b20 100644
--- a/src/test/nxt_lvlhsh_test.c
+++ b/src/test/nxt_lvlhsh_test.c
@@ -131,7 +131,7 @@ nxt_int_t
nxt_lvlhsh_test(nxt_thread_t *thr, nxt_uint_t n, nxt_bool_t use_pool)
{
void *value;
- uintptr_t key;
+ uint32_t key;
nxt_mp_t *mp;
nxt_nsec_t start, end;
nxt_uint_t i;
diff --git a/test/unit.py b/test/unit.py
index 98a0a4db..a5f96968 100644
--- a/test/unit.py
+++ b/test/unit.py
@@ -25,13 +25,36 @@ class TestUnit(unittest.TestCase):
def tearDown(self):
self.stop()
+ # detect errors and failures for current test
+
+ def list2reason(exc_list):
+ if exc_list and exc_list[-1][0] is self:
+ return exc_list[-1][1]
+
+ if hasattr(self, '_outcome'):
+ result = self.defaultTestResult()
+ self._feedErrorsToResult(result, self._outcome.errors)
+ else:
+ result = getattr(self, '_outcomeForDoCleanups',
+ self._resultForDoCleanups)
+
+ success = not list2reason(result.errors) \
+ and not list2reason(result.failures)
+
+ # check unit.log for alerts
+
with open(self.testdir + '/unit.log', 'r', encoding='utf-8',
errors='ignore') as f:
self._check_alerts(f.read())
- if '--leave' not in sys.argv:
+ # remove unit.log
+
+ if '--leave' not in sys.argv and success:
shutil.rmtree(self.testdir)
+ else:
+ self._print_path_to_log()
+
def check_modules(self, *modules):
self._run()
@@ -171,11 +194,16 @@ class TestUnit(unittest.TestCase):
for skip in self.skip_alerts:
alerts = [al for al in alerts if re.search(skip, al) is None]
- self.assertFalse(alerts, 'alert(s)')
+ if alerts:
+ self._print_path_to_log()
+ self.assertFalse(alerts, 'alert(s)')
if not self.skip_sanitizer:
- self.assertFalse(re.findall('.+Sanitizer.+', log),
- 'sanitizer error(s)')
+ sanitizer_errors = re.findall('.+Sanitizer.+', log)
+
+ if sanitizer_errors:
+ self._print_path_to_log()
+ self.assertFalse(sanitizer_error, 'sanitizer error(s)')
if found:
print('skipped.')
@@ -199,6 +227,9 @@ class TestUnit(unittest.TestCase):
return ret
+ def _print_path_to_log(self):
+ print('Path to unit.log:\n' + self.testdir + '/unit.log')
+
class TestUnitHTTP(TestUnit):
def http(self, start_str, **kwargs):