Dynamic modules.
The auto/module script is extended to understand ngx_module_link=DYNAMIC.
When set, it links the module as a shared object rather than statically
into nginx binary. The module can later be loaded using the "load_module"
directive.
New auto/module parameter ngx_module_order allows to define module loading
order in complex cases. By default the order is set based on ngx_module_type.
3rd party modules can be compiled dynamically using the --add-dynamic-module
configure option, which will preset ngx_module_link to "DYNAMIC" before
calling the module config script.
Win32 support is rudimentary, and only works when using MinGW gcc (which
is able to handle exports/imports automatically).
In collaboration with Ruslan Ermilov.
diff --git a/auto/cc/conf b/auto/cc/conf
index edc6d74..35fd39c 100644
--- a/auto/cc/conf
+++ b/auto/cc/conf
@@ -5,12 +5,17 @@
LINK="\$(CC)"
+MAIN_LINK=
+MODULE_LINK="-shared"
+
ngx_include_opt="-I "
ngx_compile_opt="-c"
+ngx_pic_opt="-fPIC"
ngx_objout="-o "
ngx_binout="-o "
ngx_objext="o"
ngx_binext=
+ngx_modext=".so"
ngx_long_start=
ngx_long_end=
@@ -45,6 +50,9 @@
sunc)
+ MAIN_LINK=
+ MODULE_LINK="-G"
+
case "$NGX_MACHINE" in
i86pc)
@@ -156,6 +164,20 @@
fi
+ ngx_feature="-Wl,-E switch"
+ ngx_feature_name=
+ ngx_feature_run=no
+ ngx_feature_incs=
+ ngx_feature_path=
+ ngx_feature_libs=-Wl,-E
+ ngx_feature_test=
+ . auto/feature
+
+ if [ $ngx_found = yes ]; then
+ MAIN_LINK="-Wl,-E"
+ fi
+
+
ngx_feature="gcc builtin atomic operations"
ngx_feature_name=NGX_HAVE_GCC_ATOMIC
ngx_feature_run=yes
diff --git a/auto/cc/msvc b/auto/cc/msvc
index 393ba32..e588c48 100644
--- a/auto/cc/msvc
+++ b/auto/cc/msvc
@@ -118,6 +118,12 @@
CORE_LINK="$NGX_RES $CORE_LINK"
+# dynamic modules
+#MAIN_LINK="-link -def:$NGX_OBJS/nginx.def"
+#MODULE_LINK="-LD $NGX_OBJS/nginx.lib"
+
+
+ngx_pic_opt=
ngx_objout="-Fo"
ngx_binout="-Fe"
ngx_objext="obj"
diff --git a/auto/cc/sunc b/auto/cc/sunc
index 8f12d7c..8360c49 100644
--- a/auto/cc/sunc
+++ b/auto/cc/sunc
@@ -57,6 +57,9 @@
esac
+MAIN_LINK=
+MODULE_LINK="-G"
+
# optimizations
diff --git a/auto/init b/auto/init
index 910f529..c593eda 100644
--- a/auto/init
+++ b/auto/init
@@ -5,6 +5,7 @@
NGX_MAKEFILE=$NGX_OBJS/Makefile
NGX_MODULES_C=$NGX_OBJS/ngx_modules.c
+NGX_MODULES=
NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h
NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h
diff --git a/auto/install b/auto/install
index f7f686c..4dcc743 100644
--- a/auto/install
+++ b/auto/install
@@ -26,6 +26,18 @@
esac
+case ".$NGX_MODULES_PATH" in
+ ./*)
+ ;;
+
+ *)
+ NGX_MODULES_PATH=$NGX_PREFIX/$NGX_MODULES_PATH
+ ;;
+esac
+
+NGX_MODULES_PATH=`dirname $NGX_MODULES_PATH/.`
+
+
case ".$NGX_CONF_PATH" in
./*)
;;
@@ -158,12 +170,24 @@
fi
+if test -n "$NGX_MODULES"; then
+ cat << END >> $NGX_MAKEFILE
+
+ test -d '\$(DESTDIR)$NGX_MODULES_PATH' \
+ || mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH'
+ cp $NGX_MODULES '\$(DESTDIR)$NGX_MODULES_PATH'
+END
+
+fi
+
+
# create Makefile
cat << END >> Makefile
build:
\$(MAKE) -f $NGX_MAKEFILE
+ \$(MAKE) -f $NGX_MAKEFILE modules
\$(MAKE) -f $NGX_MAKEFILE manpage
install:
diff --git a/auto/lib/conf b/auto/lib/conf
index e1e4475..6aaa43a 100644
--- a/auto/lib/conf
+++ b/auto/lib/conf
@@ -58,11 +58,11 @@
. auto/lib/zlib/conf
fi
-if [ $USE_LIBXSLT = YES ]; then
+if [ $USE_LIBXSLT != NO ]; then
. auto/lib/libxslt/conf
fi
-if [ $USE_LIBGD = YES ]; then
+if [ $USE_LIBGD != NO ]; then
. auto/lib/libgd/conf
fi
@@ -70,7 +70,7 @@
. auto/lib/perl/conf
fi
-if [ $HTTP_GEOIP = YES ]; then
+if [ $USE_GEOIP != NO ]; then
. auto/lib/geoip/conf
fi
diff --git a/auto/lib/geoip/conf b/auto/lib/geoip/conf
index 53c274d..ebd2e15 100644
--- a/auto/lib/geoip/conf
+++ b/auto/lib/geoip/conf
@@ -67,7 +67,12 @@
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+
+ if [ $USE_GEOIP = YES ]; then
+ CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+ fi
+
+ NGX_LIB_GEOIP=$ngx_feature_libs
if [ $NGX_IPV6 = YES ]; then
ngx_feature="GeoIP IPv6 support"
diff --git a/auto/lib/libgd/conf b/auto/lib/libgd/conf
index ff99054..6e4e91c 100644
--- a/auto/lib/libgd/conf
+++ b/auto/lib/libgd/conf
@@ -67,7 +67,12 @@
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+
+ if [ $USE_LIBGD = YES ]; then
+ CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+ fi
+
+ NGX_LIB_LIBGD=$ngx_feature_libs
else
diff --git a/auto/lib/libxslt/conf b/auto/lib/libxslt/conf
index bc19d83..3a0f37b 100644
--- a/auto/lib/libxslt/conf
+++ b/auto/lib/libxslt/conf
@@ -76,7 +76,12 @@
if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+
+ if [ $USE_LIBXSLT = YES ]; then
+ CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+ fi
+
+ NGX_LIB_LIBXSLT=$ngx_feature_libs
else
@@ -152,5 +157,9 @@
if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS -lexslt"
+ if [ $USE_LIBXSLT = YES ]; then
+ CORE_LIBS="$CORE_LIBS -lexslt"
+ fi
+
+ NGX_LIB_LIBXSLT="$NGX_LIB_LIBXSLT -lexslt"
fi
diff --git a/auto/make b/auto/make
index 76b5806..039a70f 100644
--- a/auto/make
+++ b/auto/make
@@ -98,9 +98,11 @@
# the mail dependencies and include paths
-if [ $MAIL = YES ]; then
+if [ $MAIL != NO ]; then
- ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS"
+ if [ $MAIL = YES ]; then
+ ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS"
+ fi
ngx_deps=`echo $MAIL_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
@@ -124,9 +126,11 @@
# the stream dependencies and include paths
-if [ $STREAM = YES ]; then
+if [ $STREAM != NO ]; then
- ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS"
+ if [ $STREAM = YES ]; then
+ ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS"
+ fi
ngx_deps=`echo $STREAM_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
@@ -204,6 +208,7 @@
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
+ngx_libs=
if test -n "$NGX_LD_OPT$CORE_LIBS"; then
ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
@@ -212,13 +217,18 @@
ngx_link=${CORE_LINK:+`echo $CORE_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
+ngx_main_link=${MAIN_LINK:+`echo $MAIN_LINK \
+ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
+
cat << END >> $NGX_MAKEFILE
$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer
- \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link
+ \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link
$ngx_rcc
${ngx_long_end}
+
+modules:
END
@@ -472,3 +482,186 @@
END
fi
+
+
+# dynamic modules
+
+if test -n "$NGX_PCH"; then
+ ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
+else
+ ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) \$(ALL_INCS)"
+fi
+
+ngx_obj_deps="\$(CORE_DEPS)"
+if [ $HTTP != NO ]; then
+ ngx_obj_deps="$ngx_obj_deps \$(HTTP_DEPS)"
+fi
+if [ $MAIL != NO ]; then
+ ngx_obj_deps="$ngx_obj_deps \$(MAIL_DEPS)"
+fi
+if [ $STREAM != NO ]; then
+ ngx_obj_deps="$ngx_obj_deps \$(STREAM_DEPS)"
+fi
+
+for ngx_module in $DYNAMIC_MODULES
+do
+ eval ngx_module_srcs="\$${ngx_module}_SRCS"
+ eval eval ngx_module_libs="\\\"\$${ngx_module}_LIBS\\\""
+
+ eval ngx_module_modules="\$${ngx_module}_MODULES"
+ eval ngx_module_order="\$${ngx_module}_ORDER"
+
+ ngx_modules_c=$NGX_OBJS/${ngx_module}_modules.c
+
+ cat << END > $ngx_modules_c
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+END
+
+ for mod in $ngx_module_modules
+ do
+ echo "extern ngx_module_t $mod;" >> $ngx_modules_c
+ done
+
+ echo >> $ngx_modules_c
+ echo 'ngx_module_t *ngx_modules[] = {' >> $ngx_modules_c
+
+ for mod in $ngx_module_modules
+ do
+ echo " &$mod," >> $ngx_modules_c
+ done
+
+ cat << END >> $ngx_modules_c
+ NULL
+};
+
+END
+
+ echo 'char *ngx_module_names[] = {' >> $ngx_modules_c
+
+ for mod in $ngx_module_modules
+ do
+ echo " \"$mod\"," >> $ngx_modules_c
+ done
+
+ cat << END >> $ngx_modules_c
+ NULL
+};
+
+END
+
+ echo 'char *ngx_module_order[] = {' >> $ngx_modules_c
+
+ for mod in $ngx_module_order
+ do
+ echo " \"$mod\"," >> $ngx_modules_c
+ done
+
+ cat << END >> $ngx_modules_c
+ NULL
+};
+
+END
+
+ ngx_modules_c=`echo $ngx_modules_c | sed -e "s/\//$ngx_regex_dirsep/g"`
+
+ ngx_modules_obj=`echo $ngx_modules_c \
+ | sed -e "s/\(.*\.\)c/\1$ngx_objext/"`
+
+ ngx_module_objs=
+ for ngx_src in $ngx_module_srcs
+ do
+ case "$ngx_src" in
+ src/*)
+ ngx_obj=$ngx_src
+ ;;
+ *)
+ ngx_obj="addon/`basename \`dirname $ngx_src\``"
+ mkdir -p $NGX_OBJS/$ngx_obj
+ ngx_obj="$ngx_obj/`basename $ngx_src`"
+ ;;
+ esac
+
+ ngx_module_objs="$ngx_module_objs $ngx_obj"
+ done
+
+ ngx_module_objs=`echo $ngx_module_objs \
+ | sed -e "s#\([^ ]*\.\)cpp#$NGX_OBJS\/\1$ngx_objext#g" \
+ -e "s#\([^ ]*\.\)cc#$NGX_OBJS\/\1$ngx_objext#g" \
+ -e "s#\([^ ]*\.\)c#$NGX_OBJS\/\1$ngx_objext#g" \
+ -e "s#\([^ ]*\.\)S#$NGX_OBJS\/\1$ngx_objext#g"`
+
+ ngx_deps=`echo $ngx_module_objs $ngx_modules_obj $LINK_DEPS \
+ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
+ -e "s/\//$ngx_regex_dirsep/g"`
+
+ ngx_objs=`echo $ngx_module_objs $ngx_modules_obj \
+ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
+ -e "s/\//$ngx_regex_dirsep/g"`
+
+ ngx_obj=$NGX_OBJS${ngx_dirsep}${ngx_module}${ngx_modext}
+
+ NGX_MODULES="$NGX_MODULES $ngx_obj"
+
+ if [ "$NGX_PLATFORM" = win32 ]; then
+ ngx_module_libs="$CORE_LIBS $ngx_module_libs"
+ fi
+
+ ngx_libs=
+ if test -n "$NGX_LD_OPT$ngx_module_libs"; then
+ ngx_libs=`echo $NGX_LD_OPT $ngx_module_libs \
+ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
+ fi
+
+ ngx_link=${CORE_LINK:+`echo $CORE_LINK \
+ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
+
+ ngx_module_link=${MODULE_LINK:+`echo $MODULE_LINK \
+ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
+
+
+ cat << END >> $NGX_MAKEFILE
+
+modules: $ngx_obj
+
+$ngx_obj: $ngx_deps$ngx_spacer
+ \$(LINK) $ngx_long_start$ngx_binout$ngx_obj$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_module_link
+$ngx_long_end
+
+$ngx_modules_obj: \$(CORE_DEPS)$ngx_cont$ngx_modules_c
+ $ngx_cc$ngx_tab$ngx_objout$ngx_modules_obj$ngx_tab$ngx_modules_c$NGX_AUX
+
+END
+
+ for ngx_src in $ngx_module_srcs
+ do
+ case "$ngx_src" in
+ src/*)
+ ngx_obj=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
+ ;;
+ *)
+ ngx_obj="addon/`basename \`dirname $ngx_src\``"
+ ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
+ | sed -e "s/\//$ngx_regex_dirsep/g"`
+ ;;
+ esac
+
+ ngx_obj=`echo $ngx_obj \
+ | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
+ -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
+ -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
+ -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
+
+ ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
+
+ cat << END >> $NGX_MAKEFILE
+
+$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src
+ $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
+
+END
+
+ done
+done
diff --git a/auto/module b/auto/module
index 33ee181..908f0c6 100644
--- a/auto/module
+++ b/auto/module
@@ -9,7 +9,58 @@
esac
-if [ "$ngx_module_link" = YES ]; then
+if [ "$ngx_module_link" = DYNAMIC ]; then
+
+ for ngx_module in $ngx_module_name; do
+ # extract the first name
+ break
+ done
+
+ DYNAMIC_MODULES="$DYNAMIC_MODULES $ngx_module"
+ eval ${ngx_module}_SRCS=\"$ngx_module_srcs\"
+
+ eval ${ngx_module}_MODULES=\"$ngx_module_name\"
+
+ if [ -z "$ngx_module_order" -a \
+ \( "$ngx_module_type" = "HTTP_FILTER" \
+ -o "$ngx_module_type" = "HTTP_AUX_FILTER" \) ]
+ then
+ eval ${ngx_module}_ORDER=\"$ngx_module_name \
+ ngx_http_copy_filter_module\"
+ else
+ eval ${ngx_module}_ORDER=\"$ngx_module_order\"
+ fi
+
+ if test -n "$ngx_module_incs"; then
+ CORE_INCS="$CORE_INCS $ngx_module_incs"
+ fi
+
+ libs=
+ for lib in $ngx_module_libs
+ do
+ case $lib in
+
+ LIBXSLT | LIBGD | GEOIP)
+ libs="$libs \$NGX_LIB_$lib"
+
+ if eval [ "\$USE_${lib}" = NO ] ; then
+ eval USE_${lib}=DYNAMIC
+ fi
+ ;;
+
+ PCRE | OPENSSL | MD5 | SHA1 | ZLIB | PERL)
+ eval USE_${lib}=YES
+ ;;
+
+ *)
+ libs="$libs $lib"
+ ;;
+
+ esac
+ done
+ eval ${ngx_module}_LIBS=\'$libs\'
+
+elif [ "$ngx_module_link" = YES ]; then
eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \
$ngx_module_name\"
diff --git a/auto/modules b/auto/modules
index 8256b65..b68a96f 100644
--- a/auto/modules
+++ b/auto/modules
@@ -159,6 +159,35 @@
ngx_module_type=HTTP_FILTER
HTTP_FILTER_MODULES=
+ngx_module_order="ngx_http_static_module \
+ ngx_http_gzip_static_module \
+ ngx_http_dav_module \
+ ngx_http_autoindex_module \
+ ngx_http_index_module \
+ ngx_http_random_index_module \
+ ngx_http_access_module \
+ ngx_http_realip_module \
+ ngx_http_write_filter_module \
+ ngx_http_header_filter_module \
+ ngx_http_chunked_filter_module \
+ ngx_http_v2_filter_module \
+ ngx_http_range_header_filter_module \
+ ngx_http_gzip_filter_module \
+ ngx_http_postpone_filter_module \
+ ngx_http_ssi_filter_module \
+ ngx_http_charset_filter_module \
+ ngx_http_xslt_filter_module \
+ ngx_http_image_filter_module \
+ ngx_http_sub_filter_module \
+ ngx_http_addition_filter_module \
+ ngx_http_gunzip_filter_module \
+ ngx_http_userid_filter_module \
+ ngx_http_headers_filter_module \
+ ngx_http_copy_filter_module \
+ ngx_http_range_body_filter_module \
+ ngx_http_not_modified_filter_module \
+ ngx_http_slice_filter_module"
+
if :; then
ngx_module_name=ngx_http_write_filter_module
ngx_module_incs=
@@ -263,7 +292,7 @@
. auto/module
fi
-if [ $HTTP_XSLT = YES ]; then
+if [ $HTTP_XSLT != NO ]; then
ngx_module_name=ngx_http_xslt_filter_module
ngx_module_incs=
ngx_module_deps=
@@ -274,7 +303,7 @@
. auto/module
fi
-if [ $HTTP_IMAGE_FILTER = YES ]; then
+if [ $HTTP_IMAGE_FILTER != NO ]; then
ngx_module_name=ngx_http_image_filter_module
ngx_module_incs=
ngx_module_deps=
@@ -579,14 +608,14 @@
. auto/module
fi
-if [ $HTTP_GEOIP = YES ]; then
+if [ $HTTP_GEOIP != NO ]; then
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
ngx_module_name=ngx_http_geoip_module
ngx_module_incs=
ngx_module_deps=
ngx_module_srcs=src/http/modules/ngx_http_geoip_module.c
- ngx_module_libs=
+ ngx_module_libs=GEOIP
ngx_module_link=$HTTP_GEOIP
. auto/module
@@ -864,7 +893,7 @@
fi
-if [ $MAIL == YES ]; then
+if [ $MAIL != NO ]; then
MAIL_MODULES=
MAIL_DEPS=
MAIL_INCS=
@@ -873,6 +902,8 @@
ngx_module_libs=
ngx_module_link=YES
+ ngx_module_order=
+
ngx_module_name="ngx_mail_module ngx_mail_core_module"
ngx_module_incs="src/mail"
ngx_module_deps="src/mail/ngx_mail.h"
@@ -937,7 +968,7 @@
fi
-if [ $STREAM = YES ]; then
+if [ $STREAM != NO ]; then
STREAM_MODULES=
STREAM_DEPS=
STREAM_INCS=
@@ -948,6 +979,8 @@
ngx_module_libs=
ngx_module_link=YES
+ ngx_module_order=
+
ngx_module_name="ngx_stream_module \
ngx_stream_core_module \
ngx_stream_proxy_module \
@@ -1041,6 +1074,7 @@
ngx_module_deps=
ngx_module_srcs=
ngx_module_libs=
+ ngx_module_order=
ngx_module_link=ADDON
if test -f $ngx_addon_dir/config; then
@@ -1056,6 +1090,36 @@
fi
+if test -n "$DYNAMIC_ADDONS"; then
+
+ echo configuring additional dynamic modules
+
+ for ngx_addon_dir in $DYNAMIC_ADDONS
+ do
+ echo "adding module in $ngx_addon_dir"
+
+ ngx_module_type=
+ ngx_module_name=
+ ngx_module_incs=
+ ngx_module_deps=
+ ngx_module_srcs=
+ ngx_module_libs=
+ ngx_module_order=
+ ngx_module_link=DYNAMIC
+
+ if test -f $ngx_addon_dir/config; then
+ . $ngx_addon_dir/config
+
+ echo " + $ngx_addon_name was configured"
+
+ else
+ echo "$0: error: no $ngx_addon_dir/config was found"
+ exit 1
+ fi
+ done
+fi
+
+
if [ $USE_OPENSSL = YES ]; then
ngx_module_type=CORE
ngx_module_name=ngx_openssl_module
@@ -1065,6 +1129,7 @@
src/event/ngx_event_openssl_stapling.c"
ngx_module_libs=
ngx_module_link=YES
+ ngx_module_order=
. auto/module
fi
@@ -1078,6 +1143,7 @@
ngx_module_srcs=src/core/ngx_regex.c
ngx_module_libs=
ngx_module_link=YES
+ ngx_module_order=
. auto/module
fi
@@ -1100,14 +1166,42 @@
fi
-if [ $MAIL = YES ]; then
- modules="$modules $MAIL_MODULES"
+if [ $MAIL != NO ]; then
+
+ if [ $MAIL = YES ]; then
+ modules="$modules $MAIL_MODULES"
+
+ elif [ $MAIL = DYNAMIC ]; then
+ ngx_module_name=$MAIL_MODULES
+ ngx_module_incs=
+ ngx_module_deps=$MAIL_DEPS
+ ngx_module_srcs=$MAIL_SRCS
+ ngx_module_libs=
+ ngx_module_link=DYNAMIC
+
+ . auto/module
+ fi
+
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
fi
-if [ $STREAM = YES ]; then
- modules="$modules $STREAM_MODULES"
+if [ $STREAM != NO ]; then
+
+ if [ $STREAM = YES ]; then
+ modules="$modules $STREAM_MODULES"
+
+ elif [ $STREAM = DYNAMIC ]; then
+ ngx_module_name=$STREAM_MODULES
+ ngx_module_incs=
+ ngx_module_deps=$STREAM_DEPS
+ ngx_module_srcs=$STREAM_SRCS
+ ngx_module_libs=
+ ngx_module_link=DYNAMIC
+
+ . auto/module
+ fi
+
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(STREAM_DEPS)"
fi
@@ -1167,3 +1261,16 @@
};
END
+
+echo 'char *ngx_module_names[] = {' >> $NGX_MODULES_C
+
+for mod in $modules
+do
+ echo " \"$mod\"," >> $NGX_MODULES_C
+done
+
+cat << END >> $NGX_MODULES_C
+ NULL
+};
+
+END
diff --git a/auto/options b/auto/options
index 931dabb..36b34bc 100644
--- a/auto/options
+++ b/auto/options
@@ -7,6 +7,7 @@
NGX_PREFIX=
NGX_SBIN_PATH=
+NGX_MODULES_PATH=
NGX_CONF_PREFIX=
NGX_CONF_PATH=
NGX_ERROR_LOG_PATH=
@@ -120,7 +121,11 @@
STREAM_UPSTREAM_LEAST_CONN=YES
STREAM_UPSTREAM_ZONE=YES
+DYNAMIC_MODULES=
+
NGX_ADDONS=
+NGX_ADDON_DEPS=
+DYNAMIC_ADDONS=
USE_PCRE=NO
PCRE=NONE
@@ -151,6 +156,7 @@
USE_LIBXSLT=NO
USE_LIBGD=NO
+USE_GEOIP=NO
NGX_GOOGLE_PERFTOOLS=NO
NGX_CPP_TEST=NO
@@ -178,6 +184,7 @@
--prefix=) NGX_PREFIX="!" ;;
--prefix=*) NGX_PREFIX="$value" ;;
--sbin-path=*) NGX_SBIN_PATH="$value" ;;
+ --modules-path=*) NGX_MODULES_PATH="$value" ;;
--conf-path=*) NGX_CONF_PATH="$value" ;;
--error-log-path=*) NGX_ERROR_LOG_PATH="$value";;
--pid-path=*) NGX_PID_PATH="$value" ;;
@@ -215,8 +222,13 @@
--with-http_realip_module) HTTP_REALIP=YES ;;
--with-http_addition_module) HTTP_ADDITION=YES ;;
--with-http_xslt_module) HTTP_XSLT=YES ;;
+ --with-http_xslt_module=dynamic) HTTP_XSLT=DYNAMIC ;;
--with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;;
+ --with-http_image_filter_module=dynamic)
+ HTTP_IMAGE_FILTER=DYNAMIC ;;
--with-http_geoip_module) HTTP_GEOIP=YES ;;
+ --with-http_geoip_module=dynamic)
+ HTTP_GEOIP=DYNAMIC ;;
--with-http_sub_module) HTTP_SUB=YES ;;
--with-http_dav_module) HTTP_DAV=YES ;;
--with-http_flv_module) HTTP_FLV=YES ;;
@@ -266,6 +278,7 @@
--with-http_stub_status_module) HTTP_STUB_STATUS=YES ;;
--with-mail) MAIL=YES ;;
+ --with-mail=dynamic) MAIL=DYNAMIC ;;
--with-mail_ssl_module) MAIL_SSL=YES ;;
# STUB
--with-imap)
@@ -285,6 +298,7 @@
--without-mail_smtp_module) MAIL_SMTP=NO ;;
--with-stream) STREAM=YES ;;
+ --with-stream=dynamic) STREAM=DYNAMIC ;;
--with-stream_ssl_module) STREAM_SSL=YES ;;
--without-stream_limit_conn_module)
STREAM_LIMIT_CONN=NO ;;
@@ -300,6 +314,7 @@
--with-cpp_test_module) NGX_CPP_TEST=YES ;;
--add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
+ --add-dynamic-module=*) DYNAMIC_ADDONS="$DYNAMIC_ADDONS $value" ;;
--with-cc=*) CC="$value" ;;
--with-cpp=*) CPP="$value" ;;
@@ -356,6 +371,7 @@
--prefix=PATH set installation prefix
--sbin-path=PATH set nginx binary pathname
+ --modules-path=PATH set modules path
--conf-path=PATH set nginx.conf pathname
--error-log-path=PATH set error log pathname
--pid-path=PATH set nginx.pid pathname
@@ -384,8 +400,12 @@
--with-http_realip_module enable ngx_http_realip_module
--with-http_addition_module enable ngx_http_addition_module
--with-http_xslt_module enable ngx_http_xslt_module
+ --with-http_xslt_module=dynamic enable dynamic ngx_http_xslt_module
--with-http_image_filter_module enable ngx_http_image_filter_module
+ --with-http_image_filter_module=dynamic
+ enable dynamic ngx_http_image_filter_module
--with-http_geoip_module enable ngx_http_geoip_module
+ --with-http_geoip_module=dynamic enable dynamic ngx_http_geoip_module
--with-http_sub_module enable ngx_http_sub_module
--with-http_dav_module enable ngx_http_dav_module
--with-http_flv_module enable ngx_http_flv_module
@@ -451,12 +471,14 @@
--without-http-cache disable HTTP cache
--with-mail enable POP3/IMAP4/SMTP proxy module
+ --with-mail=dynamic enable dynamic POP3/IMAP4/SMTP proxy module
--with-mail_ssl_module enable ngx_mail_ssl_module
--without-mail_pop3_module disable ngx_mail_pop3_module
--without-mail_imap_module disable ngx_mail_imap_module
--without-mail_smtp_module disable ngx_mail_smtp_module
--with-stream enable TCP proxy module
+ --with-stream=dynamic enable dynamic TCP proxy module
--with-stream_ssl_module enable ngx_stream_ssl_module
--without-stream_limit_conn_module disable ngx_stream_limit_conn_module
--without-stream_access_module disable ngx_stream_access_module
@@ -470,7 +492,8 @@
--with-google_perftools_module enable ngx_google_perftools_module
--with-cpp_test_module enable ngx_cpp_test_module
- --add-module=PATH enable an external module
+ --add-module=PATH enable external module
+ --add-dynamic-module=PATH enable dynamic external module
--with-cc=PATH set C compiler pathname
--with-cpp=PATH set C preprocessor pathname
@@ -533,6 +556,7 @@
NGX_SBIN_PATH=${NGX_SBIN_PATH:-sbin/nginx}
+NGX_MODULES_PATH=${NGX_MODULES_PATH:-modules}
NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}
NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}
diff --git a/auto/os/darwin b/auto/os/darwin
index 1d3e3d3..9b31b1f 100644
--- a/auto/os/darwin
+++ b/auto/os/darwin
@@ -14,6 +14,9 @@
ngx_spacer='
'
+MAIN_LINK=
+MODULE_LINK="-shared -Wl,-undefined,dynamic_lookup"
+
# kqueue
echo " + kqueue found"
diff --git a/auto/os/win32 b/auto/os/win32
index 82fc212..14ae3b8 100644
--- a/auto/os/win32
+++ b/auto/os/win32
@@ -12,10 +12,15 @@
NGX_ICONS="$NGX_WIN32_ICONS"
SELECT_SRCS=$WIN32_SELECT_SRCS
+ngx_pic_opt=
+
case "$NGX_CC_NAME" in
gcc)
CORE_LIBS="$CORE_LIBS -ladvapi32 -lws2_32"
+ MAIN_LINK="$MAIN_LINK -Wl,--export-all-symbols"
+ MAIN_LINK="$MAIN_LINK -Wl,--out-implib=$NGX_OBJS/libnginx.a"
+ MODULE_LINK="-shared -L $NGX_OBJS -lnginx"
;;
*)
diff --git a/auto/summary b/auto/summary
index 1be975d..dc8fe4f 100644
--- a/auto/summary
+++ b/auto/summary
@@ -60,6 +60,7 @@
cat << END
nginx path prefix: "$NGX_PREFIX"
nginx binary file: "$NGX_SBIN_PATH"
+ nginx modules path: "$NGX_MODULES_PATH"
nginx configuration prefix: "$NGX_CONF_PREFIX"
nginx configuration file: "$NGX_CONF_PATH"
nginx pid file: "$NGX_PID_PATH"
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 22441a8..6ce030c 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -24,6 +24,10 @@
void *conf);
static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_load_module(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+#if (NGX_HAVE_DLOPEN)
+static void ngx_unload_module(void *data);
+#endif
static ngx_conf_enum_t ngx_debug_points[] = {
@@ -133,6 +137,13 @@
0,
NULL },
+ { ngx_string("load_module"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+ ngx_load_module,
+ 0,
+ 0,
+ NULL },
+
ngx_null_command
};
@@ -1403,3 +1414,101 @@
return NGX_CONF_OK;
}
+
+
+static char *
+ngx_load_module(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+#if (NGX_HAVE_DLOPEN)
+ void *handle;
+ char **names, **order;
+ ngx_str_t *value, file;
+ ngx_uint_t i;
+ ngx_module_t *module, **modules;
+ ngx_pool_cleanup_t *cln;
+
+ if (cf->cycle->modules_used) {
+ return "is specified too late";
+ }
+
+ value = cf->args->elts;
+
+ file = value[1];
+
+ if (ngx_conf_full_name(cf->cycle, &file, 0) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ cln = ngx_pool_cleanup_add(cf->cycle->pool, 0);
+ if (cln == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ handle = ngx_dlopen(file.data);
+ if (handle == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ ngx_dlopen_n " \"%s\" failed (%s)",
+ file.data, ngx_dlerror());
+ return NGX_CONF_ERROR;
+ }
+
+ cln->handler = ngx_unload_module;
+ cln->data = handle;
+
+ modules = ngx_dlsym(handle, "ngx_modules");
+ if (modules == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ ngx_dlsym_n " \"%V\", \"%s\" failed (%s)",
+ &value[1], "ngx_modules", ngx_dlerror());
+ return NGX_CONF_ERROR;
+ }
+
+ names = ngx_dlsym(handle, "ngx_module_names");
+ if (names == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ ngx_dlsym_n " \"%V\", \"%s\" failed (%s)",
+ &value[1], "ngx_module_names", ngx_dlerror());
+ return NGX_CONF_ERROR;
+ }
+
+ order = ngx_dlsym(handle, "ngx_module_order");
+
+ for (i = 0; modules[i]; i++) {
+ module = modules[i];
+ module->name = names[i];
+
+ if (ngx_add_module(cf, &file, module, order) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0, "module: %s i:%i",
+ module->name, module->index);
+ }
+
+ return NGX_CONF_OK;
+
+#else
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"load_module\" is not supported "
+ "on this platform");
+ return NGX_CONF_ERROR;
+
+#endif
+}
+
+
+#if (NGX_HAVE_DLOPEN)
+
+static void
+ngx_unload_module(void *data)
+{
+ void *handle = data;
+
+ if (ngx_dlclose(handle) != 0) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ ngx_dlclose_n " failed (%s)", ngx_dlerror());
+ }
+}
+
+#endif
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index 946f8c0..f103266 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -212,7 +212,10 @@
ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);
- cycle->modules = ngx_modules;
+ if (ngx_cycle_modules(cycle) != NGX_OK) {
+ ngx_destroy_pool(pool);
+ return NULL;
+ }
for (i = 0; cycle->modules[i]; i++) {
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 736fb65..27401d0 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -49,6 +49,8 @@
ngx_uint_t free_connection_n;
ngx_module_t **modules;
+ ngx_uint_t modules_n;
+ ngx_uint_t modules_used; /* unsigned modules_used:1; */
ngx_queue_t reusable_connections_queue;
diff --git a/src/core/ngx_module.c b/src/core/ngx_module.c
index df3cfde..1e947c9 100644
--- a/src/core/ngx_module.c
+++ b/src/core/ngx_module.c
@@ -10,7 +10,16 @@
#include <ngx_core.h>
-ngx_uint_t ngx_max_module;
+#define NGX_MAX_DYNAMIC_MODULES 128
+
+
+static ngx_uint_t ngx_module_index(ngx_cycle_t *cycle);
+static ngx_uint_t ngx_module_ctx_index(ngx_cycle_t *cycle, ngx_uint_t type,
+ ngx_uint_t index);
+
+
+ngx_uint_t ngx_max_module;
+static ngx_uint_t ngx_modules_n;
ngx_int_t
@@ -20,9 +29,36 @@
ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
- ngx_modules[i]->index = ngx_max_module++;
+ ngx_modules[i]->index = i;
+ ngx_modules[i]->name = ngx_module_names[i];
}
+ ngx_modules_n = i;
+ ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_cycle_modules(ngx_cycle_t *cycle)
+{
+ /*
+ * create a list of modules to be used for this cycle,
+ * copy static modules to it
+ */
+
+ cycle->modules = ngx_pcalloc(cycle->pool, (ngx_max_module + 1)
+ * sizeof(ngx_module_t *));
+ if (cycle->modules == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(cycle->modules, ngx_modules,
+ ngx_modules_n * sizeof(ngx_module_t *));
+
+ cycle->modules_n = ngx_modules_n;
+
return NGX_OK;
}
@@ -47,19 +83,279 @@
ngx_int_t
ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type)
{
- ngx_uint_t i, max;
+ ngx_uint_t i, next, max;
+ ngx_module_t *module;
+ next = 0;
max = 0;
/* count appropriate modules, set up their indices */
for (i = 0; cycle->modules[i]; i++) {
- if (cycle->modules[i]->type != type) {
+ module = cycle->modules[i];
+
+ if (module->type != type) {
continue;
}
- cycle->modules[i]->ctx_index = max++;
+ if (module->ctx_index != NGX_MODULE_UNSET_INDEX) {
+
+ /* if ctx_index was assigned, preserve it */
+
+ if (module->ctx_index > max) {
+ max = module->ctx_index;
+ }
+
+ if (module->ctx_index == next) {
+ next++;
+ }
+
+ continue;
+ }
+
+ /* search for some free index */
+
+ module->ctx_index = ngx_module_ctx_index(cycle, type, next);
+
+ if (module->ctx_index > max) {
+ max = module->ctx_index;
+ }
+
+ next = module->ctx_index + 1;
}
- return max;
+ /*
+ * make sure the number returned is big enough for previous
+ * cycle as well, else there will be problems if the number
+ * will be stored in a global variable (as it's used to be)
+ * and we'll have to roll back to the previous cycle
+ */
+
+ if (cycle->old_cycle && cycle->old_cycle->modules) {
+
+ for (i = 0; cycle->old_cycle->modules[i]; i++) {
+ module = cycle->old_cycle->modules[i];
+
+ if (module->type != type) {
+ continue;
+ }
+
+ if (module->ctx_index > max) {
+ max = module->ctx_index;
+ }
+ }
+ }
+
+ /* prevent loading of additional modules */
+
+ cycle->modules_used = 1;
+
+ return max + 1;
+}
+
+
+ngx_int_t
+ngx_add_module(ngx_conf_t *cf, ngx_str_t *file, ngx_module_t *module,
+ char **order)
+{
+ void *rv;
+ ngx_uint_t i, m, before;
+ ngx_core_module_t *core_module;
+
+ if (cf->cycle->modules_n >= ngx_max_module) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "too many modules loaded");
+ return NGX_ERROR;
+ }
+
+ if (module->version != nginx_version) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "module \"%V\" version %ui instead of %ui",
+ file, module->version, nginx_version);
+ return NGX_ERROR;
+ }
+
+ if (ngx_strcmp(module->signature, NGX_MODULE_SIGNATURE) != 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "module \"%V\" is not binary compatible",
+ file);
+ return NGX_ERROR;
+ }
+
+ for (m = 0; cf->cycle->modules[m]; m++) {
+ if (ngx_strcmp(cf->cycle->modules[m]->name, module->name) == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "module \"%s\" is already loaded",
+ module->name);
+ return NGX_ERROR;
+ }
+ }
+
+ /*
+ * if the module wasn't previously loaded, assign an index
+ */
+
+ if (module->index == NGX_MODULE_UNSET_INDEX) {
+ module->index = ngx_module_index(cf->cycle);
+
+ if (module->index >= ngx_max_module) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "too many modules loaded");
+ return NGX_ERROR;
+ }
+ }
+
+ /*
+ * put the module into the cycle->modules array
+ */
+
+ before = cf->cycle->modules_n;
+
+ if (order) {
+ for (i = 0; order[i]; i++) {
+ if (ngx_strcmp(order[i], module->name) == 0) {
+ i++;
+ break;
+ }
+ }
+
+ for ( /* void */ ; order[i]; i++) {
+
+#if 0
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0,
+ "module: %s before %s",
+ module->name, order[i]);
+#endif
+
+ for (m = 0; m < before; m++) {
+ if (ngx_strcmp(cf->cycle->modules[m]->name, order[i]) == 0) {
+
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, cf->log, 0,
+ "module: %s before %s:%i",
+ module->name, order[i], m);
+
+ before = m;
+ break;
+ }
+ }
+ }
+ }
+
+ /* put the module before modules[before] */
+
+ if (before != cf->cycle->modules_n) {
+ ngx_memmove(&cf->cycle->modules[before + 1],
+ &cf->cycle->modules[before],
+ (cf->cycle->modules_n - before) * sizeof(ngx_module_t *));
+ }
+
+ cf->cycle->modules[before] = module;
+ cf->cycle->modules_n++;
+
+ if (module->type == NGX_CORE_MODULE) {
+
+ /*
+ * we are smart enough to initialize core modules;
+ * other modules are expected to be loaded before
+ * initialization - e.g., http modules must be loaded
+ * before http{} block
+ */
+
+ core_module = module->ctx;
+
+ if (core_module->create_conf) {
+ rv = core_module->create_conf(cf->cycle);
+ if (rv == NULL) {
+ return NGX_ERROR;
+ }
+
+ cf->cycle->conf_ctx[module->index] = rv;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_uint_t
+ngx_module_index(ngx_cycle_t *cycle)
+{
+ ngx_uint_t i, index;
+ ngx_module_t *module;
+
+ index = 0;
+
+again:
+
+ /* find an unused index */
+
+ for (i = 0; cycle->modules[i]; i++) {
+ module = cycle->modules[i];
+
+ if (module->index == index) {
+ index++;
+ goto again;
+ }
+ }
+
+ /* check previous cycle */
+
+ if (cycle->old_cycle && cycle->old_cycle->modules) {
+
+ for (i = 0; cycle->old_cycle->modules[i]; i++) {
+ module = cycle->old_cycle->modules[i];
+
+ if (module->index == index) {
+ index++;
+ goto again;
+ }
+ }
+ }
+
+ return index;
+}
+
+
+static ngx_uint_t
+ngx_module_ctx_index(ngx_cycle_t *cycle, ngx_uint_t type, ngx_uint_t index)
+{
+ ngx_uint_t i;
+ ngx_module_t *module;
+
+again:
+
+ /* find an unused ctx_index */
+
+ for (i = 0; cycle->modules[i]; i++) {
+ module = cycle->modules[i];
+
+ if (module->type != type) {
+ continue;
+ }
+
+ if (module->ctx_index == index) {
+ index++;
+ goto again;
+ }
+ }
+
+ /* check previous cycle */
+
+ if (cycle->old_cycle && cycle->old_cycle->modules) {
+
+ for (i = 0; cycle->old_cycle->modules[i]; i++) {
+ module = cycle->old_cycle->modules[i];
+
+ if (module->type != type) {
+ continue;
+ }
+
+ if (module->ctx_index == index) {
+ index++;
+ goto again;
+ }
+ }
+ }
+
+ return index;
}
diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h
index fb5ac9b..cd28c49 100644
--- a/src/core/ngx_module.h
+++ b/src/core/ngx_module.h
@@ -12,9 +12,234 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <nginx.h>
-#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1
+#define NGX_MODULE_UNSET_INDEX (ngx_uint_t) -1
+
+
+#define NGX_MODULE_SIGNATURE_0 \
+ ngx_value(NGX_PTR_SIZE) "," \
+ ngx_value(NGX_SIG_ATOMIC_T_SIZE) "," \
+ ngx_value(NGX_TIME_T_SIZE) ","
+
+#if (NGX_HAVE_KQUEUE)
+#define NGX_MODULE_SIGNATURE_1 "1"
+#else
+#define NGX_MODULE_SIGNATURE_1 "0"
+#endif
+
+#if (NGX_HAVE_IOCP)
+#define NGX_MODULE_SIGNATURE_2 "1"
+#else
+#define NGX_MODULE_SIGNATURE_2 "0"
+#endif
+
+#if (NGX_HAVE_FILE_AIO)
+#define NGX_MODULE_SIGNATURE_3 "1"
+#else
+#define NGX_MODULE_SIGNATURE_3 "0"
+#endif
+
+#if (NGX_HAVE_AIO_SENDFILE)
+#define NGX_MODULE_SIGNATURE_4 "1"
+#else
+#define NGX_MODULE_SIGNATURE_4 "0"
+#endif
+
+#if (NGX_HAVE_EVENTFD)
+#define NGX_MODULE_SIGNATURE_5 "1"
+#else
+#define NGX_MODULE_SIGNATURE_5 "0"
+#endif
+
+#if (NGX_HAVE_EPOLL)
+#define NGX_MODULE_SIGNATURE_6 "1"
+#else
+#define NGX_MODULE_SIGNATURE_6 "0"
+#endif
+
+#if (NGX_HAVE_KEEPALIVE_TUNABLE)
+#define NGX_MODULE_SIGNATURE_7 "1"
+#else
+#define NGX_MODULE_SIGNATURE_7 "0"
+#endif
+
+#if (NGX_HAVE_INET6)
+#define NGX_MODULE_SIGNATURE_8 "1"
+#else
+#define NGX_MODULE_SIGNATURE_8 "0"
+#endif
+
+#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+#define NGX_MODULE_SIGNATURE_9 "1"
+#else
+#define NGX_MODULE_SIGNATURE_9 "0"
+#endif
+
+#if (NGX_HAVE_REUSEPORT)
+#define NGX_MODULE_SIGNATURE_10 "1"
+#else
+#define NGX_MODULE_SIGNATURE_10 "0"
+#endif
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+#define NGX_MODULE_SIGNATURE_11 "1"
+#else
+#define NGX_MODULE_SIGNATURE_11 "0"
+#endif
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+#define NGX_MODULE_SIGNATURE_12 "1"
+#else
+#define NGX_MODULE_SIGNATURE_12 "0"
+#endif
+
+#if (NGX_HAVE_SETFIB)
+#define NGX_MODULE_SIGNATURE_13 "1"
+#else
+#define NGX_MODULE_SIGNATURE_13 "0"
+#endif
+
+#if (NGX_HAVE_TCP_FASTOPEN)
+#define NGX_MODULE_SIGNATURE_14 "1"
+#else
+#define NGX_MODULE_SIGNATURE_14 "0"
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+#define NGX_MODULE_SIGNATURE_15 "1"
+#else
+#define NGX_MODULE_SIGNATURE_15 "0"
+#endif
+
+#if (NGX_HAVE_VARIADIC_MACROS)
+#define NGX_MODULE_SIGNATURE_16 "1"
+#else
+#define NGX_MODULE_SIGNATURE_16 "0"
+#endif
+
+#if (NGX_HAVE_MD5)
+#define NGX_MODULE_SIGNATURE_17 "1"
+#else
+#define NGX_MODULE_SIGNATURE_17 "0"
+#endif
+
+#if (NGX_HAVE_SHA1)
+#define NGX_MODULE_SIGNATURE_18 "1"
+#else
+#define NGX_MODULE_SIGNATURE_18 "0"
+#endif
+
+#if (NGX_HAVE_OPENAT)
+#define NGX_MODULE_SIGNATURE_19 "1"
+#else
+#define NGX_MODULE_SIGNATURE_19 "0"
+#endif
+
+#if (NGX_HAVE_ATOMIC_OPS)
+#define NGX_MODULE_SIGNATURE_20 "1"
+#else
+#define NGX_MODULE_SIGNATURE_20 "0"
+#endif
+
+#if (NGX_HAVE_POSIX_SEM)
+#define NGX_MODULE_SIGNATURE_21 "1"
+#else
+#define NGX_MODULE_SIGNATURE_21 "0"
+#endif
+
+#if (NGX_THREADS)
+#define NGX_MODULE_SIGNATURE_22 "1"
+#else
+#define NGX_MODULE_SIGNATURE_22 "0"
+#endif
+
+#if (NGX_PCRE)
+#define NGX_MODULE_SIGNATURE_23 "1"
+#else
+#define NGX_MODULE_SIGNATURE_23 "0"
+#endif
+
+#if (NGX_HTTP_SSL)
+#define NGX_MODULE_SIGNATURE_24 "1"
+#else
+#define NGX_MODULE_SIGNATURE_24 "0"
+#endif
+
+#if (NGX_HTTP_V2)
+#define NGX_MODULE_SIGNATURE_25 "1"
+#else
+#define NGX_MODULE_SIGNATURE_25 "0"
+#endif
+
+#if (NGX_HTTP_GZIP)
+#define NGX_MODULE_SIGNATURE_26 "1"
+#else
+#define NGX_MODULE_SIGNATURE_26 "0"
+#endif
+
+#if (NGX_HTTP_DEGRADATION)
+#define NGX_MODULE_SIGNATURE_27 "1"
+#else
+#define NGX_MODULE_SIGNATURE_27 "0"
+#endif
+
+#if (NGX_HTTP_X_FORWARDED_FOR)
+#define NGX_MODULE_SIGNATURE_28 "1"
+#else
+#define NGX_MODULE_SIGNATURE_28 "0"
+#endif
+
+#if (NGX_HTTP_REALIP)
+#define NGX_MODULE_SIGNATURE_29 "1"
+#else
+#define NGX_MODULE_SIGNATURE_29 "0"
+#endif
+
+#if (NGX_HTTP_HEADERS)
+#define NGX_MODULE_SIGNATURE_30 "1"
+#else
+#define NGX_MODULE_SIGNATURE_30 "0"
+#endif
+
+#if (NGX_HTTP_DAV)
+#define NGX_MODULE_SIGNATURE_31 "1"
+#else
+#define NGX_MODULE_SIGNATURE_31 "0"
+#endif
+
+#if (NGX_HTTP_CACHE)
+#define NGX_MODULE_SIGNATURE_32 "1"
+#else
+#define NGX_MODULE_SIGNATURE_32 "0"
+#endif
+
+#if (NGX_HTTP_UPSTREAM_ZONE)
+#define NGX_MODULE_SIGNATURE_33 "1"
+#else
+#define NGX_MODULE_SIGNATURE_33 "0"
+#endif
+
+#define NGX_MODULE_SIGNATURE \
+ NGX_MODULE_SIGNATURE_0 NGX_MODULE_SIGNATURE_1 NGX_MODULE_SIGNATURE_2 \
+ NGX_MODULE_SIGNATURE_3 NGX_MODULE_SIGNATURE_4 NGX_MODULE_SIGNATURE_5 \
+ NGX_MODULE_SIGNATURE_6 NGX_MODULE_SIGNATURE_7 NGX_MODULE_SIGNATURE_8 \
+ NGX_MODULE_SIGNATURE_9 NGX_MODULE_SIGNATURE_10 NGX_MODULE_SIGNATURE_11 \
+ NGX_MODULE_SIGNATURE_12 NGX_MODULE_SIGNATURE_13 NGX_MODULE_SIGNATURE_14 \
+ NGX_MODULE_SIGNATURE_15 NGX_MODULE_SIGNATURE_16 NGX_MODULE_SIGNATURE_17 \
+ NGX_MODULE_SIGNATURE_18 NGX_MODULE_SIGNATURE_19 NGX_MODULE_SIGNATURE_20 \
+ NGX_MODULE_SIGNATURE_21 NGX_MODULE_SIGNATURE_22 NGX_MODULE_SIGNATURE_23 \
+ NGX_MODULE_SIGNATURE_24 NGX_MODULE_SIGNATURE_25 NGX_MODULE_SIGNATURE_26 \
+ NGX_MODULE_SIGNATURE_27 NGX_MODULE_SIGNATURE_28 NGX_MODULE_SIGNATURE_29 \
+ NGX_MODULE_SIGNATURE_30 NGX_MODULE_SIGNATURE_31 NGX_MODULE_SIGNATURE_32 \
+ NGX_MODULE_SIGNATURE_33
+
+
+#define NGX_MODULE_V1 \
+ NGX_MODULE_UNSET_INDEX, NGX_MODULE_UNSET_INDEX, \
+ NULL, 0, 0, nginx_version, NGX_MODULE_SIGNATURE
+
#define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0
@@ -22,12 +247,13 @@
ngx_uint_t ctx_index;
ngx_uint_t index;
+ char *name;
+
ngx_uint_t spare0;
ngx_uint_t spare1;
- ngx_uint_t spare2;
- ngx_uint_t spare3;
ngx_uint_t version;
+ char *signature;
void *ctx;
ngx_command_t *commands;
@@ -63,12 +289,19 @@
ngx_int_t ngx_preinit_modules();
+ngx_int_t ngx_cycle_modules(ngx_cycle_t *cycle);
ngx_int_t ngx_init_modules(ngx_cycle_t *cycle);
ngx_int_t ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type);
+ngx_int_t ngx_add_module(ngx_conf_t *cf, ngx_str_t *file,
+ ngx_module_t *module, char **order);
+
+
extern ngx_module_t *ngx_modules[];
extern ngx_uint_t ngx_max_module;
+extern char *ngx_module_names[];
+
#endif /* _NGX_MODULE_H_INCLUDED_ */