The new module configuration interface.
Configuration and building example:
./configure
./configure python
./configure php
./configure go
make all
or
./configure
make nginext
./configure python
make python
./configure php
make php
./configure go
make go
Modules configuration options and building examples:
./configure python --module=python2 --config=python2.7-config
make python2
./configure php --module=php7 --config=php7.0-config
--lib-path=/usr/local/php7.0
make php7
./configure go --go=go1.6 --go-path=${HOME}/go1.6
make go1.6
This commit is contained in:
45
auto/make
45
auto/make
@@ -20,6 +20,11 @@ NXT_EXEC_LINK = $NXT_EXEC_LINK $NXT_LD_OPT
|
||||
NXT_SHARED_LOCAL_LINK = $NXT_SHARED_LOCAL_LINK $NXT_LD_OPT
|
||||
NXT_MODULE_LINK = $NXT_MODULE_LINK $NXT_LD_OPT
|
||||
|
||||
.PHONY: $NXT_BIN
|
||||
$NXT_BIN: $NXT_BUILD_DIR/$NXT_BIN
|
||||
|
||||
all: $NXT_BIN
|
||||
|
||||
END
|
||||
|
||||
|
||||
@@ -169,24 +174,19 @@ $echo >> $NXT_MAKEFILE
|
||||
|
||||
# Object files list.
|
||||
|
||||
nxt_modules_obj=`$echo $NXT_MODULES_SRC | sed -e "s/\.c$/\.o/"`
|
||||
|
||||
$echo "NXT_OBJS = \\" >> $NXT_MAKEFILE
|
||||
|
||||
for nxt_src in $NXT_MAKE_SRCS $NXT_MODULES_SRCS
|
||||
for nxt_src in $NXT_MAKE_SRCS
|
||||
do
|
||||
nxt_obj=`$echo $nxt_src | sed -e "s/\.c$/\.o/"`
|
||||
$echo " $NXT_BUILD_DIR/$nxt_obj \\" >> $NXT_MAKEFILE
|
||||
done
|
||||
|
||||
$echo " $nxt_modules_obj" >> $NXT_MAKEFILE
|
||||
$echo >> $NXT_MAKEFILE
|
||||
|
||||
|
||||
# nginext executable.
|
||||
|
||||
NXT_BIN=nginext
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
$NXT_BUILD_DIR/$NXT_BIN: $NXT_BUILD_DIR/$NXT_LIB_STATIC \\
|
||||
@@ -215,48 +215,17 @@ END
|
||||
done
|
||||
|
||||
|
||||
# nxt_modules.c.
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
$nxt_modules_obj: $NXT_MODULES_SRC \$(NXT_DEPS)
|
||||
\$(CC) -c \$(CFLAGS) \$(NXT_INCS) \\
|
||||
$NXT_LIB_AUX_CFLAGS \\
|
||||
-o $nxt_modules_obj \\
|
||||
$NXT_MODULES_SRC
|
||||
END
|
||||
|
||||
|
||||
if [ $NXT_PYTHON_MODULE != NO ]; then
|
||||
. auto/modules/python/make
|
||||
fi
|
||||
|
||||
if [ $NXT_PHP_MODULE != NO ]; then
|
||||
. auto/modules/php/make
|
||||
fi
|
||||
|
||||
if [ $NXT_GO_MODULE != NO ]; then
|
||||
. auto/modules/go/make
|
||||
fi
|
||||
|
||||
|
||||
# Makefile.
|
||||
# *.dSYM is MacOSX Clang debug information.
|
||||
|
||||
cat << END > Makefile
|
||||
|
||||
.PHONY: $NXT_BIN lib_test
|
||||
|
||||
all: $NXT_BIN
|
||||
|
||||
include $NXT_MAKEFILE
|
||||
|
||||
|
||||
.PHONY: lib_test
|
||||
lib_test: $NXT_BUILD_DIR/lib_unit_test $NXT_BUILD_DIR/utf8_file_name_test
|
||||
|
||||
clean:
|
||||
rm -rf $NXT_BUILD_DIR *.dSYM Makefile
|
||||
|
||||
$NXT_BIN: $NXT_BUILD_DIR/$NXT_BIN
|
||||
|
||||
END
|
||||
|
||||
37
auto/modules/conf
Normal file
37
auto/modules/conf
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
# Copyright (C) Igor Sysoev
|
||||
# Copyright (C) NGINX, Inc.
|
||||
|
||||
|
||||
if [ ! -f $NXT_AUTOCONF_DATA ]; then
|
||||
echo
|
||||
echo Please run common $0 before configuring module \"$nxt_module\".
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. $NXT_AUTOCONF_DATA
|
||||
|
||||
|
||||
case "$nxt_module" in
|
||||
|
||||
python)
|
||||
. auto/modules/python
|
||||
;;
|
||||
|
||||
php)
|
||||
. auto/modules/php
|
||||
;;
|
||||
|
||||
go)
|
||||
. auto/modules/go
|
||||
;;
|
||||
|
||||
*)
|
||||
echo
|
||||
echo $0: error: invalid module \"$nxt_module\".
|
||||
echo
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
109
auto/modules/go
Normal file
109
auto/modules/go
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
# Copyright (C) Max Romanov
|
||||
# Copyright (C) NGINX, Inc.
|
||||
|
||||
|
||||
shift
|
||||
|
||||
NXT_GO=go
|
||||
|
||||
for nxt_option; do
|
||||
|
||||
case "$nxt_option" in
|
||||
-*=*) value=`$echo "$nxt_option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) value="" ;;
|
||||
esac
|
||||
|
||||
case "$nxt_option" in
|
||||
--go=*) NXT_GO="$value" ;;
|
||||
--go-path=*) NXT_GO_PATH="$value" ;;
|
||||
|
||||
--help)
|
||||
cat << END
|
||||
|
||||
--go=NAME set go executable
|
||||
--go-path=PATH set GOPATH variable to install package
|
||||
|
||||
END
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
$echo
|
||||
$echo $0: error: invalid Go option \"$nxt_option\"
|
||||
$echo
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
|
||||
$echo "configuring Go package"
|
||||
$echo "configuring Go package ..." >> $NXT_AUTOCONF_ERR
|
||||
|
||||
$echo -n "checking for Go ..."
|
||||
$echo "checking for Go ..." >> $NXT_AUTOCONF_ERR
|
||||
|
||||
nxt_go_test="GOPATH=`pwd` CGO_CPPFLAGS=-DNXT_CONFIGURE \
|
||||
\"${NXT_GO}\" build -o build/nxt_go_gen.a --buildmode=c-archive nginext"
|
||||
|
||||
|
||||
if /bin/sh -c "$nxt_go_test" >> $NXT_AUTOCONF_ERR 2>&1; then
|
||||
$echo " found"
|
||||
|
||||
NXT_GO_VERSION="`${NXT_GO} version`"
|
||||
$echo " + ${NXT_GO_VERSION}"
|
||||
|
||||
else
|
||||
$echo "----------" >> $NXT_AUTOCONF_ERR
|
||||
$echo $nxt_go_test >> $NXT_AUTOCONF_ERR
|
||||
$echo "----------" >> $NXT_AUTOCONF_ERR
|
||||
$echo
|
||||
$echo
|
||||
$echo $0: error: no Go found.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
|
||||
NXT_GO_PATH=${NXT_GO_PATH=`go env GOPATH`}
|
||||
NXT_GO_PATH=${NXT_GO_PATH:-`pwd`/${NXT_GO}}
|
||||
|
||||
$echo " + Go package path: \"${NXT_GO_PATH}\""
|
||||
|
||||
if grep ^$NXT_GO: $NXT_MAKEFILE 2>&1 > /dev/null; then
|
||||
$echo
|
||||
$echo $0: error: duplicate \"$NXT_GO\" package configured.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
.PHONY: ${NXT_GO}
|
||||
|
||||
NXT_ROOT = `pwd`
|
||||
|
||||
GOPATH = $NXT_GO_PATH
|
||||
GOOS = `go env GOOS`
|
||||
GOARCH = `go env GOARCH`
|
||||
|
||||
${NXT_GO}:
|
||||
install -d \$(GOPATH)/src/nginext
|
||||
install -p ./src/nginext/*.c ./src/nginext/*.h \\
|
||||
./src/nginext/*.go \$(GOPATH)/src/nginext/
|
||||
CGO_CFLAGS="-I\$(NXT_ROOT)/build -I\$(NXT_ROOT)/src" \\
|
||||
CGO_LDFLAGS="-L\$(NXT_ROOT)/build" \\
|
||||
GOPATH=$NXT_GO_PATH \\
|
||||
go install -v nginext
|
||||
|
||||
${NXT_GO}-uninstall:
|
||||
rm -rf \$(GOPATH)/src/nginext
|
||||
rm -f \$(GOPATH)/pkg/\$(GOOS)_\$(GOARCH)/nginext.a
|
||||
|
||||
END
|
||||
|
||||
sed -i.bak -e "s/\(all:.*\)/\1 ${NXT_GO}/" $NXT_MAKEFILE
|
||||
152
auto/modules/php
Normal file
152
auto/modules/php
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
# Copyright (C) Max Romanov
|
||||
# Copyright (C) Igor Sysoev
|
||||
# Copyright (C) NGINX, Inc.
|
||||
|
||||
|
||||
shift
|
||||
|
||||
for nxt_option; do
|
||||
|
||||
case "$nxt_option" in
|
||||
-*=*) value=`$echo "$nxt_option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) value="" ;;
|
||||
esac
|
||||
|
||||
case "$nxt_option" in
|
||||
--config=*) NXT_PHP_CONFIG="$value" ;;
|
||||
--module=*) NXT_PHP_MODULE="$value" ;;
|
||||
--lib-path=*) NXT_PHP_LIB_PATH="$value" ;;
|
||||
|
||||
--help)
|
||||
cat << END
|
||||
|
||||
--config=NAME set php-config name
|
||||
--module=NAME set php module name
|
||||
--lib-path=PATH set path to libphp.so library
|
||||
|
||||
END
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
$echo
|
||||
$echo $0: error: invalid PHP option \"$nxt_option\"
|
||||
$echo
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
|
||||
done
|
||||
|
||||
|
||||
NXT_PHP_CONFIG=${NXT_PHP_CONFIG=php-config}
|
||||
NXT_PHP=${NXT_PHP_CONFIG%-config*}
|
||||
NXT_PHP_MODULE=${NXT_PHP_MODULE=${NXT_PHP##*/}}
|
||||
NXT_PHP_LIB_PATH=${NXT_PHP_LIB_PATH=}
|
||||
|
||||
|
||||
$echo "configuring PHP module"
|
||||
$echo "configuring PHP module ..." >> $NXT_AUTOCONF_ERR
|
||||
|
||||
$echo -n "checking for PHP ..."
|
||||
$echo "checking for PHP ..." >> $NXT_AUTOCONF_ERR
|
||||
|
||||
NXT_PHP_LDFLAGS=
|
||||
|
||||
if /bin/sh -c "${NXT_PHP_CONFIG} --version" >> $NXT_AUTOCONF_ERR 2>&1; then
|
||||
|
||||
$echo " found"
|
||||
|
||||
NXT_PHP_VERSION="`${NXT_PHP_CONFIG} --version`"
|
||||
$echo " + PHP version: ${NXT_PHP_VERSION}"
|
||||
$echo " + PHP SAPI: [`${NXT_PHP_CONFIG} --php-sapis`]"
|
||||
|
||||
NXT_PHP_INCLUDE="`${NXT_PHP_CONFIG} --includes`"
|
||||
NXT_PHP_LIB="-lphp${NXT_PHP_VERSION%%.*}"
|
||||
|
||||
if [ "$NXT_PHP_LIB_PATH" != "" ]; then
|
||||
# "php-config --ldflags" does not contain path to libphp.
|
||||
NXT_PHP_LDFLAGS="-L${NXT_PHP_LIB_PATH} -Wl,-rpath ${NXT_PHP_LIB_PATH}"
|
||||
fi
|
||||
|
||||
nxt_feature="PHP embed SAPI"
|
||||
nxt_feature_name=NXT_HAVE_PHP
|
||||
nxt_feature_run=no
|
||||
nxt_feature_incs="${NXT_PHP_INCLUDE}"
|
||||
nxt_feature_libs="${NXT_PHP_LIB} ${NXT_PHP_LDFLAGS}"
|
||||
nxt_feature_test="
|
||||
#include <php.h>
|
||||
#include <php_main.h>
|
||||
|
||||
int main() {
|
||||
php_request_startup();
|
||||
return 0;
|
||||
}"
|
||||
|
||||
. auto/feature
|
||||
|
||||
if [ $nxt_found = no ]; then
|
||||
$echo
|
||||
$echo $0: error: no PHP embed SAPI found.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
else
|
||||
$echo
|
||||
$echo $0: error: no PHP found.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if grep ^$NXT_PHP_MODULE: $NXT_MAKEFILE 2>&1 > /dev/null; then
|
||||
$echo
|
||||
$echo $0: error: duplicate \"$NXT_PHP_MODULE\" module configured.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
$echo " + PHP module: nginext.${NXT_PHP_MODULE}"
|
||||
|
||||
|
||||
$echo >> $NXT_MAKEFILE
|
||||
|
||||
NXT_PHP_MODULE_SRCS=" \
|
||||
src/nxt_php_sapi.c \
|
||||
"
|
||||
|
||||
# The php module object files.
|
||||
|
||||
nxt_objs=
|
||||
|
||||
for nxt_src in $NXT_PHP_MODULE_SRCS; do
|
||||
|
||||
nxt_obj=`$echo $nxt_src | sed -e "s/\.c$/-$NXT_PHP_MODULE.o/"`
|
||||
nxt_objs="$nxt_objs $NXT_BUILD_DIR/$nxt_obj"
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
$NXT_BUILD_DIR/$nxt_obj: $nxt_src
|
||||
\$(CC) -c \$(CFLAGS) \$(NXT_INCS) $NXT_PHP_INCLUDE \\
|
||||
-o $NXT_BUILD_DIR/$nxt_obj $nxt_src
|
||||
END
|
||||
|
||||
done
|
||||
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
.PHONY: ${NXT_PHP_MODULE}
|
||||
|
||||
${NXT_PHP_MODULE}: $NXT_BUILD_DIR/nginext.${NXT_PHP_MODULE}
|
||||
|
||||
$NXT_BUILD_DIR/nginext.${NXT_PHP_MODULE}: $nxt_objs
|
||||
$NXT_MODULE_LINK -o $NXT_BUILD_DIR/nginext.${NXT_PHP_MODULE} \\
|
||||
$nxt_objs ${NXT_PHP_LIB} ${NXT_PHP_LDFLAGS}
|
||||
|
||||
END
|
||||
|
||||
sed -i.bak -e "s/\(all:.*\)/\1 ${NXT_PHP_MODULE}/" $NXT_MAKEFILE
|
||||
148
auto/modules/python
Normal file
148
auto/modules/python
Normal file
@@ -0,0 +1,148 @@
|
||||
|
||||
# Copyright (C) Valentin V. Bartenev
|
||||
# Copyright (C) Igor Sysoev
|
||||
# Copyright (C) NGINX, Inc.
|
||||
|
||||
|
||||
shift
|
||||
|
||||
for nxt_option; do
|
||||
|
||||
case "$nxt_option" in
|
||||
-*=*) value=`$echo "$nxt_option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) value="" ;;
|
||||
esac
|
||||
|
||||
case "$nxt_option" in
|
||||
|
||||
--config=*) NXT_PYTHON_CONFIG="$value" ;;
|
||||
--module=*) NXT_PYTHON_MODULE="$value" ;;
|
||||
|
||||
--help)
|
||||
cat << END
|
||||
|
||||
--config=NAME set python-config name
|
||||
--module=NAME set python module name
|
||||
|
||||
END
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
$echo
|
||||
$echo $0: error: invalid Python option \"$nxt_option\"
|
||||
$echo
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
|
||||
NXT_PYTHON_CONFIG=${NXT_PYTHON_CONFIG=python-config}
|
||||
NXT_PYTHON=${NXT_PYTHON_CONFIG%-config*}
|
||||
NXT_PYTHON_MODULE=${NXT_PYTHON_MODULE=${NXT_PYTHON##*/}}
|
||||
|
||||
|
||||
$echo "configuring Python module"
|
||||
$echo "configuring Python module ..." >> $NXT_AUTOCONF_ERR
|
||||
|
||||
nxt_found=no
|
||||
|
||||
if /bin/sh -c "$NXT_PYTHON_CONFIG --prefix" >> $NXT_AUTOCONF_ERR 2>&1; then
|
||||
|
||||
NXT_PYTHON_INCLUDE=`${NXT_PYTHON_CONFIG} --includes`
|
||||
NXT_PYTHON_LIBS=`${NXT_PYTHON_CONFIG} --ldflags`
|
||||
|
||||
nxt_feature="Python"
|
||||
nxt_feature_name=NXT_HAVE_PYTHON
|
||||
nxt_feature_run=no
|
||||
nxt_feature_incs="${NXT_PYTHON_INCLUDE}"
|
||||
nxt_feature_libs="${NXT_PYTHON_LIBS}"
|
||||
nxt_feature_test="
|
||||
#include <Python.h>
|
||||
|
||||
int main() {
|
||||
Py_Initialize();
|
||||
return 0;
|
||||
}"
|
||||
|
||||
. auto/feature
|
||||
|
||||
else
|
||||
$echo "checking for Python ... not found"
|
||||
fi
|
||||
|
||||
if [ $nxt_found = no ]; then
|
||||
$echo
|
||||
$echo $0: error: no Python found.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
nxt_feature="Python version"
|
||||
nxt_feature_name=NXT_PYTHON_VERSION
|
||||
nxt_feature_run=value
|
||||
nxt_feature_incs="${NXT_PYTHON_INCLUDE}"
|
||||
nxt_feature_libs="${NXT_PYTHON_LIBS}"
|
||||
nxt_feature_test="
|
||||
#include <Python.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("PY_VERSION");
|
||||
return 0;
|
||||
}"
|
||||
|
||||
. auto/feature
|
||||
|
||||
|
||||
if grep ^$NXT_PYTHON_MODULE: $NXT_MAKEFILE 2>&1 > /dev/null; then
|
||||
$echo
|
||||
$echo $0: error: duplicate \"$NXT_PYTHON_MODULE\" module configured.
|
||||
$echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
$echo " + Python module: nginext.${NXT_PYTHON_MODULE}"
|
||||
|
||||
|
||||
$echo >> $NXT_MAKEFILE
|
||||
|
||||
NXT_PYTHON_MODULE_SRCS=" \
|
||||
src/nxt_python_wsgi.c \
|
||||
"
|
||||
|
||||
# The python module object files.
|
||||
|
||||
nxt_objs=
|
||||
|
||||
for nxt_src in $NXT_PYTHON_MODULE_SRCS; do
|
||||
|
||||
nxt_obj=`$echo $nxt_src | sed -e "s/\.c$/-$NXT_PYTHON_MODULE.o/"`
|
||||
nxt_objs="$nxt_objs $NXT_BUILD_DIR/$nxt_obj"
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
$NXT_BUILD_DIR/$nxt_obj: $nxt_src
|
||||
\$(CC) -c \$(CFLAGS) \$(NXT_INCS) $NXT_PYTHON_INCLUDE \\
|
||||
-o $NXT_BUILD_DIR/$nxt_obj $nxt_src
|
||||
END
|
||||
|
||||
done
|
||||
|
||||
|
||||
cat << END >> $NXT_MAKEFILE
|
||||
|
||||
.PHONY: ${NXT_PYTHON_MODULE}
|
||||
|
||||
${NXT_PYTHON_MODULE}: $NXT_BUILD_DIR/nginext.${NXT_PYTHON_MODULE}
|
||||
|
||||
$NXT_BUILD_DIR/nginext.${NXT_PYTHON_MODULE}: $nxt_objs
|
||||
$NXT_MODULE_LINK -o $NXT_BUILD_DIR/nginext.${NXT_PYTHON_MODULE} \\
|
||||
$nxt_objs $NXT_PYTHON_LIBS
|
||||
|
||||
END
|
||||
|
||||
sed -i.bak -e "s/\(all:.*\)/\1 ${NXT_PYTHON_MODULE}/" $NXT_MAKEFILE
|
||||
20
auto/options
20
auto/options
@@ -41,16 +41,6 @@ NXT_TEST_BUILD_HPUX_SENDFILE=NO
|
||||
|
||||
NXT_LIB_UNIT_TEST=NO
|
||||
|
||||
NXT_PYTHON=python
|
||||
NXT_PYTHON_MODULE=NO
|
||||
|
||||
NXT_PHP=php
|
||||
NXT_PHP_LDFLAGS=
|
||||
NXT_PHP_MODULE=NO
|
||||
|
||||
NXT_GO=go
|
||||
NXT_GO_MODULE=NO
|
||||
|
||||
for nxt_option
|
||||
do
|
||||
case "$nxt_option" in
|
||||
@@ -96,16 +86,6 @@ do
|
||||
|
||||
--with-lib-unit-tests) NXT_LIB_UNIT_TEST=YES ;;
|
||||
|
||||
--with-python=*) NXT_PYTHON="$value" ;;
|
||||
--with-python_module) NXT_PYTHON_MODULE=YES ;;
|
||||
|
||||
--with-php=*) NXT_PHP="$value" ;;
|
||||
--with-php-ldflags=*) NXT_PHP_LDFLAGS="$value" ;;
|
||||
--with-php_module) NXT_PHP_MODULE=YES ;;
|
||||
|
||||
--with-go=*) NXT_GO="$value" ;;
|
||||
--with-go_module) NXT_GO_MODULE=YES ;;
|
||||
|
||||
*)
|
||||
$echo
|
||||
$echo "$0: error: invalid option \"$nxt_option\"".
|
||||
|
||||
@@ -26,7 +26,6 @@ case "$NXT_SYSTEM" in
|
||||
NXT_SHARED_LOCAL_LINK="\$(CC) -shared \
|
||||
-Wl,-soname,\\\$\$ORIGIN/libnxt.so"
|
||||
NXT_MODULE_LINK="\$(CC) -shared"
|
||||
NXT_MODULE_LINK="\$(CC) -shared"
|
||||
|
||||
# "-Wl,-E" exports symbols of executable file.
|
||||
NXT_EXEC_LINK="\$(CC) -Wl,-E"
|
||||
@@ -104,8 +103,8 @@ case "$NXT_SYSTEM" in
|
||||
# MacOSX 10.6 (Snow Leopard) has deprecated ucontext(3).
|
||||
# MacOSX 10.7 (Lion) has deprecated system OpenSSL.
|
||||
# MAC_OS_X_VERSION_MIN_REQUIRED macro does not help.
|
||||
# The minimum version allowed for i386 is 10.4 (Tiger).
|
||||
NXT_CFLAGS="$NXT_CFLAGS -mmacosx-version-min=10.4"
|
||||
# "-rpath" is supported since MacOSX 10.5 (Leopard).
|
||||
NXT_CFLAGS="$NXT_CFLAGS -mmacosx-version-min=10.5"
|
||||
|
||||
NXT_STATIC_LINK="ar -r -c"
|
||||
NXT_SHARED_LINK="\$(CC) -dynamiclib"
|
||||
@@ -113,7 +112,8 @@ case "$NXT_SYSTEM" in
|
||||
-install_name @executable_path/libnxt.dylib"
|
||||
|
||||
# Prior to MacOSX 10.5 (Leopard) only bundles could be unloaded.
|
||||
NXT_MODULE_LINK="\$(CC) -bundle -undefined dynamic_lookup"
|
||||
# NXT_MODULE_LINK="\$(CC) -bundle -undefined dynamic_lookup"
|
||||
NXT_MODULE_LINK="\$(CC) -dynamiclib -undefined dynamic_lookup"
|
||||
|
||||
NXT_EXEC_LINK="\$(CC)"
|
||||
NXT_SHARED_LOCAL_EXEC_LINK=
|
||||
|
||||
@@ -41,7 +41,7 @@ case "$NXT_SYSTEM" in
|
||||
echo=echo
|
||||
CC=${CC:-cc}
|
||||
|
||||
NXT_TEST_CFLAGS="$NXT_TEST_CFLAGS -mmacosx-version-min=10.4"
|
||||
NXT_TEST_CFLAGS="$NXT_TEST_CFLAGS -mmacosx-version-min=10.5"
|
||||
;;
|
||||
|
||||
AIX)
|
||||
|
||||
24
auto/save
Normal file
24
auto/save
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
# Copyright (C) Igor Sysoev
|
||||
# Copyright (C) NGINX, Inc.
|
||||
|
||||
|
||||
cat << END > $NXT_AUTOCONF_DATA
|
||||
|
||||
CC='$CC'
|
||||
CFLAGS='$CFLAGS'
|
||||
|
||||
NXT_CFLAGS='$NXT_CFLAGS'
|
||||
NXT_CC_OPT='$NXT_CC_OPT'
|
||||
NXT_LD_OPT='$NXT_LD_OPT'
|
||||
NXT_MODULE_LINK='$NXT_MODULE_LINK'
|
||||
|
||||
NXT_TEST_CFLAGS='$NXT_TEST_CFLAGS'
|
||||
NXT_TEST_LIBS='$NXT_TEST_LIBS'
|
||||
|
||||
echo=$NXT_BUILD_DIR/echo
|
||||
|
||||
NXT_LIB_AUX_CFLAGS=
|
||||
NXT_LIB_AUX_LIBS=
|
||||
|
||||
END
|
||||
@@ -147,6 +147,7 @@ NXT_LIB_SRCS=" \
|
||||
src/nxt_controller.c \
|
||||
src/nxt_router.c \
|
||||
src/nxt_application.c \
|
||||
src/nxt_go.c \
|
||||
src/nxt_port_hash.c \
|
||||
"
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ fi
|
||||
|
||||
# FreeBSD dlopen() is in libc.
|
||||
# MacOSX libdl.dylib is a symlink to libSystem.dylib.
|
||||
# GCC5 AddressSanitizer intercepts dlopen() and dlclose() but not dlsym()
|
||||
# so all dynamic linker functions should be tested.
|
||||
|
||||
NXT_LIBDL=
|
||||
|
||||
@@ -85,7 +87,9 @@ nxt_feature_test="#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int main() {
|
||||
dlopen(NULL, 0);
|
||||
void *h = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
|
||||
dlsym(h, \"\");
|
||||
dlclose(h);
|
||||
return 0;
|
||||
}"
|
||||
. auto/feature
|
||||
|
||||
33
configure
vendored
33
configure
vendored
@@ -20,16 +20,37 @@ NXT_TEST_CFLAGS=${NXT_TEST_CFLAGS=}
|
||||
NXT_TEST_LIBS=${NXT_TEST_LIBS=}
|
||||
NXT_UNIT_TEST_TARGETS=${NXT_UNIT_TEST_TARGETS=}
|
||||
|
||||
# STUB
|
||||
NXT_BUILD_DIR=build
|
||||
|
||||
NXT_AUTOTEST=$NXT_BUILD_DIR/autotest
|
||||
NXT_AUTOCONF_ERR=$NXT_BUILD_DIR/autoconf.err
|
||||
NXT_AUTOCONF_DATA=$NXT_BUILD_DIR/autoconf.data
|
||||
NXT_AUTO_CONFIG_H=$NXT_BUILD_DIR/nxt_auto_config.h
|
||||
NXT_MAKEFILE=$NXT_BUILD_DIR/Makefile
|
||||
NXT_BIN=nginext
|
||||
|
||||
nxt_module=${1:-no}
|
||||
|
||||
case $nxt_module in
|
||||
no|--*)
|
||||
;;
|
||||
|
||||
unit)
|
||||
shift
|
||||
;;
|
||||
|
||||
*)
|
||||
. auto/modules/conf
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
. auto/os/test
|
||||
. auto/options
|
||||
|
||||
test -d $NXT_BUILD_DIR || mkdir $NXT_BUILD_DIR
|
||||
|
||||
NXT_AUTOTEST=$NXT_BUILD_DIR/autotest
|
||||
NXT_AUTOCONF_ERR=$NXT_BUILD_DIR/autoconf.err
|
||||
NXT_AUTO_CONFIG_H=$NXT_BUILD_DIR/nxt_auto_config.h
|
||||
NXT_MAKEFILE=$NXT_BUILD_DIR/Makefile
|
||||
|
||||
> $NXT_AUTOCONF_ERR
|
||||
> $NXT_AUTO_CONFIG_H
|
||||
|
||||
@@ -102,6 +123,7 @@ fi
|
||||
|
||||
. auto/test_build
|
||||
. auto/sources
|
||||
. auto/save
|
||||
|
||||
# LOOK
|
||||
|
||||
@@ -113,5 +135,4 @@ NXT_LIB_AUX_LIBS="$NXT_OPENSSL_LIBS $NXT_GNUTLS_LIBS \\
|
||||
$NXT_CYASSL_LIBS $NXT_POLARSSL_LIBS \\
|
||||
$NXT_PCRE_LIB"
|
||||
|
||||
. auto/modules/conf
|
||||
. auto/make
|
||||
|
||||
@@ -11,8 +11,22 @@
|
||||
#include <nxt_application.h>
|
||||
#include <nxt_master_process.h>
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
nxt_str_t type;
|
||||
nxt_str_t version;
|
||||
nxt_str_t file;
|
||||
} nxt_module_t;
|
||||
|
||||
|
||||
static nxt_buf_t *nxt_discovery_modules(nxt_task_t *task, const char *path);
|
||||
static nxt_int_t nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_array_t *modules, const char *name);
|
||||
static nxt_app_module_t *nxt_app_module_load(nxt_task_t *task,
|
||||
const char *name);
|
||||
|
||||
nxt_application_module_t *nxt_app_modules[NXT_APP_MAX];
|
||||
|
||||
static nxt_thread_mutex_t nxt_app_mutex;
|
||||
static nxt_thread_cond_t nxt_app_cond;
|
||||
@@ -22,14 +36,243 @@ static nxt_http_fields_hash_t *nxt_app_request_fields_hash;
|
||||
|
||||
static nxt_application_module_t *nxt_app;
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_discovery_start(nxt_task_t *task, void *data)
|
||||
{
|
||||
nxt_buf_t *b;
|
||||
nxt_port_t *main_port;
|
||||
nxt_runtime_t *rt;
|
||||
|
||||
nxt_debug(task, "DISCOVERY");
|
||||
|
||||
b = nxt_discovery_modules(task, "build/nginext.*");
|
||||
|
||||
rt = task->thread->runtime;
|
||||
main_port = rt->port_by_type[NXT_PROCESS_MASTER];
|
||||
|
||||
nxt_port_socket_write(task, main_port, NXT_PORT_MSG_MODULES, -1,
|
||||
0, -1, b);
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_discovery_completion_handler(nxt_task_t *task, void *obj, void *data)
|
||||
{
|
||||
nxt_mp_t *mp;
|
||||
nxt_buf_t *b;
|
||||
|
||||
b = obj;
|
||||
mp = b->data;
|
||||
|
||||
nxt_mp_destroy(mp);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static nxt_buf_t *
|
||||
nxt_discovery_modules(nxt_task_t *task, const char *path)
|
||||
{
|
||||
char *name;
|
||||
u_char *p, *end;
|
||||
size_t size;
|
||||
glob_t glb;
|
||||
nxt_mp_t *mp;
|
||||
nxt_buf_t *b;
|
||||
nxt_int_t ret;
|
||||
nxt_uint_t i, n;
|
||||
nxt_array_t *modules;
|
||||
nxt_module_t *module;
|
||||
|
||||
b = NULL;
|
||||
|
||||
mp = nxt_mp_create(1024, 128, 256, 32);
|
||||
if (mp == NULL) {
|
||||
return b;
|
||||
}
|
||||
|
||||
ret = glob(path, 0, NULL, &glb);
|
||||
|
||||
if (ret == 0) {
|
||||
n = glb.gl_pathc;
|
||||
|
||||
modules = nxt_array_create(mp, n, sizeof(nxt_module_t));
|
||||
if (modules == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
name = glb.gl_pathv[i];
|
||||
|
||||
ret = nxt_discovery_module(task, mp, modules, name);
|
||||
if (ret != NXT_OK) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
size = sizeof("[]") - 1;
|
||||
module = modules->elts;
|
||||
n = modules->nelts;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
nxt_debug(task, "module: %V %V %V",
|
||||
&module[i].type, &module[i].version, &module[i].file);
|
||||
|
||||
size += sizeof("{\"type\": \"\",") - 1;
|
||||
size += sizeof(" \"version\": \"\",") - 1;
|
||||
size += sizeof(" \"file\": \"\"},") - 1;
|
||||
|
||||
size += module[i].type.length
|
||||
+ module[i].version.length
|
||||
+ module[i].file.length;
|
||||
}
|
||||
|
||||
b = nxt_buf_mem_alloc(mp, size, 0);
|
||||
if (b == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
b->completion_handler = nxt_discovery_completion_handler;
|
||||
|
||||
p = b->mem.free;
|
||||
end = b->mem.end;
|
||||
*p++ = '[';
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
p = nxt_sprintf(p, end,
|
||||
"{\"type\": \"%V\", \"version\": \"%V\", \"file\": \"%V\"},",
|
||||
&module[i].type, &module[i].version, &module[i].file);
|
||||
}
|
||||
|
||||
*p++ = ']';
|
||||
b->mem.free = p;
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
globfree(&glb);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp, nxt_array_t *modules,
|
||||
const char *name)
|
||||
{
|
||||
void *dl;
|
||||
nxt_str_t *s;
|
||||
nxt_int_t ret;
|
||||
nxt_uint_t i, n;
|
||||
nxt_module_t *module;
|
||||
nxt_application_module_t *app;
|
||||
|
||||
/*
|
||||
* Only memory allocation failure should return NXT_ERROR.
|
||||
* Any module processing errors are ignored.
|
||||
*/
|
||||
ret = NXT_ERROR;
|
||||
|
||||
dl = dlopen(name, RTLD_GLOBAL | RTLD_NOW);
|
||||
|
||||
if (dl == NULL) {
|
||||
nxt_log(task, NXT_LOG_CRIT, "dlopen(\"%s\"), failed: \"%s\"",
|
||||
name, dlerror());
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
app = dlsym(dl, "nxt_app_module");
|
||||
|
||||
if (app != NULL) {
|
||||
nxt_log(task, NXT_LOG_NOTICE, "module: %V \"%s\"",
|
||||
&app->version, name);
|
||||
|
||||
module = modules->elts;
|
||||
n = modules->nelts;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (nxt_strstr_eq(&app->version, &module[i].version)) {
|
||||
nxt_log(task, NXT_LOG_NOTICE,
|
||||
"ignoring %s module with the same "
|
||||
"application language version %V as in %s",
|
||||
name, &module[i].version, &module[i].file);
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
module = nxt_array_add(modules);
|
||||
if (module == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s = nxt_str_dup(mp, &module->type, &app->type);
|
||||
if (s == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s = nxt_str_dup(mp, &module->version, &app->version);
|
||||
if (s == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
module->file.length = nxt_strlen(name);
|
||||
|
||||
module->file.start = nxt_mp_alloc(mp, module->file.length);
|
||||
if (module->file.start == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nxt_memcpy(module->file.start, name, module->file.length);
|
||||
|
||||
} else {
|
||||
nxt_log(task, NXT_LOG_CRIT, "dlsym(\"%s\"), failed: \"%s\"",
|
||||
name, dlerror());
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
ret = NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
if (dlclose(dl) != 0) {
|
||||
nxt_log(task, NXT_LOG_CRIT, "dlclose(\"%s\"), failed: \"%s\"",
|
||||
name, dlerror());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_app_start(nxt_task_t *task, void *data)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
nxt_app_lang_module_t *lang;
|
||||
nxt_common_app_conf_t *app_conf;
|
||||
|
||||
app_conf = data;
|
||||
|
||||
lang = nxt_app_lang_module(task->thread->runtime, &app_conf->type);
|
||||
if (nxt_slow_path(lang == NULL)) {
|
||||
nxt_log(task, NXT_LOG_CRIT, "unknown application type: \"%V\"",
|
||||
&app_conf->type);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_app = lang->module;
|
||||
|
||||
if (nxt_app == NULL) {
|
||||
nxt_debug(task, "application language module: %V \"%s\"",
|
||||
&lang->version, lang->file);
|
||||
|
||||
nxt_app = nxt_app_module_load(task, lang->file);
|
||||
}
|
||||
|
||||
if (nxt_slow_path(nxt_thread_mutex_create(&nxt_app_mutex) != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
@@ -38,8 +281,6 @@ nxt_app_start(nxt_task_t *task, void *data)
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_app = nxt_app_modules[app_conf->type_id];
|
||||
|
||||
ret = nxt_app->init(task, data);
|
||||
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
@@ -53,6 +294,24 @@ nxt_app_start(nxt_task_t *task, void *data)
|
||||
}
|
||||
|
||||
|
||||
static nxt_app_module_t *
|
||||
nxt_app_module_load(nxt_task_t *task, const char *name)
|
||||
{
|
||||
void *dl;
|
||||
|
||||
dl = dlopen(name, RTLD_GLOBAL | RTLD_LAZY);
|
||||
|
||||
if (dl != NULL) {
|
||||
return dlsym(dl, "nxt_app_module");
|
||||
}
|
||||
|
||||
nxt_log(task, NXT_LOG_CRIT, "dlopen(\"%s\"), failed: \"%s\"",
|
||||
name, dlerror());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_app_http_init(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
{
|
||||
@@ -681,30 +940,56 @@ nxt_app_msg_write_raw(nxt_task_t *task, nxt_app_wmsg_t *msg, const u_char *c,
|
||||
}
|
||||
|
||||
|
||||
nxt_app_lang_module_t *
|
||||
nxt_app_lang_module(nxt_runtime_t *rt, nxt_str_t *name)
|
||||
{
|
||||
u_char *p, *end, *version;
|
||||
size_t type_length, version_length;
|
||||
nxt_uint_t i, n;
|
||||
nxt_app_lang_module_t *lang;
|
||||
|
||||
end = name->start + name->length;
|
||||
version = end;
|
||||
|
||||
for (p = name->start; p < end; p++) {
|
||||
if (*p == ' ') {
|
||||
version = p + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
version = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
type_length = p - name->start;
|
||||
version_length = end - version;
|
||||
|
||||
lang = rt->languages->elts;
|
||||
n = rt->languages->nelts;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (nxt_str_eq(&lang[i].type, name->start, type_length)
|
||||
&& nxt_str_start(&lang[i].version, version, version_length))
|
||||
{
|
||||
return &lang[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
nxt_app_type_t
|
||||
nxt_app_parse_type(nxt_str_t *str)
|
||||
{
|
||||
if (nxt_str_eq(str, "python", 6)) {
|
||||
return NXT_APP_PYTHON;
|
||||
|
||||
} else if (nxt_str_eq(str, "python2", 7)) {
|
||||
return NXT_APP_PYTHON2;
|
||||
|
||||
} else if (nxt_str_eq(str, "python3", 7)) {
|
||||
return NXT_APP_PYTHON3;
|
||||
|
||||
} else if (nxt_str_eq(str, "php", 3)) {
|
||||
return NXT_APP_PHP;
|
||||
|
||||
} else if (nxt_str_eq(str, "php5", 4)) {
|
||||
return NXT_APP_PHP5;
|
||||
|
||||
} else if (nxt_str_eq(str, "php7", 4)) {
|
||||
return NXT_APP_PHP7;
|
||||
|
||||
} else if (nxt_str_eq(str, "ruby", 4)) {
|
||||
return NXT_APP_RUBY;
|
||||
|
||||
} else if (nxt_str_eq(str, "go", 2)) {
|
||||
return NXT_APP_GO;
|
||||
|
||||
|
||||
@@ -10,20 +10,26 @@
|
||||
|
||||
|
||||
typedef enum {
|
||||
NXT_APP_UNKNOWN = 0,
|
||||
NXT_APP_PYTHON,
|
||||
NXT_APP_PYTHON2,
|
||||
NXT_APP_PYTHON3,
|
||||
NXT_APP_PHP,
|
||||
NXT_APP_PHP5,
|
||||
NXT_APP_PHP7,
|
||||
NXT_APP_RUBY,
|
||||
NXT_APP_GO,
|
||||
|
||||
NXT_APP_MAX,
|
||||
NXT_APP_UNKNOWN,
|
||||
} nxt_app_type_t;
|
||||
|
||||
|
||||
typedef struct nxt_app_module_s nxt_application_module_t;
|
||||
typedef struct nxt_app_module_s nxt_app_module_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
nxt_str_t type;
|
||||
nxt_str_t version;
|
||||
char *file;
|
||||
nxt_application_module_t *module;
|
||||
} nxt_app_lang_module_t;
|
||||
|
||||
|
||||
typedef struct nxt_common_app_conf_s nxt_common_app_conf_t;
|
||||
|
||||
|
||||
@@ -48,7 +54,6 @@ typedef struct {
|
||||
struct nxt_common_app_conf_s {
|
||||
nxt_str_t name;
|
||||
nxt_str_t type;
|
||||
nxt_app_type_t type_id;
|
||||
nxt_str_t user;
|
||||
nxt_str_t group;
|
||||
|
||||
@@ -148,13 +153,13 @@ nxt_inline u_char *
|
||||
nxt_app_msg_write_length(u_char *dst, size_t length);
|
||||
|
||||
/* TODO asynchronous mmap buffer assignment */
|
||||
u_char *nxt_app_msg_write_get_buf(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
size_t size);
|
||||
NXT_EXPORT u_char *nxt_app_msg_write_get_buf(nxt_task_t *task,
|
||||
nxt_app_wmsg_t *msg, size_t size);
|
||||
|
||||
nxt_int_t nxt_app_msg_write(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_write(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
u_char *c, size_t size);
|
||||
|
||||
nxt_int_t nxt_app_msg_write_prefixed_upcase(nxt_task_t *task,
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_write_prefixed_upcase(nxt_task_t *task,
|
||||
nxt_app_wmsg_t *msg, const nxt_str_t *prefix, const nxt_str_t *v);
|
||||
|
||||
nxt_inline nxt_int_t
|
||||
@@ -178,44 +183,37 @@ nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
nxt_inline nxt_int_t nxt_app_msg_write_size(nxt_task_t *task,
|
||||
nxt_app_wmsg_t *msg, size_t size);
|
||||
|
||||
nxt_int_t nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
nxt_bool_t last);
|
||||
|
||||
nxt_int_t nxt_app_msg_write_raw(nxt_task_t *task, nxt_app_wmsg_t *msg,
|
||||
const u_char *c, size_t size);
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_write_raw(nxt_task_t *task,
|
||||
nxt_app_wmsg_t *msg, const u_char *c, size_t size);
|
||||
|
||||
nxt_int_t nxt_app_msg_read_str(nxt_task_t *task, nxt_app_rmsg_t *msg,
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_read_str(nxt_task_t *task, nxt_app_rmsg_t *msg,
|
||||
nxt_str_t *str);
|
||||
|
||||
size_t nxt_app_msg_read_raw(nxt_task_t *task, nxt_app_rmsg_t *msg, void *buf,
|
||||
size_t size);
|
||||
NXT_EXPORT size_t nxt_app_msg_read_raw(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *msg, void *buf, size_t size);
|
||||
|
||||
nxt_int_t nxt_app_msg_read_nvp(nxt_task_t *task, nxt_app_rmsg_t *rmsg,
|
||||
nxt_str_t *n, nxt_str_t *v);
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_read_nvp(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, nxt_str_t *n, nxt_str_t *v);
|
||||
|
||||
nxt_int_t nxt_app_msg_read_size(nxt_task_t *task, nxt_app_rmsg_t *rmsg,
|
||||
size_t *size);
|
||||
NXT_EXPORT nxt_int_t nxt_app_msg_read_size(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, size_t *size);
|
||||
|
||||
|
||||
typedef struct nxt_app_module_s nxt_application_module_t;
|
||||
typedef struct nxt_app_module_s nxt_app_module_t;
|
||||
|
||||
struct nxt_app_module_s {
|
||||
nxt_str_t type;
|
||||
nxt_str_t version;
|
||||
|
||||
nxt_int_t (*init)(nxt_task_t *task,
|
||||
nxt_common_app_conf_t *conf);
|
||||
nxt_int_t (*prepare_msg)(nxt_task_t *task,
|
||||
nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg);
|
||||
nxt_int_t (*run)(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg,
|
||||
nxt_app_wmsg_t *wmsg);
|
||||
};
|
||||
|
||||
|
||||
extern nxt_application_module_t *nxt_app_modules[NXT_APP_MAX];
|
||||
|
||||
|
||||
|
||||
nxt_int_t nxt_app_http_read_body(nxt_app_request_t *r, u_char *data,
|
||||
size_t len);
|
||||
nxt_int_t nxt_app_write(nxt_app_request_t *r, const u_char *data, size_t len);
|
||||
@@ -290,6 +288,11 @@ nxt_app_msg_read_length(u_char *src, size_t *length)
|
||||
}
|
||||
|
||||
|
||||
nxt_app_lang_module_t *nxt_app_lang_module(nxt_runtime_t *rt, nxt_str_t *name);
|
||||
nxt_app_type_t nxt_app_parse_type(nxt_str_t *str);
|
||||
|
||||
|
||||
extern nxt_application_module_t nxt_go_module;
|
||||
|
||||
|
||||
#endif /* _NXT_APPLICATION_H_INCLIDED_ */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <nxt_main.h>
|
||||
#include <nxt_conf.h>
|
||||
#include <nxt_application.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -214,10 +215,19 @@ nxt_conf_vldt_app(nxt_conf_value_t *conf, nxt_str_t *name,
|
||||
nxt_conf_value_t *value)
|
||||
{
|
||||
nxt_str_t type;
|
||||
nxt_uint_t n;
|
||||
nxt_thread_t *thread;
|
||||
nxt_conf_value_t *type_value;
|
||||
nxt_app_lang_module_t *lang;
|
||||
|
||||
static nxt_str_t type_str = nxt_string("type");
|
||||
|
||||
static void *members[] = {
|
||||
nxt_conf_vldt_python_members,
|
||||
nxt_conf_vldt_php_members,
|
||||
nxt_conf_vldt_go_members,
|
||||
};
|
||||
|
||||
type_value = nxt_conf_get_object_member(value, &type_str, NULL);
|
||||
|
||||
if (nxt_slow_path(type_value == NULL)) {
|
||||
@@ -230,16 +240,16 @@ nxt_conf_vldt_app(nxt_conf_value_t *conf, nxt_str_t *name,
|
||||
|
||||
nxt_conf_get_string(type_value, &type);
|
||||
|
||||
if (nxt_str_eq(&type, "python", 6)) {
|
||||
return nxt_conf_vldt_object(conf, value, nxt_conf_vldt_python_members);
|
||||
thread = nxt_thread();
|
||||
|
||||
lang = nxt_app_lang_module(thread->runtime, &type);
|
||||
if (lang == NULL) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
if (nxt_str_eq(&type, "php", 3)) {
|
||||
return nxt_conf_vldt_object(conf, value, nxt_conf_vldt_php_members);
|
||||
}
|
||||
|
||||
if (nxt_str_eq(&type, "go", 2)) {
|
||||
return nxt_conf_vldt_object(conf, value, nxt_conf_vldt_go_members);
|
||||
n = nxt_app_parse_type(&lang->type);
|
||||
if (n != NXT_APP_UNKNOWN) {
|
||||
return nxt_conf_vldt_object(conf, value, members[n]);
|
||||
}
|
||||
|
||||
return NXT_ERROR;
|
||||
|
||||
95
src/nxt_go.c
95
src/nxt_go.c
@@ -10,30 +10,17 @@
|
||||
|
||||
static nxt_int_t nxt_go_init(nxt_task_t *task, nxt_common_app_conf_t *conf);
|
||||
|
||||
static nxt_int_t nxt_go_prepare_msg(nxt_task_t *task,
|
||||
nxt_app_request_t *r, nxt_app_wmsg_t *msg);
|
||||
|
||||
static nxt_int_t nxt_go_run(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *msg);
|
||||
|
||||
nxt_application_module_t nxt_go_module = {
|
||||
nxt_string("go"),
|
||||
nxt_string("go"),
|
||||
nxt_go_init,
|
||||
nxt_go_prepare_msg,
|
||||
nxt_go_run
|
||||
nxt_go_run,
|
||||
};
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_go_module_init(nxt_thread_t *thr, nxt_runtime_t *rt);
|
||||
|
||||
nxt_int_t
|
||||
nxt_go_module_init(nxt_thread_t *thr, nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_app_modules[NXT_APP_GO] = &nxt_go_module;
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
extern char **environ;
|
||||
|
||||
nxt_inline int
|
||||
@@ -112,82 +99,6 @@ nxt_go_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_go_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
nxt_int_t rc;
|
||||
nxt_buf_t *b;
|
||||
nxt_http_field_t *field;
|
||||
nxt_app_request_header_t *h;
|
||||
|
||||
static const nxt_str_t eof = nxt_null_string;
|
||||
|
||||
h = &r->header;
|
||||
|
||||
#define RC(S) \
|
||||
do { \
|
||||
rc = (S); \
|
||||
if (nxt_slow_path(rc != NXT_OK)) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NXT_WRITE(N) \
|
||||
RC(nxt_app_msg_write_str(task, wmsg, N))
|
||||
|
||||
/* TODO error handle, async mmap buffer assignment */
|
||||
|
||||
NXT_WRITE(&h->method);
|
||||
NXT_WRITE(&h->target);
|
||||
if (h->path.start == h->target.start) {
|
||||
NXT_WRITE(&eof);
|
||||
} else {
|
||||
NXT_WRITE(&h->path);
|
||||
}
|
||||
|
||||
if (h->query.start != NULL) {
|
||||
RC(nxt_app_msg_write_size(task, wmsg,
|
||||
h->query.start - h->target.start + 1));
|
||||
} else {
|
||||
RC(nxt_app_msg_write_size(task, wmsg, 0));
|
||||
}
|
||||
|
||||
NXT_WRITE(&h->version);
|
||||
|
||||
NXT_WRITE(&h->host);
|
||||
NXT_WRITE(&h->cookie);
|
||||
NXT_WRITE(&h->content_type);
|
||||
NXT_WRITE(&h->content_length);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, h->parsed_content_length));
|
||||
|
||||
nxt_list_each(field, h->fields) {
|
||||
NXT_WRITE(&field->name);
|
||||
NXT_WRITE(&field->value);
|
||||
|
||||
} nxt_list_loop;
|
||||
|
||||
/* end-of-headers mark */
|
||||
NXT_WRITE(&eof);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
|
||||
|
||||
for(b = r->body.buf; b != NULL; b = b->next) {
|
||||
RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
|
||||
nxt_buf_mem_used_size(&b->mem)));
|
||||
}
|
||||
|
||||
#undef NXT_WRITE
|
||||
#undef RC
|
||||
|
||||
return NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_go_run(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *msg)
|
||||
|
||||
@@ -27,6 +27,8 @@ static nxt_int_t nxt_master_start_controller_process(nxt_task_t *task,
|
||||
nxt_runtime_t *rt);
|
||||
static nxt_int_t nxt_master_start_router_process(nxt_task_t *task,
|
||||
nxt_runtime_t *rt);
|
||||
static nxt_int_t nxt_master_start_discovery_process(nxt_task_t *task,
|
||||
nxt_runtime_t *rt);
|
||||
static nxt_int_t nxt_master_start_worker_process(nxt_task_t *task,
|
||||
nxt_runtime_t *rt, nxt_common_app_conf_t *app_conf, uint32_t stream);
|
||||
static nxt_int_t nxt_master_create_worker_process(nxt_task_t *task,
|
||||
@@ -44,6 +46,9 @@ static void nxt_master_port_socket_handler(nxt_task_t *task,
|
||||
nxt_port_recv_msg_t *msg);
|
||||
static nxt_int_t nxt_master_listening_socket(nxt_sockaddr_t *sa,
|
||||
nxt_listening_socket_t *ls);
|
||||
static void nxt_master_port_modules_handler(nxt_task_t *task,
|
||||
nxt_port_recv_msg_t *msg);
|
||||
static int nxt_cdecl nxt_app_lang_compare(const void *v1, const void *v2);
|
||||
|
||||
|
||||
const nxt_sig_event_t nxt_master_process_signals[] = {
|
||||
@@ -63,8 +68,6 @@ nxt_int_t
|
||||
nxt_master_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
||||
nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
|
||||
rt->types |= (1U << NXT_PROCESS_MASTER);
|
||||
|
||||
if (nxt_master_process_port_create(task, rt) != NXT_OK) {
|
||||
@@ -73,12 +76,12 @@ nxt_master_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
||||
|
||||
nxt_master_process_title(task);
|
||||
|
||||
ret = nxt_master_start_controller_process(task, rt);
|
||||
if (ret != NXT_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return nxt_master_start_router_process(task, rt);
|
||||
/*
|
||||
* The dicsovery process will send a message processed by
|
||||
* nxt_master_port_modules_handler() which starts the controller
|
||||
* and router processes.
|
||||
*/
|
||||
return nxt_master_start_discovery_process(task, rt);
|
||||
}
|
||||
|
||||
|
||||
@@ -197,8 +200,6 @@ nxt_port_master_start_worker_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
||||
return;
|
||||
}
|
||||
|
||||
app_conf.type_id = nxt_app_parse_type(&app_conf.type);
|
||||
|
||||
ret = nxt_master_start_worker_process(task, task->thread->runtime,
|
||||
&app_conf, msg->port_msg.stream);
|
||||
|
||||
@@ -216,6 +217,7 @@ static nxt_port_handler_t nxt_master_process_port_handlers[] = {
|
||||
nxt_port_ready_handler,
|
||||
nxt_port_master_start_worker_handler,
|
||||
nxt_master_port_socket_handler,
|
||||
nxt_master_port_modules_handler,
|
||||
nxt_port_rpc_handler,
|
||||
nxt_port_rpc_handler,
|
||||
};
|
||||
@@ -289,7 +291,7 @@ nxt_master_start_controller_process(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_process_init_t *init;
|
||||
|
||||
init = nxt_mp_get(rt->mem_pool, sizeof(nxt_process_init_t));
|
||||
init = nxt_malloc(sizeof(nxt_process_init_t));
|
||||
if (nxt_slow_path(init == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
@@ -308,12 +310,36 @@ nxt_master_start_controller_process(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_master_start_discovery_process(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_process_init_t *init;
|
||||
|
||||
init = nxt_malloc(sizeof(nxt_process_init_t));
|
||||
if (nxt_slow_path(init == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
init->start = nxt_discovery_start;
|
||||
init->name = "discovery";
|
||||
init->user_cred = &rt->user_cred;
|
||||
init->port_handlers = nxt_discovery_process_port_handlers;
|
||||
init->signals = nxt_worker_process_signals;
|
||||
init->type = NXT_PROCESS_DISCOVERY;
|
||||
init->data = rt;
|
||||
init->stream = 0;
|
||||
init->restart = 0;
|
||||
|
||||
return nxt_master_create_worker_process(task, rt, init);
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_master_start_router_process(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_process_init_t *init;
|
||||
|
||||
init = nxt_mp_get(rt->mem_pool, sizeof(nxt_process_init_t));
|
||||
init = nxt_malloc(sizeof(nxt_process_init_t));
|
||||
if (nxt_slow_path(init == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
@@ -885,3 +911,130 @@ fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static nxt_conf_map_t nxt_app_lang_module_map[] = {
|
||||
{
|
||||
nxt_string("type"),
|
||||
NXT_CONF_MAP_STR_COPY,
|
||||
offsetof(nxt_app_lang_module_t, type),
|
||||
},
|
||||
|
||||
{
|
||||
nxt_string("version"),
|
||||
NXT_CONF_MAP_STR_COPY,
|
||||
offsetof(nxt_app_lang_module_t, version),
|
||||
},
|
||||
|
||||
{
|
||||
nxt_string("file"),
|
||||
NXT_CONF_MAP_CSTRZ,
|
||||
offsetof(nxt_app_lang_module_t, file),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
nxt_master_port_modules_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
||||
{
|
||||
uint32_t index;
|
||||
nxt_mp_t *mp;
|
||||
nxt_int_t ret;
|
||||
nxt_buf_t *b;
|
||||
nxt_runtime_t *rt;
|
||||
nxt_conf_value_t *conf, *root, *value;
|
||||
nxt_app_lang_module_t *lang;
|
||||
|
||||
static nxt_str_t root_path = nxt_string("/");
|
||||
|
||||
rt = task->thread->runtime;
|
||||
|
||||
if (msg->port_msg.pid != rt->port_by_type[NXT_PROCESS_DISCOVERY]->pid) {
|
||||
return;
|
||||
}
|
||||
|
||||
b = msg->buf;
|
||||
|
||||
if (b == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nxt_debug(task, "application languages: \"%*s\"",
|
||||
b->mem.free - b->mem.pos, b->mem.pos);
|
||||
|
||||
mp = nxt_mp_create(1024, 128, 256, 32);
|
||||
if (mp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
conf = nxt_conf_json_parse(mp, b->mem.pos, b->mem.free, NULL);
|
||||
if (conf == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
root = nxt_conf_get_path(conf, &root_path);
|
||||
if (root == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (index = 0; /* void */ ; index++) {
|
||||
value = nxt_conf_get_array_element(root, index);
|
||||
if (value == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
lang = nxt_array_add(rt->languages);
|
||||
if (lang == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lang->module = NULL;
|
||||
|
||||
ret = nxt_conf_map_object(rt->mem_pool, value, nxt_app_lang_module_map,
|
||||
nxt_nitems(nxt_app_lang_module_map), lang);
|
||||
|
||||
if (ret != NXT_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nxt_debug(task, "lang %V %V \"%s\"",
|
||||
&lang->type, &lang->version, lang->file);
|
||||
}
|
||||
|
||||
qsort(rt->languages->elts, rt->languages->nelts,
|
||||
sizeof(nxt_app_lang_module_t), nxt_app_lang_compare);
|
||||
|
||||
fail:
|
||||
|
||||
nxt_mp_destroy(mp);
|
||||
|
||||
ret = nxt_master_start_controller_process(task, rt);
|
||||
|
||||
if (ret == NXT_OK) {
|
||||
(void) nxt_master_start_router_process(task, rt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int nxt_cdecl
|
||||
nxt_app_lang_compare(const void *v1, const void *v2)
|
||||
{
|
||||
int n;
|
||||
size_t length;
|
||||
const nxt_app_lang_module_t *lang1, *lang2;
|
||||
|
||||
lang1 = v1;
|
||||
lang2 = v2;
|
||||
|
||||
length = nxt_min(lang1->version.length, lang2->version.length);
|
||||
|
||||
n = nxt_strncmp(lang1->version.start, lang2->version.start, length);
|
||||
|
||||
if (n == 0) {
|
||||
n = lang1->version.length - lang2->version.length;
|
||||
}
|
||||
|
||||
/* Negate result to move higher versions to the beginning. */
|
||||
|
||||
return -n;
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ void nxt_master_stop_worker_processes(nxt_task_t *task, nxt_runtime_t *runtime);
|
||||
|
||||
nxt_int_t nxt_controller_start(nxt_task_t *task, void *data);
|
||||
nxt_int_t nxt_router_start(nxt_task_t *task, void *data);
|
||||
nxt_int_t nxt_discovery_start(nxt_task_t *task, void *data);
|
||||
nxt_int_t nxt_app_start(nxt_task_t *task, void *data);
|
||||
|
||||
extern nxt_port_handler_t nxt_controller_process_port_handlers[];
|
||||
extern nxt_port_handler_t nxt_worker_process_port_handlers[];
|
||||
extern nxt_port_handler_t nxt_discovery_process_port_handlers[];
|
||||
extern nxt_port_handler_t nxt_app_process_port_handlers[];
|
||||
extern nxt_port_handler_t nxt_router_process_port_handlers[];
|
||||
extern const nxt_sig_event_t nxt_master_process_signals[];
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
static nxt_int_t nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf);
|
||||
|
||||
static nxt_int_t nxt_php_prepare_msg(nxt_task_t *task,
|
||||
nxt_app_request_t *r, nxt_app_wmsg_t *wmsg);
|
||||
|
||||
static nxt_int_t nxt_php_run(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg);
|
||||
|
||||
@@ -58,8 +55,6 @@ static int nxt_php_read_post(char *buffer, uint count_bytes TSRMLS_DC);
|
||||
|
||||
static void nxt_php_flush(void *server_context);
|
||||
|
||||
extern nxt_int_t nxt_php_sapi_init(nxt_thread_t *thr, nxt_runtime_t *rt);
|
||||
|
||||
|
||||
static sapi_module_struct nxt_php_sapi_module =
|
||||
{
|
||||
@@ -173,30 +168,14 @@ nxt_php_str_trim_lead(nxt_str_t *str, u_char t)
|
||||
}
|
||||
|
||||
|
||||
nxt_application_module_t nxt_php_module = {
|
||||
NXT_EXPORT nxt_application_module_t nxt_app_module = {
|
||||
nxt_string("php"),
|
||||
nxt_string(PHP_VERSION),
|
||||
nxt_php_init,
|
||||
nxt_php_prepare_msg,
|
||||
nxt_php_run
|
||||
nxt_php_run,
|
||||
};
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_php_sapi_init(nxt_thread_t *thr, nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_app_modules[NXT_APP_PHP] = &nxt_php_module;
|
||||
|
||||
#if PHP_MAJOR_VERSION == 5
|
||||
nxt_app_modules[NXT_APP_PHP5] = &nxt_php_module;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION == 7
|
||||
nxt_app_modules[NXT_APP_PHP7] = &nxt_php_module;
|
||||
#endif
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
||||
{
|
||||
@@ -356,92 +335,6 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
nxt_int_t rc;
|
||||
nxt_buf_t *b;
|
||||
nxt_http_field_t *field;
|
||||
nxt_app_request_header_t *h;
|
||||
|
||||
static const nxt_str_t prefix = nxt_string("HTTP_");
|
||||
static const nxt_str_t eof = nxt_null_string;
|
||||
|
||||
h = &r->header;
|
||||
|
||||
#define RC(S) \
|
||||
do { \
|
||||
rc = (S); \
|
||||
if (nxt_slow_path(rc != NXT_OK)) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NXT_WRITE(N) \
|
||||
RC(nxt_app_msg_write_str(task, wmsg, N))
|
||||
|
||||
/* TODO error handle, async mmap buffer assignment */
|
||||
|
||||
NXT_WRITE(&h->method);
|
||||
NXT_WRITE(&h->target);
|
||||
if (h->path.start == h->target.start) {
|
||||
NXT_WRITE(&eof);
|
||||
} else {
|
||||
NXT_WRITE(&h->path);
|
||||
}
|
||||
|
||||
if (h->query.start != NULL) {
|
||||
RC(nxt_app_msg_write_size(task, wmsg,
|
||||
h->query.start - h->target.start + 1));
|
||||
} else {
|
||||
RC(nxt_app_msg_write_size(task, wmsg, 0));
|
||||
}
|
||||
|
||||
NXT_WRITE(&h->version);
|
||||
|
||||
// PHP_SELF
|
||||
// SCRIPT_NAME
|
||||
// SCRIPT_FILENAME
|
||||
// DOCUMENT_ROOT
|
||||
|
||||
NXT_WRITE(&r->remote);
|
||||
|
||||
NXT_WRITE(&h->host);
|
||||
NXT_WRITE(&h->cookie);
|
||||
NXT_WRITE(&h->content_type);
|
||||
NXT_WRITE(&h->content_length);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, h->parsed_content_length));
|
||||
|
||||
nxt_list_each(field, h->fields) {
|
||||
RC(nxt_app_msg_write_prefixed_upcase(task, wmsg,
|
||||
&prefix, &field->name));
|
||||
NXT_WRITE(&field->value);
|
||||
|
||||
} nxt_list_loop;
|
||||
|
||||
/* end-of-headers mark */
|
||||
NXT_WRITE(&eof);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
|
||||
|
||||
for(b = r->body.buf; b != NULL; b = b->next) {
|
||||
RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
|
||||
nxt_buf_mem_used_size(&b->mem)));
|
||||
}
|
||||
|
||||
#undef NXT_WRITE
|
||||
#undef RC
|
||||
|
||||
return NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_php_run(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg)
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef enum {
|
||||
_NXT_PORT_MSG_READY,
|
||||
_NXT_PORT_MSG_START_WORKER,
|
||||
_NXT_PORT_MSG_SOCKET,
|
||||
_NXT_PORT_MSG_MODULES,
|
||||
_NXT_PORT_MSG_RPC_READY,
|
||||
_NXT_PORT_MSG_RPC_ERROR,
|
||||
|
||||
@@ -41,6 +42,7 @@ typedef enum {
|
||||
NXT_PORT_MSG_START_WORKER = _NXT_PORT_MSG_START_WORKER |
|
||||
NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_SOCKET = _NXT_PORT_MSG_SOCKET | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_MODULES = _NXT_PORT_MSG_MODULES | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_RPC_READY = _NXT_PORT_MSG_RPC_READY,
|
||||
NXT_PORT_MSG_RPC_READY_LAST = _NXT_PORT_MSG_RPC_READY | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_RPC_ERROR = _NXT_PORT_MSG_RPC_ERROR | NXT_PORT_MSG_LAST,
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef enum {
|
||||
NXT_PROCESS_CONTROLLER,
|
||||
NXT_PROCESS_ROUTER,
|
||||
NXT_PROCESS_WORKER,
|
||||
NXT_PROCESS_DISCOVERY,
|
||||
|
||||
NXT_PROCESS_MAX,
|
||||
} nxt_process_type_t;
|
||||
|
||||
@@ -61,9 +61,6 @@ typedef struct nxt_python_run_ctx_s nxt_python_run_ctx_t;
|
||||
|
||||
static nxt_int_t nxt_python_init(nxt_task_t *task, nxt_common_app_conf_t *conf);
|
||||
|
||||
static nxt_int_t nxt_python_prepare_msg(nxt_task_t *task,
|
||||
nxt_app_request_t *r, nxt_app_wmsg_t *msg);
|
||||
|
||||
static nxt_int_t nxt_python_run(nxt_task_t *task,
|
||||
nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *msg);
|
||||
|
||||
@@ -93,13 +90,12 @@ nxt_inline nxt_int_t nxt_python_write(nxt_python_run_ctx_t *ctx,
|
||||
nxt_inline nxt_int_t nxt_python_write_py_str(nxt_python_run_ctx_t *ctx,
|
||||
PyObject *str, nxt_bool_t flush, nxt_bool_t last);
|
||||
|
||||
extern nxt_int_t nxt_python_wsgi_init(nxt_thread_t *thr, nxt_runtime_t *rt);
|
||||
|
||||
|
||||
nxt_application_module_t nxt_python_module = {
|
||||
NXT_EXPORT nxt_application_module_t nxt_app_module = {
|
||||
nxt_string("python"),
|
||||
nxt_string(PY_VERSION),
|
||||
nxt_python_init,
|
||||
nxt_python_prepare_msg,
|
||||
nxt_python_run
|
||||
nxt_python_run,
|
||||
};
|
||||
|
||||
|
||||
@@ -177,23 +173,6 @@ static PyObject *nxt_py_environ_ptyp;
|
||||
static nxt_python_run_ctx_t *nxt_python_run_ctx;
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_python_wsgi_init(nxt_thread_t *thr, nxt_runtime_t *rt)
|
||||
{
|
||||
nxt_app_modules[NXT_APP_PYTHON] = &nxt_python_module;
|
||||
|
||||
#if PY_MAJOR_VERSION == 2
|
||||
nxt_app_modules[NXT_APP_PYTHON2] = &nxt_python_module;
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION == 3
|
||||
nxt_app_modules[NXT_APP_PYTHON3] = &nxt_python_module;
|
||||
#endif
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_python_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
|
||||
{
|
||||
@@ -319,84 +298,6 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
nxt_int_t rc;
|
||||
nxt_buf_t *b;
|
||||
nxt_http_field_t *field;
|
||||
nxt_app_request_header_t *h;
|
||||
|
||||
static const nxt_str_t prefix = nxt_string("HTTP_");
|
||||
static const nxt_str_t eof = nxt_null_string;
|
||||
|
||||
h = &r->header;
|
||||
|
||||
#define RC(S) \
|
||||
do { \
|
||||
rc = (S); \
|
||||
if (nxt_slow_path(rc != NXT_OK)) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NXT_WRITE(N) \
|
||||
RC(nxt_app_msg_write_str(task, wmsg, N))
|
||||
|
||||
/* TODO error handle, async mmap buffer assignment */
|
||||
|
||||
NXT_WRITE(&h->method);
|
||||
NXT_WRITE(&h->target);
|
||||
if (h->path.start == h->target.start) {
|
||||
NXT_WRITE(&eof);
|
||||
} else {
|
||||
NXT_WRITE(&h->path);
|
||||
}
|
||||
|
||||
if (h->query.start != NULL) {
|
||||
RC(nxt_app_msg_write_size(task, wmsg,
|
||||
h->query.start - h->target.start + 1));
|
||||
} else {
|
||||
RC(nxt_app_msg_write_size(task, wmsg, 0));
|
||||
}
|
||||
|
||||
NXT_WRITE(&h->version);
|
||||
|
||||
NXT_WRITE(&r->remote);
|
||||
|
||||
NXT_WRITE(&h->host);
|
||||
NXT_WRITE(&h->content_type);
|
||||
NXT_WRITE(&h->content_length);
|
||||
|
||||
nxt_list_each(field, h->fields) {
|
||||
RC(nxt_app_msg_write_prefixed_upcase(task, wmsg,
|
||||
&prefix, &field->name));
|
||||
NXT_WRITE(&field->value);
|
||||
|
||||
} nxt_list_loop;
|
||||
|
||||
/* end-of-headers mark */
|
||||
NXT_WRITE(&eof);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
|
||||
|
||||
for(b = r->body.buf; b != NULL; b = b->next) {
|
||||
RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
|
||||
nxt_buf_mem_used_size(&b->mem)));
|
||||
}
|
||||
|
||||
#undef NXT_WRITE
|
||||
#undef RC
|
||||
|
||||
return NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_python_run(nxt_task_t *task, nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
|
||||
277
src/nxt_router.c
277
src/nxt_router.c
@@ -134,6 +134,12 @@ static void nxt_router_process_http_request(nxt_task_t *task,
|
||||
nxt_conn_t *c, nxt_app_parse_ctx_t *ap);
|
||||
static void nxt_router_process_http_request_mp(nxt_task_t *task,
|
||||
nxt_req_app_link_t *ra, nxt_port_t *port);
|
||||
static nxt_int_t nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg);
|
||||
static nxt_int_t nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg);
|
||||
static nxt_int_t nxt_go_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg);
|
||||
static void nxt_router_conn_ready(nxt_task_t *task, void *obj, void *data);
|
||||
static void nxt_router_conn_close(nxt_task_t *task, void *obj, void *data);
|
||||
static void nxt_router_conn_free(nxt_task_t *task, void *obj, void *data);
|
||||
@@ -146,6 +152,14 @@ static void nxt_router_gen_error(nxt_task_t *task, nxt_conn_t *c, int code,
|
||||
|
||||
static nxt_router_t *nxt_router;
|
||||
|
||||
|
||||
static nxt_app_prepare_msg_t nxt_app_prepare_msg[] = {
|
||||
nxt_python_prepare_msg,
|
||||
nxt_php_prepare_msg,
|
||||
nxt_go_prepare_msg,
|
||||
};
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_router_start(nxt_task_t *task, void *data)
|
||||
{
|
||||
@@ -654,6 +668,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
nxt_conf_value_t *applications, *application;
|
||||
nxt_conf_value_t *listeners, *listener;
|
||||
nxt_socket_conf_t *skcf;
|
||||
nxt_app_lang_module_t *lang;
|
||||
nxt_router_app_conf_t apcf;
|
||||
nxt_router_listener_conf_t lscf;
|
||||
|
||||
@@ -735,17 +750,27 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
nxt_debug(task, "application type: %V", &apcf.type);
|
||||
nxt_debug(task, "application workers: %D", apcf.workers);
|
||||
|
||||
type = nxt_app_parse_type(&apcf.type);
|
||||
lang = nxt_app_lang_module(task->thread->runtime, &apcf.type);
|
||||
|
||||
if (type == NXT_APP_UNKNOWN) {
|
||||
if (lang == NULL) {
|
||||
nxt_log(task, NXT_LOG_CRIT, "unknown application type: \"%V\"",
|
||||
&apcf.type);
|
||||
goto app_fail;
|
||||
}
|
||||
|
||||
if (nxt_app_modules[type] == NULL) {
|
||||
nxt_debug(task, "application language module: \"%s\"", lang->file);
|
||||
|
||||
type = nxt_app_parse_type(&lang->type);
|
||||
|
||||
if (type == NXT_APP_UNKNOWN) {
|
||||
nxt_log(task, NXT_LOG_CRIT, "unknown application type: \"%V\"",
|
||||
&lang->type);
|
||||
goto app_fail;
|
||||
}
|
||||
|
||||
if (nxt_app_prepare_msg[type] == NULL) {
|
||||
nxt_log(task, NXT_LOG_CRIT, "unsupported application type: \"%V\"",
|
||||
&apcf.type);
|
||||
&lang->type);
|
||||
goto app_fail;
|
||||
}
|
||||
|
||||
@@ -763,7 +788,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
app->type = type;
|
||||
app->max_workers = apcf.workers;
|
||||
app->live = 1;
|
||||
app->module = nxt_app_modules[type];
|
||||
app->prepare_msg = nxt_app_prepare_msg[type];
|
||||
|
||||
nxt_queue_insert_tail(&tmcf->apps, &app->link);
|
||||
}
|
||||
@@ -2687,7 +2712,7 @@ nxt_router_process_http_request_mp(nxt_task_t *task, nxt_req_app_link_t *ra,
|
||||
wmsg.buf = &wmsg.write;
|
||||
wmsg.stream = ra->req_id;
|
||||
|
||||
res = port->app->module->prepare_msg(task, &ap->r, &wmsg);
|
||||
res = port->app->prepare_msg(task, &ap->r, &wmsg);
|
||||
|
||||
if (nxt_slow_path(res != NXT_OK)) {
|
||||
nxt_router_gen_error(task, c, 500,
|
||||
@@ -2710,6 +2735,246 @@ nxt_router_process_http_request_mp(nxt_task_t *task, nxt_req_app_link_t *ra,
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
nxt_int_t rc;
|
||||
nxt_buf_t *b;
|
||||
nxt_http_field_t *field;
|
||||
nxt_app_request_header_t *h;
|
||||
|
||||
static const nxt_str_t prefix = nxt_string("HTTP_");
|
||||
static const nxt_str_t eof = nxt_null_string;
|
||||
|
||||
h = &r->header;
|
||||
|
||||
#define RC(S) \
|
||||
do { \
|
||||
rc = (S); \
|
||||
if (nxt_slow_path(rc != NXT_OK)) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NXT_WRITE(N) \
|
||||
RC(nxt_app_msg_write_str(task, wmsg, N))
|
||||
|
||||
/* TODO error handle, async mmap buffer assignment */
|
||||
|
||||
NXT_WRITE(&h->method);
|
||||
NXT_WRITE(&h->target);
|
||||
if (h->path.start == h->target.start) {
|
||||
NXT_WRITE(&eof);
|
||||
} else {
|
||||
NXT_WRITE(&h->path);
|
||||
}
|
||||
|
||||
if (h->query.start != NULL) {
|
||||
RC(nxt_app_msg_write_size(task, wmsg,
|
||||
h->query.start - h->target.start + 1));
|
||||
} else {
|
||||
RC(nxt_app_msg_write_size(task, wmsg, 0));
|
||||
}
|
||||
|
||||
NXT_WRITE(&h->version);
|
||||
|
||||
NXT_WRITE(&r->remote);
|
||||
|
||||
NXT_WRITE(&h->host);
|
||||
NXT_WRITE(&h->content_type);
|
||||
NXT_WRITE(&h->content_length);
|
||||
|
||||
nxt_list_each(field, h->fields) {
|
||||
RC(nxt_app_msg_write_prefixed_upcase(task, wmsg,
|
||||
&prefix, &field->name));
|
||||
NXT_WRITE(&field->value);
|
||||
|
||||
} nxt_list_loop;
|
||||
|
||||
/* end-of-headers mark */
|
||||
NXT_WRITE(&eof);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
|
||||
|
||||
for(b = r->body.buf; b != NULL; b = b->next) {
|
||||
RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
|
||||
nxt_buf_mem_used_size(&b->mem)));
|
||||
}
|
||||
|
||||
#undef NXT_WRITE
|
||||
#undef RC
|
||||
|
||||
return NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
|
||||
nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
nxt_int_t rc;
|
||||
nxt_buf_t *b;
|
||||
nxt_http_field_t *field;
|
||||
nxt_app_request_header_t *h;
|
||||
|
||||
static const nxt_str_t prefix = nxt_string("HTTP_");
|
||||
static const nxt_str_t eof = nxt_null_string;
|
||||
|
||||
h = &r->header;
|
||||
|
||||
#define RC(S) \
|
||||
do { \
|
||||
rc = (S); \
|
||||
if (nxt_slow_path(rc != NXT_OK)) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NXT_WRITE(N) \
|
||||
RC(nxt_app_msg_write_str(task, wmsg, N))
|
||||
|
||||
/* TODO error handle, async mmap buffer assignment */
|
||||
|
||||
NXT_WRITE(&h->method);
|
||||
NXT_WRITE(&h->target);
|
||||
if (h->path.start == h->target.start) {
|
||||
NXT_WRITE(&eof);
|
||||
} else {
|
||||
NXT_WRITE(&h->path);
|
||||
}
|
||||
|
||||
if (h->query.start != NULL) {
|
||||
RC(nxt_app_msg_write_size(task, wmsg,
|
||||
h->query.start - h->target.start + 1));
|
||||
} else {
|
||||
RC(nxt_app_msg_write_size(task, wmsg, 0));
|
||||
}
|
||||
|
||||
NXT_WRITE(&h->version);
|
||||
|
||||
// PHP_SELF
|
||||
// SCRIPT_NAME
|
||||
// SCRIPT_FILENAME
|
||||
// DOCUMENT_ROOT
|
||||
|
||||
NXT_WRITE(&r->remote);
|
||||
|
||||
NXT_WRITE(&h->host);
|
||||
NXT_WRITE(&h->cookie);
|
||||
NXT_WRITE(&h->content_type);
|
||||
NXT_WRITE(&h->content_length);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, h->parsed_content_length));
|
||||
|
||||
nxt_list_each(field, h->fields) {
|
||||
RC(nxt_app_msg_write_prefixed_upcase(task, wmsg,
|
||||
&prefix, &field->name));
|
||||
NXT_WRITE(&field->value);
|
||||
|
||||
} nxt_list_loop;
|
||||
|
||||
/* end-of-headers mark */
|
||||
NXT_WRITE(&eof);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
|
||||
|
||||
for(b = r->body.buf; b != NULL; b = b->next) {
|
||||
RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
|
||||
nxt_buf_mem_used_size(&b->mem)));
|
||||
}
|
||||
|
||||
#undef NXT_WRITE
|
||||
#undef RC
|
||||
|
||||
return NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_go_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, nxt_app_wmsg_t *wmsg)
|
||||
{
|
||||
nxt_int_t rc;
|
||||
nxt_buf_t *b;
|
||||
nxt_http_field_t *field;
|
||||
nxt_app_request_header_t *h;
|
||||
|
||||
static const nxt_str_t eof = nxt_null_string;
|
||||
|
||||
h = &r->header;
|
||||
|
||||
#define RC(S) \
|
||||
do { \
|
||||
rc = (S); \
|
||||
if (nxt_slow_path(rc != NXT_OK)) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define NXT_WRITE(N) \
|
||||
RC(nxt_app_msg_write_str(task, wmsg, N))
|
||||
|
||||
/* TODO error handle, async mmap buffer assignment */
|
||||
|
||||
NXT_WRITE(&h->method);
|
||||
NXT_WRITE(&h->target);
|
||||
if (h->path.start == h->target.start) {
|
||||
NXT_WRITE(&eof);
|
||||
} else {
|
||||
NXT_WRITE(&h->path);
|
||||
}
|
||||
|
||||
if (h->query.start != NULL) {
|
||||
RC(nxt_app_msg_write_size(task, wmsg,
|
||||
h->query.start - h->target.start + 1));
|
||||
} else {
|
||||
RC(nxt_app_msg_write_size(task, wmsg, 0));
|
||||
}
|
||||
|
||||
NXT_WRITE(&h->version);
|
||||
|
||||
NXT_WRITE(&h->host);
|
||||
NXT_WRITE(&h->cookie);
|
||||
NXT_WRITE(&h->content_type);
|
||||
NXT_WRITE(&h->content_length);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, h->parsed_content_length));
|
||||
|
||||
nxt_list_each(field, h->fields) {
|
||||
NXT_WRITE(&field->name);
|
||||
NXT_WRITE(&field->value);
|
||||
|
||||
} nxt_list_loop;
|
||||
|
||||
/* end-of-headers mark */
|
||||
NXT_WRITE(&eof);
|
||||
|
||||
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
|
||||
|
||||
for(b = r->body.buf; b != NULL; b = b->next) {
|
||||
RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
|
||||
nxt_buf_mem_used_size(&b->mem)));
|
||||
}
|
||||
|
||||
#undef NXT_WRITE
|
||||
#undef RC
|
||||
|
||||
return NXT_OK;
|
||||
|
||||
fail:
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static const nxt_conn_state_t nxt_router_conn_close_state
|
||||
nxt_aligned(64) =
|
||||
{
|
||||
|
||||
@@ -66,6 +66,11 @@ typedef struct {
|
||||
} nxt_joint_job_t;
|
||||
|
||||
|
||||
|
||||
typedef nxt_int_t (*nxt_app_prepare_msg_t)(nxt_task_t *task,
|
||||
nxt_app_request_t *r, nxt_app_wmsg_t *wmsg);
|
||||
|
||||
|
||||
struct nxt_app_s {
|
||||
nxt_thread_mutex_t mutex; /* Protects ports queue. */
|
||||
nxt_queue_t ports; /* of nxt_port_t.app_link */
|
||||
@@ -83,7 +88,7 @@ struct nxt_app_s {
|
||||
nxt_queue_link_t link;
|
||||
|
||||
nxt_str_t conf;
|
||||
nxt_app_module_t *module;
|
||||
nxt_app_prepare_msg_t prepare_msg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ nxt_runtime_create(nxt_task_t *task)
|
||||
nxt_int_t ret;
|
||||
nxt_array_t *listen_sockets;
|
||||
nxt_runtime_t *rt;
|
||||
nxt_app_lang_module_t *lang;
|
||||
|
||||
mp = nxt_mp_create(1024, 128, 256, 32);
|
||||
|
||||
@@ -90,6 +91,18 @@ nxt_runtime_create(nxt_task_t *task)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rt->languages = nxt_array_create(mp, 1, sizeof(nxt_app_lang_module_t));
|
||||
if (nxt_slow_path(rt->languages == NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Should not fail. */
|
||||
lang = nxt_array_add(rt->languages);
|
||||
lang->type = (nxt_str_t) nxt_string("go");
|
||||
lang->version = (nxt_str_t) nxt_null_string;
|
||||
lang->file = NULL;
|
||||
lang->module = &nxt_go_module;
|
||||
|
||||
listen_sockets = nxt_array_create(mp, 1, sizeof(nxt_listen_socket_t));
|
||||
if (nxt_slow_path(listen_sockets == NULL)) {
|
||||
goto fail;
|
||||
@@ -324,7 +337,6 @@ nxt_runtime_thread_pools(nxt_thread_t *thr, nxt_runtime_t *rt)
|
||||
static void
|
||||
nxt_runtime_start(nxt_task_t *task, void *obj, void *data)
|
||||
{
|
||||
nxt_uint_t i;
|
||||
nxt_runtime_t *rt;
|
||||
|
||||
rt = obj;
|
||||
@@ -338,12 +350,6 @@ nxt_runtime_start(nxt_task_t *task, void *obj, void *data)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < nxt_init_modules_n; i++) {
|
||||
if (nxt_init_modules[i](task->thread, rt) != NXT_OK) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (nxt_runtime_log_files_create(task, rt) != NXT_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ struct nxt_runtime_s {
|
||||
nxt_array_t *listen_sockets; /* of nxt_listen_socket_t */
|
||||
|
||||
nxt_array_t *services; /* of nxt_service_t */
|
||||
nxt_array_t *languages; /* of nxt_app_lang_module_t */
|
||||
void *data;
|
||||
|
||||
nxt_runtime_cont_t start;
|
||||
|
||||
@@ -64,8 +64,7 @@ nxt_str_dup(nxt_mp_t *mp, nxt_str_t *dst, const nxt_str_t *src)
|
||||
* nxt_str_cstrz() creates a C style zero-terminated copy of a source
|
||||
* nxt_str_t. The function is intended to create strings suitable
|
||||
* for libc and kernel interfaces so result is pointer to char instead
|
||||
* of u_char to minimize casts. The copy is aligned to 2 bytes thus
|
||||
* the lowest bit may be used as marker.
|
||||
* of u_char to minimize casts.
|
||||
*/
|
||||
|
||||
char *
|
||||
@@ -73,7 +72,7 @@ nxt_str_cstrz(nxt_mp_t *mp, const nxt_str_t *src)
|
||||
{
|
||||
char *p, *dst;
|
||||
|
||||
dst = nxt_mp_align(mp, 2, src->length + 1);
|
||||
dst = nxt_mp_alloc(mp, src->length + 1);
|
||||
|
||||
if (nxt_fast_path(dst != NULL)) {
|
||||
p = nxt_cpymem(dst, src->start, src->length);
|
||||
|
||||
@@ -158,7 +158,7 @@ nxt_str_eq(s, p, _length) \
|
||||
|
||||
#define \
|
||||
nxt_str_start(s, p, _length) \
|
||||
(((s)->length > _length) && (nxt_memcmp((s)->start, p, _length) == 0))
|
||||
(((s)->length >= _length) && (nxt_memcmp((s)->start, p, _length) == 0))
|
||||
|
||||
|
||||
#define \
|
||||
|
||||
@@ -32,6 +32,7 @@ nxt_port_handler_t nxt_controller_process_port_handlers[] = {
|
||||
NULL, /* NXT_PORT_MSG_READY */
|
||||
NULL, /* NXT_PORT_MSG_START_WORKER */
|
||||
NULL, /* NXT_PORT_MSG_SOCKET */
|
||||
NULL, /* NXT_PORT_MSG_MODULES */
|
||||
nxt_port_rpc_handler,
|
||||
nxt_port_rpc_handler,
|
||||
};
|
||||
@@ -47,6 +48,7 @@ nxt_port_handler_t nxt_worker_process_port_handlers[] = {
|
||||
NULL, /* NXT_PORT_MSG_READY */
|
||||
NULL, /* NXT_PORT_MSG_START_WORKER */
|
||||
NULL, /* NXT_PORT_MSG_SOCKET */
|
||||
NULL, /* NXT_PORT_MSG_MODULES */
|
||||
nxt_port_rpc_handler,
|
||||
nxt_port_rpc_handler,
|
||||
};
|
||||
@@ -62,6 +64,7 @@ nxt_port_handler_t nxt_app_process_port_handlers[] = {
|
||||
NULL, /* NXT_PORT_MSG_READY */
|
||||
NULL, /* NXT_PORT_MSG_START_WORKER */
|
||||
NULL, /* NXT_PORT_MSG_SOCKET */
|
||||
NULL, /* NXT_PORT_MSG_MODULES */
|
||||
nxt_port_rpc_handler,
|
||||
nxt_port_rpc_handler,
|
||||
};
|
||||
@@ -77,6 +80,23 @@ nxt_port_handler_t nxt_router_process_port_handlers[] = {
|
||||
NULL, /* NXT_PORT_MSG_READY */
|
||||
NULL, /* NXT_PORT_MSG_START_WORKER */
|
||||
NULL, /* NXT_PORT_MSG_SOCKET */
|
||||
NULL, /* NXT_PORT_MSG_MODULES */
|
||||
nxt_port_rpc_handler,
|
||||
nxt_port_rpc_handler,
|
||||
};
|
||||
|
||||
|
||||
nxt_port_handler_t nxt_discovery_process_port_handlers[] = {
|
||||
nxt_worker_process_quit_handler,
|
||||
nxt_port_new_port_handler,
|
||||
nxt_port_change_log_file_handler,
|
||||
nxt_port_mmap_handler,
|
||||
nxt_port_data_handler,
|
||||
nxt_port_remove_pid_handler,
|
||||
NULL, /* NXT_PORT_MSG_READY */
|
||||
NULL, /* NXT_PORT_MSG_START_WORKER */
|
||||
NULL, /* NXT_PORT_MSG_SOCKET */
|
||||
NULL, /* NXT_PORT_MSG_MODULES */
|
||||
nxt_port_rpc_handler,
|
||||
nxt_port_rpc_handler,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user