diff options
Diffstat (limited to '')
40 files changed, 409 insertions, 116 deletions
@@ -35,3 +35,4 @@ c1625c52dd6444ed613348719fbb54c7abcc6619 1.12.0-1 439bd957eeb48dbbffa4cd7eecf3829d497f69b0 1.13.0-1 6e28966ed1f26e119bf333229ea5e6686c60a469 1.14.0 7b483cf5cb0971067a4960e5e8a20a81de14f337 1.14.0-1 +801ac82f80fb2b2333f2c03ac9c3df6b7cec130a 1.15.0 @@ -1,4 +1,19 @@ +Changes with Unit 1.15.0 06 Feb 2020 + + *) Change: extensions of dynamically requested PHP scripts were + restricted to ".php". + + *) Feature: compatibility with Ruby 2.7. + + *) Bugfix: segmentation fault might have occurred in the router process + with multiple application processes under load; the bug had appeared + in 1.14.0. + + *) Bugfix: receiving request body over TLS connection might have + stalled. + + Changes with Unit 1.14.0 26 Dec 2019 *) Change: the Go package import name changed to "unit.nginx.org/go". @@ -1,10 +1,15 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2020 NGINX, Inc. + Copyright 2017-2020 Igor Sysoev + Copyright 2017-2020 Valentin V. Bartenev + Copyright 2017-2020 Max Romanov + Copyright 2017-2020 Andrei Zeliankou + Copyright 2017-2020 Andrei Belov + Copyright 2018-2020 Konstantin Pavlov + Copyright 2019-2020 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/auto/modules/go b/auto/modules/go index 2d53dd65..8bb9216e 100644 --- a/auto/modules/go +++ b/auto/modules/go @@ -85,6 +85,14 @@ if grep ^$NXT_GO: $NXT_MAKEFILE 2>&1 > /dev/null; then exit 1; fi +NXT_GO_LDFLAGS= + +for o in ${CFLAGS} ${NXT_CC_OPT}; do + case "$o" in + -fsanitize* | -L* | -l*) NXT_GO_LDFLAGS="${NXT_GO_LDFLAGS} $o" ;; + esac +done + cat << END >> $NXT_MAKEFILE .PHONY: ${NXT_GO} @@ -116,8 +124,9 @@ ${NXT_GO}-install-env: \$(DESTDIR)\$(NXT_GO_DST)/src/${NXT_GO_PKG}/env.go \ install -d \$(DESTDIR)\$(NXT_GO_DST)/src/${NXT_GO_PKG} $echo "package unit" > \$@ $echo "/*" >> \$@ + $echo "#cgo CFLAGS: ${CFLAGS} ${NXT_CC_OPT}" >> \$@ $echo "#cgo CPPFLAGS: -I${PWD}/src -I${PWD}/${NXT_BUILD_DIR}" >> \$@ - $echo "#cgo LDFLAGS: -L${PWD}/${NXT_BUILD_DIR}" >> \$@ + $echo "#cgo LDFLAGS: -L${PWD}/${NXT_BUILD_DIR} ${NXT_GO_LDFLAGS} ${NXT_LD_OPT}" >> \$@ $echo "*/" >> \$@ $echo 'import "C"' >> \$@ diff --git a/auto/modules/java b/auto/modules/java index b0fd62f1..68b10836 100644 --- a/auto/modules/java +++ b/auto/modules/java @@ -5,7 +5,7 @@ shift NXT_JAVA_HOME=${JAVA_HOME-} -NXT_JAR_REPO=http://central.maven.org/maven2/ +NXT_JAR_REPO=https://repo1.maven.org/maven2/ NXT_JAR_LOCAL_REPO=$HOME/.m2/repository/ for nxt_option; do @@ -22,6 +22,7 @@ for nxt_option; do --lib-path=*) NXT_JAVA_LIB_PATH="$value" ;; --repo=*) NXT_JAR_REPO="$value" ;; --local-repo=*) NXT_JAR_LOCAL_REPO="$value" ;; + --sha512=*) NXT_SHA512_TOOL="$value" ;; --jars=*) NXT_JARS="$value" ;; --help) @@ -34,6 +35,7 @@ for nxt_option; do default: "$NXT_JAR_REPO" --local-repo=DIR set local repository directory default: "$NXT_JAR_LOCAL_REPO" + --sha512=SHA512 set command for SHA512 check --jars=DIR set jars install/search directory END @@ -82,11 +84,12 @@ if [ -n "${NXT_JAVA_HOME}" ]; then NXT_JAVA="${NXT_JAVA_HOME}/bin/java" else - $echo -n "checking for java executable" + $echo -n "checking for java executable ..." $echo "checking for java executable ..." >> $NXT_AUTOCONF_ERR NXT_JAVA=`which java || :` if [ -z "$NXT_JAVA" -o ! -x "$NXT_JAVA" ]; then + $echo " not found" $echo $echo $0: error: java executable not found. $echo @@ -98,11 +101,12 @@ else "$NXT_JAVA" -version - $echo -n "checking java.home" + $echo -n "checking java.home ..." $echo "checking java.home ..." >> $NXT_AUTOCONF_ERR NXT_JAVA_HOME=`$NXT_JAVA -XshowSettings 2>&1 | grep -F -e java.home | sed -e 's/^.*= //'` if [ -z "$NXT_JAVA_HOME" ]; then + $echo " not found" $echo $echo $0: error: java.home not found. $echo @@ -147,10 +151,11 @@ case "$NXT_SYSTEM" in esac if [ -z "$NXT_JAVA_LIB_PATH" ]; then - $echo -n "checking library path" + $echo -n "checking library path ..." $echo "checking library path ..." >> $NXT_AUTOCONF_ERR if [ ! -x "$NXT_JAVA" ]; then + $echo " not found" $echo $echo $0: error: java executable not found. $echo @@ -160,6 +165,7 @@ if [ -z "$NXT_JAVA_LIB_PATH" ]; then NXT_JAVA_LIB_PATH=`$NXT_JAVA -XshowSettings 2>&1 | grep -F -e sun.boot.library.path | sed -e 's/^.*= //'` if [ -z "$NXT_JAVA_LIB_PATH" ]; then + $echo " not found" $echo $echo $0: error: library path not found. $echo diff --git a/auto/modules/java_chk_sha512 b/auto/modules/java_chk_sha512 new file mode 100644 index 00000000..10891cee --- /dev/null +++ b/auto/modules/java_chk_sha512 @@ -0,0 +1,49 @@ + +# Copyright (C) NGINX, Inc. + +# NXT_JAR_FILE= +# NXT_JAR_CHK_FILE= + +NXT_SHA512_TOOL=${NXT_SHA512_TOOL=} + +if [ -z "$NXT_SHA512_TOOL" ]; then + $echo -n "looking for sha512 check tool ..." + $echo "looking for sha512 check tool ..." >> $NXT_AUTOCONF_ERR + + if sha512sum --version >/dev/null 2>&1; then + NXT_SHA512_TOOL="sha512sum --check" + else + if shasum --version >/dev/null 2>&1; then + NXT_SHA512_TOOL="shasum -a 512 --check" + else + if openssl version >/dev/null 2>&1; then + NXT_SHA512_TOOL="openssl dgst -sha512" + fi + fi + fi + + if [ -z "$NXT_SHA512_TOOL" ]; then + $echo " not found" + $echo + $echo $0: error: no sha512 tool found. + $echo + $echo "error: no sha512 tool found" >> $NXT_AUTOCONF_ERR + exit 1 + fi + + $echo " $NXT_SHA512_TOOL" + $echo "found $NXT_SHA512_TOOL" >> $NXT_AUTOCONF_ERR +fi + +if [ -f "$NXT_JAR_CHK_FILE" ]; then + NXT_JAR_SHA512=`grep -F $NXT_JAR_FILE auto/modules/java_jar.sha512 | head -c 128` + NXT_JAR_CHK=${NXT_JAR_CHK_FILE}.sha512.$$ + $echo "$NXT_JAR_SHA512 $NXT_JAR_CHK_FILE" > $NXT_JAR_CHK + + if ! $NXT_SHA512_TOOL $NXT_JAR_CHK >/dev/null 2>&1; then + $echo "SHA512 not matched for $NXT_JAR_FILE, removing $NXT_JAR_CHK_FILE" + rm -f $NXT_JAR_CHK_FILE + fi + + rm -f $NXT_JAR_CHK +fi diff --git a/auto/modules/java_get_jar b/auto/modules/java_get_jar index 52cd146f..81b300f9 100644 --- a/auto/modules/java_get_jar +++ b/auto/modules/java_get_jar @@ -13,13 +13,23 @@ NXT_JAR_LOCAL="${NXT_JAR_LOCAL_DIR}/${NXT_JAR_FILE}" NXT_JAR_LOCAL_TMP="${NXT_JAR_LOCAL_DIR}/.${NXT_JAR_FILE}.$$" NXT_JAR_URL=${NXT_JAR_REPO}${NXT_JAR_NAMESPACE}${NXT_JAR_NAME}/${NXT_JAR_VERSION}/${NXT_JAR_FILE} +NXT_JAR_CHK_FILE="$NXT_BUILD_DIR/$NXT_JAR_FILE" +. auto/modules/java_chk_sha512 + if [ ! -f "$NXT_BUILD_DIR/$NXT_JAR_FILE" ]; then - if [ ! -f "$NXT_JAR_LOCAL" ]; then + NXT_JAR_CHK_FILE=$NXT_JAR_LOCAL + . auto/modules/java_chk_sha512 + + if [ ! -f "${NXT_JAR_LOCAL}" ]; then $echo "getting remote $NXT_JAR_FILE ... " $echo "getting remote $NXT_JAR_FILE ..." >> $NXT_AUTOCONF_ERR mkdir -p "${NXT_JAR_LOCAL_DIR}" curl --progress-bar "$NXT_JAR_URL" -o "$NXT_JAR_LOCAL_TMP" + + NXT_JAR_CHK_FILE=$NXT_JAR_LOCAL_TMP + . auto/modules/java_chk_sha512 + mv "$NXT_JAR_LOCAL_TMP" "$NXT_JAR_LOCAL" else $echo "getting local $NXT_JAR_FILE" diff --git a/auto/modules/java_jar.sha512 b/auto/modules/java_jar.sha512 new file mode 100644 index 00000000..0f6daa8e --- /dev/null +++ b/auto/modules/java_jar.sha512 @@ -0,0 +1,14 @@ +21cf5171c84fb12d0903d4f7d4f62e8b3dc60142ca1c717c46f7e09f6d40ea9a05a5bca34d468e00a00b427991de966fb060dcc282d532ee6a21567f802abfab classgraph-4.4.11.jar +7287b1ea3e18423d027a99ce40ae72e46e1700a65b474d2ec09af6a17b10653b7c2e69e9bb87efe14f4c593dc66b6370ea566fce90edb4b4190a903046817e6f ecj-3.13.102.jar +4626b970aa4d04422db93a4847eb9749768042255e0ba4d4944e1a8ca854de9e5eb093fbf5f0c05b122b65885324a9afdb1819acfb936514848c0726537cd403 jetty-http-9.4.12.v20180830.jar +19c0ea335efd54f6758b64725b4938cd124e60856b8966e1c60d33a5ebe3c62eea5babe5974c3a1b2c5ea49013ba5fc99aaa1a27e5a9c85e46f693fc679e5309 jetty-server-9.4.12.v20180830.jar +37ab6c29e925138d09a99bba9ead16b693318d8e098f1cf19fb56438c5d96479410628a84fa5a6c410850226acf1542aeab2a4894cebc9af8afa021c767d71f0 jetty-util-9.4.12.v20180830.jar +bf57568311fceb52f6611a2284d395cf181b634e4b44179766201f27b5a8c6981339aa35b3a0cb270d81d2a026e3ee724912040e0df5cf5ffd6442588b5b1e49 tomcat-api-9.0.13.jar +68238e5e00c7d0f0b159950a3c7ad6f666b343f7b31c5f0349a1e3184dea9c96ef50def82cc1025d6bcd4bc564d36306a169f96be7677185585ea2469b84a128 tomcat-el-api-9.0.13.jar +51c40eca728a34a96b2af0891355733e5ab5fc3ac5eec62f57e1ea905426b573bf9d55637d3b831838694054fc4d9dd06e48eb98eca57584d2750651bd286e0b tomcat-jasper-9.0.13.jar +ec64d3796a7f7224b451659f7f2b4a48da8a63da46557934d82c07420fa237a23c077f94908caa557ef51776d9e0a98b75cf43e6639c07f26aedb1ed4be99a62 tomcat-jasper-el-9.0.13.jar +2b5b92269c92e981268e346dc1484ebf4c7e481c2be26d90b02f650f94097bc8b9f9f1bc6579896e036a69747f41bf8493b3fa8d7626beaba95b28ae77f0f8ab tomcat-jsp-api-9.0.13.jar +f97891d80a6f96e9c10e5aa1d6a917961307f1a523266f4b0b857bb9a9bbe13ad09352a52e287d2dff84d18948ca25908ff13689eaea5bd806053c87822a892d tomcat-juli-9.0.13.jar +6579b30d95fa104663e2dced86115593868f18448f38235d88ccb003eeeeb61b49532300a30e7437e5c709891601f6b9909c33f1f7bcdf93ac118b67a742fdf1 tomcat-servlet-api-9.0.13.jar +af5d2f0209b7977e3d2ff6bb87dfa72aaa6684e9cd1aab7e48b4f0d389549c052c4d42cf3bd4c08837d79738609a9dfd93c9fdcf740d7a0ae851d9f8523ff65d tomcat-util-9.0.13.jar +18fb1a0f7e4ceb3416fc005e14f2eff6c49422806df03dfdd2a16ecc1292d55d59645707d408853573294446c2f525572dc3c94d45d32856c5d040945cbe416d tomcat-util-scan-9.0.13.jar diff --git a/docs/changes.xml b/docs/changes.xml index e43bfc87..20d59b79 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -13,6 +13,59 @@ unit-perl unit-ruby unit-jsc-common unit-jsc8 unit-jsc10 unit-jsc11" + ver="1.15.0" rev="1" + date="2020-02-06" time="18:00:00 +0300" + packager="Andrei Belov <defan@nginx.com>"> + +<change> +<para> +NGINX Unit updated to 1.15.0. +</para> +</change> + +</changes> + + +<changes apply="unit" ver="1.15.0" rev="1" + date="2020-02-06" time="18:00:00 +0300" + packager="Andrei Belov <defan@nginx.com>"> + +<change type="change"> +<para> +extensions of dynamically requested PHP scripts were restricted to ".php". +</para> +</change> + +<change type="feature"> +<para> +compatibility with Ruby 2.7. +</para> +</change> + +<change type="bugfix"> +<para> +segmentation fault might have occurred in the router process with multiple +application processes under load; the bug had appeared in 1.14.0. +</para> +</change> + +<change type="bugfix"> +<para> +receiving request body over TLS connection might have stalled. +</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-go + unit-perl + unit-ruby + unit-jsc-common unit-jsc8 unit-jsc10 unit-jsc11" ver="1.14.0" rev="1" date="2019-12-26" time="18:00:00 +0300" packager="Andrei Belov <defan@nginx.com>"> diff --git a/pkg/deb/Makefile.jsc-common b/pkg/deb/Makefile.jsc-common index 029114a6..42b4ad74 100644 --- a/pkg/deb/Makefile.jsc-common +++ b/pkg/deb/Makefile.jsc-common @@ -16,7 +16,7 @@ MODULE_CONFARGS_jsc_common= java --home=/usr/lib/jvm/java-$(JAVA_MINVERSION)-ope MODULE_MAKEARGS_jsc_common= java MODULE_INSTARGS_jsc_common= java-shared-install -BUILD_DEPENDS_jsc_common= openjdk-$(JAVA_MINVERSION)-jdk-headless openjdk-$(JAVA_MINVERSION)-jre-headless +BUILD_DEPENDS_jsc_common= openjdk-$(JAVA_MINVERSION)-jdk-headless openjdk-$(JAVA_MINVERSION)-jre-headless curl BUILD_DEPENDS+= $(BUILD_DEPENDS_jsc_common) MODULE_NOARCH_jsc_common= true diff --git a/pkg/deb/debian/copyright b/pkg/deb/debian/copyright index fe52d6aa..2acb87b9 100644 --- a/pkg/deb/debian/copyright +++ b/pkg/deb/debian/copyright @@ -1,10 +1,15 @@ NGINX Unit. - Copyright 2017-2019 NGINX, Inc. - Copyright 2017-2019 Igor Sysoev - Copyright 2017-2019 Valentin V. Bartenev - Copyright 2017-2019 Max Romanov + Copyright 2017-2020 NGINX, Inc. + Copyright 2017-2020 Igor Sysoev + Copyright 2017-2020 Valentin V. Bartenev + Copyright 2017-2020 Max Romanov + Copyright 2017-2020 Andrei Zeliankou + Copyright 2017-2020 Andrei Belov + Copyright 2018-2020 Konstantin Pavlov + Copyright 2019-2020 Tiago Natel de Moura + Copyright 2019-2020 Axel Duch Copyright 2018-2019 Alexander Borisov Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/pkg/docker/Dockerfile.full b/pkg/docker/Dockerfile.full index b71b74fb..12695878 100644 --- a/pkg/docker/Dockerfile.full +++ b/pkg/docker/Dockerfile.full @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.go1.11-dev b/pkg/docker/Dockerfile.go1.11-dev index 92fa56f6..589680c8 100644 --- a/pkg/docker/Dockerfile.go1.11-dev +++ b/pkg/docker/Dockerfile.go1.11-dev @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 26a55d9c..3c3853eb 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.perl5.28 b/pkg/docker/Dockerfile.perl5.28 index 3be4a6dc..92a88516 100644 --- a/pkg/docker/Dockerfile.perl5.28 +++ b/pkg/docker/Dockerfile.perl5.28 @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.php7.3 b/pkg/docker/Dockerfile.php7.3 index 36a2dfbf..0180909b 100644 --- a/pkg/docker/Dockerfile.php7.3 +++ b/pkg/docker/Dockerfile.php7.3 @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.python2.7 b/pkg/docker/Dockerfile.python2.7 index 0dd2f9a5..2942b0b5 100644 --- a/pkg/docker/Dockerfile.python2.7 +++ b/pkg/docker/Dockerfile.python2.7 @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.python3.7 b/pkg/docker/Dockerfile.python3.7 index fd6f1639..e8ca5c4a 100644 --- a/pkg/docker/Dockerfile.python3.7 +++ b/pkg/docker/Dockerfile.python3.7 @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/docker/Dockerfile.ruby2.5 b/pkg/docker/Dockerfile.ruby2.5 index 034ae542..b706e542 100644 --- a/pkg/docker/Dockerfile.ruby2.5 +++ b/pkg/docker/Dockerfile.ruby2.5 @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" -ENV UNIT_VERSION 1.14.0-1~buster +ENV UNIT_VERSION 1.15.0-1~buster RUN set -x \ && apt-get update \ diff --git a/pkg/rpm/Makefile.jsc-common b/pkg/rpm/Makefile.jsc-common index d8c308de..959c6b9d 100644 --- a/pkg/rpm/Makefile.jsc-common +++ b/pkg/rpm/Makefile.jsc-common @@ -14,7 +14,7 @@ MODULE_INSTARGS_jsc_common= java-shared-install MODULE_SOURCES_jsc_common= COPYRIGHT.unit-jsc-common -BUILD_DEPENDS_jsc_common= java-1.8.0-openjdk-devel +BUILD_DEPENDS_jsc_common= java-1.8.0-openjdk-devel curl BUILD_DEPENDS+= $(BUILD_DEPENDS_jsc_common) define MODULE_DEFINITIONS_jsc_common diff --git a/src/nodejs/unit-http/unit.cpp b/src/nodejs/unit-http/unit.cpp index 1fa73689..64e076c1 100644 --- a/src/nodejs/unit-http/unit.cpp +++ b/src/nodejs/unit-http/unit.cpp @@ -844,7 +844,7 @@ Unit::response_write(napi_env env, napi_callback_info info) res_len = nxt_unit_response_write_nb(req, ptr, have_buf_len, 0); - ret = res_len < 0 ? -res_len : NXT_UNIT_OK; + ret = res_len < 0 ? -res_len : (int) NXT_UNIT_OK; } if (ret != NXT_UNIT_OK) { diff --git a/src/nxt_buf_pool.c b/src/nxt_buf_pool.c index 8259c60a..f2be88a7 100644 --- a/src/nxt_buf_pool.c +++ b/src/nxt_buf_pool.c @@ -172,11 +172,12 @@ nxt_buf_pool_free(nxt_buf_pool_t *bp, nxt_buf_t *b) void nxt_buf_pool_destroy(nxt_buf_pool_t *bp) { - nxt_buf_t *b; + nxt_buf_t *b, *n; bp->destroy = 1; - for (b = bp->free; b != NULL; b = b->next) { + for (b = bp->free; b != NULL; b = n) { + n = b->next; nxt_buf_free(bp->mem_pool, b); } diff --git a/src/nxt_event_engine.c b/src/nxt_event_engine.c index 6f051067..4384d3b1 100644 --- a/src/nxt_event_engine.c +++ b/src/nxt_event_engine.c @@ -156,9 +156,9 @@ signals_fail: #if 0 fibers_fail: +#endif nxt_free(engine); -#endif return NULL; } diff --git a/src/nxt_http_route_addr.c b/src/nxt_http_route_addr.c index 3c7e9c84..6d4955ed 100644 --- a/src/nxt_http_route_addr.c +++ b/src/nxt_http_route_addr.c @@ -18,7 +18,7 @@ nxt_int_t nxt_http_route_addr_pattern_parse(nxt_mp_t *mp, nxt_http_route_addr_pattern_t *pattern, nxt_conf_value_t *cv) { - u_char *delim, *end; + u_char *delim; nxt_int_t ret, cidr_prefix; nxt_str_t addr, port; nxt_http_route_addr_base_t *base; @@ -59,6 +59,7 @@ nxt_http_route_addr_pattern_parse(nxt_mp_t *mp, if (nxt_str_looks_like_ipv6(&addr)) { #if (NXT_INET6) + u_char *end; uint8_t i; nxt_int_t len; nxt_http_route_in6_addr_range_t *inet6; @@ -179,7 +180,10 @@ nxt_http_route_addr_pattern_parse(nxt_mp_t *mp, return NXT_ADDR_PATTERN_FORMAT_ERROR; } - nxt_inet6_addr(&inet6->start, addr.start, addr.length); + ret = nxt_inet6_addr(&inet6->start, addr.start, addr.length); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ADDR_PATTERN_FORMAT_ERROR; + } goto parse_port; #endif diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index 53ed0381..832d1f0d 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -633,10 +633,6 @@ nxt_openssl_conn_io_recvbuf(nxt_conn_t *c, nxt_buf_t *b) c->socket.fd, b->mem.free, size, ret, err); if (ret > 0) { - if ((size_t) ret < size) { - c->socket.read_ready = 0; - } - return ret; } diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c index 0f6ce686..26bf915f 100644 --- a/src/nxt_php_sapi.c +++ b/src/nxt_php_sapi.c @@ -599,20 +599,27 @@ nxt_php_request_handler(nxt_unit_request_info_t *req) path.start = nxt_unit_sptr_get(&r->path); if (nxt_php_script_filename.start == NULL) { + nxt_str_null(&script_name); + ctx->path_info.start = (u_char *) strstr((char *) path.start, ".php/"); if (ctx->path_info.start != NULL) { ctx->path_info.start += 4; path.length = ctx->path_info.start - path.start; ctx->path_info.length = r->path_length - path.length; - } - if (path.start[path.length - 1] == '/') { + } else if (path.start[path.length - 1] == '/') { script_name = nxt_php_index; } else { - script_name.length = 0; - script_name.start = NULL; + if (nxt_slow_path(path.length < 4 + || nxt_memcmp(path.start + (path.length - 4), + ".php", 4))) + { + nxt_unit_request_done(req, NXT_UNIT_ERROR); + + return; + } } ctx->script_filename.length = nxt_php_root.length + path.length diff --git a/src/nxt_router.c b/src/nxt_router.c index 6a1f3792..3ff048c5 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -3750,8 +3750,6 @@ nxt_router_response_error_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, nxt_router_app_prepare_request(task, req_app_link); } - nxt_request_app_link_use(task, req_app_link, -1); - msg->port_msg.last = 0; return; @@ -4220,28 +4218,23 @@ re_ra_cancelled: if (nxt_router_port_post_select(task, &state) == NXT_OK) { /* * There should be call nxt_request_app_link_inc_use(re_ra), - * but we need to decrement use then. So, let's skip both. + * because of one more link in the queue. + * Corresponding decrement is in nxt_router_app_process_request(). */ + nxt_request_app_link_inc_use(re_ra); + nxt_work_queue_add(&task->thread->engine->fast_work_queue, nxt_router_app_process_request, &task->thread->engine->task, app, re_ra); - - } else { - /* - * This call should be unconditional, but we want to spare - * couple of CPU ticks to postpone the head death of the universe. - */ - - nxt_request_app_link_use(task, re_ra, -1); } } if (req_app_link != NULL) { /* - * Here we do the same trick as described above, - * but without conditions. - * Skip required nxt_request_app_link_inc_use(req_app_link). + * There should be call nxt_request_app_link_inc_use(req_app_link), + * because of one more link in the queue. But one link was + * recently removed from app->requests link. */ nxt_work_queue_add(&task->thread->engine->fast_work_queue, @@ -5205,8 +5198,6 @@ nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data) if (nxt_router_port_post_select(task, &state) == NXT_OK) { nxt_router_app_prepare_request(task, pending_ra); } - - nxt_request_app_link_use(task, pending_ra, -1); } nxt_debug(task, "send quit to app '%V' pid %PI", &app->name, port->pid); diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 95874db3..7c3d945c 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -23,10 +23,6 @@ #define NXT_UNIT_LOCAL_BUF_SIZE \ (NXT_UNIT_MAX_PLAIN_SIZE + sizeof(nxt_port_msg_t)) -#define NXT_UNIT_MAX_PLAIN_SIZE 1024 -#define NXT_UNIT_LOCAL_BUF_SIZE \ - (NXT_UNIT_MAX_PLAIN_SIZE + sizeof(nxt_port_msg_t)) - typedef struct nxt_unit_impl_s nxt_unit_impl_t; typedef struct nxt_unit_mmap_s nxt_unit_mmap_t; typedef struct nxt_unit_mmaps_s nxt_unit_mmaps_t; @@ -871,7 +867,8 @@ nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg) if (nxt_slow_path(ioctl(recv_msg->fd, FIONBIO, &nb) == -1)) { nxt_unit_alert(ctx, "#%"PRIu32": new_port: ioctl(%d, FIONBIO, 0) " - "failed: %s (%d)", recv_msg->fd, strerror(errno), errno); + "failed: %s (%d)", + recv_msg->stream, recv_msg->fd, strerror(errno), errno); return NXT_UNIT_ERROR; } @@ -3206,6 +3203,7 @@ nxt_unit_get_outgoing_buf(nxt_unit_ctx_t *ctx, nxt_unit_process_t *process, mmap_buf->port_id = *port_id; mmap_buf->process = process; mmap_buf->free_ptr = NULL; + mmap_buf->ctx_impl = nxt_container_of(ctx, nxt_unit_ctx_impl_t, ctx); nxt_unit_debug(ctx, "outgoing mmap allocation: (%d,%d,%d)", (int) hdr->id, (int) c, diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index e4b30319..417e2d8d 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -52,7 +52,8 @@ static int nxt_ruby_hash_info(VALUE r_key, VALUE r_value, VALUE arg); static int nxt_ruby_hash_add(VALUE r_key, VALUE r_value, VALUE arg); static int nxt_ruby_rack_result_body(VALUE result); static int nxt_ruby_rack_result_body_file_write(VALUE filepath); -static VALUE nxt_ruby_rack_result_body_each(VALUE body); +static VALUE nxt_ruby_rack_result_body_each(VALUE body, VALUE arg, + int argc, const VALUE *argv, VALUE blockarg); static void nxt_ruby_exception_log(nxt_task_t *task, uint32_t level, const char *desc); @@ -813,7 +814,8 @@ nxt_ruby_rack_result_body_file_write(VALUE filepath) static VALUE -nxt_ruby_rack_result_body_each(VALUE body) +nxt_ruby_rack_result_body_each(VALUE body, VALUE arg, int argc, + const VALUE *argv, VALUE blockarg) { int rc; diff --git a/src/ruby/nxt_ruby_stream_io.c b/src/ruby/nxt_ruby_stream_io.c index fcfcf5dd..7e8b3ce1 100644 --- a/src/ruby/nxt_ruby_stream_io.c +++ b/src/ruby/nxt_ruby_stream_io.c @@ -10,15 +10,15 @@ static VALUE nxt_ruby_stream_io_new(VALUE class, VALUE wrap); static VALUE nxt_ruby_stream_io_initialize(int argc, VALUE *argv, VALUE self); -static VALUE nxt_ruby_stream_io_gets(VALUE obj, VALUE args); -static VALUE nxt_ruby_stream_io_each(VALUE obj, VALUE args); +static VALUE nxt_ruby_stream_io_gets(VALUE obj); +static VALUE nxt_ruby_stream_io_each(VALUE obj); static VALUE nxt_ruby_stream_io_read(VALUE obj, VALUE args); -static VALUE nxt_ruby_stream_io_rewind(VALUE obj, VALUE args); +static VALUE nxt_ruby_stream_io_rewind(VALUE obj); static VALUE nxt_ruby_stream_io_puts(VALUE obj, VALUE args); static VALUE nxt_ruby_stream_io_write(VALUE obj, VALUE args); nxt_inline long nxt_ruby_stream_io_s_write(nxt_ruby_run_ctx_t *run_ctx, VALUE val); -static VALUE nxt_ruby_stream_io_flush(VALUE obj, VALUE args); +static VALUE nxt_ruby_stream_io_flush(VALUE obj); VALUE @@ -85,7 +85,7 @@ nxt_ruby_stream_io_initialize(int argc, VALUE *argv, VALUE self) static VALUE -nxt_ruby_stream_io_gets(VALUE obj, VALUE args) +nxt_ruby_stream_io_gets(VALUE obj) { VALUE buf; char *p; @@ -132,7 +132,7 @@ nxt_ruby_stream_io_gets(VALUE obj, VALUE args) static VALUE -nxt_ruby_stream_io_each(VALUE obj, VALUE args) +nxt_ruby_stream_io_each(VALUE obj) { VALUE chunk; @@ -141,7 +141,7 @@ nxt_ruby_stream_io_each(VALUE obj, VALUE args) } for ( ;; ) { - chunk = nxt_ruby_stream_io_gets(obj, Qnil); + chunk = nxt_ruby_stream_io_gets(obj); if (chunk == Qnil) { return Qnil; @@ -203,7 +203,7 @@ nxt_ruby_stream_io_read(VALUE obj, VALUE args) static VALUE -nxt_ruby_stream_io_rewind(VALUE obj, VALUE args) +nxt_ruby_stream_io_rewind(VALUE obj) { return Qnil; } @@ -266,7 +266,7 @@ nxt_ruby_stream_io_s_write(nxt_ruby_run_ctx_t *run_ctx, VALUE val) static VALUE -nxt_ruby_stream_io_flush(VALUE obj, VALUE args) +nxt_ruby_stream_io_flush(VALUE obj) { return Qnil; } diff --git a/test/php/phpinfo/index.wrong b/test/php/phpinfo/index.wrong new file mode 100644 index 00000000..6c9e0678 --- /dev/null +++ b/test/php/phpinfo/index.wrong @@ -0,0 +1,3 @@ +<?php +header('Content-Length: 0'); +?> diff --git a/test/python/upload/wsgi.py b/test/python/upload/wsgi.py new file mode 100644 index 00000000..37ee89eb --- /dev/null +++ b/test/python/upload/wsgi.py @@ -0,0 +1,27 @@ +from tempfile import TemporaryFile +import os, cgi + +def read(environ): + length = int(environ.get('CONTENT_LENGTH', 0)) + + body = TemporaryFile(mode='w+b') + body.write(bytes(environ['wsgi.input'].read(length))) + body.seek(0) + + environ['wsgi.input'] = body + return body + +def application(environ, start_response): + file = read(environ) + + form = cgi.FieldStorage(fp=file, environ=environ, keep_blank_values=True) + + filename = form['file'].filename + data = filename.encode() + form['file'].file.read() + + start_response('200 OK', [ + ('Content-Type', 'text/plain'), + ('Content-Length', str(len(data))), + ]) + + return data diff --git a/test/run.py b/test/run.py index 0504a6f7..b79d0484 100755 --- a/test/run.py +++ b/test/run.py @@ -4,16 +4,17 @@ import unittest import sys import os -loader = unittest.TestLoader() -suite = unittest.TestSuite() +if __name__ == '__main__': + loader = unittest.TestLoader() + suite = unittest.TestSuite() -this_dir = os.path.dirname(__file__) -tests = loader.discover(start_dir=this_dir) -suite.addTests(tests) + this_dir = os.path.dirname(__file__) + tests = loader.discover(start_dir=this_dir) + suite.addTests(tests) -runner = unittest.TextTestRunner(verbosity=3) -result = runner.run(suite) + runner = unittest.TextTestRunner(verbosity=3) + result = runner.run(suite) -ret = not (len(result.failures) == len(result.errors) == 0) + ret = not (len(result.failures) == len(result.errors) == 0) -sys.exit(ret) + sys.exit(ret) diff --git a/test/test_java_application.py b/test/test_java_application.py index d2b97f88..9d873d6b 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -1,3 +1,4 @@ +import io import os import time import unittest @@ -1223,31 +1224,25 @@ class TestJavaApplication(TestApplicationJava): os.mkdir(fulldst) self.public_dir(fulldst) - body = ( - """Preamble. Should be ignored.\r -\r ---12345\r -Content-Disposition: form-data; name="file"; filename="sample.txt"\r -Content-Type: text/plain\r -\r -Data from sample file\r ---12345\r -Content-Disposition: form-data; name="destination"\r -\r -%s\r ---12345\r -Content-Disposition: form-data; name="upload"\r -\r -Upload\r ---12345--\r -\r -Epilogue. Should be ignored.""" - % fulldst - ) + fields = { + 'file': { + 'filename': 'sample.txt', + 'type': 'text/plain', + 'data': io.StringIO('Data from sample file'), + }, + 'destination': fulldst, + 'upload': 'Upload', + } + + encoded, content_type = self.multipart_encode(fields) + + preamble = 'Preamble. Should be ignored.' + epilogue = 'Epilogue. Should be ignored.' + body = "%s\r\n%s\r\n%s" % (preamble, encoded.decode(), epilogue) resp = self.post( headers={ - 'Content-Type': 'multipart/form-data; boundary=12345', + 'Content-Type': content_type, 'Host': 'localhost', 'Connection': 'close', }, diff --git a/test/test_php_application.py b/test/test_php_application.py index d614885c..837181e6 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -500,7 +500,17 @@ class TestPHPApplication(TestApplicationPHP): ), 'configure index default' ) - self.assertEqual(self.get()['status'], 200, 'status') + resp = self.get() + + self.assertEqual(resp['status'], 200, 'status') + self.assertNotEqual(resp['body'], '', 'body not empty') + + def test_php_application_extension_check(self): + self.load('phpinfo') + + self.assertNotEqual( + self.get(url='/index.wrong')['status'], 200, 'status' + ) if __name__ == '__main__': TestPHPApplication.main() diff --git a/test/test_proxy.py b/test/test_proxy.py index 4697b88f..5d158285 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -10,11 +10,12 @@ class TestProxy(TestApplicationPython): SERVER_PORT = 7999 - def run_server(self): + @staticmethod + def run_server(server_port): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - server_address = ('', self.SERVER_PORT) + server_address = ('', server_port) sock.bind(server_address) sock.listen(5) @@ -57,7 +58,7 @@ Content-Length: 10 def setUp(self): super().setUp() - self.run_process(self.run_server) + self.run_process(self.run_server, self.SERVER_PORT) self.waitforsocket(self.SERVER_PORT) self.assertIn( diff --git a/test/test_tls.py b/test/test_tls.py index 3514bbcb..1ead111c 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -1,3 +1,5 @@ +import io +import os import re import ssl import subprocess @@ -591,5 +593,25 @@ basicConstraints = critical,CA:TRUE""" 'url scheme https', ) + def test_tls_big_upload(self): + self.load('upload') + + self.certificate() + + self.add_tls(application='upload') + + filename = 'test.txt' + data = '0123456789' * 9000 + + res = self.post_ssl(body={ + 'file': { + 'filename': filename, + 'type': 'text/plain', + 'data': io.StringIO(data), + } + }) + self.assertEqual(res['status'], 200, 'status ok') + self.assertEqual(res['body'], filename + data) + if __name__ == '__main__': TestTLS.main() diff --git a/test/unit/http.py b/test/unit/http.py index 839e91a2..c71e8f7e 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -1,3 +1,6 @@ +import binascii +import io +import os import re import time import json @@ -68,6 +71,10 @@ class TestHTTP(TestUnit): if body != b'': if isinstance(body, str): body = body.encode() + elif isinstance(body, dict): + body, content_type = self.form_encode(body) + + headers['Content-Type'] = content_type if 'Content-Length' not in headers: headers['Content-Length'] = len(body) @@ -266,3 +273,69 @@ class TestHTTP(TestUnit): sock.close() self.assertTrue(ret, 'socket connected') + + def form_encode(self, fields): + is_multipart = False + + for _, value in fields.items(): + if isinstance(value, dict): + is_multipart = True + break + + if is_multipart: + body, content_type = self.multipart_encode(fields) + + else: + body, content_type = self.form_url_encode(fields) + + return body, content_type + + def form_url_encode(self, fields): + data = "&".join("%s=%s" % (name, value) + for name, value in fields.items()).encode() + return data, 'application/x-www-form-urlencoded' + + def multipart_encode(self, fields): + boundary = binascii.hexlify(os.urandom(16)).decode('ascii') + + body = '' + + for field, value in fields.items(): + filename = '' + datatype = '' + + if isinstance(value, dict): + datatype = 'text/plain' + filename = value['filename'] + + if value.get('type'): + datatype = value['type'] + + if not isinstance(value['data'], io.IOBase): + self.fail('multipart encoding of file requires a stream.') + + data = value['data'].read() + + elif isinstance(value, str): + data = value + + else: + self.fail('multipart requires a string or stream data') + + body += ( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"" + ) % (boundary, field) + + if filename != '': + body += "; filename=\"%s\"" % filename + + body += "\r\n" + + if datatype != '': + body += "Content-Type: %s\r\n" % datatype + + body += "\r\n%s\r\n" % data + + body += "--%s--\r\n" % boundary + + return body.encode(), "multipart/form-data; boundary=%s" % boundary diff --git a/test/unit/main.py b/test/unit/main.py index ea6afd7f..37d01d3b 100644 --- a/test/unit/main.py +++ b/test/unit/main.py @@ -209,9 +209,7 @@ class TestUnit(unittest.TestCase): print() - def _run_unit(): - subprocess.call( - [ + self._p = Process(target=subprocess.call, args=[ [ self.unitd, '--no-daemon', '--modules', self.pardir + '/build', @@ -219,10 +217,7 @@ class TestUnit(unittest.TestCase): '--pid', self.testdir + '/unit.pid', '--log', self.testdir + '/unit.log', '--control', 'unix:' + self.testdir + '/control.unit.sock', - ] - ) - - self._p = Process(target=_run_unit) + ] ]) self._p.start() if not self.waitforfiles( @@ -299,11 +294,11 @@ class TestUnit(unittest.TestCase): if found: print('skipped.') - def run_process(self, target): + def run_process(self, target, *args): if not hasattr(self, '_processes'): self._processes = [] - process = Process(target=target) + process = Process(target=target, args=args) process.start() self._processes.append(process) @@ -1,5 +1,5 @@ # Copyright (C) NGINX, Inc. -NXT_VERSION=1.14.0 -NXT_VERNUM=11400 +NXT_VERSION=1.15.0 +NXT_VERNUM=11500 |