# HG changeset patch # User Maxim Dounin # Date 1454606729 -10800 # Node ID 85dea406e18f2c5e10e0b49f0e3609a3086dd791 # Parent 392959224560acb0dd601344f7edff24d26f7c7f 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 --- 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 @@ if test -n "$CFLAGS"; then sunc) + MAIN_LINK= + MODULE_LINK="-G" + case "$NGX_MACHINE" in i86pc) @@ -156,6 +164,20 @@ if [ "$NGX_PLATFORM" != win32 ]; then 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 --- a/auto/cc/msvc +++ b/auto/cc/msvc @@ -118,6 +118,12 @@ NGX_RCC="rc -fo$NGX_RES \$(CORE_INCS) $N 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 --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -57,6 +57,9 @@ case "$NGX_MACHINE" in esac +MAIN_LINK= +MODULE_LINK="-G" + # optimizations diff --git a/auto/init b/auto/init --- 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 --- a/auto/install +++ b/auto/install @@ -26,6 +26,18 @@ case ".$NGX_SBIN_PATH" in 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 @@ END 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 --- a/auto/lib/conf +++ b/auto/lib/conf @@ -58,11 +58,11 @@ if [ $USE_ZLIB = YES ]; then . 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 @@ if [ $USE_PERL = YES ]; then . 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 --- a/auto/lib/geoip/conf +++ b/auto/lib/geoip/conf @@ -67,7 +67,12 @@ fi 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 --- a/auto/lib/libgd/conf +++ b/auto/lib/libgd/conf @@ -67,7 +67,12 @@ fi 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 --- a/auto/lib/libxslt/conf +++ b/auto/lib/libxslt/conf @@ -76,7 +76,12 @@ fi 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 @@ fi 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 --- a/auto/make +++ b/auto/make @@ -98,9 +98,11 @@ fi # 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 @@ fi # 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 @@ ngx_objs=`echo $ngx_all_objs $ngx_module | 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 @@ fi 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 @@ if test -n "$NGX_PCH"; then 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 +#include + +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 --- a/auto/module +++ b/auto/module @@ -9,7 +9,58 @@ case $ngx_module_type in 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 --- a/auto/modules +++ b/auto/modules @@ -159,6 +159,35 @@ fi 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 @@ if [ $HTTP_CHARSET = YES ]; then . 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 @@ if [ $HTTP_XSLT = YES ]; then . 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 @@ if [ $HTTP_GEO = YES ]; then . 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 @@ if [ $HTTP_STUB_STATUS = YES ]; then fi -if [ $MAIL == YES ]; then +if [ $MAIL != NO ]; then MAIL_MODULES= MAIL_DEPS= MAIL_INCS= @@ -873,6 +902,8 @@ if [ $MAIL == YES ]; then 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 @@ if [ $MAIL == YES ]; then fi -if [ $STREAM = YES ]; then +if [ $STREAM != NO ]; then STREAM_MODULES= STREAM_DEPS= STREAM_INCS= @@ -948,6 +979,8 @@ if [ $STREAM = YES ]; then 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 @@ if test -n "$NGX_ADDONS"; then 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 @@ if test -n "$NGX_ADDONS"; then 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 @@ if [ $USE_OPENSSL = YES ]; then src/event/ngx_event_openssl_stapling.c" ngx_module_libs= ngx_module_link=YES + ngx_module_order= . auto/module fi @@ -1078,6 +1143,7 @@ if [ $USE_PCRE = YES ]; then 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 @@ if [ $HTTP = YES ]; then 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 @@ cat << END }; 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 --- a/auto/options +++ b/auto/options @@ -7,6 +7,7 @@ help=no NGX_PREFIX= NGX_SBIN_PATH= +NGX_MODULES_PATH= NGX_CONF_PREFIX= NGX_CONF_PATH= NGX_ERROR_LOG_PATH= @@ -120,7 +121,11 @@ STREAM_UPSTREAM_HASH=YES 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 @@ NGX_PERL=perl USE_LIBXSLT=NO USE_LIBGD=NO +USE_GEOIP=NO NGX_GOOGLE_PERFTOOLS=NO NGX_CPP_TEST=NO @@ -178,6 +184,7 @@ do --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 @@ do --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 @@ do --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 @@ use the \"--with-mail_ssl_module\" optio --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 @@ use the \"--with-mail_ssl_module\" optio --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 @@ cat << END --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 @@ cat << END --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 @@ cat << END --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 @@ cat << END --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 @@ fi 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 --- a/auto/os/darwin +++ b/auto/os/darwin @@ -14,6 +14,9 @@ CORE_SRCS="$UNIX_SRCS $DARWIN_SRCS" 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 --- a/auto/os/win32 +++ b/auto/os/win32 @@ -12,10 +12,15 @@ OS_CONFIG="$WIN32_CONFIG" 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 --- a/auto/summary +++ b/auto/summary @@ -60,6 +60,7 @@ echo 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 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -24,6 +24,10 @@ static char *ngx_set_cpu_affinity(ngx_co 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 @@ static ngx_command_t ngx_core_commands[ 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 @@ ngx_set_worker_processes(ngx_conf_t *cf, 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 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -212,7 +212,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) 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 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -49,6 +49,8 @@ struct ngx_cycle_s { 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 --- a/src/core/ngx_module.c +++ b/src/core/ngx_module.c @@ -10,7 +10,16 @@ #include -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_preinit_modules() 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_init_modules(ngx_cycle_t *cycle) 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; + } + + 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; } - cycle->modules[i]->ctx_index = max++; + /* 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; + } + + /* + * 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; + } } - return max; + /* + * 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 --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -12,9 +12,234 @@ #include #include +#include + + +#define NGX_MODULE_UNSET_INDEX (ngx_uint_t) -1 -#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 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 @@ struct ngx_module_s { 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 @@ typedef struct { 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_ */