From 402952f18c29b1538d3526956012e0f81890b445 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Thu, 31 May 2012 19:29:48 +0800 Subject: [PATCH 01/36] 1 fix bugs of the limit_req module(please read this issue https://github.com/taobao/tengine/pull/1). 2 refactor some code. --- src/http/modules/ngx_http_limit_req_module.c | 194 ++++++++++--------- 1 file changed, 107 insertions(+), 87 deletions(-) diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c index 87c00b9da1..9f767bf6c1 100644 --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -255,10 +255,11 @@ ngx_http_limit_req_handler(ngx_http_request_t *r) ngx_http_limit_req_conf_t *lrcf; delay_excess = 0; + excess = 0; delay_postion = 0; nodelay = 0; ctx = NULL; - rc = 0; + rc = NGX_DECLINED; if (r->main->limit_req_set) { return NGX_DECLINED; @@ -293,12 +294,12 @@ ngx_http_limit_req_handler(ngx_http_request_t *r) ngx_crc32_final(hash); - r->main->limit_req_set = 1; - ngx_shmtx_lock(&ctx->shpool->mutex); ngx_http_limit_req_expire(r, ctx, 1); + rc = ngx_http_limit_req_lookup(r, &limit_req[i], hash, &excess); + ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "limit_req module: %i %ui.%03ui " "hash is %ui total_len is %i", @@ -342,54 +343,51 @@ ngx_http_limit_req_handler(ngx_http_request_t *r) ngx_shmtx_unlock(&ctx->shpool->mutex); - if (rc == NGX_OK) { - continue; + if (rc == NGX_BUSY || rc == NGX_ERROR) { + break; } - /* need limit request */ + /* NGX_AGAIN or NGX_OK */ + + if (delay_excess < excess) { + delay_excess = excess; + nodelay = limit_req[i].nodelay; + delay_postion = i; + } + } + + r->main->limit_req_set = 1; + + if (rc == NGX_BUSY || rc == NGX_ERROR) { if (rc == NGX_BUSY) { ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, - "limit_req limiting requests, " - "excess: %ui.%03ui by zone \"%V\"", + "limiting requests, excess: %ui.%03ui by zone \"%V\"", excess / 1000, excess % 1000, &limit_req[i].shm_zone->shm.name); + } - if (limit_req[i].forbid_action.len == 0) { - - return NGX_HTTP_SERVICE_UNAVAILABLE; - } else if (limit_req[i].forbid_action.data[0] == '@') { - - ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, - "limiting requests, forbid_action is %V", - &limit_req[i].forbid_action); - (void) ngx_http_named_location(r, &limit_req[i].forbid_action); - - } else { + if (rc == NGX_ERROR || limit_req[i].forbid_action.len == 0) { - ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, - "limiting requests, forbid_action is %V", - &limit_req[i].forbid_action); - (void) ngx_http_internal_redirect(r, - &limit_req[i].forbid_action, - &r->args); - } + return NGX_HTTP_SERVICE_UNAVAILABLE; + } else if (limit_req[i].forbid_action.data[0] == '@') { - ngx_http_finalize_request(r, NGX_DONE); - return NGX_DONE; + ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, + "limiting requests, forbid_action is %V", + &limit_req[i].forbid_action); + (void) ngx_http_named_location(r, &limit_req[i].forbid_action); - } + } else { - if (rc == NGX_AGAIN) { - if (delay_excess < excess) { - delay_excess = excess; - nodelay = limit_req[i].nodelay; - delay_postion = i; - } + ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, + "limiting requests, forbid_action is %V", + &limit_req[i].forbid_action); + (void) ngx_http_internal_redirect(r, + &limit_req[i].forbid_action, + &r->args); } - } - if (rc == 0) { - return NGX_DECLINED; + ngx_http_finalize_request(r, NGX_DONE); + return NGX_DONE; } /* rc = NGX_AGAIN */ @@ -805,7 +803,8 @@ static char * ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; - size_t size, len; + size_t len; + ssize_t size; ngx_str_t *value, name, s; ngx_int_t rate, scale; ngx_uint_t i; @@ -837,25 +836,32 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) p = (u_char *) ngx_strchr(name.data, ':'); - if (p) { - *p = '\0'; + if (p == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } - name.len = p - name.data; + name.len = p - name.data; - p++; + s.data = p + 1; + s.len = value[i].data + value[i].len - s.data; - s.len = value[i].data + value[i].len - p; - s.data = p; + size = ngx_parse_size(&s); - size = ngx_parse_size(&s); - if (size > 8191) { - continue; - } + if (size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; } - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid zone size \"%V\"", &value[i]); - return NGX_CONF_ERROR; + if (size < (ssize_t) (8 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "zone \"%V\" is too small", &value[i]); + return NGX_CONF_ERROR; + } + + continue; } if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { @@ -907,7 +913,7 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - if (name.len == 0 || size == 0) { + if (name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); @@ -917,8 +923,8 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (variables->nelts == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "no variable is defined for limit_req_zone \"%V\"", - &cmd->name); + "no variable is defined for %V \"%V\"", + &cmd->name, &name); return NGX_CONF_ERROR; } @@ -955,35 +961,26 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lrcf = conf; - char *rv; ngx_int_t burst; - ngx_str_t *value, s; - ngx_uint_t i; + ngx_str_t *value, s, forbid_action; + ngx_uint_t i, nodelay; + ngx_shm_zone_t *shm_zone; ngx_http_limit_req_t *limit_req; - if (lrcf->rules == NULL) { - lrcf->rules = ngx_array_create(cf->pool, 5, - sizeof(ngx_http_limit_req_t)); - if (lrcf->rules == NULL) { - return NGX_CONF_ERROR; - } - } - - limit_req = ngx_array_push(lrcf->rules); - if (limit_req == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(limit_req, sizeof(ngx_http_limit_req_t)); - value = cf->args->elts; - if (cf->args->nelts == 2) { - rv = ngx_conf_set_flag_slot(cf, cmd, lrcf); - return rv; + if (ngx_strncmp(value[1].data, "off", 3) == 0) { + lrcf->enable = 0; + return NGX_CONF_OK; + } } + lrcf->enable = 1; + + shm_zone = NULL; burst = 0; + nodelay = 1; + forbid_action.len = 0; for (i = 1; i < cf->args->nelts; i++) { @@ -992,9 +989,9 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) s.len = value[i].len - 5; s.data = value[i].data + 5; - limit_req->shm_zone = ngx_shared_memory_add(cf, &s, 0, - &ngx_http_limit_req_module); - if (limit_req->shm_zone == NULL) { + shm_zone = ngx_shared_memory_add(cf, &s, 0, + &ngx_http_limit_req_module); + if (shm_zone == NULL) { return NGX_CONF_ERROR; } @@ -1024,13 +1021,13 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - limit_req->forbid_action = s; + forbid_action = s; continue; } if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) { - limit_req->nodelay = 1; + nodelay = 1; continue; } @@ -1039,25 +1036,48 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - if (limit_req->shm_zone == NULL) { + if (shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } - if (limit_req->shm_zone->data == NULL) { + if (shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", - &limit_req->shm_zone->shm.name); + &shm_zone->shm.name); return NGX_CONF_ERROR; } - limit_req->burst = burst * 1000; - if (lrcf->enable == NGX_CONF_UNSET) { - lrcf->enable = 1; + if (lrcf->rules == NULL) { + lrcf->rules = ngx_array_create(cf->pool, 5, + sizeof(ngx_http_limit_req_t)); + if (lrcf->rules == NULL) { + return NGX_CONF_ERROR; + } + } + + limit_req = lrcf->rules->elts; + + for (i = 0; i < lrcf->rules->nelts; i++) { + if (shm_zone == limit_req[i].shm_zone) { + return "is duplicate"; + } } + limit_req = ngx_array_push(lrcf->rules); + if (limit_req == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(limit_req, sizeof(ngx_http_limit_req_t)); + + limit_req->shm_zone = shm_zone; + limit_req->burst = burst * 1000; + limit_req->nodelay = nodelay; + limit_req->forbid_action = forbid_action; + return NGX_CONF_OK; } From efe6f857e89e28eb479b616e5f8b8f1fa53020e0 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Fri, 1 Jun 2012 12:00:30 +0800 Subject: [PATCH 02/36] add limit_req module(enhanced) test case. --- tests/nginx-tests/cases/limit_req_enhance.t | 218 ++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 tests/nginx-tests/cases/limit_req_enhance.t diff --git a/tests/nginx-tests/cases/limit_req_enhance.t b/tests/nginx-tests/cases/limit_req_enhance.t new file mode 100644 index 0000000000..aeba8b213c --- /dev/null +++ b/tests/nginx-tests/cases/limit_req_enhance.t @@ -0,0 +1,218 @@ +#!/usr/bin/perl + +# (C) diaoliang + +# Tests for nginx limit_req module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +#select STDERR; $| = 1; +#select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(27); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +master_process off; +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + limit_req_zone $binary_remote_addr zone=one:3m rate=1r/s; + limit_req_zone $binary_remote_addr $uri zone=two:3m rate=1r/s; + limit_req_zone $binary_remote_addr $uri $args zone=thre:3m rate=1r/s; + limit_req_zone $binary_remote_addr zone=long:3m rate=1r/s; + limit_req_zone $binary_remote_addr zone=fast:3m rate=1000r/s; + + limit_req_zone $uri zone=inter:3m rate=1r/s; + + geo $white_ip1 { + default 0; + 127.0.8.9 1; + } + + geo $white_ip2 { + default 0; + 127.0.0.0/24 1; + } + limit_req_whitelist geo_var_name=white_ip1 geo_var_value=1; + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + limit_req zone=one burst=5; + limit_req zone=two forbid_action=@t; + limit_req zone=thre burst=3; + } + + location @t { + rewrite ^ /t.html; + } + + location /one { + limit_req zone=one; + } + location /two { + limit_req zone=two; + } + location /thre { + limit_req zone=thre; + } + location /long { + limit_req zone=long burst=5; + } + location /fast { + limit_req zone=fast burst=1; + } + + location /white { + limit_req_whitelist geo_var_name=white_ip2 geo_var_value=1; + limit_req zone=one; + } + + location /inter { + expires 1h; + limit_req zone=inter forbid_action=/t.html; + } + + location /t.html { + expires 1h; + } + } +} + +EOF + +$t->write_file('one.html', 'XtestX'); +$t->write_file('one2.html', 'XtestX'); +$t->write_file('two.html', 'XtestX'); +$t->write_file('two2.html', 'XtestX'); +$t->write_file('thre.html', 'XtestX'); +$t->write_file('long.html', "1234567890\n" x (1 << 16)); +$t->write_file('fast.html', 'XtestX'); +$t->write_file('collect1.html', 'collect1'); +$t->write_file('collect2.html', 'collect2'); +$t->write_file('t.html', 'test'); +$t->write_file('white.html', 'test'); +$t->write_file('inter.html', 'test'); +$t->run(); + +############################################################################### +like(http_get('/inter.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/inter.html'), qr/test/m, 'request accept'); + +like(http_get('/one.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/two.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/thre.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); + +http_get('/one.html'); +like(http_get('/one2.html'), qr/^HTTP\/1.. 503 /m, 'request rejected'); +http_get('/two.html'); +like(http_get('/two2.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +http_get('/thre.html?a=3'); +like(http_get('/thre.html?a=5'), qr/^HTTP\/1.. 200 /m, 'request accept'); +http_get('/thre.html?a=4'); +like(http_get('/thre.html?a=4'), qr/^HTTP\/1.. 503 /m, 'request rejected'); +http_get('/thre.html'); +like(http_get('/thre.html'), qr/^HTTP\/1.. 200 /m, 'request accpet'); + +# Second request will be delayed by limit_req, make sure it isn't truncated. +# The bug only manifests itself if buffer will be filled, so sleep for a while +# before reading response. + +my $l1 = length(http_get('/long.html')); +my $l2 = length(http_get('/long.html', sleep => 1.1)); +is($l2, $l1, 'delayed big request not truncated'); + +# make sure negative excess values are handled properly + +http_get('/fast.html'); +select (undef, undef, undef, 0.1); +like(http_get('/fast.html'), qr/^HTTP\/1.. 200 /m, 'negative excess'); + +#whitelist +like(http_get('/white.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/white.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); + +#test mutil condition +like(http_get('/collect2.html?a=3'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/collect1.html?a=4'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/collect1.html?a=4', sleep => 1.1), qr/^HTTP\/1.. 200 /m, 'request accept'); + + +like(http_get('/collect1.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/collect2.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); + +like(http_get('/collect1.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/collect1.html'), qr/test/m, 'request accept'); + + +$t->stop(); + + +########################################################################################## + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +master_process off; +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + limit_req_zone $binary_remote_addr zone=one:3m rate=1r/s; + + limit_req zone=one; + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + limit_req off; + } + + location /limit { + } + } +} + +EOF +$t->write_file('switch.html', 'switch'); +$t->write_file('limit.html', 'limit'); + +$t->run(); + +#switch test +like(http_get('/switch.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/switch.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/switch.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/switch.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); + +like(http_get('/limit.html'), qr/^HTTP\/1.. 200 /m, 'request accept'); +like(http_get('/limit.html'), qr/^HTTP\/1.. 503 /m, 'request rejected'); + +$t->stop(); From 361f599111cd8d1683e634f24ecfe154c507a38d Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Mon, 11 Jun 2012 18:13:32 +0800 Subject: [PATCH 03/36] fixed code style. --- src/http/modules/ngx_http_limit_req_module.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c index 9f767bf6c1..6c3055679f 100644 --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -372,15 +372,15 @@ ngx_http_limit_req_handler(ngx_http_request_t *r) } else if (limit_req[i].forbid_action.data[0] == '@') { ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, - "limiting requests, forbid_action is %V", - &limit_req[i].forbid_action); + "limiting requests, forbid_action is %V", + &limit_req[i].forbid_action); (void) ngx_http_named_location(r, &limit_req[i].forbid_action); } else { ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, - "limiting requests, forbid_action is %V", - &limit_req[i].forbid_action); + "limiting requests, forbid_action is %V", + &limit_req[i].forbid_action); (void) ngx_http_internal_redirect(r, &limit_req[i].forbid_action, &r->args); From ab9e7174829bc1e6995bda994de21549e82acd7d Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Mon, 11 Jun 2012 19:34:04 +0800 Subject: [PATCH 04/36] fix compile warning. --- src/http/modules/ngx_http_limit_req_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c index 6c3055679f..8c2ff97ea6 100644 --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -980,7 +980,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) shm_zone = NULL; burst = 0; nodelay = 1; - forbid_action.len = 0; + ngx_str_null(&forbid_action); for (i = 1; i < cf->args->nelts; i++) { From 36f9fe10d827c0a00b29f641e5f19c8ce829f223 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 11 Jul 2012 12:09:44 +0800 Subject: [PATCH 05/36] add Dynamic Shared Object(dso) module. --- auto/cc/conf | 1 + auto/init | 3 + auto/install | 57 ++ auto/lib/conf | 4 +- auto/lib/geoip/conf | 7 +- auto/lib/lua/conf | 16 +- auto/make | 219 ++++++- auto/modules | 222 ++++++- auto/options | 362 +++++++++-- auto/sources | 6 + auto/summary | 4 + auto/unix | 7 + contrib/dso.in | 339 +++++++++++ docs/modules/ngx_dso_module.md | 119 ++++ src/core/nginx.c | 16 +- src/core/ngx_conf_file.h | 11 +- src/core/ngx_cycle.c | 20 + src/core/ngx_cycle.h | 1 + src/core/ngx_dso_module.c | 575 ++++++++++++++++++ tests/nginx-tests/cases/concat.t | 8 + tests/nginx-tests/cases/slice.t | 8 + .../nginx-tests/nginx-tests/lib/Test/Nginx.pm | 25 + .../test-nginx/lib/Test/Nginx/Socket.pm | 9 + .../test-nginx/lib/Test/Nginx/Util.pm | 108 +++- 24 files changed, 2058 insertions(+), 89 deletions(-) create mode 100644 contrib/dso.in create mode 100644 docs/modules/ngx_dso_module.md create mode 100644 src/core/ngx_dso_module.c diff --git a/auto/cc/conf b/auto/cc/conf index 162b37663f..a80d3e9a8d 100644 --- a/auto/cc/conf +++ b/auto/cc/conf @@ -11,6 +11,7 @@ ngx_objout="-o " ngx_binout="-o " ngx_objext="o" ngx_binext= +ngx_soext=".so" ngx_long_start= ngx_long_end= diff --git a/auto/init b/auto/init index 910f5294b6..904065596f 100644 --- a/auto/init +++ b/auto/init @@ -16,6 +16,9 @@ NGX_AUTOCONF_ERR=$NGX_OBJS/autoconf.err NGX_ERR=$NGX_OBJS/autoconf.err MAKEFILE=$NGX_OBJS/Makefile +#dso +NGX_DSO_COMPILE=$NGX_OBJS/dso_tools +NGX_MODULE_ORDER=$NGX_OBJS/module_order NGX_PCH= NGX_USE_PCH= diff --git a/auto/install b/auto/install index f40c104ce4..04469103f7 100644 --- a/auto/install +++ b/auto/install @@ -73,6 +73,16 @@ case ".$NGX_HTTP_LOG_PATH" in esac +case ".$NGX_DSO_PATH" in + ./*) + ;; + + *) + NGX_DSO_PATH=$NGX_PREFIX/$NGX_DSO_PATH + ;; +esac + + if test -f man/nginx.8 ; then NGX_MAN=man/nginx.8 else @@ -96,8 +106,27 @@ $NGX_OBJS/nginx.8: $NGX_MAN $NGX_AUTO_CONFIG_H -e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\ < $NGX_MAN > \$@ +END + +if test -n "$NGX_SHARED_MODULES"; then + +cat << END >> $NGX_MAKEFILE + +install: all \ + $NGX_INSTALL_PERL_MODULES +END + +else +cat << END >> $NGX_MAKEFILE + install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \ $NGX_INSTALL_PERL_MODULES +END + +fi + +cat << END >> $NGX_MAKEFILE + test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX' test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \ @@ -173,6 +202,34 @@ END fi +if [ $NGX_DSO = YES ] ; then + + cat << END >> $NGX_MAKEFILE + test -d '\$(DESTDIR)$NGX_DSO_PATH' \ + || mkdir -p '\$(DESTDIR)$NGX_DSO_PATH' +END + + for ngx_dso_module in $NGX_DSO_ALL_TARGETS + do + cat << END >> $NGX_MAKEFILE + + cp $ngx_dso_module \$(DESTDIR)$NGX_DSO_PATH + +END + done + + cat << END >> $NGX_MAKEFILE + + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/module_order' \ + || cp $NGX_MODULE_ORDER '\$(DESTDIR)$NGX_CONF_PREFIX' + cp $NGX_MODULE_ORDER '\$(DESTDIR)$NGX_CONF_PREFIX/module_order' + chmod 0755 $NGX_DSO_COMPILE + cp $NGX_DSO_COMPILE '$NGX_PREFIX/sbin' +END + +fi + + # create Makefile cat << END >> Makefile diff --git a/auto/lib/conf b/auto/lib/conf index f523df4838..44d20b9b6f 100644 --- a/auto/lib/conf +++ b/auto/lib/conf @@ -70,11 +70,11 @@ if [ $USE_PERL = YES ]; then . auto/lib/perl/conf fi -if [ $HTTP_LUA = YES ]; then +if [ $HTTP_LUA = YES ] || [ $HTTP_LUA_SHARED = YES ]; then . auto/lib/lua/conf fi -if [ $HTTP_GEOIP = YES ]; then +if [ $HTTP_GEOIP = YES ] || [ $HTTP_GEOIP_SHARED = YES ]; then . auto/lib/geoip/conf fi diff --git a/auto/lib/geoip/conf b/auto/lib/geoip/conf index 3764d76497..4c3bc8c175 100644 --- a/auto/lib/geoip/conf +++ b/auto/lib/geoip/conf @@ -64,8 +64,11 @@ fi if [ $ngx_found = yes ]; then - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" - + if [ $HTTP_GEOIP_SHARED = YES ]; then + DSO_LIBS="$DSO_LIBS|$HTTP_GEOIP_MODULE:$ngx_feature_libs" + else + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + fi else cat << END diff --git a/auto/lib/lua/conf b/auto/lib/lua/conf index 8656a2c6a8..a9acddb69c 100644 --- a/auto/lib/lua/conf +++ b/auto/lib/lua/conf @@ -129,8 +129,13 @@ END fi if [ $ngx_found = yes ]; then - CORE_INCS="$CORE_INCS $ngx_feature_path" - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + if [ $HTTP_LUA_SHARED = YES ]; then + DSO_INCS="$DSO_INCS|$NGX_HTTP_LUA_MODULE:$ngx_feature_path" + DSO_LIBS="$DSO_LIBS|$NGX_HTTP_LUA_MODULE:$ngx_feature_libs" + else + CORE_INCS="$CORE_INCS $ngx_feature_path" + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + fi else cat << END $0: error: ngx_http_lua_module requires the Lua library. @@ -150,6 +155,9 @@ ngx_feature_test='printf("hello");' . auto/feature if [ $ngx_found = yes ]; then - CORE_LIBS="-Wl,-E $CORE_LIBS" + if [ $HTTP_LUA_SHARED = YES ]; then + DSO_LIBS="$DSO_LIBS $ngx_feature_libs" + else + CORE_LIBS="-Wl,-E $CORE_LIBS" + fi fi - diff --git a/auto/make b/auto/make index 76f379c0f6..b9d4a791ed 100644 --- a/auto/make +++ b/auto/make @@ -3,6 +3,17 @@ # Copyright (C) Nginx, Inc. +if test -n "$NGX_SHARED_MODULES"; then + if [ $NGX_DSO != YES ]; then + cat << END + +when you use shared modules, you should enable dso module. +END + exit 1 + fi +fi + + echo "creating $NGX_MAKEFILE" mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \ @@ -12,7 +23,8 @@ mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \ $NGX_OBJS/src/http/modules/lua \ $NGX_OBJS/src/mail \ $NGX_OBJS/src/misc \ - $NGX_OBJS/src/proc + $NGX_OBJS/src/proc \ + $NGX_OBJS/dso_modules ngx_objs_dir=$NGX_OBJS$ngx_regex_dirsep @@ -47,6 +59,8 @@ ALL_INCS = $ngx_include_opt$ngx_incs END +dso_all_incs=$ngx_include_opt$ngx_incs + ngx_all_srcs="$CORE_SRCS" @@ -70,6 +84,9 @@ CORE_INCS = $ngx_include_opt$ngx_incs END +dso_core_deps=$ngx_deps +dso_core_incs=$ngx_include_opt$ngx_incs + # the http dependences and include pathes @@ -94,6 +111,9 @@ HTTP_INCS = $ngx_include_opt$ngx_incs END +dso_http_deps=$ngx_deps +dso_http_incs=$ngx_include_opt$ngx_incs + fi @@ -188,6 +208,25 @@ ngx_link=${CORE_LINK:+`echo $CORE_LINK \ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`} +for ngx_shared_modules in $NGX_SHARED_MODULES +do + NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}lib_${ngx_shared_modules}${ngx_soext}" +done + +if test -n "$NGX_DSO_ALL_TARGETS"; then + +ngx_dso_target=`echo $NGX_DSO_ALL_TARGETS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + +cat << END >> $NGX_MAKEFILE + +all: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} $ngx_dso_target + +END + +fi + cat << END >> $NGX_MAKEFILE $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer @@ -417,3 +456,181 @@ $ngx_pch END fi + + +if [ $NGX_DSO = YES ] ; then + + ngx_dso_cflag=" -fPIC " + ngx_dso_link_flag=" -shared " + ngx_dso_index=2 + + ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)" + + for ngx_shared_modules in $NGX_SHARED_MODULES + do + ngx_dso_all_objs= + ngx_dso_srcs=`echo $NGX_SHARED_SRCS \ + | awk -v dso_index=$ngx_dso_index 'BEGIN { FS="|" } {print $dso_index}'` + + for ngx_source in $ngx_dso_srcs + do + ngx_src=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"` + ngx_obj=`echo $ngx_src \ + | 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_dso_all_objs="$ngx_dso_all_objs $ngx_obj" + + done + + ngx_dso_feture_path=`echo $DSO_INCS | awk 'BEGIN { FS="|" } \ + {for (i=1; i<=NF; i++) print $i}' | awk -v module_name=$ngx_shared_modules \ + 'BEGIN { FS=":"} {if ($1 == module_name) print $2}'` + + for ngx_source in $ngx_dso_srcs + do + ngx_src=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"` + ngx_obj=`echo $ngx_src \ + | 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"` + + cat << END >> $NGX_MAKEFILE + +$ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src + $ngx_cc$ngx_dso_cflag $ngx_dso_feture_path$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX + +END + + done + ngx_dso_deps=`echo $ngx_dso_all_objs $ngx_res $LINK_DEPS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + ngx_dso_objs=`echo $ngx_dso_all_objs \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + ngx_dso_link=${CORE_LINK:+`echo $CORE_LINK \ + | sed -e "s/\//$ngx_regex_dirsep%%/g" -e "s/^/$ngx_long_regex_cont/"`} + + ngx_dso_feture_lib=`echo $DSO_LIBS | awk 'BEGIN { FS="|" } \ + {for (i=1; i<=NF; i++) print $i}' | awk -v module_name=$ngx_shared_modules \ + 'BEGIN { FS=":"} {if ($1 == module_name) print $2}'` + + cat << END >> $NGX_MAKEFILE + +$NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}lib_${ngx_shared_modules}${ngx_soext}: $ngx_dso_deps$ngx_spacer + \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/dso_modules${ngx_dirsep}lib_${ngx_shared_modules}${ngx_soext}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib + $ngx_rcc +${ngx_long_end} +END + + ngx_dso_index=$(($ngx_dso_index+1)) + done + + core_deps_temp= + core_incs_temp= + http_deps_temp= + http_incs_temp= + all_incs_temp= + + for dai in $dso_all_incs + do + if [ "$dai" = "-I" ]; then + all_incs_temp="$all_incs_temp $dai" + elif [ "$dai" = "\\" ]; then + all_incs_temp="$all_incs_temp \\" + elif test -n "$dai"; then + all_incs_temp="$all_incs_temp $dai" + fi + done + + for cdep in $dso_core_deps + do + if test -n "$cdep"; then + core_deps_temp="$core_deps_temp $cdep" + fi + done + + for dci in $dso_core_incs + do + if [ "$dci" = "-I" ]; then + core_incs_temp="$core_incs_temp $dci" + elif [ "$dci" = "\\" ]; then + core_incs_temp="$core_incs_temp \\" + elif test -n "$dci"; then + core_incs_temp="$core_incs_temp $dci" + fi + done + + for hdep in $dso_http_deps + do + if test -n "$hdep"; then + http_deps_temp="$http_deps_temp $hdep" + fi + done + + for dhi in $dso_http_incs + do + if [ "$dhi" = "-I" ]; then + http_incs_temp="$http_incs_temp $dhi" + elif [ "$dhi" = "\\" ]; then + http_incs_temp="$http_incs_temp \\" + elif test -n "$dhi"; then + http_incs_temp="$http_incs_temp $dhi" + fi + done + + cat << END > $NGX_DSO_COMPILE +#!/bin/sh + +ngx_soext='.so' +CC=$CC +CFLAGS='$CFLAGS -fPIC' +CPP='$CPP' +LINK='$LINK -fPIC -shared' + + +CORE_LIBS='$CORE_LIBS' +CORE_LINK='$ngx_link' + +NGX_LD_OPT='$NGX_LD_OPT' +NGX_PREFIX=$NGX_PREFIX + +ngx_regex_dirsep='$ngx_regex_dirsep' +ngx_cont='$ngx_cont' +ngx_cc='$ngx_cc' +ngx_tab='$ngx_tab' +ngx_objout='$ngx_objout' +NGX_AUX='$NGX_AUX' +ngx_long_regex_cont='$ngx_long_regex_cont' +ngx_dirsep='$ngx_dirsep' +ngx_binext='$ngx_binext' +ngx_long_start='$ngx_long_start' +ngx_long_cont='$ngx_long_cont' +ngx_rcc='$ngx_rcc' +ngx_spacer='$ngx_spacer' +ngx_objext='$ngx_objext' +ngx_regex_cont='$ngx_regex_cont' +ngx_binout='$ngx_binout' +ngx_binout='$ngx_binout' +NGX_DSO_PATH=$NGX_DSO_PATH +NGX_AUTOCONF_ERR=$NGX_AUTOCONF_ERR +NGX_AUTOTEST=$NGX_AUTOTEST +NGX_AUTO_CONFIG_H=$NGX_AUTO_CONFIG_H + +END + + sed -e "s|%%ALL_INCS%%|'$all_incs_temp'|g" \ + -e "s|%%CORE_DEPS%%|'$core_deps_temp'|g" \ + -e "s|%%CORE_INCS%%|'$core_incs_temp'|g" \ + -e "s|%%HTTP_DEPS%%|'$http_deps_temp'|g" \ + -e "s|%%HTTP_INCS%%|'$http_incs_temp'|g" \ + -e "s|%%NGX_SOURCE_HOME%%|`pwd`|g" \ + -e "s|%%ngx_soext%%|'\.so'|g" \ + contrib/dso.in >> $NGX_DSO_COMPILE +fi diff --git a/auto/modules b/auto/modules index d8cbedee78..69f1f556e1 100644 --- a/auto/modules +++ b/auto/modules @@ -61,6 +61,17 @@ if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then fi +if [ $NGX_DSO = YES ] ; then + have=NGX_DSO . auto/have + have=NGX_DSO_MAX value="$NGX_DSO_MAX" . auto/define + have=NGX_DSO_PATH value="\"$NGX_DSO_PATH\"" . auto/define + CORE_MODULES="$CORE_MODULES $DSO_MODULE" + CORE_SRCS="$CORE_SRCS $DSO_SRCS" + CORE_LIBS="$CORE_LIBS $NGX_LIBDL" + LINK="$LINK -rdynamic" +fi + + if [ $PROCS = YES ]; then have=NGX_PROCS . auto/have CORE_SRCS="$CORE_SRCS $PROCS_SRCS" @@ -156,38 +167,75 @@ if [ $HTTP_CHARSET = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS" fi +if [ $HTTP_CHARSET_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_CHARSET_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_CHARSET_SRCS" +fi + if [ $HTTP_XSLT = YES ]; then USE_LIBXSLT=YES HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_XSLT_SRCS" fi +if [ $HTTP_XSLT_SHARED = YES ]; then + USE_LIBXSLT=YES + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_XSLT_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_XSLT_SRCS" +fi + if [ $HTTP_IMAGE_FILTER = YES ]; then USE_LIBGD=YES HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_IMAGE_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_IMAGE_SRCS" fi +if [ $HTTP_IMAGE_FILTER_SHARED = YES ]; then + USE_LIBGD=YES + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_IMAGE_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_IMAGE_SRCS" +fi + if [ $HTTP_SUB = YES ]; then HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SUB_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_SUB_SRCS" fi +if [ $HTTP_SUB_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_SUB_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_SUB_SRCS" +fi + if [ $HTTP_ADDITION = YES ]; then HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_ADDITION_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_ADDITION_SRCS" fi +if [ $HTTP_ADDITION_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_ADDITION_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_ADDITION_SRCS" +fi + if [ $HTTP_USERID = YES ]; then HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_USERID_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS" fi +if [ $HTTP_USERID_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_USERID_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_USERID_SRCS" +fi + if [ $HTTP_FOOTER = YES ]; then HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_FOOTER_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_FOOTER_FILTER_SRCS" fi +if [ $HTTP_FOOTER_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_FOOTER_FILTER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_FOOTER_FILTER_SRCS" +fi + HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE" if [ $HTTP_GZIP_STATIC = YES ]; then @@ -207,6 +255,11 @@ if [ $HTTP_AUTOINDEX = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_AUTOINDEX_SRCS" fi +if [ $HTTP_AUTOINDEX_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_AUTOINDEX_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_AUTOINDEX_SRCS" +fi + HTTP_MODULES="$HTTP_MODULES $HTTP_INDEX_MODULE" if [ $HTTP_RANDOM_INDEX = YES ]; then @@ -214,11 +267,21 @@ if [ $HTTP_RANDOM_INDEX = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_RANDOM_INDEX_SRCS" fi +if [ $HTTP_RANDOM_INDEX_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_RANDOM_INDEX_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_RANDOM_INDEX_SRCS" +fi + if [ $HTTP_CONCAT = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_CONCAT_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_CONCAT_SRCS" fi +if [ $HTTP_CONCAT_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_CONCAT_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_CONCAT_SRCS" +fi + if [ $HTTP_AUTH_BASIC = YES ]; then USE_MD5=YES USE_SHA1=YES @@ -233,16 +296,31 @@ if [ $HTTP_ACCESS = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS" fi +if [ $HTTP_ACCESS_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_ACCESS_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_ACCESS_SRCS" +fi + if [ $HTTP_LIMIT_CONN = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_CONN_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_CONN_SRCS" fi +if [ $HTTP_LIMIT_CONN_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_LIMIT_CONN_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_LIMIT_CONN_SRCS" +fi + if [ $HTTP_LIMIT_REQ = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_REQ_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_REQ_SRCS" fi +if [ $HTTP_LIMIT_REQ_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_LIMIT_REQ_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_LIMIT_REQ_SRCS" +fi + if [ $HTTP_REALIP = YES ]; then have=NGX_HTTP_REALIP . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_REALIP_MODULE" @@ -254,6 +332,11 @@ if [ $HTTP_STATUS = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_STATUS_SRCS" fi +if [ $HTTP_STATUS_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_STATUS_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_STATUS_SRCS" +fi + if [ $HTTP_GEO = YES ]; then have=NGX_HTTP_GEO . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_GEO_MODULE" @@ -265,27 +348,53 @@ if [ $HTTP_GEOIP = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS" fi +if [ $HTTP_GEOIP_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_GEOIP_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_GEOIP_SRCS" +fi + if [ $HTTP_MAP = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_MAP_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_MAP_SRCS" fi +if [ $HTTP_MAP_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_MAP_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_MAP_SRCS" +fi + if [ $HTTP_SPLIT_CLIENTS = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_SPLIT_CLIENTS_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_SPLIT_CLIENTS_SRCS" fi +if [ $HTTP_SPLIT_CLIENTS_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_SPLIT_CLIENTS_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_SPLIT_CLIENTS_SRCS" +fi + if [ $HTTP_REFERER = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_REFERER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_REFERER_SRCS" fi +if [ $HTTP_REFERER_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_REFERER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_REFERER_SRCS" +fi + if [ $HTTP_REWRITE = YES -a $USE_PCRE != DISABLED ]; then USE_PCRE=YES HTTP_MODULES="$HTTP_MODULES $HTTP_REWRITE_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_REWRITE_SRCS" fi +if [ $HTTP_REWRITE_SHARED = YES -a $USE_PCRE != DISABLED ]; then + USE_PCRE=YES + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_REWRITE_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_REWRITE_SRCS" +fi + if [ $HTTP_SSL = YES ]; then USE_OPENSSL=YES have=NGX_HTTP_SSL . auto/have @@ -307,16 +416,31 @@ if [ $HTTP_FASTCGI = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_FASTCGI_SRCS" fi +if [ $HTTP_FASTCGI_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_FASTCGI_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_FASTCGI_SRCS" +fi + if [ $HTTP_UWSGI = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_UWSGI_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_UWSGI_SRCS" fi +if [ $HTTP_UWSGI_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_UWSGI_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_UWSGI_SRCS" +fi + if [ $HTTP_SCGI = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_SCGI_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_SCGI_SRCS" fi +if [ $HTTP_SCGI_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_SCGI_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_SCGI_SRCS" +fi + if [ $HTTP_PERL = YES ]; then USE_PERL=YES HTTP_MODULES="$HTTP_MODULES $HTTP_PERL_MODULE" @@ -326,39 +450,73 @@ if [ $HTTP_PERL = YES ]; then fi if [ $HTTP_LUA = YES ]; then - USE_MD5=YES - USE_SHA1=YES + USE_MD5=YES + USE_SHA1=YES HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES $NGX_HTTP_LUA_MODULE" HTTP_DEPS="$HTTP_DEPS $NGX_HTTP_LUA_MODULE_DEPS" HTTP_SRCS="$HTTP_SRCS $NGX_HTTP_LUA_MODULE_SRCS" fi +if [ $HTTP_LUA_SHARED = YES ]; then + USE_MD5=YES + USE_SHA1=YES + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $NGX_HTTP_LUA_MODULE" + HTTP_DEPS="$HTTP_DEPS $NGX_HTTP_LUA_MODULE_DEPS" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$NGX_HTTP_LUA_MODULE_SRCS" +fi + if [ $HTTP_MEMCACHED = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_MEMCACHED_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_MEMCACHED_SRCS" fi +if [ $HTTP_MEMCACHED_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_MEMCACHED_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_MEMCACHED_SRCS" +fi + if [ $HTTP_EMPTY_GIF = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_EMPTY_GIF_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_EMPTY_GIF_SRCS" fi +if [ $HTTP_EMPTY_GIF_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_EMPTY_GIF_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_EMPTY_GIF_SRCS" +fi + if [ $HTTP_BROWSER = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_BROWSER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_BROWSER_SRCS" fi +if [ $HTTP_BROWSER_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_BROWSER_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_BROWSER_SRCS" +fi + if [ $HTTP_USER_AGENT = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_USER_AGENT_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_USER_AGENT_SRCS" fi +if [ $HTTP_USER_AGENT_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_USER_AGENT_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_USER_AGENT_SRCS" +fi + if [ $HTTP_SECURE_LINK = YES ]; then USE_MD5=YES HTTP_MODULES="$HTTP_MODULES $HTTP_SECURE_LINK_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_SECURE_LINK_SRCS" fi +if [ $HTTP_SECURE_LINK_SHARED = YES ]; then + USE_MD5=YES + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_SECURE_LINK_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_SECURE_LINK_SRCS" +fi + if [ $HTTP_DEGRADATION = YES ]; then have=NGX_HTTP_DEGRADATION . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_DEGRADATION_MODULE" @@ -370,26 +528,51 @@ if [ $HTTP_SYSGUARD = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_SYSGUARD_SRCS" fi +if [ $HTTP_SYSGUARD_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_SYSGUARD_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_SYSGUARD_SRCS" +fi + if [ $HTTP_FLV = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_FLV_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS" fi +if [ $HTTP_FLV_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_FLV_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_FLV_SRCS" +fi + if [ $HTTP_SLICE = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_SLICE_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_SLICE_SRCS" fi +if [ $HTTP_SLICE_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_SLICE_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_SLICE_SRCS" +fi + if [ $HTTP_MP4 = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_MP4_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_MP4_SRCS" fi +if [ $HTTP_MP4_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_MP4_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_MP4_SRCS" +fi + if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS" fi +if [ $HTTP_UPSTREAM_IP_HASH_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_UPSTREAM_IP_HASH_SRCS" +fi + if [ $HTTP_UPSTREAM_CHECK = YES ]; then have=NGX_HTTP_UPSTREAM_CHECK . auto/have HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_CHECK_MODULE" @@ -545,6 +728,15 @@ do echo " &$mod," >> $NGX_MODULES_C done +if [ $NGX_DSO = YES ] ; then + + for i in `seq 1 $NGX_DSO_MAX` + do + echo ' NULL,' >> $NGX_MODULES_C + done + +fi + echo ' NULL' >> $NGX_MODULES_C echo '};' >> $NGX_MODULES_C @@ -561,3 +753,29 @@ cat << END >> $NGX_MODULES_C }; END + +if [ $NGX_DSO = YES ] ; then + echo >> $NGX_MODULES_C + echo 'const char *ngx_all_module_names[] = {' >> $NGX_MODULES_C + + for mod in $NGX_ALL_MODULES + do + echo " \"$mod\"," >> $NGX_MODULES_C + done + + cat << END >> $NGX_MODULES_C + NULL +}; + +END + + + echo 'dso_order {' > $NGX_MODULE_ORDER + + for mod in $NGX_ALL_MODULES + do + echo " $mod;" >> $NGX_MODULE_ORDER + done + echo '}' >> $NGX_MODULE_ORDER + +fi diff --git a/auto/options b/auto/options index f679101144..796eef42ec 100644 --- a/auto/options +++ b/auto/options @@ -15,6 +15,9 @@ NGX_LOCK_PATH= NGX_USER= NGX_GROUP= +NGX_DSO_PATH= +NGX_SOURCE_PATH=`pwd` + CC=${CC:-gcc} CPP= NGX_OBJS=objs @@ -47,6 +50,81 @@ USE_THREADS=NO NGX_FILE_AIO=NO NGX_IPV6=NO +NGX_DSO=YES +NGX_DSO_MAX=128 +NGX_ALL_MODULES=" + ngx_core_module + ngx_errlog_module + ngx_conf_module + ngx_events_module + ngx_event_core_module + ngx_epoll_module + ngx_openssl_module + ngx_http_module + ngx_http_core_module + ngx_http_log_module + ngx_http_upstream_module + 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_concat_module + ngx_http_auth_basic_module + ngx_http_access_module + ngx_http_limit_conn_module + ngx_http_limit_req_module + ngx_http_realip_module + ngx_http_geo_module + ngx_http_geoip_module + ngx_http_map_module + ngx_http_split_clients_module + ngx_http_referer_module + ngx_http_rewrite_module + ngx_http_ssl_module + ngx_http_proxy_module + ngx_http_fastcgi_module + ngx_http_uwsgi_module + ngx_http_scgi_module + ngx_http_memcached_module + ngx_http_empty_gif_module + ngx_http_browser_module + ngx_http_user_agent_module + ngx_http_secure_link_module + ngx_http_degradation_module + ngx_http_sysguard_module + ngx_http_flv_module + ngx_http_slice_module + ngx_http_mp4_module + ngx_http_upstream_ip_hash_module + ngx_http_stub_status_module + ngx_http_write_filter_module + ngx_http_header_filter_module + ngx_http_chunked_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_userid_filter_module + ngx_http_footer_filter_module + ngx_http_headers_filter_module + ngx_http_copy_filter_module + ngx_http_range_body_filter_module + ngx_http_not_modified_filter_module" +# dso shared +NGX_SHARED_MODULES= +NGX_SHARED_SRCS= +NGX_SHARED_LIBS= +NGX_SHARED_PATH= +NGX_DSO_ALL_TARGETS= + + HTTP=YES NGX_HTTP_LOG_PATH= @@ -108,6 +186,41 @@ HTTP_UPSTREAM_KEEPALIVE=YES # STUB HTTP_STUB_STATUS=NO +#shared module +HTTP_XSLT_SHARED=NO +HTTP_IMAGE_FILTER_SHARED=NO +HTTP_SUB_SHARED=NO +HTTP_ADDITION_SHARED=NO +HTTP_CONCAT_SHARED=NO +HTTP_RANDOM_INDEX_SHARED=NO +HTTP_GEOIP_SHARED=NO +HTTP_LUA_SHARED=NO +HTTP_SECURE_LINK_SHARED=NO +HTTP_SYSGUARD_SHARED=NO +HTTP_FLV_SHARED=NO +HTTP_SLICE_SHARED=NO +HTTP_MP4_SHARED=NO +HTTP_CHARSET_SHARED=NO +HTTP_USERID_SHARED=NO +HTTP_FOOTER_SHARED=NO +HTTP_ACCESS_SHARED=NO +HTTP_AUTOINDEX_SHARED=NO +HTTP_STATUS_SHARED=NO +HTTP_MAP_SHARED=NO +HTTP_SPLIT_CLIENTS_SHARED=NO +HTTP_REFERER_SHARED=NO +HTTP_REWRITE_SHARED=NO +HTTP_FASTCGI_SHARED=NO +HTTP_UWSGI_SHARED=NO +HTTP_SCGI_SHARED=NO +HTTP_MEMCACHED_SHARED=NO +HTTP_LIMIT_CONN_SHARED=NO +HTTP_LIMIT_REQ_SHARED=NO +HTTP_EMPTY_GIF_SHARED=NO +HTTP_BROWSER_SHARED=NO +HTTP_USER_AGENT_SHARED=NO +HTTP_UPSTREAM_IP_HASH_SHARED=NO + MAIL=NO MAIL_SSL=NO MAIL_POP3=YES @@ -178,67 +291,147 @@ do esac case "$option" in - --help) help=yes ;; + --help) help=yes ;; + + --prefix=) NGX_PREFIX="!" ;; + --prefix=*) NGX_PREFIX="$value" ;; + --sbin-path=*) NGX_SBIN_PATH="$value" ;; + --conf-path=*) NGX_CONF_PATH="$value" ;; + --error-log-path=*) NGX_ERROR_LOG_PATH="$value";; + --pid-path=*) NGX_PID_PATH="$value" ;; + --lock-path=*) NGX_LOCK_PATH="$value" ;; + --user=*) NGX_USER="$value" ;; + --group=*) NGX_GROUP="$value" ;; - --prefix=) NGX_PREFIX="!" ;; - --prefix=*) NGX_PREFIX="$value" ;; - --sbin-path=*) NGX_SBIN_PATH="$value" ;; - --conf-path=*) NGX_CONF_PATH="$value" ;; - --error-log-path=*) NGX_ERROR_LOG_PATH="$value";; - --pid-path=*) NGX_PID_PATH="$value" ;; - --lock-path=*) NGX_LOCK_PATH="$value" ;; - --user=*) NGX_USER="$value" ;; - --group=*) NGX_GROUP="$value" ;; + --dso-path=*) NGX_DSO_PATH="$value" ;; - --crossbuild=*) NGX_PLATFORM="$value" ;; + --crossbuild=*) NGX_PLATFORM="$value" ;; - --builddir=*) NGX_OBJS="$value" ;; + --builddir=*) NGX_OBJS="$value" ;; - --with-rtsig_module) EVENT_RTSIG=YES ;; - --with-select_module) EVENT_SELECT=YES ;; - --without-select_module) EVENT_SELECT=NONE ;; - --with-poll_module) EVENT_POLL=YES ;; - --without-poll_module) EVENT_POLL=NONE ;; - --with-aio_module) EVENT_AIO=YES ;; + --with-rtsig_module) EVENT_RTSIG=YES ;; + --with-select_module) EVENT_SELECT=YES ;; + --without-select_module) EVENT_SELECT=NONE ;; + --with-poll_module) EVENT_POLL=YES ;; + --without-poll_module) EVENT_POLL=NONE ;; + --with-aio_module) EVENT_AIO=YES ;; - #--with-threads=*) USE_THREADS="$value" ;; - #--with-threads) USE_THREADS="pthreads" ;; + #--with-threads=*) USE_THREADS="$value" ;; + #--with-threads) USE_THREADS="pthreads" ;; # PROCS - --without-procs) PROCS=NO ;; - - --with-file-aio) NGX_FILE_AIO=YES ;; - --with-ipv6) NGX_IPV6=YES ;; - --with-syslog) NGX_SYSLOG=YES ;; - - --without-http) HTTP=NO ;; - --without-http-cache) HTTP_CACHE=NO ;; - - --http-log-path=*) NGX_HTTP_LOG_PATH="$value" ;; - --http-client-body-temp-path=*) NGX_HTTP_CLIENT_TEMP_PATH="$value" ;; - --http-proxy-temp-path=*) NGX_HTTP_PROXY_TEMP_PATH="$value" ;; - --http-fastcgi-temp-path=*) NGX_HTTP_FASTCGI_TEMP_PATH="$value" ;; - --http-uwsgi-temp-path=*) NGX_HTTP_UWSGI_TEMP_PATH="$value" ;; - --http-scgi-temp-path=*) NGX_HTTP_SCGI_TEMP_PATH="$value" ;; - - --with-http_ssl_module) HTTP_SSL=YES ;; - --with-http_realip_module) HTTP_REALIP=YES ;; - --with-http_addition_module) HTTP_ADDITION=YES ;; - --with-http_xslt_module) HTTP_XSLT=YES ;; - --with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;; - --with-http_geoip_module) HTTP_GEOIP=YES ;; - --with-http_sub_module) HTTP_SUB=YES ;; - --with-http_dav_module) HTTP_DAV=YES ;; - --with-http_flv_module) HTTP_FLV=YES ;; - --with-http_slice_module) HTTP_SLICE=YES ;; - --with-http_mp4_module) HTTP_MP4=YES ;; - --with-http_gzip_static_module) HTTP_GZIP_STATIC=YES ;; - --with-http_concat_module) HTTP_CONCAT=YES ;; - --with-http_random_index_module) HTTP_RANDOM_INDEX=YES ;; - --with-http_secure_link_module) HTTP_SECURE_LINK=YES ;; - --with-http_degradation_module) HTTP_DEGRADATION=YES ;; - --with-http_sysguard_module) HTTP_SYSGUARD=YES ;; - --with-http_upstream_check_module) HTTP_UPSTREAM_CHECK=YES ;; + --without-procs) PROCS=NO ;; + + --with-file-aio) NGX_FILE_AIO=YES ;; + --with-ipv6) NGX_IPV6=YES ;; + --with-syslog) NGX_SYSLOG=YES ;; + + --without-dso) NGX_DSO=NO ;; + + --without-http) HTTP=NO ;; + --without-http-cache) HTTP_CACHE=NO ;; + + --http-log-path=*) NGX_HTTP_LOG_PATH="$value" ;; + --http-client-body-temp-path=*) NGX_HTTP_CLIENT_TEMP_PATH="$value" ;; + --http-proxy-temp-path=*) NGX_HTTP_PROXY_TEMP_PATH="$value" ;; + --http-fastcgi-temp-path=*) NGX_HTTP_FASTCGI_TEMP_PATH="$value" ;; + --http-uwsgi-temp-path=*) NGX_HTTP_UWSGI_TEMP_PATH="$value" ;; + --http-scgi-temp-path=*) NGX_HTTP_SCGI_TEMP_PATH="$value" ;; + + --with-http_ssl_module) HTTP_SSL=YES ;; + --with-http_realip_module) HTTP_REALIP=YES ;; + --with-http_addition_module) HTTP_ADDITION=YES + HTTP_ADDITION_SHARED=NO ;; + --with-http_xslt_module) HTTP_XSLT=YES + HTTP_XSLT_SHARED=NO ;; + --with-http_image_filter_module) HTTP_IMAGE_FILTER=YES + HTTP_IMAGE_FILTER_SHARED=NO ;; + --with-http_geoip_module) HTTP_GEOIP=YES + HTTP_GEOIP_SHARED=NO ;; + --with-http_sub_module) HTTP_SUB=YES + HTTP_SUB_SHARED=NO ;; + --with-http_dav_module) HTTP_DAV=YES ;; + --with-http_flv_module) HTTP_FLV=YES + HTTP_FLV_SHARED=NO ;; + --with-http_slice_module) HTTP_SLICE=YES + HTTP_SLICE_SHARED=NO ;; + --with-http_mp4_module) HTTP_MP4=YES + HTTP_MP4_SHARED=NO ;; + --with-http_gzip_static_module) HTTP_GZIP_STATIC=YES ;; + --with-http_concat_module) HTTP_CONCAT=YES + HTTP_CONCAT_SHARED=NO ;; + --with-http_random_index_module) HTTP_RANDOM_INDEX=YES + HTTP_RANDOM_INDEX_SHARED=NO ;; + --with-http_secure_link_module) HTTP_SECURE_LINK=YES + HTTP_SECURE_LINK_SHARED=NO ;; + --with-http_degradation_module) HTTP_DEGRADATION=YES ;; + --with-http_sysguard_module) HTTP_SYSGUARD=YES + HTTP_SYSGUARD_SHARED=NO ;; + --with-http_upstream_check_module) HTTP_UPSTREAM_CHECK=YES ;; + + --with-http_addition_module=shared) HTTP_ADDITION_SHARED=YES + HTTP_ADDITION=NO ;; + --with-http_xslt_module=shared) HTTP_XSLT_SHARED=YES + HTTP_XSL=NO ;; + --with-http_image_filter_module=shared) HTTP_IMAGE_FILTER_SHARED=YES + HTTP_IMAGE_FILTER=NO ;; + --with-http_geoip_module=shared) HTTP_GEOIP_SHARED=YES + HTTP_GEOIP=NO ;; + --with-http_sub_module=shared) HTTP_SUB_SHARED=YES + HTTP_SUB=NO ;; + --with-http_flv_module=shared) HTTP_FLV_SHARED=YES + HTTP_FLV=NO ;; + --with-http_slice_module=shared) HTTP_SLICE_SHARED=YES + HTTP_SLICE=NO ;; + --with-http_mp4_module=shared) HTTP_MP4_SHARED=YES + HTTP_MP4=NO ;; + --with-http_concat_module=shared) HTTP_CONCAT_SHARED=YES + HTTP_CONCAT=NO ;; + --with-http_random_index_module=shared) HTTP_RANDOM_INDEX_SHARED=YES + HTTP_RANDOM_INDEX=NO ;; + --with-http_secure_link_module=shared) HTTP_SECURE_LINK_SHARED=YES + HTTP_SECURE_LINK=NO ;; + --with-http_sysguard_module=shared) HTTP_SYSGUARD_SHARED=YES + HTTP_SYSGUARD=NO ;; + --with-http_charset_filter_module=shared) HTTP_CHARSET_SHARED=YES + HTTP_CHARSET=NO ;; + --with-http_userid_filter_module=shared) HTTP_USERID_SHARED=YES + HTTP_USERID=NO ;; + --with-http_footer_filter_module=shared) HTTP_FOOTER_SHARED=YES + HTTP_FOOTER=NO ;; + --with-http_access_module=shared) HTTP_ACCESS_SHARED=YES + HTTP_ACCESS=NO ;; + --with-http_autoindex_module=shared) HTTP_AUTOINDEX_SHARED=YES + HTTP_AUTOINDEX=NO ;; + --with-http_map_module=shared) HTTP_MAP_SHARED=YES + HTTP_MAP=NO ;; + --with-http_split_clients_module=shared) HTTP_SPLIT_CLIENTS_SHARED=YES + HTTP_SPLIT_CLIENTS=NO ;; + --with-http_referer_module=shared) HTTP_REFERER_SHARED=YES + HTTP_REFERER=NO ;; + --with-http_rewrite_module=shared) HTTP_REWRITE_SHARED=YES + HTTP_REWRITE=NO ;; + --with-http_fastcgi_module=shared) HTTP_FASTCGI_SHARED=YES + HTTP_FASTCGI=NO ;; + --with-http_uwsgi_module=shared) HTTP_UWSGI_SHARED=YES + HTTP_UWSGI=NO ;; + --with-http_scgi_module=shared) HTTP_SCGI_SHARED=YES + HTTP_SCGI=NO ;; + --with-http_memcached_module=shared) HTTP_MEMCACHED_SHARED=YES + HTTP_MEMCACHED=NO ;; + --with-http_limit_conn_module=shared) HTTP_LIMIT_CONN_SHARED=YES + HTTP_LIMIT_CONN=NO ;; + --with-http_limit_req_module=shared) HTTP_LIMIT_REQ_SHARED=YES + HTTP_LIMIT_REQ=NO ;; + --with-http_empty_gif_module=shared) HTTP_EMPTY_GIF_SHARED=YES + HTTP_EMPTY_GIF=NO ;; + --with-http_browser_module=shared) HTTP_BROWSER_SHARED=YES + HTTP_BROWSER=NO ;; + --with-http_user_agent_module=shared) HTTP_USER_AGENT_SHARED=YES + HTTP_USER_AGENT=NO ;; + --with-http_upstream_ip_hash_module=shared) + HTTP_UPSTREAM_IP_HASH_SHARED=YES + HTTP_UPSTREAM_IP_HASH=NO ;; --without-http_charset_module) HTTP_CHARSET=NO ;; --without-http_gzip_module) HTTP_GZIP=NO ;; @@ -278,13 +471,15 @@ use the \"--without-http_limit_conn_module\" option instead" --with-perl=*) NGX_PERL="$value" ;; --with-http_lua_module) HTTP_LUA=YES ;; + --with-http_lua_module=shared) HTTP_LUA_SHARED=YES + HTTP_LUA=NO ;; --with-luajit-inc=*) LUAJIT_INC="$value" ;; --with-luajit-lib=*) LUAJIT_LIB="$value" ;; --with-lua-inc=*) LUA_INC="$value" ;; --with-lua-lib=*) LUA_LIB="$value" ;; # STUB - --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;; + --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;; --with-mail) MAIL=YES ;; --with-mail_ssl_module) MAIL_SSL=YES ;; @@ -369,6 +564,8 @@ cat << END --builddir=DIR set build directory + --dso-path=*) set dso default load path + --with-rtsig_module enable rtsig module --with-select_module enable select module --without-select_module disable select module @@ -381,13 +578,15 @@ cat << END --with-ipv6 enable IPv6 support --with-syslog enable syslog logging + --without-dso disable dso module load + --with-http_ssl_module enable ngx_http_ssl_module --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_addition_module enable ngx_http_addition_filter_module + --with-http_xslt_module enable ngx_http_xslt_filter_module --with-http_image_filter_module enable ngx_http_image_filter_module --with-http_geoip_module enable ngx_http_geoip_module - --with-http_sub_module enable ngx_http_sub_module + --with-http_sub_module enable ngx_http_sub_filter_module --with-http_dav_module enable ngx_http_dav_module --with-http_flv_module enable ngx_http_flv_module --with-http_slice_module enable ngx_http_slice_module @@ -401,17 +600,50 @@ cat << END --with-http_stub_status_module enable ngx_http_stub_status_module --with-http_upstream_check_module enable ngx_http_upstream_check_module - --without-http_charset_module disable ngx_http_charset_module - --without-http_gzip_module disable ngx_http_gzip_module + --with-http_charset_filter_module=shared + enable ngx_http_charset_filter_module(shared) + --with-http_userid_filter_module=shared + enable ngx_http_userid_filter_module(shared) + --with-http_footer_filter_module=shared + enable ngx_http_footer_filter_module(shared) + --with-http_access_module=shared enable ngx_http_access_module(shared) + --with-http_autoindex_module=shared + enable ngx_http_autoindex_module(shared) + --with-http_map_module=shared enable ngx_http_map_module(shared) + --with-http_split_clients_module=shared + enable ngx_http_split_clients_module(shared) + --with-http_referer_module=shared enable ngx_http_referer_module(shared) + --with-http_rewrite_module=shared enable ngx_http_rewrite_module(shared) + --with-http_fastcgi_module=shared enable ngx_http_fastcgi_module(shared) + --with-http_uwsgi_module=shared enable ngx_http_uwsgi_module(shared) + --with-http_scgi_module=shared enable ngx_http_scgi_module(shared) + --with-http_memcached_module=shared + enable ngx_http_memcached_module(shared) + --with-http_limit_conn_module=shared + enable ngx_http_limit_conn_module(shared) + --with-http_limit_req_module=shared + enable ngx_http_limit_req_module(shared) + --with-http_empty_gif_module=shared + enable ngx_http_empty_gif_module(shared) + --with-http_browser_module=shared enable ngx_http_browser_module(shared) + --with-http_user_agent_module=shared + enable ngx_http_user_agent_module(shared) + --with-http_upstream_ip_hash_module=shared + enable ngx_http_upstream_ip_hash_module(shared) + + --without-http_charset_module disable ngx_http_charset_filter_module + --without-http_gzip_module disable ngx_http_gzip_filter_module --without-http_ssi_module disable ngx_http_ssi_module - --without-http_userid_module disable ngx_http_userid_module - --without-http_footer_module disable ngx_http_footer_module + --without-http_userid_module disable ngx_http_userid_filter_module + --without-http_footer_filter_module + disable ngx_http_footer_filter_module --without-http_access_module disable ngx_http_access_module --without-http_auth_basic_module disable ngx_http_auth_basic_module --without-http_autoindex_module disable ngx_http_autoindex_module --without-http_geo_module disable ngx_http_geo_module --without-http_map_module disable ngx_http_map_module - --without-http_split_clients_module disable ngx_http_split_clients_module + --without-http_split_clients_module + disable ngx_http_split_clients_module --without-http_referer_module disable ngx_http_referer_module --without-http_rewrite_module disable ngx_http_rewrite_module --without-http_proxy_module disable ngx_http_proxy_module @@ -535,6 +767,10 @@ else NGX_ERROR_LOG_PATH=${NGX_ERROR_LOG_PATH:-logs/error.log} fi + +NGX_DSO_PATH=${NGX_MODULE_PATH:-modules} + + NGX_HTTP_LOG_PATH=${NGX_HTTP_LOG_PATH:-logs/access.log} NGX_HTTP_CLIENT_TEMP_PATH=${NGX_HTTP_CLIENT_TEMP_PATH:-client_body_temp} NGX_HTTP_PROXY_TEMP_PATH=${NGX_HTTP_PROXY_TEMP_PATH:-proxy_temp} diff --git a/auto/sources b/auto/sources index eaf7c38e68..0a90f35ece 100644 --- a/auto/sources +++ b/auto/sources @@ -77,6 +77,12 @@ REGEX_DEPS=src/core/ngx_regex.h REGEX_SRCS=src/core/ngx_regex.c +DSO_MODULE=ngx_dso_module +DSO_SRCS="src/core/ngx_dso_module.c" +DSO_LIBS= +DSO_INCS= + + OPENSSL_MODULE=ngx_openssl_module OPENSSL_DEPS=src/event/ngx_event_openssl.h OPENSSL_SRCS=src/event/ngx_event_openssl.c diff --git a/auto/summary b/auto/summary index dcebec9f0f..f98951232c 100644 --- a/auto/summary +++ b/auto/summary @@ -97,6 +97,10 @@ cat << END nginx http client request body temporary files: "$NGX_HTTP_CLIENT_TEMP_PATH" END +if [ $NGX_DSO = YES ]; then + echo " nginx dso module path: \"$NGX_DSO_PATH\"" +fi + if [ $HTTP_PROXY = YES ]; then echo " nginx http proxy temporary files: \"$NGX_HTTP_PROXY_TEMP_PATH\"" fi diff --git a/auto/unix b/auto/unix index 7a29f9826a..20de53a47b 100755 --- a/auto/unix +++ b/auto/unix @@ -272,6 +272,13 @@ if [ $ngx_found != yes ]; then if [ $ngx_found = yes ]; then NGX_LIBDL="-ldl" + else + if [ $NGX_DSO = YES] ; then + cat << END +dlopen(3) required by dso not found, please disable dso (--without-dso). + +END + fi fi fi diff --git a/contrib/dso.in b/contrib/dso.in new file mode 100644 index 0000000000..3c402dec65 --- /dev/null +++ b/contrib/dso.in @@ -0,0 +1,339 @@ +DSO_ALL_INCS=%%ALL_INCS%% +DSO_CORE_DEPS=%%CORE_DEPS%% +DSO_CORE_INCS=%%CORE_INCS%% +DSO_HTTP_DEPS=%%HTTP_DEPS%% +DSO_HTTP_INCS=%%HTTP_INCS%% + + +ALL_INCS= +CORE_INCS= +CORE_DEPS= +HTTP_INCS= +HTTP_DEPS= + +NGX_SOURCE_HOME=%%NGX_SOURCE_HOME%% + +opt= +help=no + +for option +do + opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`" + + case "$option" in + -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) value="" ;; + esac + + case "$option" in + --help) help=yes ;; + + --prefix=) NGX_DSO_PREFIX="!" ;; + --prefix=*) NGX_DSO_PREFIX="$value" ;; + + --add-module=*) NGX_DSO_ADDONS="$NGX_DSO_ADDONS $value" ;; + + --with-nginx-source=*) NGX_SOURCE_HOME="$value" ;; + + *) + echo "$0: error: invalid option \"$option\"" + exit 1 + ;; + esac +done + + +NGX_CONFIGURE="$opt" + + +if [ $help = yes ]; then + +cat << END + + --help print this message + + --prefix=PATH set module installation prefix + + --add-module=PATH external module of will compile;; + + --with-nginx-source=NGX_SOURCE_HOM set nginx source path;; + +END + + exit 1 +fi + + + +# arg1 is addon dir +# arg2 is addon deps +# arg3 is addon src + +generate_make () { + # mkdir build temp + cd $1 + dso_binout=$ngx_addon_name + NGX_DSO_MAKEFILE=objs/Makefile + NGX_ADDON_DEPS=$2 + NGX_OBJS=objs + + if test -d $NGX_OBJS; then + rm -rf $NGX_OBJS + fi + + mkdir -p $NGX_OBJS + + cat << END > $NGX_DSO_MAKEFILE + +CC = $CC +CFLAGS = $CFLAGS +CPP = $CPP +LINK = $LINK + + +CORE_LIBS = $CORE_LIBS +CORE_LINK = $CORE_LINK +NGX_LD_OPT = $NGX_LD_OPT + +END + + + cat << END >> $NGX_DSO_MAKEFILE + +ALL_INCS = $ALL_INCS + +CORE_DEPS = $CORE_DEPS + +CORE_INCS = $CORE_INCS + +HTTP_DEPS = $HTTP_DEPS + + +HTTP_INCS = $HTTP_INCS + +ADDON_DEPS = \$(CORE_DEPS) $NGX_ADDON_DEPS + +END + + + 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/"` + fi + + for ngx_src in $NGX_ADDON_SRCS + do + ngx_obj="objs/src/`basename \`dirname $ngx_src\``" + + test -d $ngx_obj || mkdir -p $ngx_obj + + ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` | sed -e "s/\//$ngx_regex_dirsep/g"` + + 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_dso_all_objs="$ngx_dso_all_objs $ngx_obj" + + done + + ngx_deps=`echo $ngx_dso_all_objs $ngx_res $LINK_DEPS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + ngx_objs=`echo $ngx_dso_all_objs \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + ngx_link=${CORE_LINK:+`echo $CORE_LINK \ + | sed -e "s/\//$ngx_regex_dirsep%%/g" -e "s/^/$ngx_long_regex_cont/"`} + + cat << END >> $NGX_DSO_MAKEFILE + +$NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext}: $ngx_deps$ngx_spacer + \$(LINK) ${ngx_long_start}${ngx_binout} $NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext}$ngx_long_cont$ngx_objs$ngx_libs$ngx_link + $ngx_rcc +${ngx_long_end} +END + + for ngx_src in $NGX_ADDON_SRCS + do + ngx_obj="objs/src/`basename \`dirname $ngx_src\``" + + test -d $ngx_obj || mkdir -p $ngx_obj + + ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` | sed -e "s#/#$ngx_regex_dirsep#g"` + + 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_DSO_MAKEFILE + +$ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src + $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX + +END + + done + + make -f $NGX_DSO_MAKEFILE + if test -n "$NGX_DSO_PREFIX"; then + cp $NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext} $NGX_DSO_PREFIX + else + cp $NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext} $NGX_PREFIX/$NGX_DSO_PATH + fi +} + + +if test -n "$NGX_DSO_ADDONS"; then + + echo configuring additional modules + + for dai in $DSO_ALL_INCS + do + if [ "$dai" = "-I" ]; then + ALL_INCS="$ALL_INCS $dai" + elif test -n "$dai"; then + case ".$dai" in + ./*) + ALL_INCS="$ALL_INCS $dai" + ;; + + *) + ALL_INCS="$ALL_INCS $NGX_SOURCE_HOME/$dai" + ;; + esac + fi + done + + for dcd in $DSO_CORE_DEPS + do + if test -n "$dcd"; then + case ".$dcd" in + ./*) + CORE_DEPS="$CORE_DEPS $dcd" + ;; + + *) + CORE_DEPS="$CORE_DEPS $NGX_SOURCE_HOME/$dcd" + ;; + esac + fi + done + + for dci in $DSO_CORE_INCS + do + if [ "$dci" = "-I" ]; then + CORE_INCS="$CORE_INCS $dci" + elif test -n "$dci"; then + case ".$dci" in + ./*) + CORE_INCS="$CORE_INCS $dci" + ;; + + *) + CORE_INCS="$CORE_INCS $NGX_SOURCE_HOME/$dci" + ;; + esac + fi + done + + for dhi in $DSO_HTTP_INCS + do + if [ "$dhi" = "-I" ]; then + HTTP_INCS="$HTTP_INCS $dhi" + elif test -n "$dhi"; then + case ".$dhi" in + ./*) + HTTP_INCS="$HTTP_INCS $dhi" + ;; + + *) + HTTP_INCS="$HTTP_INCS $NGX_SOURCE_HOME/$dhi" + ;; + esac + fi + done + + for dhd in $DSO_HTTP_DEPS + do + if test -n "$dhd"; then + case ".$dhd" in + ./*) + HTTP_DEPS="$HTTP_DEPS $dhd" + ;; + + *) + HTTP_DEPS="$HTTP_DEPS $NGX_SOURCE_HOME/$dhd" + ;; + esac + fi + done + + for ngx_addon_dir in $NGX_DSO_ADDONS + do + echo "adding module in $ngx_addon_dir" + if test -f $ngx_addon_dir/config; then + NGX_ADDON_SRCS= + NGX_ADDON_DEPS= + cd $NGX_SOURCE_HOME + + CORE_INCS_TEMP=$CORE_INCS + HTTP_INCS_TEMP=$HTTP_INCS + CORE_LIBS_TEMP=$CORE_LIBS + CORE_INCS= + HTTP_INCS= + CORE_LIBS= + + . $ngx_addon_dir/config + + dso_core_incs=`echo $CORE_INCS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + dso_http_incs=`echo $HTTP_INCS \ + | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \ + -e "s/\//$ngx_regex_dirsep/g"` + + dso_core_libs=`echo $CORE_LIBS \ + | sed -e "s/\//$ngx_regex_dirsep/g"` + + if test -n "$dso_core_incs"; then + CORE_INCS="$CORE_INCS_TEMP -I $dso_core_incs" + else + CORE_INCS=$CORE_INCS_TEMP + fi + + if test -n "$dso_http_incs"; then + HTTP_INCS="$HTTP_INCS_TEMP -I $dso_http_incs" + else + HTTP_INCS=$HTTP_INCS_TEMP + fi + + if test -n "$dso_core_libs"; then + CORE_LIBS="$CORE_LIBS_TEMP $dso_core_libs" + else + CORE_LIBS=$CORE_LIBS_TEMP + fi + + cd - + echo " + $ngx_addon_name will be compiled" + generate_make $ngx_addon_dir $NGX_ADDON_DEPS $NGX_ADDON_SRCS $ngx_addon_name + else + echo "$0: error: no $ngx_addon_dir/config was found" + exit 1 + fi + done +else + echo "please assign module path" + exit 1 +fi + diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md new file mode 100644 index 0000000000..7d0c0225e9 --- /dev/null +++ b/docs/modules/ngx_dso_module.md @@ -0,0 +1,119 @@ +Name +==== + +* dso module + +Description +=========== + +* On selected operating systems this module can be used to load modules into Tengine at runtime via the DSO (Dynamic Shared Object) mechanism, rather than requiring a recompilation. + +* If you want to compile official module with DSO, you should add the configure argument named --with-http\_xxx_module, see the ./configure --help for detail. + +* DSO loaded module will limit to 128. + +* This module are tested successfully in Linux/FreeeBSD/MacOS. + + +Exampe +=========== + + dso_path /home/nginx-dso/module/; + + dso_load ngx_http_hat_filter_module lib_ngx_http_hat_filter_module.so; + dso_load ngx_http_lua_module lib_ngx_http_lua_module.so; + dso_load ngx_http_addition_filter_module lib_ngx_http_addition_filter_module.so; + dso_load ngx_http_concat_module lib_ngx_http_concat_module.so; + dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; + dso_load ngx_http_image_filter_module lib_ngx_http_image_filter_module.so; + +Directives +========== + +dso_order +------------- + +**Syntax**: *dso_order {.....}* + +**Default**: *none* + +**Context**: *main* + + +This directive can insert your module to nginx' module order list(please see conf/module_order). Be careful, it will change the module runtime order. This directive does not need to be set in most cases. + +Example: + + dso_order { + ngx_core_module; + ngx_errlog_module; + ngx_conf_module; + ngx_events_module; + ngx_event_core_module; + ngx_epoll_module; + ngx_openssl_module; + ngx_http_module; + ngx_http_core_module; + ....................... + ngx_http_addition_filter_module; + ngx_http_my_filter_module; + } + +this will insert my\_filter before addition\_filter module. + + +dso_path +------------------------ + +**Syntax**: *dso_path path* + +**Default**: *none* + +**Context**: *main* + +The dso_path set default path for DSO module + +Example: + + dso_path /home/dso/module/; + +Set default path to /home/dso/module/. + +dso_load +------------------------ + +**Syntax**: *dso_load module_name module_path* + +**Default**: *none* + +**Context**: *main* + +The dso_load directive links in the object file or library filename and adds the module structure named module to the list of active modules,module\_name is the name of the DSO module, module\_path is the path of the DSO module. + +There are three possibility with the module_path. It will search the module in below order. + +1 absolute path. +2 relative to path that dso_path directive. +3 relative to default path(NGX\_PREFIX/modules or path which is specified with --dso-path when configure). + + +Example: + + dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; + +load empty_gif module from lib\_ngx\_http\_empty\_gif\_module.so. + + +Tools +=========== + +dso_tools +------------------------ + +This tools is used to compile the third nginx'module. + +Example: + + ./dso_tools --add-module=/home/dso/lua-nginx-module + +This will compile ngx_lua module to dso, and install dso to default module path. diff --git a/src/core/nginx.c b/src/core/nginx.c index c9e93f931f..16b77974ea 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -187,9 +187,9 @@ ngx_module_t ngx_core_module = { ngx_uint_t ngx_max_module; ngx_uint_t ngx_dump_config; + static ngx_uint_t ngx_show_help; static ngx_uint_t ngx_show_version; -static ngx_uint_t ngx_show_modules; static ngx_uint_t ngx_show_configure; static ngx_uint_t ngx_show_directives; static u_char *ngx_prefix; @@ -270,14 +270,6 @@ main(int argc, char *const *argv) "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } - if (ngx_show_modules) { - ngx_log_stderr(0, "compiled in modules:"); - - for (i = 0; ngx_module_names[i]; i++) { - ngx_log_stderr(0, " %s", ngx_module_names[i]); - } - } - if (ngx_show_directives) { ngx_log_stderr(0, "all available directives:"); @@ -295,7 +287,7 @@ main(int argc, char *const *argv) } } - if(!ngx_test_config) { + if(!ngx_test_config && !ngx_show_modules) { return 0; } } @@ -382,6 +374,10 @@ main(int argc, char *const *argv) return 0; } + if (ngx_show_modules) { + return 0; + } + if (ngx_dump_config) { return 0; } diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h index 1f8793a79f..61c39c2525 100644 --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -53,7 +53,6 @@ #define NGX_ANY_CONF 0x0F000000 - #define NGX_CONF_UNSET -1 #define NGX_CONF_UNSET_UINT (ngx_uint_t) -1 #define NGX_CONF_UNSET_PTR (void *) -1 @@ -105,7 +104,10 @@ struct ngx_open_file_s { }; -#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1 +#define NGX_NUMBER_MAJOR 1 +#define NGX_NUMBER_MINOR 1 + +#define NGX_MODULE_V1 0, 0, 0, 0, 0, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 struct ngx_module_s { @@ -115,9 +117,9 @@ struct ngx_module_s { ngx_uint_t spare0; ngx_uint_t spare1; ngx_uint_t spare2; - ngx_uint_t spare3; - ngx_uint_t version; + ngx_uint_t major_version; + ngx_uint_t minor_version; void *ctx; ngx_command_t *commands; @@ -345,6 +347,7 @@ extern ngx_uint_t ngx_dump_config; extern ngx_uint_t ngx_max_module; extern ngx_module_t *ngx_modules[]; extern const char *ngx_module_names[]; +extern const char *ngx_all_module_names[]; #endif /* _NGX_HTTP_CONF_FILE_H_INCLUDED_ */ diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index b1ccaf2879..e8b1ef98de 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -10,6 +10,11 @@ #include +#if (NGX_DSO) +void ngx_show_dso_modules(ngx_conf_t *cf); +#endif + + static void ngx_destroy_cycle_pools(ngx_conf_t *conf); static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2); static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle, @@ -26,6 +31,7 @@ static ngx_event_t ngx_cleaner_event; ngx_uint_t ngx_test_config; ngx_uint_t ngx_quiet_mode; +ngx_uint_t ngx_show_modules; #if (NGX_THREADS) ngx_tls_key_t ngx_core_tls_key; @@ -275,6 +281,20 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) return NULL; } + if (ngx_show_modules) { + ngx_log_stderr(0, "loaded modules:"); + + for (i = 0; ngx_module_names[i]; i++) { + ngx_log_stderr(0, " %s (static)", ngx_module_names[i]); + } + +#if (NGX_DSO) + ngx_show_dso_modules(&conf); +#endif + ngx_destroy_cycle_pools(&conf); + return cycle; + } + if (ngx_test_config && !ngx_quiet_mode) { ngx_log_stderr(0, "the configuration file %s syntax is ok", cycle->conf_file.data); diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h index d24b70c87b..5339a6b927 100644 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -138,6 +138,7 @@ extern volatile ngx_cycle_t *ngx_cycle; extern ngx_array_t ngx_old_cycles; extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_test_config; +extern ngx_uint_t ngx_show_modules; extern ngx_uint_t ngx_quiet_mode; #if (NGX_THREADS) extern ngx_tls_key_t ngx_core_tls_key; diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c new file mode 100644 index 0000000000..fd768f9b28 --- /dev/null +++ b/src/core/ngx_dso_module.c @@ -0,0 +1,575 @@ + +/* + * Copyright (C) 2010-2012 Alibaba Group Holding Limited + */ + + +#include +#include +#include +#include + + +#define NGX_DSO_MODULE_PREFIX "ngx_" + + +typedef struct { + ngx_str_t type; + ngx_str_t entry; +} ngx_dso_flagpole_t; + + +typedef struct { + ngx_str_t name; + ngx_str_t path; + void *dl_handle; + ngx_module_t *module; +} ngx_dso_module_t; + + +typedef struct { + ngx_str_t path; + ngx_int_t flag_postion; + ngx_array_t *order; + ngx_array_t *modules; +} ngx_dso_conf_t; + + +static void *ngx_dso_create_conf(ngx_cycle_t *cycle); +static char *ngx_dso_init_conf(ngx_cycle_t *cycle, void *conf); + +static char *ngx_dso_load(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, + ngx_str_t *name, ngx_str_t *path); +static char *ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_dso_order_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); + +static ngx_int_t ngx_dso_get_position(ngx_str_t *module_entry); + +static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_t *dcf, ngx_str_t module_name); + + +static ngx_command_t ngx_dso_module_commands[] = { + + { ngx_string("dso_order"), + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_dso_order_block, + 0, + 0, + NULL }, + + { ngx_string("dso_path"), + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + 0, + offsetof(ngx_dso_conf_t, path), + NULL }, + + { ngx_string("dso_load"), + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE2, + ngx_dso_load, + 0, + 0, + NULL }, + + ngx_null_command +}; + + +static ngx_core_module_t ngx_dso_module_ctx = { + ngx_string("dso"), + ngx_dso_create_conf, + ngx_dso_init_conf +}; + + +ngx_module_t ngx_dso_module = { + NGX_MODULE_V1, + &ngx_dso_module_ctx, /* module context */ + ngx_dso_module_commands, /* module directives */ + NGX_CORE_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +extern ngx_uint_t ngx_max_module; +static ngx_str_t ngx_default_modules_prefix = ngx_string(NGX_DSO_PATH); + + +static ngx_dso_flagpole_t module_flagpole[] = { + + { ngx_string("filter"), ngx_string("ngx_http_copy_filter_module")}, + {ngx_null_string, ngx_null_string} +}; + + +static ngx_int_t +ngx_dso_get_position(ngx_str_t *entry) +{ + size_t len; + ngx_int_t i; + + /* start insert filter list */ + for (i = 0; ngx_module_names[i]; i++) { + + len = ngx_strlen(ngx_module_names[i]); + + if (len == entry->len + && ngx_strncasecmp((u_char *) ngx_module_names[i], + entry->data, len) == 0) + { + return i; + } + } + + return NGX_ERROR; +} + + +static ngx_int_t +ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, + ngx_str_t *name, ngx_str_t *path) +{ + size_t len; + ngx_uint_t i, j; + ngx_dso_module_t *m; + ngx_dso_conf_t *old_dcf; + ngx_dso_module_t *old_dl_m; + + if (cycle->old_cycle->conf_ctx != NULL) { + old_dcf = (ngx_dso_conf_t *) ngx_get_conf(cycle->old_cycle->conf_ctx, + ngx_dso_module); + if (old_dcf != NULL) { + old_dl_m = old_dcf->modules->elts; + + for (i = 0; i < old_dcf->modules->nelts; i++) { + if (old_dl_m[i].name.len == 0) { + continue; + } + + if ((name->len == old_dl_m[i].name.len + && ngx_strncmp(name->data, old_dl_m[i].name.data, old_dl_m[i].name.len) == 0) + || (path->len == old_dl_m[i].path.len + && ngx_strncmp(path->data, old_dl_m[i].path.data, old_dl_m[i].path.len) == 0)) + { + return NGX_DECLINED; + } + } + } + } + + for (j = 0; ngx_module_names[j]; j++) { + len = ngx_strlen(ngx_module_names[j]); + + if (len == name->len && ngx_strncmp(ngx_module_names[j], + name->data, name->len) == 0) + { + ngx_log_stderr(0, "module %V is already static loaded, skipping", + name); + return NGX_DECLINED; + } + } + + m = modules->elts; + for (j = 0; j < modules->nelts; j++) { + if ((m[j].name.len == name->len + && ngx_strncmp(m[j].name.data, name->data, name->len) == 0) + || (m[j].path.len == path->len + && ngx_strncmp(m[j].path.data, path->data, path->len) == 0)) + { + ngx_log_stderr(0, "module %V/%V is already dynamic loaded, skipping", + path, name); + m[j].name.len = 0; + return NGX_DECLINED; + } + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_t *dcf, ngx_str_t *name) +{ + size_t len, size; + u_char *p, *n, *prefix; + + if (name->data[0] == '/') { + return NGX_OK; + } + + if (dcf->path.data == NULL) { + if (ngx_default_modules_prefix.data[0] != '/') { + prefix = cycle->prefix.data; + len = cycle->prefix.len; + size = len + ngx_default_modules_prefix.len + name->len + 1; + } else { + prefix = ngx_default_modules_prefix.data; + len = ngx_default_modules_prefix.len; + size = len + name->len + 1; + } + } else { + if (dcf->path.data[0] != '/') { + return NGX_ERROR; + } + + len = dcf->path.len; + prefix = dcf->path.data; + size = len + name->len + 1; + } + + n = ngx_pnalloc(cycle->pool, size + 1); + if (n == NULL) { + return NGX_ERROR; + } + + p = ngx_cpymem(n, prefix, len); + + if (dcf->path.data == NULL + && ngx_default_modules_prefix.data[0] != '/') { + p = ngx_cpymem(p, ngx_default_modules_prefix.data, + ngx_default_modules_prefix.len); + } + + p = ngx_cpymem(p, "/", 1); + ngx_cpystrn(p, name->data, name->len + 1); + + name->len = size; + name->data = n; + + return NGX_OK; +} + + +static ngx_int_t +ngx_dso_open(ngx_dso_module_t *dl_m) +{ + void *dl_handle; + ngx_str_t module_name, module_path; + ngx_module_t *module; + + module_name = dl_m->name; + module_path = dl_m->path; + + dl_handle = dlopen((char *) module_path.data, RTLD_NOW | RTLD_GLOBAL); + if (dl_handle == NULL) { + ngx_log_stderr(errno, "load module failed %s", dlerror()); + return NGX_ERROR; + } + + module = dlsym(dl_handle, (const char *) module_name.data); + if (module == NULL) { + ngx_log_stderr(errno, "Can't locate sym in module(%V)", &module_name); + return NGX_ERROR; + } + + dl_m->dl_handle = dl_handle; + dl_m->module = module; + + return NGX_OK; +} + + +static char * +ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) +{ + ngx_uint_t j; + ngx_module_t *m; + + m = NULL; + /* start insert filter list */ + for (j = flag_postion; ngx_modules[j]; j++) { + m = ngx_modules[j]; + + ngx_modules[j] = module; + + module = m; + } + + if (m == NULL) { + return NGX_CONF_ERROR; + } + + ngx_modules[j] = module; + + return NGX_CONF_OK; +} + + +static char * +ngx_dso_order_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *rv; + ngx_conf_t save; + ngx_dso_conf_t *dcf; + + dcf = conf; + + if (dcf->order != NULL) { + return "is duplicate"; + } + + if (dcf->modules->nelts > 0) { + return "order block must appear to before load derective"; + } + + dcf->order = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); + if (dcf->order == NULL) { + return NGX_CONF_ERROR; + } + + save = *cf; + cf->module_type = NGX_CORE_MODULE; + + cf->handler = ngx_dso_order; + cf->handler_conf = (void *) dcf; + + rv = ngx_conf_parse(cf, NULL); + + *cf = save; + + return rv; +} + + +static char * +ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_dso_conf_t *dcf = conf; + + ngx_str_t *value, *module_name; + + value = cf->args->elts; + + if (cf->args->nelts != 1 + || ngx_strncasecmp(value[0].data, (u_char *) NGX_DSO_MODULE_PREFIX, + sizeof(NGX_DSO_MODULE_PREFIX) - 1) != 0) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown directive \"%s\"", value[0].data); + return NGX_CONF_ERROR; + } + + module_name = ngx_array_push(dcf->order); + if (module_name == NULL) { + return NGX_CONF_ERROR; + } + + *module_name = value[0]; + + return NGX_CONF_OK; +} + + +static char * +ngx_dso_load(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_dso_conf_t *dcf = conf; + + char *rv; + ngx_int_t postion; + ngx_str_t *value, module_path, module_name; + ngx_dso_module_t *dl_m; + + value = cf->args->elts; + + if (dcf->modules->nelts >= NGX_DSO_MAX) { + ngx_log_stderr(0, "Module \"%V\" could not be loaded, " + "because the dso module limit(%ui) was reached.", + &value[1], NGX_DSO_MAX); + return NGX_CONF_ERROR; + } + + module_name = value[1]; + module_path = value[2]; + + if (ngx_dso_check_duplicated(cf->cycle, dcf->modules, + &module_name, &module_path) == NGX_DECLINED) + { + return NGX_CONF_OK; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "load module(%V)", module_path); + + dl_m = ngx_array_push(dcf->modules); + + if (ngx_dso_full_name(cf->cycle, dcf, &module_path) != NGX_OK) { + return NGX_CONF_ERROR; + } + + dl_m->name = module_name; + dl_m->path = module_path; + + if (ngx_dso_open(dl_m) == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + if (dl_m->module->type == NGX_CORE_MODULE) { + ngx_log_stderr(0,"dso module not support core module"); + return NGX_CONF_ERROR; + } + + if (dl_m->module->major_version != NGX_NUMBER_MAJOR + || dl_m->module->minor_version > NGX_NUMBER_MINOR) + { + ngx_log_stderr(0,"Module \"%V\" is not compatible with this " + "version of Tengine (found %d.%d, need %d.%d). Please " + "contact the vendor for the correct version.", + &module_name, dl_m->module->major_version, + dl_m->module->minor_version, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR); + return NGX_CONF_ERROR; + } + + postion = ngx_dso_find_postion(dcf, module_name); + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "dso find postion(%i)", postion); + + rv = ngx_dso_insert_module(dl_m->module, postion); + if (rv == NGX_CONF_ERROR) { + return rv; + } + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_dso_find_postion(ngx_dso_conf_t *dcf, ngx_str_t module_name) +{ + size_t len1, len2, len3; + ngx_int_t near; + ngx_uint_t i, k; + ngx_str_t *name; + + near = dcf->flag_postion; + + if (dcf->order == NULL || dcf->order->nelts == 0) { + + for (i = 0; ngx_all_module_names[i]; i++) { + len1 = ngx_strlen(ngx_all_module_names[i]); + if (len1 == module_name.len + && ngx_strncmp(ngx_all_module_names[i], module_name.data, len1) == 0) + { + return near; + } + + if (i == 0) { + continue; + } + + len2 = ngx_strlen(ngx_all_module_names[i - 1]); + for (k = 0; ngx_module_names[k]; k++) { + len3 = ngx_strlen(ngx_module_names[k]); + + if (len2 == len3 + && ngx_strncmp(ngx_all_module_names[i - 1], ngx_module_names[k], len2) == 0) + { + near = k + 1; + break; + } + } + } + + if (ngx_all_module_names[i] == NULL) { + return ++dcf->flag_postion; + } + } + + name = dcf->order->elts; + near = dcf->flag_postion; + + for (i = 0; i < dcf->order->nelts; i++) { + if (name[i].len == module_name.len + && ngx_strncmp(name[i].data, module_name.data, name[i].len) == 0) + { + return near; + } + + if (i == 0) { + continue; + } + + for (k = 0; ngx_module_names[k]; k++) { + len1 = ngx_strlen(ngx_module_names[k]); + + if (len1 == name[i].len + && ngx_strncmp(name[i].data, ngx_module_names[k], name[i].len) == 0) + { + near = k + 1; + break; + } + } + } + + return ++dcf->flag_postion; +} + + +void +ngx_show_dso_modules(ngx_conf_t *cf) +{ + ngx_str_t module_name; + ngx_uint_t i; + ngx_module_t *module; + ngx_dso_conf_t *dcf; + ngx_dso_module_t *dl_m; + + dcf = (ngx_dso_conf_t *) ngx_get_conf(cf->cycle->conf_ctx, + ngx_dso_module); + + if (dcf == NULL) { + return; + } + + dl_m = dcf->modules->elts; + + for (i = 0; i < dcf->modules->nelts; i++) { + if (dl_m[i].name.len == 0) { + continue; + } + + module_name = dl_m[i].name; + module = dl_m[i].module; + + ngx_log_stderr(0, " %V (shared), version (%d.%d)", + &module_name, module->major_version, module->minor_version); + } +} + + +static char * +ngx_dso_init_conf(ngx_cycle_t *cycle, void *conf) +{ + return NGX_CONF_OK; +} + + +static void * +ngx_dso_create_conf(ngx_cycle_t *cycle) +{ + ngx_dso_conf_t *conf; + + conf = ngx_pcalloc(cycle->pool, sizeof(ngx_dso_conf_t)); + if (conf == NULL) { + return NGX_CONF_ERROR; + } + + conf->flag_postion = ngx_dso_get_position(&module_flagpole[0].entry); + if (conf->flag_postion == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + conf->modules = ngx_array_create(cycle->pool, 10, sizeof(ngx_dso_module_t)); + if (conf->modules == NULL) { + return NGX_CONF_ERROR; + } + + return conf; +} diff --git a/tests/nginx-tests/cases/concat.t b/tests/nginx-tests/cases/concat.t index dd3ce147e8..747ff995fd 100644 --- a/tests/nginx-tests/cases/concat.t +++ b/tests/nginx-tests/cases/concat.t @@ -20,6 +20,12 @@ select STDERR; $| = 1; select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http/)->plan(58); + +$t->set_dso("ngx_http_concat_module", "lib_ngx_http_concat_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + $t->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% @@ -27,6 +33,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } diff --git a/tests/nginx-tests/cases/slice.t b/tests/nginx-tests/cases/slice.t index efd2a68c9e..fbf863010c 100644 --- a/tests/nginx-tests/cases/slice.t +++ b/tests/nginx-tests/cases/slice.t @@ -20,6 +20,12 @@ select STDERR; $| = 1; select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http/)->plan(23); + +$t->set_dso("ngx_http_slice_module", "lib_ngx_http_slice_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + $t->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% @@ -27,6 +33,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } diff --git a/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm b/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm index 30ce2ea825..0b341f7cd7 100644 --- a/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm +++ b/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm @@ -40,6 +40,7 @@ sub new { ) or die "Can't create temp directory: $!\n"; + $self->{_dso_module} = (); return $self; } @@ -63,6 +64,12 @@ sub has($;) { return $self; } +sub set_dso($;) { + my ($self, $module_name, $module_path) = @_; + + $self->{_dso_module}{$module_name} = $module_path; +} + sub has_module($) { my ($self, $feature) = @_; @@ -234,6 +241,7 @@ sub write_file_expand($$) { my ($self, $name, $content) = @_; $content =~ s/%%TEST_GLOBALS%%/$self->test_globals()/gmse; + $content =~ s/%%TEST_GLOBALS_DSO%%/$self->test_globals_dso()/gmse; $content =~ s/%%TEST_GLOBALS_HTTP%%/$self->test_globals_http()/gmse; $content =~ s/%%TESTDIR%%/$self->{_testdir}/gms; @@ -281,6 +289,23 @@ sub test_globals() { $self->{_test_globals} = $s; } +sub test_globals_dso() { + my ($self) = @_; + + return unless defined $ENV{TEST_NGINX_DSO}; + + return $self->{_test_globals_dso} + if defined $self->{_test_globals_dso}; + + my $s = ''; + + while ( my ($key, $value) = each(%{$self->{_dso_module}}) ) { + $s .= "dso_load $key $value;\n"; + } + + $self->{_test_globals_dso} = $s; +} + sub test_globals_http() { my ($self) = @_; diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Socket.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Socket.pm index c5fa70f729..b7e5d32334 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Socket.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Socket.pm @@ -626,6 +626,15 @@ sub check_response_headers($$$$$) { if ( !defined $expected_val ) { $expected_val = ''; } + if ( !defined $name ) { + $name = ''; + } + if ( !defined $key ) { + $key = ''; + } + if ( !defined $val ) { + $val = ''; + } SKIP: { skip "$name - tests skipped due to the lack of directive $dry_run", 1 if $dry_run; like $expected_val, qr/^$val$/, "$name - header $key like ok"; diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm index 80b7b30034..6b2f92b973 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm @@ -67,6 +67,9 @@ our $SleepBeforeTest = $ENV{TEST_NGINX_SLEEP_BEFORE} || 0; our $BuildSlaveName = $ENV{TEST_NGINX_BUILDSLAVE}; our $ForceRestartOnTest = (defined $ENV{TEST_NGINX_FORCE_RESTART_ON_TEST}) ? $ENV{TEST_NGINX_FORCE_RESTART_ON_TEST} : 1; +our $DSO_path = $ENV{TEST_NGINX_DSO_PATH} || "none"; + +our @DSO_modules; sub server_port (@) { if (@_) { @@ -191,6 +194,7 @@ our $ErrLogFile = File::Spec->catfile($LogDir, 'error.log'); our $AccLogFile = File::Spec->catfile($LogDir, 'access.log'); our $HtmlDir = File::Spec->catfile($ServRoot, 'html'); our $ConfDir = File::Spec->catfile($ServRoot, 'conf'); +our $DsoDir = File::Spec->catfile($ServRoot, 'modules'); our $ConfFile = File::Spec->catfile($ConfDir, 'nginx.conf'); our $PidFile = File::Spec->catfile($LogDir, 'nginx.pid'); @@ -242,6 +246,8 @@ sub setup_server_root () { die "Can't remove $HtmlDir"; system("rm -rf $LogDir > /dev/null") == 0 or die "Can't remove $LogDir"; + system("rm -rf $DsoDir > /dev/null") == 0 or + die "Can't remove $ConfDir"; system("rm -rf $ServRoot/*_temp > /dev/null") == 0 or die "Can't remove $ServRoot/*_temp"; system("rmdir $ServRoot > /dev/null") == 0 or @@ -253,6 +259,8 @@ sub setup_server_root () { die "Failed to do mkdir $LogDir\n"; mkdir $HtmlDir or die "Failed to do mkdir $HtmlDir\n"; + mkdir $DsoDir or + die "Failed to do mkdir $DsoDir\n"; my $index_file = "$HtmlDir/index.html"; @@ -267,6 +275,88 @@ sub setup_server_root () { die "Failed to do mkdir $ConfDir\n"; } +sub include_dso_modules ($) { + my $block = shift; + + @DSO_modules = (); + my @modules; + + if (!defined $block->include_dso_modules) { + return; + } + + my $raw = $block->include_dso_modules; + my $in; + + open $in, '<', \$raw; + while (<$in>) { + if (/(\S+)(?:\s+(.+))?/) { + push @modules, [$DSO_path . $1, $2]; + } + } + + my $dso_compile_dir; + + if ($NginxBinary =~ /^(.*\/)?([^\/]+)$/) { + $dso_compile_dir = $1; + } else { + $dso_compile_dir = "./"; + } + + #warn "$NginxBinary\n"; + + my $dso_compile_script; + + $dso_compile_script = $dso_compile_dir . "dso_tools"; + + for my $module (@modules) { + my ($dir, $name) = @$module; + + my $modules_dir; + + if (-d $dir) { + $modules_dir = $DsoDir; + system("$dso_compile_script --prefix=$DsoDir --add-module=\"$dir\"") == 0 + or die "Can't compile dso module $dir"; + } + else { + #warn "$dso_compile_dir\n"; + + #The module is compiled in the modules directory? + if ($dso_compile_dir =~ /^(.*\/)?([^\/]+)\/?$/) { + $modules_dir = $1 . "modules"; + } else { + $modules_dir = "./"; + } + } + + my $dso_module_lib = $modules_dir . "/lib_" . $name . ".so"; + + if (-f "$dso_module_lib") { + push @DSO_modules, [$name, $dso_module_lib]; + } else { + die "Can't find dso module $dso_module_lib"; + } + } +} + +sub write_dso_config () { + my $content = <$ConfFile" or + if (!defined $dso_config) { + $dso_config = ''; + } + + my $out; + + open $out, ">$ConfFile" or die "Can't open $ConfFile for writing: $!\n"; + print $out <<_EOC_; worker_processes $Workers; daemon $DaemonEnabled; @@ -373,6 +475,7 @@ env MOCKEAGAIN_VERBOSE; env MOCKEAGAIN_WRITE_TIMEOUT_PATTERN; env LD_PRELOAD; +$dso_config $main_config http { @@ -724,6 +827,9 @@ start_nginx: #warn "*** Restarting the nginx server...\n"; setup_server_root(); + if ($DSO_path ne "none") { + include_dso_modules($block); + } write_user_files($block); write_config_file($config, $block->http_config, $block->main_config); #warn "nginx binary: $NginxBinary"; From 2c8dca03d5a30a7ce15556d997819c5981335fb0 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 11 Jul 2012 15:12:04 +0800 Subject: [PATCH 06/36] add some configure help message. --- auto/options | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/auto/options b/auto/options index 796eef42ec..c128226b14 100644 --- a/auto/options +++ b/auto/options @@ -600,6 +600,21 @@ cat << END --with-http_stub_status_module enable ngx_http_stub_status_module --with-http_upstream_check_module enable ngx_http_upstream_check_module + --with-http_addition_module=shared enable ngx_http_addition_filter_module(shared) + --with-http_xslt_module=shared enable ngx_http_xslt_filter_module(shared) + --with-http_image_filter_module=shared + enable ngx_http_image_filter_module(shared) + --with-http_geoip_module=shared enable ngx_http_geoip_module + --with-http_sub_module=shared enable ngx_http_sub_filter_module(shared) + --with-http_flv_module=shared enable ngx_http_flv_module(shared) + --with-http_slice_module=shared enable ngx_http_slice_module(shared) + --with-http_mp4_module=shared enable ngx_http_mp4_module(shared) + --with-http_concat_module=shared enable ngx_http_concat_module(shared) + --with-http_random_index_module=shared + enable ngx_http_random_index_module(shared) + --with-http_secure_link_module=shared + enable ngx_http_secure_link_module(shared) + --with-http_sysguard_module=shared enable ngx_http_sysguard_module(shared) --with-http_charset_filter_module=shared enable ngx_http_charset_filter_module(shared) --with-http_userid_filter_module=shared From 9be95644e277986cf70d13b6573a23055c671446 Mon Sep 17 00:00:00 2001 From: Weibin Yao Date: Wed, 11 Jul 2012 16:07:31 +0800 Subject: [PATCH 07/36] add dso test scripts --- tests/nginx-tests/README | 15 + tests/nginx-tests/cases/expires_by_types.t | 25 +- .../nginx-tests/cases/http_error_page_merge.t | 13 +- tests/nginx-tests/cases/limit_req_enhance.t | 9 + .../nginx-tests/dso-nginx-tests/auth_basic.t | 117 +++++ tests/nginx-tests/dso-nginx-tests/autoindex.t | 119 +++++ tests/nginx-tests/dso-nginx-tests/dav.t | 141 ++++++ tests/nginx-tests/dso-nginx-tests/fastcgi.t | 100 ++++ .../dso-nginx-tests/fastcgi_cache.t | 106 +++++ .../dso-nginx-tests/fastcgi_header_params.t | 128 +++++ .../dso-nginx-tests/fastcgi_merge_params.t | 143 ++++++ .../dso-nginx-tests/fastcgi_merge_params2.t | 127 +++++ tests/nginx-tests/dso-nginx-tests/gzip.t | 103 ++++ .../nginx-tests/dso-nginx-tests/gzip_flush.t | 84 ++++ .../dso-nginx-tests/http_disable_symlinks.t | 301 ++++++++++++ .../dso-nginx-tests/http_error_page.t | 138 ++++++ .../http_expect_100_continue.t | 87 ++++ tests/nginx-tests/dso-nginx-tests/http_host.t | 230 +++++++++ .../dso-nginx-tests/http_location.t | 91 ++++ .../dso-nginx-tests/http_server_name.t | 138 ++++++ .../dso-nginx-tests/http_try_files.t | 97 ++++ .../dso-nginx-tests/http_variables.t | 99 ++++ tests/nginx-tests/dso-nginx-tests/lib | 1 + tests/nginx-tests/dso-nginx-tests/limit_req.t | 98 ++++ tests/nginx-tests/dso-nginx-tests/mail_imap.t | 133 ++++++ tests/nginx-tests/dso-nginx-tests/mail_pop3.t | 128 +++++ tests/nginx-tests/dso-nginx-tests/mail_smtp.t | 242 ++++++++++ .../mail_smtp_greeting_delay.t | 76 +++ .../dso-nginx-tests/mail_smtp_xclient.t | 147 ++++++ tests/nginx-tests/dso-nginx-tests/memcached.t | 100 ++++ .../dso-nginx-tests/memcached_fake.t | 106 +++++ .../dso-nginx-tests/not_modified.t | 88 ++++ tests/nginx-tests/dso-nginx-tests/perl.t | 78 ++++ tests/nginx-tests/dso-nginx-tests/perl_gzip.t | 90 ++++ tests/nginx-tests/dso-nginx-tests/proxy.t | 126 +++++ .../nginx-tests/dso-nginx-tests/proxy_cache.t | 172 +++++++ .../dso-nginx-tests/proxy_cache_lock.t | 225 +++++++++ .../dso-nginx-tests/proxy_chunked.t | 121 +++++ .../dso-nginx-tests/proxy_cookie.t | 123 +++++ .../dso-nginx-tests/proxy_merge_headers.t | 108 +++++ .../dso-nginx-tests/proxy_noclose.t | 154 ++++++ .../dso-nginx-tests/proxy_redirect.t | 175 +++++++ .../nginx-tests/dso-nginx-tests/proxy_store.t | 108 +++++ tests/nginx-tests/dso-nginx-tests/proxy_xar.t | 89 ++++ .../dso-nginx-tests/random_index.t | 72 +++ tests/nginx-tests/dso-nginx-tests/range.t | 137 ++++++ tests/nginx-tests/dso-nginx-tests/range_flv.t | 99 ++++ .../dso-nginx-tests/range_if_range.t | 128 +++++ tests/nginx-tests/dso-nginx-tests/rewrite.t | 212 +++++++++ .../dso-nginx-tests/rewrite_unescape.t | 170 +++++++ tests/nginx-tests/dso-nginx-tests/scgi.t | 140 ++++++ tests/nginx-tests/dso-nginx-tests/scgi_gzip.t | 94 ++++ .../dso-nginx-tests/scgi_merge_params.t | 149 ++++++ .../nginx-tests/dso-nginx-tests/secure_link.t | 154 ++++++ tests/nginx-tests/dso-nginx-tests/ssi.t | 134 ++++++ tests/nginx-tests/dso-nginx-tests/ssi_if.t | 267 +++++++++++ .../dso-nginx-tests/ssi_include_big.t | 95 ++++ .../nginx-tests/dso-nginx-tests/ssi_waited.t | 70 +++ tests/nginx-tests/dso-nginx-tests/uwsgi.t | 119 +++++ tests/nginx-tests/dso-nginx-tests/xslt.t | 131 ++++++ .../nginx-tests/dso-nginx-tests/xslt_params.t | 114 +++++ tests/test-nginx/README | 15 + tests/test-nginx/dso_cases/footer.t | 47 ++ .../http_check.t | 253 ++++++++++ .../ssl_hello_check.t | 74 +++ .../tcp_check.t | 73 +++ tests/test-nginx/dso_cases/syslog.t | 223 +++++++++ tests/test-nginx/dso_cases/user_agent.t | 438 ++++++++++++++++++ 68 files changed, 8503 insertions(+), 4 deletions(-) create mode 100644 tests/nginx-tests/README create mode 100644 tests/nginx-tests/dso-nginx-tests/auth_basic.t create mode 100644 tests/nginx-tests/dso-nginx-tests/autoindex.t create mode 100644 tests/nginx-tests/dso-nginx-tests/dav.t create mode 100644 tests/nginx-tests/dso-nginx-tests/fastcgi.t create mode 100644 tests/nginx-tests/dso-nginx-tests/fastcgi_cache.t create mode 100644 tests/nginx-tests/dso-nginx-tests/fastcgi_header_params.t create mode 100644 tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params.t create mode 100644 tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params2.t create mode 100644 tests/nginx-tests/dso-nginx-tests/gzip.t create mode 100644 tests/nginx-tests/dso-nginx-tests/gzip_flush.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_error_page.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_host.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_location.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_server_name.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_try_files.t create mode 100644 tests/nginx-tests/dso-nginx-tests/http_variables.t create mode 120000 tests/nginx-tests/dso-nginx-tests/lib create mode 100644 tests/nginx-tests/dso-nginx-tests/limit_req.t create mode 100644 tests/nginx-tests/dso-nginx-tests/mail_imap.t create mode 100644 tests/nginx-tests/dso-nginx-tests/mail_pop3.t create mode 100644 tests/nginx-tests/dso-nginx-tests/mail_smtp.t create mode 100644 tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t create mode 100644 tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t create mode 100644 tests/nginx-tests/dso-nginx-tests/memcached.t create mode 100644 tests/nginx-tests/dso-nginx-tests/memcached_fake.t create mode 100644 tests/nginx-tests/dso-nginx-tests/not_modified.t create mode 100644 tests/nginx-tests/dso-nginx-tests/perl.t create mode 100644 tests/nginx-tests/dso-nginx-tests/perl_gzip.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_cache.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_chunked.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_cookie.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_noclose.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_redirect.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_store.t create mode 100644 tests/nginx-tests/dso-nginx-tests/proxy_xar.t create mode 100644 tests/nginx-tests/dso-nginx-tests/random_index.t create mode 100644 tests/nginx-tests/dso-nginx-tests/range.t create mode 100644 tests/nginx-tests/dso-nginx-tests/range_flv.t create mode 100644 tests/nginx-tests/dso-nginx-tests/range_if_range.t create mode 100644 tests/nginx-tests/dso-nginx-tests/rewrite.t create mode 100644 tests/nginx-tests/dso-nginx-tests/rewrite_unescape.t create mode 100644 tests/nginx-tests/dso-nginx-tests/scgi.t create mode 100644 tests/nginx-tests/dso-nginx-tests/scgi_gzip.t create mode 100644 tests/nginx-tests/dso-nginx-tests/scgi_merge_params.t create mode 100644 tests/nginx-tests/dso-nginx-tests/secure_link.t create mode 100644 tests/nginx-tests/dso-nginx-tests/ssi.t create mode 100644 tests/nginx-tests/dso-nginx-tests/ssi_if.t create mode 100644 tests/nginx-tests/dso-nginx-tests/ssi_include_big.t create mode 100644 tests/nginx-tests/dso-nginx-tests/ssi_waited.t create mode 100644 tests/nginx-tests/dso-nginx-tests/uwsgi.t create mode 100644 tests/nginx-tests/dso-nginx-tests/xslt.t create mode 100644 tests/nginx-tests/dso-nginx-tests/xslt_params.t create mode 100644 tests/test-nginx/README create mode 100644 tests/test-nginx/dso_cases/footer.t create mode 100644 tests/test-nginx/dso_cases/ngx_http_upstream_check_module/http_check.t create mode 100644 tests/test-nginx/dso_cases/ngx_http_upstream_check_module/ssl_hello_check.t create mode 100644 tests/test-nginx/dso_cases/ngx_http_upstream_check_module/tcp_check.t create mode 100644 tests/test-nginx/dso_cases/syslog.t create mode 100644 tests/test-nginx/dso_cases/user_agent.t diff --git a/tests/nginx-tests/README b/tests/nginx-tests/README new file mode 100644 index 0000000000..6638a43cb0 --- /dev/null +++ b/tests/nginx-tests/README @@ -0,0 +1,15 @@ +Just test static modules: + +TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove cases +TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove nginx-tests + +Just test the dso modules: + +1. RUN the test command with TEST_NGINX_DSO=1 +TEST_NGINX_DSO=1 TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove cases +TEST_NGINX_DSO=1 TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove dso-nginx-tests + +2. Add the dso module to the test script (The example module shared library should be under the modules directory): +$t->set_dso("ngx_http_example_module", "lib_ngx_http_example_module.so"); +... +%%TEST_GLOBALS_DSO%% diff --git a/tests/nginx-tests/cases/expires_by_types.t b/tests/nginx-tests/cases/expires_by_types.t index e078ca8bbd..74492196c6 100644 --- a/tests/nginx-tests/cases/expires_by_types.t +++ b/tests/nginx-tests/cases/expires_by_types.t @@ -24,14 +24,21 @@ use Time::Parse; select STDERR; $| = 1; select STDOUT; $| = 1; -my $t = Test::Nginx->new()->plan(72) - ->write_file_expand('nginx.conf', <<'EOF'); +my $t = Test::Nginx->new()->plan(72); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -159,6 +166,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -234,6 +243,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -311,6 +322,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -390,6 +403,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -471,6 +486,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -553,6 +570,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -634,6 +653,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } diff --git a/tests/nginx-tests/cases/http_error_page_merge.t b/tests/nginx-tests/cases/http_error_page_merge.t index 3a1aca9efa..14cf6479e0 100644 --- a/tests/nginx-tests/cases/http_error_page_merge.t +++ b/tests/nginx-tests/cases/http_error_page_merge.t @@ -21,14 +21,21 @@ use Test::Nginx; select STDERR; $| = 1; select STDOUT; $| = 1; -my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(16) - ->write_file_expand('nginx.conf', <<'EOF'); +my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(16); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -139,6 +146,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } diff --git a/tests/nginx-tests/cases/limit_req_enhance.t b/tests/nginx-tests/cases/limit_req_enhance.t index aeba8b213c..702fb3b16b 100644 --- a/tests/nginx-tests/cases/limit_req_enhance.t +++ b/tests/nginx-tests/cases/limit_req_enhance.t @@ -23,6 +23,11 @@ use Test::Nginx; my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(27); +$t->set_dso("ngx_http_limit_req_module", "lib_ngx_http_limit_req_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + $t->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% @@ -30,6 +35,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } @@ -178,6 +185,8 @@ $t->write_file_expand('nginx.conf', <<'EOF'); master_process off; daemon off; +%%TEST_GLOBALS_DSO%% + events { } diff --git a/tests/nginx-tests/dso-nginx-tests/auth_basic.t b/tests/nginx-tests/dso-nginx-tests/auth_basic.t new file mode 100644 index 0000000000..d8f8200582 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/auth_basic.t @@ -0,0 +1,117 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for auth basic module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use MIME::Base64; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http auth_basic/)->plan(11); + +#$t->set_dso("ngx_http_auth_basic_module", "lib_ngx_http_auth_basic_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + auth_basic "closed site"; + auth_basic_user_file %%TESTDIR%%/htpasswd; + } + } +} + +EOF + +my $d = $t->testdir(); + +$t->write_file('index.html', 'SEETHIS'); + +$t->write_file( + 'htpasswd', + 'crypt:' . crypt('password', 'salt') . "\n" . + 'crypt1:' . crypt('password', '$1$salt$') . "\n" . + 'apr1:' . '$apr1$salt$Xxd1irWT9ycqoYxGFn4cb.' . "\n" . + 'plain:' . '{PLAIN}password' . "\n" . + 'ssha:' . '{SSHA}yI6cZwQadOA1e+/f+T+H3eCQQhRzYWx0' . "\n" +); + +$t->run(); + +############################################################################### + +like(http_get('/'), qr!401 Unauthorized!ms, 'rejects unathorized'); + +like(http_get_auth('/', 'crypt', 'password'), qr!SEETHIS!, 'normal crypt'); +unlike(http_get_auth('/', 'crypt', '123'), qr!SEETHIS!, 'normal wrong'); + +like(http_get_auth('/', 'crypt1', 'password'), qr!SEETHIS!, 'crypt $1$ (md5)'); +unlike(http_get_auth('/', 'crypt1', '123'), qr!SEETHIS!, 'crypt $1$ wrong'); + +like(http_get_auth('/', 'apr1', 'password'), qr!SEETHIS!, 'apr1 md5'); +like(http_get_auth('/', 'plain', 'password'), qr!SEETHIS!, 'plain password'); + +SKIP: { + # SHA1 may not be available unless we have OpenSSL + + skip 'no sha1', 1 unless $t->has_module('--with-http_ssl_module') + or $t->has_module('--with-sha1') + or $t->has_module('--with-openssl'); + + like(http_get_auth('/', 'ssha', 'password'), qr!SEETHIS!, 'ssha'); +} + +unlike(http_get_auth('/', 'apr1', '123'), qr!SEETHIS!, 'apr1 md5 wrong'); +unlike(http_get_auth('/', 'plain', '123'), qr!SEETHIS!, 'plain wrong'); +unlike(http_get_auth('/', 'ssha', '123'), qr!SEETHIS!, 'ssha wrong'); + +############################################################################### + +sub http_get_auth { + my ($url, $user, $password) = @_; + + my $auth = encode_base64($user . ':' . $password); + + my $r = http(<new()->has(qw/http autoindex/)->plan(16); + +$t->set_dso("ngx_http_autoindex_module", "lib_ngx_http_autoindex_module.so"); +$t->set_dso("ngx_http_charset_filter_module", "lib_ngx_http_charset_filter_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + autoindex on; + } + location /utf8/ { + autoindex on; + charset utf-8; + } + } +} + +EOF + +my $d = $t->testdir(); + +mkdir("$d/test-dir"); +symlink("$d/test-dir", "$d/test-dir-link"); + +$t->write_file('test-file', ''); +symlink("$d/test-file", "$d/test-file-link"); + +$t->write_file('test-colon:blah', ''); +$t->write_file('test-long-' . ('0' x 50), ''); +$t->write_file('test-long-' . ('>' x 50), ''); +$t->write_file('test-escape-url-%', ''); +$t->write_file('test-escape-url2-?', ''); +$t->write_file('test-escape-html-<>&', ''); + +mkdir($d . '/utf8'); +$t->write_file('utf8/test-utf8-' . ("\xd1\x84" x 3), ''); +$t->write_file('utf8/test-utf8-' . ("\xd1\x84" x 45), ''); +$t->write_file('utf8/test-utf8-<>&-' . "\xd1\x84", ''); +$t->write_file('utf8/test-utf8-<>&-' . ("\xd1\x84" x 45), ''); +$t->write_file('utf8/test-utf8-' . ("\xd1\x84" x 3) . '-' . ('>' x 45), ''); + +mkdir($d . '/test-dir-escape-<>&'); + +$t->run(); + +############################################################################### + +my $r = http_get('/'); + +like($r, qr!href="test-file"!ms, 'file'); +like($r, qr!href="test-file-link"!ms, 'symlink to file'); +like($r, qr!href="test-dir/"!ms, 'directory'); +like($r, qr!href="test-dir-link/"!ms, 'symlink to directory'); + +unlike($r, qr!href="test-colon:blah"!ms, 'colon not scheme'); +like($r, qr!test-long-0{37}\.\.>!ms, 'long name'); + +like($r, qr!href="test-escape-url-%25"!ms, 'escaped url'); +like($r, qr!href="test-escape-url2-%3f"!ms, 'escaped ? in url'); +like($r, qr!test-escape-html-<>&!ms, 'escaped html'); +like($r, qr!test-long-(>){37}\.\.>!ms, 'long escaped html'); + +$r = http_get('/utf8/'); + +like($r, qr!test-utf8-(\xd1\x84){3}!ms, 'utf8'); +like($r, qr!test-utf8-(\xd1\x84){37}\.\.!ms, 'utf8 long'); + +like($r, qr!test-utf8-<>&-\xd1\x84!ms, 'utf8 escaped'); +like($r, qr!test-utf8-<>&-(\xd1\x84){33}\.\.!ms, + 'utf8 escaped long'); +like($r, qr!test-utf8-(\xd1\x84){3}-(>){33}\.\.!ms, 'utf8 long escaped'); + +like(http_get('/test-dir-escape-<>&/'), qr!test-dir-escape-<>&!ms, + 'escaped title'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/dav.t b/tests/nginx-tests/dso-nginx-tests/dav.t new file mode 100644 index 0000000000..2fe2d0de81 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/dav.t @@ -0,0 +1,141 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx dav module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http dav/)->plan(13); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + dav_methods PUT DELETE MKCOL COPY MOVE; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +my $r; + +$r = http(<testdir() . '/file', 10, 'put file size'); + +$r = http(<testdir() . '/file', 0, 'put file again size'); + +$r = http(<testdir() . '/file', 'file deleted'); + +$r = http(<testdir() . '/file', 10, + 'put file extra data size'); + +# 201 replies contain body, response should indicate it's empty + +$r = http(< 'FCGI not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http fastcgi/)->plan(5); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + fastcgi_pass 127.0.0.1:8081; + fastcgi_param REQUEST_URI $request_uri; + } + } +} + +EOF + +$t->run_daemon(\&fastcgi_daemon); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/SEE-THIS/, 'fastcgi request'); +like(http_get('/redir'), qr/302/, 'fastcgi redirect'); +like(http_get('/'), qr/^3$/m, 'fastcgi third request'); + +unlike(http_head('/'), qr/SEE-THIS/, 'no data in HEAD'); + +like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr handled'); + +############################################################################### + +sub fastcgi_daemon { + my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5); + my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, + $socket); + + my $count; + while( $request->Accept() >= 0 ) { + $count++; + + if ($ENV{REQUEST_URI} eq '/stderr') { + warn "sample stderr text" x 512; + } + + print < 'FCGI not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(5); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + fastcgi_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + fastcgi_pass 127.0.0.1:8081; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_cache NAME; + fastcgi_cache_key $request_uri; + fastcgi_cache_valid 302 1m; + } + } +} + +EOF + +$t->run_daemon(\&fastcgi_daemon); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/SEE-THIS/, 'fastcgi request'); +like(http_get('/'), qr/SEE-THIS/, 'fastcgi request cached'); + +unlike(http_head('/'), qr/SEE-THIS/, 'no data in cached HEAD'); + +like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr handled'); +like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr cached'); + +############################################################################### + +sub fastcgi_daemon { + my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5); + my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, + $socket); + + my $count; + while( $request->Accept() >= 0 ) { + $count++; + + if ($ENV{REQUEST_URI} eq '/stderr') { + warn "sample stderr text" x 512; + } + + print < 'FCGI not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http fastcgi/)->plan(1); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + fastcgi_pass 127.0.0.1:8081; + fastcgi_param HTTP_X_BLAH "blah"; + } + } +} + +EOF + +$t->run_daemon(\&fastcgi_daemon); +$t->run(); + +############################################################################### + +SKIP: { +skip 'unsafe', 1 unless $ENV{TEST_NGINX_UNSAFE}; + +local $TODO = 'not yet'; + +like(http_get_headers('/'), qr/SEE-THIS/, + 'fastcgi request with many ignored headers'); + +} + +############################################################################### + +sub http_get_headers { + my ($url, %extra) = @_; + return http(<Accept() >= 0 ) { + $count++; + + print < 'FCGI not installed') if $@; + + +my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(9); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + fastcgi_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + fastcgi_param HTTP_X_BLAH "blah"; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + fastcgi_cache NAME; + + location / { + fastcgi_pass 127.0.0.1:8081; + } + + location /no/ { + fastcgi_pass 127.0.0.1:8081; + fastcgi_cache off; + } + + location /custom/ { + fastcgi_pass 127.0.0.1:8081; + fastcgi_param HTTP_X_BLAH "custom"; + } + } +} + +EOF + +$t->run_daemon(\&fastcgi_daemon); +$t->run(); + +############################################################################### + +like(http_get_ims('/'), qr/ims=;/, + 'if-modified-since cleared with cache'); +like(http_get_ims('/'), qr/iums=;/, + 'if-unmodified-since cleared with cache'); +like(http_get_ims('/'), qr/blah=blah;/, + 'custom params with cache'); + +like(http_get_ims('/no/'), qr/ims=blah;/, + 'if-modified-since preserved without cache'); +like(http_get_ims('/no/'), qr/iums=blah;/, + 'if-unmodified-since preserved without cache'); +like(http_get_ims('/'), qr/blah=blah;/, + 'custom params without cache'); + +like(http_get_ims('/custom/'), qr/ims=;/, + 'if-modified-since cleared with cache custom'); +like(http_get_ims('/custom/'), qr/iums=;/, + 'if-unmodified-since cleared with cache custom'); +like(http_get_ims('/custom/'), qr/blah=custom;/, + 'custom params with cache custom'); + +############################################################################### + +sub http_get_ims { + my ($url) = @_; + return http(<Accept() >= 0 ) { + $count++; + + my $ims = $ENV{HTTP_IF_MODIFIED_SINCE}; + my $iums = $ENV{HTTP_IF_UNMODIFIED_SINCE}; + my $blah = $ENV{HTTP_X_BLAH}; + + print < 'FCGI not installed') if $@; + + +my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(4); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + fastcgi_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + # no fastcgi_param at all, cache switched on at server level + + server { + listen 127.0.0.1:8080; + server_name localhost; + + fastcgi_cache NAME; + + location / { + fastcgi_pass 127.0.0.1:8081; + } + + location /no/ { + fastcgi_pass 127.0.0.1:8081; + fastcgi_cache off; + } + } +} + +EOF + +$t->run_daemon(\&fastcgi_daemon); +$t->run(); + +############################################################################### + +like(http_get_ims('/'), qr/ims=;/, + 'if-modified-since cleared with cache'); +like(http_get_ims('/'), qr/iums=;/, + 'if-unmodified-since cleared with cache'); + +like(http_get_ims('/no/'), qr/ims=blah;/, + 'if-modified-since preserved without cache'); +like(http_get_ims('/no/'), qr/iums=blah;/, + 'if-unmodified-since preserved without cache'); + +############################################################################### + +sub http_get_ims { + my ($url) = @_; + return http(<Accept() >= 0 ) { + $count++; + + my $ims = $ENV{HTTP_IF_MODIFIED_SINCE}; + my $iums = $ENV{HTTP_IF_UNMODIFIED_SINCE}; + my $blah = $ENV{HTTP_X_BLAH}; + + print <new()->has(qw/http proxy gzip/)->plan(8); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + gzip on; + } + location /proxy/ { + gzip on; + proxy_pass http://127.0.0.1:8080/local/; + } + location /local/ { + gzip off; + alias %%TESTDIR%%/; + } + } +} + +EOF + +$t->write_file('index.html', 'X' x 64); + +$t->run(); + +############################################################################### + +my $r; + +$r = http_gzip_request('/'); +like($r, qr/^Content-Encoding: gzip/m, 'gzip'); +http_gzip_like($r, qr/^X{64}\Z/, 'gzip content correct'); + +$r = http_gzip_request('/proxy/'); +like($r, qr/^Content-Encoding: gzip/m, 'gzip proxied'); +http_gzip_like($r, qr/^X{64}\Z/, 'gzip proxied content'); + +# Accept-Ranges headers should be cleared + +unlike(http_gzip_request('/'), qr/Accept-Ranges/im, 'cleared accept-ranges'); +unlike(http_gzip_request('/proxy/'), qr/Accept-Ranges/im, + 'cleared headers from proxy'); + +# HEAD requests should return correct headers + +like(http_gzip_head('/'), qr/Content-Encoding: gzip/, 'gzip head'); +unlike(http_head('/'), qr/Content-Encoding: gzip/, 'no gzip head'); + +############################################################################### + +sub http_gzip_head { + my ($uri) = @_; + return http(<new()->has(qw/http gzip perl/)->plan(2); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + gzip on; + gzip_min_length 0; + + location / { + perl 'sub { + my $r = shift; + $r->send_http_header("text/html"); + return OK if $r->header_only; + $r->print("DA"); + $r->flush(); + $r->flush(); + $r->print("TA"); + return OK; + }'; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_get('/'), qr/DATA/, 'request with flush'); + +TODO: { +local $TODO = 'not yet'; + +# gzip filter doesn't properly handle empty flush buffers, see +# http://nginx.org/pipermail/nginx/2010-November/023693.html + +http_gzip_like(http_gzip_request('/'), qr/DATA/, 'gzip request with flush'); + +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t b/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t new file mode 100644 index 0000000000..da7734c8ab --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t @@ -0,0 +1,301 @@ +#!/usr/bin/perl + +# (C) Andrey Belov + +# Tests for disable_symlinks directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use POSIX; +use Cwd qw/ realpath /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite/); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name s1; + + location /on/ { + disable_symlinks on; + } + + location /not_owner/ { + disable_symlinks if_not_owner; + } + + location /try_on/ { + disable_symlinks on; + try_files $uri $uri.html =404; + } + + location /try_not_owner/ { + disable_symlinks if_not_owner; + try_files $uri $uri.txt =404; + } + + location /if_on/ { + disable_symlinks on; + if (-f $request_filename) { + return 204; + } + } + + location /if_not_owner/ { + disable_symlinks if_not_owner; + if (-f $request_filename) { + return 204; + } + } + + location /complex/1/ { + disable_symlinks on; + alias %%TESTDIR%%/./cached/../; + } + + location /complex/2/ { + disable_symlinks on; + alias %%TESTDIR%%//./cached/..//; + } + + location /complex/3/ { + disable_symlinks on; + alias ///%%TESTDIR%%//./cached/..//; + } + + location ~ (.+/)tail$ { + disable_symlinks on; + alias %%TESTDIR%%/$1; + } + + location ~ (.+/)tailowner$ { + disable_symlinks if_not_owner; + alias %%TESTDIR%%/$1; + } + + location ~ (.+/)tailoff$ { + disable_symlinks off; + alias %%TESTDIR%%/$1; + } + + location /dir { + disable_symlinks on; + try_files $uri/ =404; + } + + location /from { + disable_symlinks on from=$document_root; + + location /from/wo_slash { + alias %%TESTDIR%%/dirlink; + } + location /from/with_slash/ { + alias %%TESTDIR%%/dirlink/; + } + location ~ ^/from/exact/(.+)$ { + alias %%TESTDIR%%/$1; + } + } + } + + server { + listen 127.0.0.1:8080; + server_name s2; + + open_file_cache max=16 inactive=60s; + open_file_cache_valid 30s; + open_file_cache_min_uses 1; + open_file_cache_errors on; + + location /cached-off/ { + disable_symlinks off; + alias %%TESTDIR%%/cached/; + } + + location /cached-on/ { + disable_symlinks on; + alias %%TESTDIR%%/cached/; + } + + location /cached-if-not-owner/ { + disable_symlinks if_not_owner; + alias %%TESTDIR%%/cached/; + } + + location / { + disable_symlinks off; + } + } +} + +EOF + +eval { + open OLDERR, ">&", \*STDERR; close STDERR; + $t->run(); + open STDERR, ">&", \*OLDERR; +}; +plan(skip_all => 'no disable_symlinks') if $@; + +my $uid = getuid(); +my ($extfile) = grep { -f "$_" && $uid != (stat($_))[4] } + ('/etc/resolv.conf', '/etc/protocols', '/etc/host.conf'); + +plan(skip_all => 'no external file found') + if !defined $extfile; + +my $d = $t->testdir(); + +$t->plan(28); + +mkdir("$d/on"); +mkdir("$d/not_owner"); +mkdir("$d/try_on"); +mkdir("$d/try_not_owner"); +mkdir("$d/if_on"); +mkdir("$d/if_not_owner"); +mkdir("$d/cached"); + +$t->write_file("empty.html", ""); +symlink("empty.html", "$d/link"); +symlink($extfile, "$d/link2"); + +$t->write_file("on/empty.html", ""); +symlink("empty.html", "$d/on/link"); +symlink($extfile, "$d/on/link2"); + +$t->write_file("not_owner/empty.html", ""); +symlink("empty.html", "$d/not_owner/link"); +symlink($extfile, "$d/not_owner/link2"); + +$t->write_file("try_on/try.html", "LOCAL TRY"); +symlink($extfile, "$d/try_on/try"); + +$t->write_file("try_not_owner/try.html", "LOCAL TRY"); +symlink($extfile, "$d/try_not_owner/try"); +symlink("try.html", "$d/try_not_owner/try.txt"); + +$t->write_file("if_on/empty.html", ""); +symlink("empty.html", "$d/if_on/link"); +symlink($extfile, "$d/if_on/link2"); + +$t->write_file("if_not_owner/empty.html", ""); +symlink("empty.html", "$d/if_not_owner/link"); +symlink($extfile, "$d/if_not_owner/link2"); + +mkdir("$d/dir"); +$t->write_file("dir/empty.html", ""); +symlink("dir", "$d/dirlink"); + +symlink($extfile, "$d/cached/link"); + +############################################################################### + +SKIP: { +skip 'cannot test under symlink', 25 if $d ne realpath($d); + +like(http_get_host('s1', '/link'), qr!200 OK!, 'static (off, same uid)'); +like(http_get_host('s1', '/link2'), qr!200 OK!, 'static (off, other uid)'); + +like(http_get_host('s1', '/on/link'), qr!403 Forbidden!, + 'static (on, same uid)'); +like(http_get_host('s1', '/on/link2'), qr!403 Forbidden!, + 'static (on, other uid)'); + +like(http_get_host('s1', '/not_owner/link'), qr!200 OK!, + 'static (if_not_owner, same uid)'); +like(http_get_host('s1', '/not_owner/link2'), qr!403 Forbidden!, + 'static (if_not_owner, other uid)'); + +like(http_get_host('s1', '/try_on/try'), qr/LOCAL TRY/, + 'try_files (on)'); +like(http_get_host('s1', '/try_not_owner/try'), qr/LOCAL TRY/, + 'try_files (if_not_owner)'); + +like(http_get_host('s1', '/if_on/link'), qr!403 Forbidden!, + 'if (on, same uid)'); +like(http_get_host('s1', '/if_on/link2'), qr!403 Forbidden!, + 'if (on, other uid)'); + +like(http_get_host('s1', '/if_not_owner/link'), qr!204 No Content!, + 'if (if_not_owner, same uid)'); +like(http_get_host('s1', '/if_not_owner/link2'), qr!403 Forbidden!, + 'if (if_not_owner, other uid)'); + +like(http_get_host('s2', '/cached-off/link'), qr!200 OK!, + 'open_file_cache (pass 1)'); +like(http_get_host('s2', '/cached-on/link'), qr!403 Forbidden!, + 'open_file_cache (pass 2)'); +like(http_get_host('s2', '/cached-off/link'), qr!200 OK!, + 'open_file_cache (pass 3)'); +like(http_get_host('s2', '/cached-if-not-owner/link'), qr!403 Forbidden!, + 'open_file_cache (pass 4)'); +like(http_get_host('s2', '/cached-off/link'), qr!200 OK!, + 'open_file_cache (pass 5)'); + +like(http_get('/complex/1/empty.html'), qr!200 OK!, 'complex root 1'); +like(http_get('/complex/2/empty.html'), qr!200 OK!, 'complex root 2'); +like(http_get('/complex/3/empty.html'), qr!200 OK!, 'complex root 3'); + +# workaround for freebsd 8: we use O_EXEC instead of O_SEARCH (since there +# is no O_SEARCH), and O_DIRECTORY does nothing. setting the 'x' bit +# tests to pass as openat() will correctly fail with ENOTDIR + +chmod(0700, "$d/link"); + +like(http_get('/link/tail'), qr!40[34] !, 'file with trailing /, on'); +like(http_get('/link/tailowner'), qr!404 !, 'file with trailing /, owner'); +like(http_get('/link/tailoff'), qr!404 !, 'file with trailing /, off'); + +like(http_get('/dirlink'), qr!404 !, 'directory without /'); +like(http_get('/dirlink/'), qr!404 !, 'directory with trailing /'); + +} # SKIP: cannot test under symlink + +like(http_get('/from/wo_slash/empty.html'), qr!200 OK!, '"from=" without /'); +like(http_get('/from/with_slash/empty.html'), qr!200 OK!, '"from=" with /'); +like(http_get('/from/exact/link'), qr!200 OK!, '"from=" exact match'); + +############################################################################### + +sub http_get_host { + my ($host, $url) = @_; + return http(<new()->has(qw/http rewrite/)->plan(7); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /redirect200 { + error_page 404 =200 http://example.com/; + return 404; + } + + location /redirect497 { + # 497 implies implicit status code change + error_page 497 https://example.com/; + return 497; + } + + location /error302redirect { + error_page 302 http://example.com/; + return 302 "first"; + } + + location /error302return302text { + error_page 302 /return302text; + return 302 "first"; + } + + location /return302text { + return 302 "http://example.com/"; + } + + location /error302rewrite { + error_page 302 /rewrite; + return 302 "first"; + } + + location /rewrite { + rewrite ^ http://example.com/; + } + + location /error302directory { + error_page 302 /directory; + return 302 "first"; + } + + location /directory { + } + + location /error302auto { + error_page 302 /auto; + return 302 "first"; + } + + location /auto/ { + proxy_pass http://127.0.0.1:8081; + } + } +} + +EOF + +mkdir($t->testdir() . '/directory'); + +$t->run(); + +############################################################################### + +# tests for error_page status code change for redirects. problems +# introduced in 0.8.53 and fixed in 0.9.5. + +like(http_get('/redirect200'), qr!HTTP!, 'redirect 200'); +like(http_get('/redirect497'), qr!HTTP/1.1 302!, 'redirect 497'); + +# various tests to see if old location cleared if we happen to redirect +# again in error_page 302 + +like(http_get('/error302redirect'), + qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms, + 'error 302 redirect - old location cleared'); + +like(http_get('/error302return302text'), + qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms, + 'error 302 return 302 text - old location cleared'); + +like(http_get('/error302rewrite'), + qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms, + 'error 302 rewrite - old location cleared'); + +like(http_get('/error302directory'), + qr{HTTP/1.1 301(?!.*Location: first).*Location: http://}ms, + 'error 302 directory redirect - old location cleared'); + +like(http_get('/error302auto'), + qr{HTTP/1.1 301(?!.*Location: first).*Location: http://}ms, + 'error 302 auto redirect - old location cleared'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t b/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t new file mode 100644 index 0000000000..262756127f --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t @@ -0,0 +1,87 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for Expect: 100-continue support. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(2); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + proxy_pass http://localhost:8080/local; + } + location /local { + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_100_request('/', '1.1'), qr/100/, 'expect 100 continue'); + +# From RFC 2616, 8.2.3 Use of the 100 (Continue) Status: +# +# - An origin server SHOULD NOT send a 100 (Continue) response if +# the request message does not include an Expect request-header +# field with the "100-continue" expectation, and MUST NOT send a +# 100 (Continue) response if such a request comes from an HTTP/1.0 +# (or earlier) client. + +unlike(http_100_request('/', '1.0'), qr/100/, 'no 100 continue via http 1.0'); + +############################################################################### + +sub http_100_request { + my ($url, $version) = @_; + my $r = http(<new()->has(qw/http rewrite/)->plan(35); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + return 200 $host; + } + } +} + +EOF + +$t->run(); + +############################################################################### + + +is(http_host_header('www.abcd-ef.g02.xyz'), 'www.abcd-ef.g02.xyz', + 'domain w/o port (host header)'); +is(http_host_header('abcd-ef.g02.xyz:8080'), 'abcd-ef.g02.xyz', + 'domain w/port (host header)'); + +is(http_absolute_path('abcd-ef.g02.xyz'), 'abcd-ef.g02.xyz', + 'domain w/o port (absolute request)'); +is(http_absolute_path('www.abcd-ef.g02.xyz:10'), 'www.abcd-ef.g02.xyz', + 'domain w/port (absolute request)'); + + +is(http_host_header('www.abcd-ef.g02.xyz.'), 'www.abcd-ef.g02.xyz', + 'domain w/ ending dot w/o port (host header)'); + +TODO:{ +local $TODO = 'fix this'; + +is(http_host_header('abcd-ef.g02.xyz.:88'), 'abcd-ef.g02.xyz', + 'domain w/ ending dot w/port (host header)'); + +} + +is(http_absolute_path('www.abcd-ef.g02.xyz.'), 'www.abcd-ef.g02.xyz', + 'domain w/ ending dot w/o port (absolute request)'); +is(http_absolute_path('abcd-ef.g02.xyz.:2'), 'abcd-ef.g02.xyz', + 'domain w/ ending dot w/port (absolute request)'); + + +is(http_absolute_path('AbC-d93.0.34ZhGt-s.nk.Ru'), 'abc-d93.0.34zhgt-s.nk.ru', + 'mixed case domain w/o port (absolute request)'); +is(http_host_header('AbC-d93.0.34ZhGt-s.nk.Ru:88'), 'abc-d93.0.34zhgt-s.nk.ru', + 'mixed case domain w/port (host header)'); + + +is(http_host_header('123.40.56.78'), '123.40.56.78', + 'ipv4 w/o port (host header)'); +is(http_host_header('123.49.0.78:987'), '123.49.0.78', + 'ipv4 w/port (host header)'); + +is(http_absolute_path('123.49.0.78'), '123.49.0.78', + 'ipv4 w/o port (absolute request)'); +is(http_absolute_path('123.40.56.78:123'), '123.40.56.78', + 'ipv4 w/port (absolute request)'); + +TODO: { +local $TODO = 'ipv6 literals'; + +is(http_host_header('[abcd::ef98:0:7654:321]'), '[abcd::ef98:0:7654:321]', + 'ipv6 literal w/o port (host header)'); + +} + +is(http_host_header('[abcd::ef98:0:7654:321]:80'), '[abcd::ef98:0:7654:321]', + 'ipv6 literal w/port (host header)'); + +TODO: { +local $TODO = 'ipv6 literals'; + +is(http_absolute_path('[abcd::ef98:0:7654:321]'), '[abcd::ef98:0:7654:321]', + 'ipv6 literal w/o port (absolute request)'); +is(http_absolute_path('[abcd::ef98:0:7654:321]:5'), '[abcd::ef98:0:7654:321]', + 'ipv6 literal w/port (absolute request)'); + +is(http_host_header('[::ffff:12.30.67.89]'), '[::ffff:12.30.67.89]', + 'ipv4-mapped ipv6 w/o port (host header)'); +} + +is(http_host_header('[::123.45.67.89]:4321'), '[::123.45.67.89]', + 'ipv4-mapped ipv6 w/port (host header)'); + +TODO: { +local $TODO = 'ipv6 literals'; + +is(http_absolute_path('[::123.45.67.89]'), '[::123.45.67.89]', + 'ipv4-mapped ipv6 w/o port (absolute request)'); +is(http_absolute_path('[::ffff:12.30.67.89]:4321'), '[::ffff:12.30.67.89]', + 'ipv4-mapped ipv6 w/port (absolute request)'); + +} + +like(http_host_header('example.com/\:552', 1), qr/400/, + 'domain w/ path separators (host header)'); +like(http_absolute_path('\e/xample.com', 1), qr/400/, + 'domain w/ path separators (absolute request)'); + +like(http_host_header('..examp-LE.com', 1), qr/400/, + 'domain w/ double dot (host header)'); +like(http_absolute_path('com.exa-m.45..:', 1), qr/400/, + 'domain w/ double dot (absolute request)'); + + +like(http_host_header('[abcd::e\f98:0/:7654:321]', 1), qr/400/, + 'ipv6 literal w/ path separators (host header)'); +like(http_absolute_path('[abcd\::ef98:0:7654:321/]:12', 1), qr/400/, + 'ipv6 literal w/ path separators (absolute request)'); + +like(http_host_header('[abcd::ef98:0:7654:321]..:98', 1), qr/400/, + 'ipv6 literal w/ double dot (host header)'); +like(http_absolute_path('[ab..cd::ef98:0:7654:321]', 1), qr/400/, + 'ipv6 literal w/ double dot (absolute request)'); + + +like(http_host_header('[abcd::ef98:0:7654:321]..:98', 1), qr/400/, + 'ipv6 literal w/ double dot (host header)'); +like(http_absolute_path('[ab..cd::ef98:0:7654:321]', 1), qr/400/, + 'ipv6 literal w/ double dot (absolute request)'); + + +# As per RFC 3986, +# http://tools.ietf.org/html/rfc3986#section-3.2.2 +# +# IP-literal = "[" ( IPv6address / IPvFuture ) "]" +# +# IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) +# +# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" +# / "*" / "+" / "," / ";" / "=" +# +# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" +# + +TODO: { +local $TODO = 'IPvFuture'; + +is(http_host_header( + '[v0123456789aBcDeF.!$&\'()*+,;=-._~AbCdEfGhIjKlMnOpQrStUvWxYz' + . '0123456789:]'), + '[v0123456789abcdef.!$&\'()*+,;=-._~abcdefghijklmnopqrstuvwxyz' + . '0123456789:]', + 'IPvFuture all symbols (host header)'); + +is(http_absolute_path( + '[v0123456789aBcDeF.!$&\'()*+,;=-._~AbCdEfGhIjKlMnOpQrStUvWxYz' + . '0123456789:]'), + '[v0123456789abcdef.!$&\'()*+,;=-._~abcdefghijklmnopqrstuvwxyz' + . '0123456789:]', + 'IPvFuture all symbols (absolute request)'); + +} + +TODO: { +local $TODO = 'or not TODO'; + +is(http_host_header('123.40.56.78:9000:80'), '123.40.56.78', + 'double port hack'); + +} + +############################################################################### + +sub http_host_header { + my ($host, $all) = @_; + my ($r) = http(<new()->has(qw/http rewrite/)->plan(8); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location = / { + add_header X-Location exactlyroot; + return 204; + } + + location / { + add_header X-Location root; + return 204; + } + + location ^~ /images/ { + add_header X-Location images; + return 204; + } + + location ~* \.(gif|jpg|jpeg)$ { + add_header X-Location regex; + return 204; + } + + location ~ casefull { + add_header X-Location casefull; + return 204; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_get('/'), qr/X-Location: exactlyroot/, 'exactlyroot'); +like(http_get('/x'), qr/X-Location: root/, 'root'); +like(http_get('/images/t.gif'), qr/X-Location: images/, 'images'); +like(http_get('/t.gif'), qr/X-Location: regex/, 'regex'); +like(http_get('/t.GIF'), qr/X-Location: regex/, 'regex with mungled case'); +like(http_get('/casefull/t.gif'), qr/X-Location: regex/, 'first regex wins'); +like(http_get('/casefull/'), qr/X-Location: casefull/, 'casefull regex'); +like(http_get('/CASEFULL/'), qr/X-Location: root/, + 'casefull regex do not match wrong case'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/http_server_name.t b/tests/nginx-tests/dso-nginx-tests/http_server_name.t new file mode 100644 index 0000000000..b8560d1784 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/http_server_name.t @@ -0,0 +1,138 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for server_name selection. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(9); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server_names_hash_bucket_size 64; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + add_header X-Server $server_name; + return 204; + } + } + + server { + listen 127.0.0.1:8080; + server_name www.example.com; + + location / { + add_header X-Server $server_name; + return 204; + } + } + + server { + listen 127.0.0.1:8080; + server_name ~^EXAMPLE\.COM$; + + location / { + add_header X-Server $server_name; + return 204; + } + } + + server { + listen 127.0.0.1:8080; + server_name ~^(?P.+)\Q.example.com\E$; + + location / { + add_header X-Server $server_name; + add_header X-Match $name; + return 204; + } + } + + server { + listen 127.0.0.1:8080; + server_name "~^(?Pwww\p{N}+)\.example\.com$"; + + location / { + add_header X-Server $server_name; + add_header X-Match $name; + return 204; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +sub http_server($) { + my ($host) = @_; + return http(<.*).example.com named capture'); +like(http_server('BLAH.EXAMPLE.COM'), qr/X-Match: blah/, + '(P.*).example.com named capture uppercase'); + +like(http_server('www01.example.com'), qr/X-Match: www01/, + '\p{N} in named capture'); +like(http_server('WWW01.EXAMPLE.COM'), qr/X-Match: www01/, + '\p{N} in named capture uppercase'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/http_try_files.t b/tests/nginx-tests/dso-nginx-tests/http_try_files.t new file mode 100644 index 0000000000..64ebda2052 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/http_try_files.t @@ -0,0 +1,97 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for try_files directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(4); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + try_files $uri /fallback; + } + + location /nouri/ { + try_files $uri /fallback_nouri; + } + + location /short/ { + try_files /short $uri =404; + } + + location /fallback { + proxy_pass http://127.0.0.1:8081/fallback; + } + location /fallback_nouri { + proxy_pass http://127.0.0.1:8081; + } + } + + server { + listen 127.0.0.1:8081; + server_name localhost; + + location / { + add_header X-URI $request_uri; + return 204; + } + } +} + +EOF + +$t->write_file('found.html', 'SEE THIS'); +$t->run(); + +############################################################################### + +like(http_get('/found.html'), qr!SEE THIS!, 'found'); +like(http_get('/uri/notfound'), qr!X-URI: /fallback!, 'not found uri'); +like(http_get('/short/long'), qr!404 Not!, 'short uri in try_files'); + +TODO: { +local $TODO = 'fixed in 1.1.12'; + +like(http_get('/nouri/notfound'), qr!X-URI: /fallback!, 'not found nouri'); + +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/http_variables.t b/tests/nginx-tests/dso-nginx-tests/http_variables.t new file mode 100644 index 0000000000..002a629659 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/http_variables.t @@ -0,0 +1,99 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin +# (C) Valentin Bartenev + +# Tests for http variables. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite proxy/)->plan(3); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + log_format cc "$uri: $sent_http_cache_control"; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + access_log %%TESTDIR%%/cc.log cc; + + location / { + return 200 OK; + } + + location /set { + add_header Cache-Control max-age=3600; + add_header Cache-Control private; + add_header Cache-Control must-revalidate; + return 200 OK; + } + + location /redefine { + expires epoch; + proxy_pass http://127.0.0.1:8080/set; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +http_get('/'); +http_get('/redefine'); + +$t->stop(); + +my $log; + +{ + open LOG, $t->testdir() . '/cc.log' + or die("Can't open nginx access log file.\n"); + local $/; + $log = ; + close LOG; +} + +like($log, qr!^/: -$!m, 'no header'); +like($log, qr!^/set: max-age=3600; private; must-revalidate$!m, + 'multi headers'); + +like($log, qr!^/redefine: no-cache$!m, 'ignoring headers with (hash == 0)'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/lib b/tests/nginx-tests/dso-nginx-tests/lib new file mode 120000 index 0000000000..179ed87a9b --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/lib @@ -0,0 +1 @@ +../nginx-tests/lib/ \ No newline at end of file diff --git a/tests/nginx-tests/dso-nginx-tests/limit_req.t b/tests/nginx-tests/dso-nginx-tests/limit_req.t new file mode 100644 index 0000000000..bc4e78e19e --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/limit_req.t @@ -0,0 +1,98 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx limit_req module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(5); + +$t->set_dso("ngx_http_limit_req_module", "lib_ngx_http_limit_req_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s; + limit_req_zone $binary_remote_addr zone=long:10m rate=2r/s; + limit_req_zone $binary_remote_addr zone=fast:10m rate=1000r/s; + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + limit_req zone=one burst=1 nodelay; + } + location /long { + limit_req zone=long burst=5; + } + location /fast { + limit_req zone=fast burst=1; + } + } +} + +EOF + +$t->write_file('test1.html', 'XtestX'); +$t->write_file('long.html', "1234567890\n" x (1 << 16)); +$t->write_file('fast.html', 'XtestX'); +$t->run(); + +############################################################################### + +like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'request'); +http_get('/test1.html'); +like(http_get('/test1.html'), qr/^HTTP\/1.. 503 /m, 'request rejected'); +http_get('/test1.html'); +http_get('/test1.html'); + +# Second request will be delayed by limit_req, make sure it isn't truncated. +# The bug only manifests itself if buffer will be filled, so sleep for a while +# before reading response. + +my $l1 = length(http_get('/long.html')); +my $l2 = length(http_get('/long.html', sleep => 0.6)); +is($l2, $l1, 'delayed big request not truncated'); + +# make sure rejected requests are not counted, and access is again allowed +# after 1/rate seconds + +like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'rejects not counted'); + +# make sure negative excess values are handled properly + +http_get('/fast.html'); +select undef, undef, undef, 0.1; +like(http_get('/fast.html'), qr/^HTTP\/1.. 200 /m, 'negative excess'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/mail_imap.t b/tests/nginx-tests/dso-nginx-tests/mail_imap.t new file mode 100644 index 0000000000..c5a6f5088c --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/mail_imap.t @@ -0,0 +1,133 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx mail imap module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use IO::Socket; +use MIME::Base64; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::IMAP; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +local $SIG{PIPE} = 'IGNORE'; + +my $t = Test::Nginx->new() + ->has(qw/mail imap http rewrite/)->plan(9); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->run_daemon(\&Test::Nginx::IMAP::imap_test_daemon) + ->write_file_expand('nginx.conf', <<'EOF')->run(); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +mail { + proxy_pass_error_message on; + auth_http http://127.0.0.1:8080/mail/auth; + + server { + listen 127.0.0.1:8143; + protocol imap; + } +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location = /mail/auth { + set $reply ERROR; + + if ($http_auth_smtp_to ~ example.com) { + set $reply OK; + } + + set $userpass "$http_auth_user:$http_auth_pass"; + if ($userpass ~ '^test@example.com:secret$') { + set $reply OK; + } + + add_header Auth-Status $reply; + add_header Auth-Server 127.0.0.1; + add_header Auth-Port 8144; + add_header Auth-Wait 1; + return 204; + } + } +} + +EOF + +############################################################################### + +my $s = Test::Nginx::IMAP->new(); +$s->ok('greeting'); + +# bad auth + +$s->send('1 AUTHENTICATE'); +$s->check(qr/^\S+ BAD/, 'auth without arguments'); + +# auth plain + +$s->send('1 AUTHENTICATE PLAIN ' . encode_base64("\0test\@example.com\0bad", '')); +$s->check(qr/^\S+ NO/, 'auth plain with bad password'); + +$s->send('1 AUTHENTICATE PLAIN ' . encode_base64("\0test\@example.com\0secret", '')); +$s->ok('auth plain'); + +# auth login simple + +$s = Test::Nginx::IMAP->new(); +$s->read(); + +$s->send('1 AUTHENTICATE LOGIN'); +$s->check(qr/\+ VXNlcm5hbWU6/, 'auth login username challenge'); + +$s->send(encode_base64('test@example.com', '')); +$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login password challenge'); + +$s->send(encode_base64('secret', '')); +$s->ok('auth login simple'); + +# auth login with username + +$s = Test::Nginx::IMAP->new(); +$s->read(); + +$s->send('1 AUTHENTICATE LOGIN ' . encode_base64('test@example.com', '')); +$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login with username password challenge'); + +$s->send(encode_base64('secret', '')); +$s->ok('auth login with username'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/mail_pop3.t b/tests/nginx-tests/dso-nginx-tests/mail_pop3.t new file mode 100644 index 0000000000..dae8158e0c --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/mail_pop3.t @@ -0,0 +1,128 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx mail pop3 module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use IO::Socket; +use MIME::Base64; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::POP3; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +local $SIG{PIPE} = 'IGNORE'; + +my $t = Test::Nginx->new() + ->has(qw/mail pop3 http rewrite/)->plan(8); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->run_daemon(\&Test::Nginx::POP3::pop3_test_daemon) + ->write_file_expand('nginx.conf', <<'EOF')->run(); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +mail { + proxy_pass_error_message on; + auth_http http://127.0.0.1:8080/mail/auth; + + server { + listen 127.0.0.1:8110; + protocol pop3; + } +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location = /mail/auth { + set $reply ERROR; + + if ($http_auth_smtp_to ~ example.com) { + set $reply OK; + } + + set $userpass "$http_auth_user:$http_auth_pass"; + if ($userpass ~ '^test@example.com:secret$') { + set $reply OK; + } + + add_header Auth-Status $reply; + add_header Auth-Server 127.0.0.1; + add_header Auth-Port 8111; + add_header Auth-Wait 1; + return 204; + } + } +} + +EOF + +############################################################################### + +my $s = Test::Nginx::POP3->new(); +$s->ok('greeting'); + +# auth plain + +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", '')); +$s->check(qr/^-ERR/, 'auth plain with bad password'); + +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", '')); +$s->ok('auth plain'); + +# auth login simple + +$s = Test::Nginx::POP3->new(); +$s->read(); + +$s->send('AUTH LOGIN'); +$s->check(qr/\+ VXNlcm5hbWU6/, 'auth login username challenge'); + +$s->send(encode_base64('test@example.com', '')); +$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login password challenge'); + +$s->send(encode_base64('secret', '')); +$s->ok('auth login simple'); + +# auth login with username + +$s = Test::Nginx::POP3->new(); +$s->read(); + +$s->send('AUTH LOGIN ' . encode_base64('test@example.com', '')); +$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login with username password challenge'); + +$s->send(encode_base64('secret', '')); +$s->ok('auth login with username'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/mail_smtp.t b/tests/nginx-tests/dso-nginx-tests/mail_smtp.t new file mode 100644 index 0000000000..36007c9ec0 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/mail_smtp.t @@ -0,0 +1,242 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx mail smtp module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use MIME::Base64; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::SMTP; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +local $SIG{PIPE} = 'IGNORE'; + +my $t = Test::Nginx->new() + ->has(qw/mail smtp http rewrite/)->plan(25); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon) + ->write_file_expand('nginx.conf', <<'EOF')->run(); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +mail { + proxy_pass_error_message on; + auth_http http://127.0.0.1:8080/mail/auth; + xclient off; + + server { + listen 127.0.0.1:8025; + protocol smtp; + smtp_auth login plain none; + } +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location = /mail/auth { + set $reply ERROR; + + if ($http_auth_smtp_to ~ example.com) { + set $reply OK; + } + + set $userpass "$http_auth_user:$http_auth_pass"; + if ($userpass ~ '^test@example.com:secret$') { + set $reply OK; + } + + add_header Auth-Status $reply; + add_header Auth-Server 127.0.0.1; + add_header Auth-Port 8026; + add_header Auth-Wait 1; + return 204; + } + } +} + +EOF + +############################################################################### + +my $s = Test::Nginx::SMTP->new(); +$s->check(qr/^220 /, "greeting"); + +$s->send('EHLO example.com'); +$s->check(qr/^250 /, "ehlo"); + +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", '')); +$s->check(qr/^5.. /, 'auth plain with bad password'); + +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", '')); +$s->authok('auth plain'); + +# We are talking to backend from this point + +$s->send('MAIL FROM: SIZE=100'); +$s->ok('mail from after auth'); + +$s->send('RSET'); +$s->ok('rset'); + +$s->send('MAIL FROM: SIZE=100'); +$s->ok("idn mail from (example.test in russian)"); + +$s->send('QUIT'); +$s->ok("quit"); + +# Try auth login in simple form + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); + +$s->send('AUTH LOGIN'); +$s->check(qr/^334 VXNlcm5hbWU6/, 'auth login simple username challenge'); +$s->send(encode_base64('test@example.com', '')); +$s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login simple password challenge'); +$s->send(encode_base64('secret', '')); +$s->authok('auth login simple'); + +# Try auth plain with username. Details: +# +# [MS-XLOGIN]: SMTP Protocol AUTH LOGIN Extension Specification +# http://download.microsoft.com/download/5/D/D/5DD33FDF-91F5-496D-9884-0A0B0EE698BB/%5BMS-XLOGIN%5D.pdf + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); + +$s->send('AUTH LOGIN ' . encode_base64('test@example.com', '')); +$s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login with username password challenge'); +$s->send(encode_base64('secret', '')); +$s->authok('auth login with username'); + +# Try auth plain with pipelining + +TODO: { +local $TODO = 'pipelining not in official nginx'; +local $SIG{__WARN__} = sub {}; + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); + +$s->send('INVALID COMMAND WITH ARGUMENTS' . CRLF + . 'RSET'); +$s->read(); +$s->ok('pipelined rset after invalid command'); + +$s->send('AUTH PLAIN ' + . encode_base64("\0test\@example.com\0bad", '') . CRLF + . 'MAIL FROM: SIZE=100'); +$s->read(); +$s->ok('mail from after failed pipelined auth'); + +$s->send('AUTH PLAIN ' + . encode_base64("\0test\@example.com\0secret", '') . CRLF + . 'MAIL FROM: SIZE=100'); +$s->read(); +$s->ok('mail from after pipelined auth'); + +} + +# Try auth none + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); + +$s->send('MAIL FROM: SIZE=100'); +$s->ok('auth none - mail from'); + +$s->send('RCPT TO:'); +$s->ok('auth none - rcpt to'); + +$s->send('RSET'); +$s->ok('auth none - rset, should go to backend'); + +# Auth none with pipelining + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); + +$s->send('MAIL FROM: SIZE=100' . CRLF + . 'RCPT TO:' . CRLF + . 'RSET'); + +$s->ok('pipelined mail from'); + +TODO: { +local $TODO = 'pipelining not in official nginx'; +local $SIG{__WARN__} = sub {}; + +$s->ok('pipelined rcpt to'); +$s->ok('pipelined rset'); + +} + +# Connection must stay even if error returned to rcpt to command + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); + +$s->send('MAIL FROM: SIZE=100'); +$s->read(); # skip mail from reply + +$s->send('RCPT TO:'); +$s->check(qr/^5.. /, "bad rcpt to"); + +$s->send('RCPT TO:'); +$s->ok('good rcpt to'); + +# Make sure command splitted into many packets processed correctly + +$s = Test::Nginx::SMTP->new(); +$s->read(); + +log_out('HEL'); +$s->print('HEL'); +$s->send('O example.com'); +$s->ok('splitted command'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t b/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t new file mode 100644 index 0000000000..4b098d4c70 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t @@ -0,0 +1,76 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::SMTP; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +local $SIG{PIPE} = 'IGNORE'; + +my $t = Test::Nginx->new()->has(qw/mail smtp http/)->plan(2); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF')->run(); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +mail { + proxy_pass_error_message on; + auth_http http://127.0.0.1:8080/mail/auth; + xclient off; + + server { + listen 127.0.0.1:8025; + protocol smtp; + smtp_greeting_delay 100ms; + } +} + +http { + # stub to avoid SIGSEGV when perl module compiled in, <= 0.7.30 +} + +EOF + +############################################################################### + +# With smtp_greeting_delay session expected to be closed after first error +# message if client sent something before greeting. + +my $s = Test::Nginx::SMTP->new(); +$s->send('HELO example.com'); +$s->check(qr/^5.. /, "command before greeting - session must be rejected"); + +TODO: { +local $TODO = 'not in official nginx yet'; + +ok($s->eof(), "session have to be closed"); + +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t b/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t new file mode 100644 index 0000000000..d2b655252d --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t @@ -0,0 +1,147 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use MIME::Base64; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::SMTP; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +local $SIG{PIPE} = 'IGNORE'; + +my $t = Test::Nginx->new()->has(qw/mail smtp http rewrite/)->plan(6); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon) + ->write_file_expand('nginx.conf', <<'EOF')->run(); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +mail { + proxy_pass_error_message on; + auth_http http://127.0.0.1:8080/mail/auth; + xclient on; + + server { + listen 127.0.0.1:8025; + protocol smtp; + smtp_auth login plain none; + } +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location = /mail/auth { + add_header Auth-Status OK; + add_header Auth-Server 127.0.0.1; + add_header Auth-Port 8026; + add_header Auth-Wait 1; + return 204; + } + } +} + +EOF + +############################################################################### + +# When XCLIENT's HELO= argument isn't used, the following combinations may be +# send to backend with xclient on: +# +# xclient +# xclient, helo +# xclient, ehlo +# xclient, from, rcpt +# xclient, helo, from, rcpt +# xclient, ehlo, from, rcpt +# +# Test them in order. + +# xclient + +my $s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", '')); +$s->authok('xclient'); + +# xclient, helo + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('HELO example.com'); +$s->read(); +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", '')); +$s->authok('xclient, helo'); + +# xclient, ehlo + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); +$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", '')); +$s->authok('xclient, ehlo'); + +# xclient, from, rcpt + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('MAIL FROM:'); +$s->read(); +$s->send('RCPT TO:'); +$s->ok('xclient, from'); + +# xclient, helo, from, rcpt + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('HELO example.com'); +$s->read(); +$s->send('MAIL FROM:'); +$s->read(); +$s->send('RCPT TO:'); +$s->ok('xclient, helo, from'); + +# xclient, ehlo, from, rcpt + +$s = Test::Nginx::SMTP->new(); +$s->read(); +$s->send('EHLO example.com'); +$s->read(); +$s->send('MAIL FROM:'); +$s->read(); +$s->send('RCPT TO:'); +$s->ok('xclient, ehlo, from'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/memcached.t b/tests/nginx-tests/dso-nginx-tests/memcached.t new file mode 100644 index 0000000000..e2a9dc5716 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/memcached.t @@ -0,0 +1,100 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Test for memcached backend. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +eval { require Cache::Memcached; }; +plan(skip_all => 'Cache::Memcached not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http rewrite memcached/) + ->has_daemon('memcached')->plan(4); + +$t->set_dso("ngx_http_memcached_module", "lib_ngx_http_memcached_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + set $memcached_key $uri; + memcached_pass 127.0.0.1:8081; + } + + location /next { + set $memcached_key $uri; + memcached_next_upstream not_found; + memcached_pass 127.0.0.1:8081; + } + } +} + +EOF + +my $memhelp = `memcached -h`; +my @memopts = (); + +if ($memhelp =~ /repcached/) { + # repcached patch adds additional listen socket + push @memopts, '-X', '8082'; +} +if ($memhelp =~ /-U/) { + # UDP port is on by default in memcached 1.2.7+ + push @memopts, '-U', '0'; +} + +$t->run_daemon('memcached', '-l', '127.0.0.1', '-p', '8081', @memopts); +$t->run(); + +$t->waitforsocket('127.0.0.1:8081') + or die "Can't start memcached"; + +############################################################################### + +my $memd = Cache::Memcached->new(servers => [ '127.0.0.1:8081' ]); +$memd->set('/', 'SEE-THIS') + or die "can't put value into memcached: $!"; + +like(http_get('/'), qr/SEE-THIS/, 'memcached request'); + +like(http_get('/notfound'), qr/404/, 'memcached not found'); + +like(http_get('/next'), qr/404/, 'not found with memcached_next_upstream'); + +unlike(http_head('/'), qr/SEE-THIS/, 'memcached no data in HEAD'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/memcached_fake.t b/tests/nginx-tests/dso-nginx-tests/memcached_fake.t new file mode 100644 index 0000000000..e9c79e77da --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/memcached_fake.t @@ -0,0 +1,106 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Test for memcached backend with fake daemon. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite memcached ssi/)->plan(3); + +$t->set_dso("ngx_http_memcached_module", "lib_ngx_http_memcached_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + set $memcached_key $uri; + memcached_pass 127.0.0.1:8081; + } + + location /ssi { + default_type text/html; + ssi on; + } + } +} + +EOF + +$t->write_file('ssi.html', 'blah: '); +$t->run_daemon(\&memcached_fake_daemon); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/SEE-THIS/, 'memcached split trailer'); + +like(http_get('/ssi.html'), qr/SEE-THIS/, 'memcached ssi var'); + +like(`grep -F '[error]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no error'); + +############################################################################### + +sub memcached_fake_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + while (<$client>) { + last if (/\x0d\x0a$/); + } + + print $client 'VALUE / 0 8' . CRLF; + print $client 'SEE-TH'; + select(undef, undef, undef, 0.1); + print $client 'IS'; + select(undef, undef, undef, 0.1); + print $client CRLF . 'EN'; + select(undef, undef, undef, 0.1); + print $client 'D' . CRLF; + close $client; + } +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/not_modified.t b/tests/nginx-tests/dso-nginx-tests/not_modified.t new file mode 100644 index 0000000000..2229e94c80 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/not_modified.t @@ -0,0 +1,88 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for not modified filter module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has('http')->plan(4); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + if_modified_since before; + } + } +} + +EOF + +$t->write_file('t', ''); + +$t->run(); + +############################################################################### + +like(http_get_ims('/t', 'Wed, 08 Jul 2037 22:53:52 GMT'), qr/304/, + '0x7F000000'); +like(http_get_ims('/t', 'Tue, 19 Jan 2038 03:14:07 GMT'), qr/304/, + '0x7FFFFFFF'); + +SKIP: { + skip "only for 32-bit time_t", 2 if (gmtime(0xFFFFFFFF))[5] == 206; + + like(http_get_ims('/t', 'Tue, 19 Jan 2038 03:14:08 GMT'), qr/200/, + '0x7FFFFFFF + 1'); + like(http_get_ims('/t', 'Fri, 25 Feb 2174 09:42:23 GMT'), qr/200/, + '0x17FFFFFFF'); +} + +############################################################################### + +sub http_get_ims { + my ($url, $ims) = @_; + return http(<new()->has(qw/http perl rewrite/)->plan(1); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + set $testvar "TEST"; + perl 'sub { + use warnings; + use strict; + + my $r = shift; + + $r->send_http_header("text/plain"); + + return OK if $r->header_only; + + my $v = $r->variable("testvar"); + + $r->print("$v"); + + return OK; + }'; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_get('/'), qr/TEST/, 'perl response'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/perl_gzip.t b/tests/nginx-tests/dso-nginx-tests/perl_gzip.t new file mode 100644 index 0000000000..c5e97367a6 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/perl_gzip.t @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for embedded perl module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx qw/ :DEFAULT :gzip /; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +eval { require IO::Compress::Gzip; }; +Test::More::plan(skip_all => "IO::Compress::Gzip not found") if $@; + +my $t = Test::Nginx->new()->has(qw/http perl gzip/)->plan(2); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + gzip on; + gzip_types text/plain; + + location / { + perl 'sub { + my $r = shift; + $r->send_http_header("text/plain"); + return OK if $r->header_only; + $r->print("TEST"); + return OK; + }'; + } + + location /gz { + perl 'sub { + my $r = shift; + $r->header_out("Content-Encoding", "gzip"); + $r->send_http_header("text/plain"); + return OK if $r->header_only; + use IO::Compress::Gzip; + my $in = "TEST"; + my $out; + IO::Compress::Gzip::gzip(\\$in => \\$out); + $r->print($out); + return OK; + }'; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +http_gzip_like(http_gzip_request('/'), qr/TEST/, 'perl response gzipped'); +http_gzip_like(http_gzip_request('/gz'), qr/TEST/, 'not doublegzipped'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy.t b/tests/nginx-tests/dso-nginx-tests/proxy.t new file mode 100644 index 0000000000..0f46d4a6c5 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy.t @@ -0,0 +1,126 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for http proxy module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(3); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8081; + proxy_read_timeout 1s; + } + } +} + +EOF + +$t->run_daemon(\&http_daemon); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/SEE-THIS/, 'proxy request'); +like(http_get('/multi'), qr/AND-THIS/, 'proxy request with multiple packets'); + +unlike(http_head('/'), qr/SEE-THIS/, 'proxy head request'); + +############################################################################### + +sub http_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalHost => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + my $headers = ''; + my $uri = ''; + + while (<$client>) { + $headers .= $_; + last if (/^\x0d?\x0a?$/); + } + + $uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i; + + if ($uri eq '/') { + print $client <<'EOF'; +HTTP/1.1 200 OK +Connection: close + +EOF + print $client "TEST-OK-IF-YOU-SEE-THIS" + unless $headers =~ /^HEAD/i; + + } elsif ($uri eq '/multi') { + + print $client <<"EOF"; +HTTP/1.1 200 OK +Connection: close + +TEST-OK-IF-YOU-SEE-THIS +EOF + + select undef, undef, undef, 0.1; + print $client 'AND-THIS'; + + } else { + + print $client <<"EOF"; +HTTP/1.1 404 Not Found +Connection: close + +Oops, '$uri' not found +EOF + } + + close $client; + } +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_cache.t b/tests/nginx-tests/dso-nginx-tests/proxy_cache.t new file mode 100644 index 0000000000..ac11791802 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_cache.t @@ -0,0 +1,172 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for http proxy cache. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx qw/ :DEFAULT :gzip /; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy cache gzip/)->plan(12); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + proxy_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + gzip on; + gzip_min_length 0; + + location / { + proxy_pass http://127.0.0.1:8081; + + proxy_cache NAME; + + proxy_cache_valid 200 302 1s; + proxy_cache_valid 301 1d; + proxy_cache_valid any 1m; + + proxy_cache_min_uses 1; + + proxy_cache_use_stale error timeout invalid_header http_500 + http_404; + } + + location /fake/ { + proxy_pass http://127.0.0.1:8082; + proxy_cache NAME; + } + } + server { + listen 127.0.0.1:8081; + server_name localhost; + + location / { + } + } +} + +EOF + +$t->write_file('t.html', 'SEE-THIS'); +$t->write_file('t2.html', 'SEE-THIS'); +$t->write_file('empty.html', ''); +$t->run_daemon(\&http_fake_daemon); +$t->run(); + +############################################################################### + +like(http_get('/t.html'), qr/SEE-THIS/, 'proxy request'); + +$t->write_file('t.html', 'NOOP'); +like(http_get('/t.html'), qr/SEE-THIS/, 'proxy request cached'); + +unlike(http_head('/t2.html'), qr/SEE-THIS/, 'head request'); +like(http_get('/t2.html'), qr/SEE-THIS/, 'get after head'); +unlike(http_head('/t2.html'), qr/SEE-THIS/, 'head after get'); + +like(http_get_range('/t.html', 'Range: bytes=4-'), qr/^THIS/m, 'cached range'); +like(http_get_range('/t.html', 'Range: bytes=0-2,4-'), qr/^SEE.*^THIS/ms, + 'cached multipart range'); + +like(http_get('/empty.html'), qr/HTTP/, 'empty get first'); +like(http_get('/empty.html'), qr/HTTP/, 'empty get second'); + +sleep(2); +unlink $t->testdir() . '/t.html'; +like(http_gzip_request('/t.html'), + qr/HTTP.*1c\x0d\x0a.{28}\x0d\x0a0\x0d\x0a\x0d\x0a\z/s, + 'non-empty get stale'); + +unlink $t->testdir() . '/empty.html'; +like(http_gzip_request('/empty.html'), + qr/HTTP.*14\x0d\x0a.{20}\x0d\x0a0\x0d\x0a\x0d\x0a\z/s, + 'empty get stale'); + +{ +local $TODO = 'patch pending'; + +http_get('/fake/unfinished'); +like(http_get('/fake/unfinished'), qr/unfinished 2/, 'unfinished not cached'); +} + +############################################################################### + +sub http_get_range { + my ($url, $extra) = @_; + return http(<new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:8082', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + my $num = 0; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + while (<$client>) { + last if (/^\x0d?\x0a?$/); + } + + $num++; + print $client <<"EOF"; +HTTP/1.1 200 OK +Content-Length: 100 +Cache-Control: max-age=300 +Connection: close + +unfinished $num +EOF + } +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t b/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t new file mode 100644 index 0000000000..c8591cc894 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t @@ -0,0 +1,225 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for http proxy cache lock. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy cache/); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + proxy_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8081; + proxy_cache NAME; + + proxy_cache_lock on; + } + + location /timeout { + proxy_pass http://127.0.0.1:8081; + proxy_cache NAME; + + proxy_cache_lock on; + proxy_cache_lock_timeout 300ms; + } + + location /nolock { + proxy_pass http://127.0.0.1:8081; + proxy_cache NAME; + } + } +} + +EOF + +$t->run_daemon(\&http_fake_daemon); + +eval { + open OLDERR, ">&", \*STDERR; close STDERR; + $t->run(); + open STDERR, ">&", \*OLDERR; +}; +plan(skip_all => 'no proxy_cache_lock') if $@; + +$t->plan(19); +$t->waitforsocket('127.0.0.1:8081'); + +############################################################################### + +# sequentional requests + +for my $i (1 .. 5) { + like(http_get('/seq'), qr/request 1/, 'sequentional request ' . $i); +} + +# parallel requests + +my @sockets; + +for my $i (1 .. 5) { + $sockets[$i] = http_start('/par1'); +} + +for my $i (1 .. 5) { + like(http_end($sockets[$i]), qr/request 1/, 'parallel request ' . $i); +} + +like(http_get('/par1'), qr/request 1/, 'first request cached'); + +# parallel requests with cache lock timeout + +for my $i (1 .. 3) { + $sockets[$i] = http_start('/timeout'); +} + +for my $i (1 .. 3) { + like(http_end($sockets[$i]), qr/request $i/, 'lock timeout ' . $i); +} + +like(http_get('/timeout'), qr/request 3/, 'lock timeout - last cached'); + +# no lock + +for my $i (1 .. 3) { + $sockets[$i] = http_start('/nolock'); +} + +for my $i (1 .. 3) { + like(http_end($sockets[$i]), qr/request $i/, 'nolock ' . $i); +} + +like(http_get('/nolock'), qr/request 3/, 'nolock - last cached'); + +############################################################################### + +sub http_start { + my ($uri) = @_; + + my $s; + my $request = "GET $uri HTTP/1.0" . CRLF . CRLF; + + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + local $SIG{PIPE} = sub { die "sigpipe\n" }; + alarm(2); + $s = IO::Socket::INET->new( + Proto => 'tcp', + PeerAddr => '127.0.0.1:8080' + ); + log_out($request); + $s->print($request); + alarm(0); + }; + alarm(0); + if ($@) { + log_in("died: $@"); + return undef; + } + return $s; +} + +sub http_end { + my ($s) = @_; + my $reply; + + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + local $SIG{PIPE} = sub { die "sigpipe\n" }; + alarm(2); + local $/; + $reply = $s->getline(); + log_in($reply); + alarm(0); + }; + alarm(0); + if ($@) { + log_in("died: $@"); + return undef; + } + return $reply; +} + +############################################################################### + +sub http_fake_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + my $num = 0; + my $uri = ''; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + while (<$client>) { + if (/GET (.*) HTTP/ && $1 ne $uri) { + $uri = $1; + $num = 0; + } + + $uri = $1 if /GET (.*) HTTP/; + last if /^\x0d?\x0a?$/; + } + + next unless $uri; + + sleep(1); + + $num++; + print $client <<"EOF"; +HTTP/1.1 200 OK +Cache-Control: max-age=300 +Connection: close + +request $num +EOF + } +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t b/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t new file mode 100644 index 0000000000..e536105619 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t @@ -0,0 +1,121 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Test for http backend returning response with Transfer-Encoding: chunked. + +# Since nginx uses HTTP/1.0 in requests to backend it's backend bug, but we +# want to handle this gracefully. And anyway chunked support will be required +# for HTTP/1.1 backend connections. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +use IO::Select; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy ssi/)->plan(3); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8081; + proxy_read_timeout 1s; + } + location /nobuffering { + proxy_pass http://127.0.0.1:8081; + proxy_read_timeout 1s; + proxy_buffering off; + } + location /inmemory.html { + ssi on; + } + } +} + +EOF + +$t->write_file('inmemory.html', + ''); + +$t->run_daemon(\&http_chunked_daemon); +$t->run(); + +############################################################################### + +{ +local $TODO = 'not yet'; + +like(http_get('/'), qr/\x0d\x0aSEE-THIS$/s, 'chunked'); +like(http_get('/nobuffering'), qr/\x0d\x0aSEE-THIS$/s, 'chunked nobuffering'); +like(http_get('/inmemory.html'), qr/\x0d\x0aSEE-THIS$/s, 'chunked inmemory'); +} + +############################################################################### + +sub http_chunked_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + while (<$client>) { + last if (/^\x0d?\x0a?$/); + } + + print $client <<'EOF'; +HTTP/1.1 200 OK +Connection: close +Transfer-Encoding: chunked + +9 +SEE-THIS + +0 + +EOF + + close $client; + } +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t b/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t new file mode 100644 index 0000000000..8d9599fd0d --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t @@ -0,0 +1,123 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin +# (C) Valentin Bartenev + +# Tests for the proxy_cookie_domain and proxy_cookie_path directives. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy rewrite/); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8081; + + proxy_cookie_domain www.example.org .example.com; + proxy_cookie_domain .$server_name.com en.$server_name.org; + proxy_cookie_domain ~^(.+)\.com$ $1.org; + + proxy_cookie_path /path/ /new/; + proxy_cookie_path /$server_name/ /new/$server_name/; + proxy_cookie_path ~^/regex/(.+)$ /$1; + proxy_cookie_path ~*^/caseless/(.+)$ /$1; + } + } + + server { + listen 127.0.0.1:8081; + server_name localhost; + + location / { + if ($arg_domain) { + set $sc_domain "; Domain=$arg_domain"; + } + if ($arg_path) { + set $sc_path "; Path=$arg_path"; + } + add_header Set-Cookie v=path=domain=$sc_domain$sc_path; + return 200 OK; + } + } +} + +EOF + +eval { + open OLDERR, ">&", \*STDERR; close STDERR; + $t->run(); + open STDERR, ">&", \*OLDERR; +}; +plan(skip_all => 'no proxy_cookie') if $@; + +$t->plan(8); + +############################################################################### + +is(http_get_set_cookie('/?domain=www.Example.org'), + 'v=path=domain=; Domain=example.com', 'domain rewrite'); +is(http_get_set_cookie('/?domain=.LocalHost.com'), + 'v=path=domain=; Domain=.en.localhost.org', + 'domain rewrite with vars'); +is(http_get_set_cookie('/?domain=www.example.COM'), + 'v=path=domain=; Domain=www.example.org', 'domain regex rewrite'); + +is(http_get_set_cookie('/?path=/path/test.html'), + 'v=path=domain=; Path=/new/test.html', 'path rewrite'); +is(http_get_set_cookie('/?path=/localhost/test.html'), + 'v=path=domain=; Path=/new/localhost/test.html', + 'path rewrite with vars'); +is(http_get_set_cookie('/?path=/regex/test.html'), + 'v=path=domain=; Path=/test.html', 'path regex rewrite'); +is(http_get_set_cookie('/?path=/CASEless/test.html'), + 'v=path=domain=; Path=/test.html', 'path caseless regex rewrite'); + +is(http_get_set_cookie('/?domain=www.example.org&path=/path/test.html'), + 'v=path=domain=; Domain=example.com; Path=/new/test.html', + 'domain and path rewrite'); + +############################################################################### + +sub http_get_set_cookie { + my ($uri) = @_; + http_get("http://127.0.0.1:8080$uri") =~ /^Set-Cookie:\s(.+?)\x0d?$/mi; + return $1; +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t b/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t new file mode 100644 index 0000000000..1a2b4f99ac --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t @@ -0,0 +1,108 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for proxy_set_header inheritance. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy cache rewrite/)->plan(3); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + proxy_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + proxy_set_header X-Blah "blah"; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + proxy_cache NAME; + + location / { + proxy_pass http://127.0.0.1:8081; + } + + location /no/ { + proxy_pass http://127.0.0.1:8081; + proxy_cache off; + } + + location /setbody/ { + proxy_pass http://127.0.0.1:8081; + proxy_set_body "body"; + } + } + + server { + listen 127.0.0.1:8081; + server_name localhost; + + location / { + return 200 "ims=$http_if_modified_since;blah=$http_x_blah;"; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_get_ims('/'), qr/ims=;blah=blah;/, + 'if-modified-since cleared with cache'); + +like(http_get_ims('/no/'), qr/ims=blah;blah=blah;/, + 'if-modified-since preserved without cache'); + +like(http_get_ims('/setbody/'), qr/blah=blah;/, + 'proxy_set_header inherited with proxy_set_body'); + +############################################################################### + +sub http_get_ims { + my ($url) = @_; + return http(<new()->has(qw/http proxy/)->plan(4); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + proxy_pass http://127.0.0.1:8081; + proxy_read_timeout 1s; + } + + location /uselen { + proxy_pass http://127.0.0.1:8081; + + # test will wait only 2s for reply, we it will fail if + # Content-Length not used as a hint + + proxy_read_timeout 10s; + } + } +} + +EOF + +$t->run_daemon(\&http_noclose_daemon); +$t->run(); + +############################################################################### + +TODO: { +local $TODO = 'not fixed yet, patches under review'; +local $SIG{__WARN__} = sub {}; + +like(http_get('/'), qr/SEE-THIS/, 'request to bad backend'); +like(http_get('/multi'), qr/AND-THIS/, 'bad backend - multiple packets'); +like(http_get('/nolen'), qr/SEE-THIS/, 'bad backend - no content length'); +like(http_get('/uselen'), qr/SEE-THIS/, 'content-length actually used'); + +} + +############################################################################### + +sub http_noclose_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + my $multi = 0; + my $nolen = 0; + + while (<$client>) { + $multi = 1 if /multi/; + $nolen = 1 if /nolen/; + last if (/^\x0d?\x0a?$/); + } + + if ($nolen) { + + print $client <<'EOF'; +HTTP/1.1 200 OK +Connection: close + +TEST-OK-IF-YOU-SEE-THIS +EOF + } elsif ($multi) { + + print $client <<"EOF"; +HTTP/1.1 200 OK +Content-Length: 32 +Connection: close + +TEST-OK-IF-YOU-SEE-THIS +EOF + + select undef, undef, undef, 0.1; + print $client 'AND-THIS'; + + } else { + + print $client <<"EOF"; +HTTP/1.1 200 OK +Content-Length: 24 +Connection: close + +TEST-OK-IF-YOU-SEE-THIS +EOF + } + + my $select = IO::Select->new($client); + $select->can_read(10); + close $client; + } +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t b/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t new file mode 100644 index 0000000000..d10b782416 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t @@ -0,0 +1,175 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin +# (C) Valentin Bartenev + +# Tests for the proxy_redirect directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy rewrite/)->plan(15); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + set $some_var var_here; + + proxy_pass http://127.0.0.1:8081; + + proxy_redirect http://127.0.0.1:8081/var_in_second/ /$some_var/; + proxy_redirect http://127.0.0.1:8081/$some_var/ /replaced/; + + proxy_redirect ~^(.+)81/regex_w_([^/]+) $180/$2/test.html; + proxy_redirect ~*re+gexp? /replaced/test.html; + } + + location /expl_default/ { + proxy_pass http://127.0.0.1:8081/replace_this/; + proxy_redirect wrong wrong; + proxy_redirect default; + } + + location /impl_default/ { + proxy_pass http://127.0.0.1:8081/replace_this/; + } + + location /off/ { + proxy_pass http://127.0.0.1:8081/; + proxy_redirect off; + + location /off/on/ { + proxy_pass http://127.0.0.1:8081; + proxy_redirect http://127.0.0.1:8081/off/ /; + + location /off/on/on/ { + proxy_pass http://127.0.0.1:8081; + } + } + } + } + + server { + listen 127.0.0.1:8081; + server_name localhost; + + location / { + add_header Refresh "7; url=http://127.0.0.1:8081$uri"; + return http://127.0.0.1:8081$uri; + } + } +} + +EOF + +$t->run(); + +############################################################################### + + +is(http_get_location('http://127.0.0.1:8080/impl_default/test.html'), + 'http://127.0.0.1:8080/impl_default/test.html', 'implicit default'); +is(http_get_location('http://127.0.0.1:8080/expl_default/test.html'), + 'http://127.0.0.1:8080/expl_default/test.html', 'explicit default'); + +is(http_get_refresh('http://127.0.0.1:8080/impl_default/test.html'), + '7; url=/impl_default/test.html', 'implicit default (refresh)'); +is(http_get_refresh('http://127.0.0.1:8080/expl_default/test.html'), + '7; url=/expl_default/test.html', 'explicit default (refresh)'); + +is(http_get_location('http://127.0.0.1:8080/var_in_second/test.html'), + 'http://127.0.0.1:8080/var_here/test.html', 'variable in second arg'); +is(http_get_refresh('http://127.0.0.1:8080/var_in_second/test.html'), + '7; url=/var_here/test.html', 'variable in second arg (refresh)'); + +is(http_get_location('http://127.0.0.1:8080/off/test.html'), + 'http://127.0.0.1:8081/test.html', 'rewrite off'); +is(http_get_location('http://127.0.0.1:8080/off/on/test.html'), + 'http://127.0.0.1:8080/on/test.html', 'rewrite off overwrite'); + +TODO: { +local $TODO = 'rewrite off inheritance bug'; + +is(http_get_location('http://127.0.0.1:8080/off/on/on/test.html'), + 'http://127.0.0.1:8080/on/on/test.html', 'rewrite inheritance'); + +} + +TODO: { +local $TODO = 'support variables in first argument'; + +is(http_get_location('http://127.0.0.1:8080/var_here/test.html'), + 'http://127.0.0.1:8080/replaced/test.html', 'variable in first arg'); +is(http_get_refresh('http://127.0.0.1:8080/var_here/test.html'), + '7; url=/replaced/test.html', 'variable in first arg (refresh)'); + +} + +TODO: { +local $TODO = 'support for regular expressions'; + +is(http_get_location('http://127.0.0.1:8080/ReeegEX/test.html'), + 'http://127.0.0.1:8080/replaced/test.html', 'caseless regexp'); +is(http_get_location('http://127.0.0.1:8080/regex_w_captures/test.html'), + 'http://127.0.0.1:8080/captures/test.html', 'regexp w/captures'); + +} + +TODO: { +local $TODO = 'regular expressions and Refresh header'; + +is(http_get_refresh('http://127.0.0.1:8080/ReeegEX/test.html'), + '7; url=/replaced/test.html', 'caseless regexp (refresh)'); +is(http_get_refresh('http://127.0.0.1:8080/regex_w_captures/test.html'), + '7; url=http://127.0.0.1:8080/captures/test.html', + 'regexp w/captures (refresh)'); + +} + +############################################################################### + +sub http_get_location { + my ($url) = @_; + http_get($url) =~ /^Location:\s(.+?)\x0d?$/mi; + return $1; +} + +sub http_get_refresh { + my ($url) = @_; + http_get($url) =~ /^Refresh:\s(.+?)\x0d?$/mi; + return $1; +} diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_store.t b/tests/nginx-tests/dso-nginx-tests/proxy_store.t new file mode 100644 index 0000000000..35f2565e0e --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_store.t @@ -0,0 +1,108 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for proxy_store functionality. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new(); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF')->has(qw/http proxy ssi/)->plan(7); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /store- { + proxy_pass http://127.0.0.1:8080/; + proxy_store on; + } + location /ssi.html { + ssi on; + } + location /index-nostore.html { + add_header X-Accel-Expires 0; + } + location /index-big.html { + limit_rate 200k; + } + } +} + +EOF + +$t->write_file('index.html', 'SEE-THIS'); +$t->write_file('index-nostore.html', 'SEE-THIS'); +$t->write_file('index-big.html', 'x' x (100 << 10)); +$t->write_file('ssi.html', + '' . + '' +); +$t->run(); + +############################################################################### + +like(http_get('/store-index.html'), qr/SEE-THIS/, 'proxy request'); +ok(-e $t->testdir() . '/store-index.html', 'result stored'); + +like(http_get('/store-index-nostore.html'), qr/SEE-THIS/, + 'proxy request with x-accel-expires'); + +TODO: { +local $TODO = 'patch under review'; + +ok(!-e $t->testdir() . '/store-index-nostore.html', 'result not stored'); +} + +ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0, 'no temp files'); + +http_get('/store-index-big.html', aborted => 1, sleep => 0.1); +sleep(1); + +ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0, + 'no temp files after aborted request'); + +TODO: { +local $TODO = 'not fixed yet'; + +http_get('/ssi.html', aborted => 1, sleep => 0.1); +sleep(1); + +ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0, + 'no temp files after aborted ssi'); + +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_xar.t b/tests/nginx-tests/dso-nginx-tests/proxy_xar.t new file mode 100644 index 0000000000..81e909141f --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/proxy_xar.t @@ -0,0 +1,89 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for proxy X-Accel-Redirect functionality. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy rewrite/)->plan(8); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /proxy { + proxy_pass http://127.0.0.1:8080/return-xar; + } + location /return-xar { + add_header X-Accel-Redirect /index.html; + + # this headers will be preserved on + # X-Accel-Redirect + + add_header Content-Type text/blah; + add_header Set-Cookie blah=blah; + add_header Content-Disposition attachment; + add_header Cache-Control no-cache; + add_header Expires fake; + add_header Accept-Ranges parrots; + + # others won't be + add_header Something other; + + return 204; + } + } +} + +EOF + +$t->write_file('index.html', 'SEE-THIS'); +$t->run(); + +############################################################################### + +my $r = http_get('/proxy'); +like($r, qr/SEE-THIS/, 'X-Accel-Redirect works'); +like($r, qr/^Content-Type: text\/blah/m, 'Content-Type preserved'); +like($r, qr/^Set-Cookie: blah=blah/m, 'Set-Cookie preserved'); +like($r, qr/^Content-Disposition: attachment/m, 'Content-Disposition preserved'); +like($r, qr/^Cache-Control: no-cache/m, 'Cache-Control preserved'); +like($r, qr/^Expires: fake/m, 'Expires preserved'); +like($r, qr/^Accept-Ranges: parrots/m, 'Accept-Ranges preserved'); +unlike($r, qr/^Something/m, 'other headers stripped'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/random_index.t b/tests/nginx-tests/dso-nginx-tests/random_index.t new file mode 100644 index 0000000000..98ce8de909 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/random_index.t @@ -0,0 +1,72 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for random index module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http random_index/)->plan(1); + +$t->set_dso("ngx_http_random_index_module", "lib_ngx_http_random_index_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + random_index on; + } + } +} + +EOF + +my $d = $t->testdir(); + +mkdir("$d/x"); +mkdir("$d/x/test-dir"); +symlink("$d/x/test-dir", "$d/x/test-dir-link"); + +$t->write_file('test-file', 'RIGHT'); +symlink("$d/test-file", "$d/x/test-file-link"); + +$t->run(); + +############################################################################### + +like(http_get('/x/'), qr/RIGHT/s, 'file'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/range.t b/tests/nginx-tests/dso-nginx-tests/range.t new file mode 100644 index 0000000000..098ee8a235 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/range.t @@ -0,0 +1,137 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for range filter module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http charset/)->plan(31); + +$t->set_dso("ngx_http_charset_filter_module", "lib_ngx_http_charset_filter_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + charset_map B A { + 58 59; # X -> Y + } + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /t2.html { + charset A; + source_charset B; + } + } +} + +EOF + +$t->write_file('t1.html', + join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99))); +$t->write_file('t2.html', + join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99))); +$t->run(); + +############################################################################### + +my $t1; + +$t1 = http_get_range('/t1.html', 'Range: bytes=0-8'); +like($t1, qr/206/, 'range request - 206 partial reply'); +like($t1, qr/Content-Length: 9/, 'range request - correct length'); +like($t1, qr/Content-Range: bytes 0-8\/1000/, 'range request - content range'); +like($t1, qr/^X000XXXXX$/m, 'range request - correct content'); + +$t1 = http_get_range('/t1.html', 'Range: bytes=-10'); +like($t1, qr/206/, 'final bytes - 206 partial reply'); +like($t1, qr/Content-Length: 10/, 'final bytes - content length'); +like($t1, qr/Content-Range: bytes 990-999\/1000/, + 'final bytes - content range'); +like($t1, qr/^X099XXXXXX$/m, 'final bytes - correct content'); + +$t1 = http_get_range('/t1.html', 'Range: bytes=990-'); +like($t1, qr/206/, 'final bytes explicit - 206 partial reply'); +like($t1, qr/Content-Length: 10/, 'final bytes explicit - content length'); +like($t1, qr/Content-Range: bytes 990-999\/1000/, + 'final bytes explicit - content range'); +like($t1, qr/^X099XXXXXX$/m, 'final bytes explicit - correct content'); + +$t1 = http_get_range('/t1.html', 'Range: bytes=990-1990'); +like($t1, qr/206/, 'more than length - 206 partial reply'); +like($t1, qr/Content-Length: 10/, 'more than length - content length'); +like($t1, qr/Content-Range: bytes 990-999\/1000/, + 'more than length - content range'); +like($t1, qr/^X099XXXXXX$/m, 'more than length - correct content'); + +$t1 = http_get_range('/t2.html', 'Range: bytes=990-1990'); +like($t1, qr/206/, 'recoded - 206 partial reply'); +like($t1, qr/Content-Length: 10/, 'recoded - content length'); +like($t1, qr/Content-Range: bytes 990-999\/1000/, 'recoded - content range'); +like($t1, qr/^Y099YYYYYY$/m, 'recoded - correct content'); + +$t1 = http_get_range('/t1.html', 'Range: bytes=0-9, -10, 10-19'); +like($t1, qr/206/, 'multipart - 206 partial reply'); +like($t1, qr/Content-Type: multipart\/byteranges; boundary=/, + 'multipart - content type'); +like($t1, qr/X000XXXXXX/m, 'multipart - content 0-9'); +like($t1, qr/^X099XXXXXX\x0d?$/m, 'multipart - content -10 aka 990-999'); +like($t1, qr/X001XXXXXX\x0d?$/m, 'multipart - content 10-19'); + +$t1 = http_get_range('/t1.html', 'Range: bytes=0-9, -10, 100000-, 10-19'); +like($t1, qr/206/, 'multipart big - 206 partial reply'); +like($t1, qr/Content-Type: multipart\/byteranges; boundary=/, + 'multipart big - content type'); +like($t1, qr/X000XXXXXX/m, 'multipart big - content 0-9'); +like($t1, qr/^X099XXXXXX\x0d?$/m, 'multipart big - content -10 aka 990-999'); +like($t1, qr/X001XXXXXX\x0d?$/m, 'multipart big - content 10-19'); + +like(http_get_range('/t1.html', 'Range: bytes=100000-'), qr/416/, + 'not satisfiable'); + +############################################################################### + +sub http_get_range { + my ($url, $extra) = @_; + return http(<new()->has(qw/http flv/)->plan(12); + +$t->set_dso("ngx_http_flv_module", "lib_ngx_http_flv_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + flv; + } + } +} + +EOF + +$t->write_file('t1.flv', + join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99))); +$t->run(); + +############################################################################### + +my $t1; + +# FLV has 13 byte header at start. + +$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=0-9'); +like($t1, qr/206/, 'first bytes - 206 partial reply'); +like($t1, qr/Content-Length: 10/, 'first bytes - correct length'); +like($t1, qr/Content-Range: bytes 0-9\/913/, 'first bytes - content range'); +like($t1, qr/^FLV.{7}$/m, 'first bytes - correct content'); + +$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=-10'); +like($t1, qr/206/, 'final bytes - 206 partial reply'); +like($t1, qr/Content-Length: 10/, 'final bytes - content length'); +like($t1, qr/Content-Range: bytes 903-912\/913/, + 'final bytes - content range'); +like($t1, qr/^X099XXXXXX$/m, 'final bytes - correct content'); + +$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=0-99'); +like($t1, qr/206/, 'multi buffers - 206 partial reply'); +like($t1, qr/Content-Length: 100/, 'multi buffers - content length'); +like($t1, qr/Content-Range: bytes 0-99\/913/, 'multi buffers - content range'); +like($t1, qr/^FLV.{10}X010XXXXXX(X01[1-7]XXXXXX){7}X018XXX$/m, + 'multi buffers - correct content'); + +############################################################################### + +sub http_get_range { + my ($url, $extra) = @_; + return http(<new()->has(qw/http/)->plan(8); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /t2.html { + add_header Last-Modified ""; + } + + location /t3.html { + add_header Last-Modified "Mon, 28 Sep 1970 06:00:00 GMT"; + } + } +} + +EOF + +$t->write_file('t1.html', + join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99))); +$t->write_file('t2.html', + join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99))); +$t->write_file('t3.html', + join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99))); +$t->run(); + +############################################################################### + +my $t1; + +# If-Range + +$t1 = http_get_range('/t1.html', "Range: bytes=0-9\nIf-Range: wrong"); +like($t1, qr/200 OK/, 'if-range wrong'); +like($t1, qr/Last-Modified: /, 'if-range wrong - last modified'); + +$t1 =~ m/Last-Modified: (.*)/m; +my $last = $1; + +$t1 = http_get_range('/t1.html', "Range: bytes=0-9\nIf-Range: $last"); +like($t1, qr/206/, 'if-range'); + +# If-Range + add_header Last-Modified "" + +$t1 = http_get_range('/t2.html', "Range: bytes=0-9\nIf-Range: wrong"); + +TODO: { +local $TODO = 'not yet'; + +like($t1, qr/200 OK/, 'if-range notime'); + +} + +unlike($t1, qr/Last-Modified: /, 'if-range notime - no last modified'); + +# If-Range + add_header Last-Modified "Mon, 28 Sep 1970 06:00:00 GMT" + +$t1 = http_get_range('/t3.html', "Range: bytes=0-9\nIf-Range: wrong"); + +TODO: { +local $TODO = 'not yet'; + +like($t1, qr/200 OK/, 'if-range time wrong'); + +} + +like($t1, qr/Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT/, + 'if-range time wrong - last modified'); + +$t1 = http_get_range('/t3.html', + "Range: bytes=0-9\nIf-Range: Mon, 28 Sep 1970 06:00:00 GMT"); +like($t1, qr/206/, 'if-range time'); + +############################################################################### + +sub http_get_range { + my ($url, $extra) = @_; + return http(<new()->has(qw/http rewrite/)->plan(19); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + rewrite ^ http://example.com/ redirect; + } + + location /add { + rewrite ^ http://example.com/?c=d redirect; + } + + location /no { + rewrite ^ http://example.com/?c=d? redirect; + } + + location /return204 { + return 204; + } + + location /return200 { + return 200; + } + + location /return405 { + return 405; + } + + location /error404return405 { + error_page 404 /return405; + return 404; + } + + location /error405return204 { + error_page 405 /return204; + return 405; + } + + location /error405return200 { + error_page 405 /return200; + return 405; + } + + location /return200text { + return 200 "text"; + } + + location /return404text { + return 404 "text"; + } + + location /return302text { + return 302 "text"; + } + + location /error405return200text { + error_page 405 /return200text; + return 405; + } + + location /error302return200text { + error_page 302 /return200text; + return 302 "text"; + } + + location /error405return302text { + error_page 405 /return302text; + return 405; + } + + location /error405rewrite { + error_page 405 /; + return 405; + } + + location /error405directory { + error_page 405 /directory; + return 405; + } + + location /directory { + } + } +} + +EOF + +mkdir($t->testdir() . '/directory'); + +$t->run(); + +############################################################################### + +like(http_get('/'), qr!^Location: http://example.com/\x0d?$!ms, 'simple'); +like(http_get('/?a=b'), qr!^Location: http://example.com/\?a=b\x0d?$!ms, + 'simple with args'); +like(http_get('/add'), qr!^Location: http://example.com/\?c=d\x0d?$!ms, + 'add args'); + +like(http_get('/add?a=b'), qr!^Location: http://example.com/\?c=d&a=b\x0d?$!ms, + 'add args with args'); + +like(http_get('/no?a=b'), qr!^Location: http://example.com/\?c=d\x0d?$!ms, + 'no args with args'); + +like(http_get('/return204'), qr!204 No Content!, 'return 204'); +like(http_get('/return200'), qr!200 OK!, 'return 200'); +like(http_get('/return405'), qr!HTTP/1.1 405.*body!ms, 'return 405'); + +like(http_get('/error404return405'), qr!HTTP/1.1 404!, 'error 404 return 405'); + +# status code should be 405, and entity body is expected (vs. normal 204 +# replies which doesn't expect to have body); use HTTP/1.1 for test +# to make problem clear + +my $r = http(<new()->has(qw/http rewrite/)->plan(9); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /t1 { + rewrite ^ $arg_r? redirect; + } + + location /t2 { + rewrite ^ http://example.com$request_uri? redirect; + } + + location /t3 { + rewrite ^ http://example.com$uri redirect; + } + + location /t4 { + rewrite ^(.*) http://example.com$1 redirect; + } + + location /t5 { + rewrite ^ http://example.com/blah%20%3Fblah redirect; + } + + location /t6 { + rewrite ^ http://example.com/blah%20%2Fblah redirect; + } + } +} + +EOF + +mkdir($t->testdir() . '/directory'); + +$t->run(); + +############################################################################### + +# Some rewrites and expected (?) behaviour +# +# /t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom +# rewrite ^ $arg_r? redirect; +# expected: http://example.com/?from +# got: http://example.com/?from +# +# /t1?r=http%3A%2F%2Fexample.com%0D%0Asplit +# rewrite ^ $arg_r? redirect; +# expected: http://example.com%0D%0Asplit +# got: http://example.com%0D%0Asplit +# +# /t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom%3Dblah +# rewrite ^ $arg_r? redirect; +# expected: http://example.com/?from=blah +# got: http://example.com/?from%3Dblah +# +# /blah%3Fblah +# rewrite ^ http://example.com$request_uri? redirect; +# expected: http://example.com/blah%3Fblah +# got: http://example.com/blah?blah +# +# /blah%3Fblah +# rewrite ^ http://example.com$uri redirect; +# expected: http://example.com/blah%3Fblah +# got: http://example.com/blah?blah +# +# /blah%3Fblah +# rewrite ^(.*) http://example.com$1 redirect; +# expected: http://example.com/blah%3Fblah +# got: http://example.com/blah?blah +# +# / +# rewrite ^ http://example.com/blah%3Fblah redirect; +# expected: http://example.com/blah%3Fblah +# got: http://example.com/blah?blah +# + +location('/t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom', + 'http://example.com/?from', 'escaped argument'); + +location('/t1?r=http%3A%2F%2Fexample.com%0D%0Asplit', + 'http://example.com%0D%0Asplit', 'escaped argument header splitting'); + +TODO: { +local $TODO = 'not yet'; + +# Fixing this cases will require major changes to the whole aproach and +# likely to break some currently working cases. On the other hand, current +# behaviour is far from acceptable. Should be carefully thought. + +location('/t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom%3Dblah', + 'http://example.com/?from=blah', 'escaped argument with complex query'); + +location('/t2/blah%20%3Fblah', + 'http://example.com/t2/blah%20%3Fblah', 'escaped $request_uri'); + +location('/t3/blah%20%3Fblah', + 'http://example.com/t3/blah%20%3Fblah', 'escaped $uri'); + +location('/t4/blah%20%3Fblah', + 'http://example.com/t4/blah%20%3Fblah', 'escaped $1'); + +location('/t5', + 'http://example.com/blah%20%3Fblah', 'escaped static'); + +location('/t5?arg=blah', + 'http://example.com/blah%20%3Fblah?arg=blah', + 'escaped static with argument'); + +location('/t6', + 'http://example.com/blah%20%2Fblah', 'escaped static slash'); + +} + +############################################################################### + +sub location { + my ($url, $value, $name) = @_; + my $data = http_get($url); + if ($data !~ qr!^Location: (.*?)\x0d?$!ms) { + fail($name); + return; + } + my $location = $1; + is($location, $value, $name); +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/scgi.t b/tests/nginx-tests/dso-nginx-tests/scgi.t new file mode 100644 index 0000000000..8f39e064f4 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/scgi.t @@ -0,0 +1,140 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Test for scgi backend. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +eval { require SCGI; }; +plan(skip_all => 'SCGI not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http scgi/)->plan(5); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + scgi_pass 127.0.0.1:8081; + scgi_param SCGI 1; + scgi_param REQUEST_URI $request_uri; + scgi_param HTTP_X_BLAH "blah"; + } + } +} + +EOF + +$t->run_daemon(\&scgi_daemon); +$t->run(); + +############################################################################### + +like(http_get('/'), qr/SEE-THIS/, 'scgi request'); +like(http_get('/redir'), qr/302/, 'scgi redirect'); +like(http_get('/'), qr/^3$/m, 'scgi third request'); + +unlike(http_head('/'), qr/SEE-THIS/, 'no data in HEAD'); + +SKIP: { +skip 'unsafe', 1 unless $ENV{TEST_NGINX_UNSAFE}; +local $TODO = 'not yet'; + +like(http_get_headers('/headers'), qr/SEE-THIS/, + 'scgi request with many ignored headers'); + +} + +############################################################################### + +sub http_get_headers { + my ($url, %extra) = @_; + return http(<new( + Proto => 'tcp', + LocalHost => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + my $scgi = SCGI->new($server, blocking => 1); + my $count = 0; + + while (my $request = $scgi->accept()) { + $count++; + $request->read_env(); + + $request->connection()->print(< 'SCGI not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http scgi gzip/)->plan(1); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + gzip on; + scgi_pass 127.0.0.1:8081; + scgi_param SCGI 1; + scgi_param REQUEST_URI $request_uri; + scgi_param HTTP_X_BLAH "blah"; + } + } +} + +EOF + +$t->run_daemon(\&scgi_daemon); +$t->run(); + +############################################################################### + +like(http_gzip_request('/'), qr/Content-Encoding: gzip/, 'scgi request'); + +############################################################################### + +sub scgi_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalHost => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + my $scgi = SCGI->new($server, blocking => 1); + + while (my $request = $scgi->accept()) { + $request->read_env(); + + $request->connection()->print(< 'SCGI not installed') if $@; + +my $t = Test::Nginx->new()->has(qw/http scgi cache/)->plan(9); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + scgi_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + scgi_param SCGI 1; + scgi_param HTTP_X_BLAH "blah"; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + scgi_cache NAME; + + location / { + scgi_pass 127.0.0.1:8081; + } + + location /no/ { + scgi_pass 127.0.0.1:8081; + scgi_cache off; + } + + location /custom/ { + scgi_pass 127.0.0.1:8081; + scgi_param SCGI 1; + scgi_param HTTP_X_BLAH "custom"; + } + } +} + +EOF + +$t->run_daemon(\&scgi_daemon); +$t->run(); + +############################################################################### + +like(http_get_ims('/'), qr/ims=;/, + 'if-modified-since cleared with cache'); +like(http_get_ims('/'), qr/iums=;/, + 'if-unmodified-since cleared with cache'); +like(http_get_ims('/'), qr/blah=blah;/, + 'custom params with cache'); + +like(http_get_ims('/no/'), qr/ims=blah;/, + 'if-modified-since preserved without cache'); +like(http_get_ims('/no/'), qr/iums=blah;/, + 'if-unmodified-since preserved without cache'); +like(http_get_ims('/'), qr/blah=blah;/, + 'custom params without cache'); + +like(http_get_ims('/custom/'), qr/ims=;/, + 'if-modified-since cleared with cache custom'); +like(http_get_ims('/custom/'), qr/iums=;/, + 'if-unmodified-since cleared with cache custom'); +like(http_get_ims('/custom/'), qr/blah=custom;/, + 'custom params with cache custom'); + +############################################################################### + +sub http_get_ims { + my ($url) = @_; + return http(<new( + Proto => 'tcp', + LocalHost => '127.0.0.1:8081', + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + my $scgi = SCGI->new($server, blocking => 1); + my $count = 0; + + while (my $request = $scgi->accept()) { + $count++; + $request->read_env(); + + my $ims = $request->env->{HTTP_IF_MODIFIED_SINCE} || ''; + my $iums = $request->env->{HTTP_IF_UNMODIFIED_SINCE} || ''; + my $blah = $request->env->{HTTP_X_BLAH} || ''; + + $request->connection()->print(<new()->has(qw/http secure_link/)->plan(8); + +$t->set_dso("ngx_http_secure_link_module", "lib_ngx_http_secure_link_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + # new style + # /test.html?hash=BASE64URL + + secure_link $arg_hash; + secure_link_md5 secret$uri; + + # invalid hash + if ($secure_link = "") { + return 403; + } + + # expired + if ($secure_link = "0") { + return 403; + } + + # $secure_link = "1" + } + + location = /expires.html { + # new style with expires + # /test.html?hash=BASE64URL&expires=12345678 + + secure_link $arg_hash,$arg_expires; + secure_link_md5 secret$uri$arg_expires; + + # invalid hash + if ($secure_link = "") { + return 403; + } + + # expired + if ($secure_link = "0") { + return 403; + } + + # $secure_link = "1" + } + + location /p/ { + # old style + # /p/d8e8fca2dc0f896fd7cb4cb0031ba249/test.html + + secure_link_secret secret; + + if ($secure_link = "") { + return 403; + } + + rewrite ^ /$secure_link break; + } + } +} + +EOF + +$t->write_file('test.html', 'PASSED'); +$t->write_file('expires.html', 'PASSED'); +$t->run(); + +############################################################################### + +# new style + +like(http_get('/test.html?hash=q-5vpkjBkRXXtkUMXiJVHA=='), + qr/PASSED/, 'request md5'); +like(http_get('/test.html?hash=q-5vpkjBkRXXtkUMXiJVHA'), + qr/PASSED/, 'request md5 no padding'); +like(http_get('/test.html'), qr/^HTTP.*403/, 'request no hash'); + +# new style with expires + +my ($expires, $hash); + +$expires = time() + 86400; +$hash = encode_base64url(md5("secret/expires.html$expires")); +like(http_get('/expires.html?hash=' . $hash . '&expires=' . $expires), + qr/PASSED/, 'request md5 not expired'); + +$expires = time() - 86400; +$hash = encode_base64url(md5("secret/expires.html$expires")); +like(http_get('/expires.html?hash=' . $hash . '&expires=' . $expires), + qr/^HTTP.*403/, 'request md5 expired'); + +# old style + +like(http_get('/p/' . md5_hex('test.html' . 'secret') . '/test.html'), + qr/PASSED/, 'request old style'); +like(http_get('/p/' . md5_hex('fake') . '/test.html'), qr/^HTTP.*403/, + 'request old style fake hash'); +like(http_get('/p/test.html'), qr/^HTTP.*403/, 'request old style no hash'); + +############################################################################### + +sub encode_base64url { + my $e = encode_base64(shift, ""); + $e =~ s/=+\z//; + $e =~ tr[+/][-_]; + return $e; +} + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/ssi.t b/tests/nginx-tests/dso-nginx-tests/ssi.t new file mode 100644 index 0000000000..bad9ddc16a --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/ssi.t @@ -0,0 +1,134 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx ssi module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http ssi cache proxy rewrite/)->plan(18); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + proxy_cache_path %%TESTDIR%%/cache levels=1:2 + keys_zone=NAME:10m; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + if ($args = "found") { + return 204; + } + + location / { + ssi on; + } + location /proxy/ { + ssi on; + proxy_pass http://127.0.0.1:8080/local/; + } + location /cache/ { + proxy_pass http://127.0.0.1:8080/local/; + proxy_cache NAME; + proxy_cache_valid 200 1h; + } + location /local/ { + ssi off; + alias %%TESTDIR%%/; + } + } +} + +EOF + +$t->write_file('test1.html', 'XX'); +$t->write_file('test2.html', + 'XX'); +$t->write_file('test3.html', + 'XX'); +$t->write_file('test-args-rewrite.html', + 'XX'); +$t->write_file('test-empty1.html', 'XX'); +$t->write_file('test-empty2.html', + 'XX'); +$t->write_file('test-empty3.html', + 'XX'); +$t->write_file('empty.html', ''); + +$t->run(); + +############################################################################### + +like(http_get('/test1.html'), qr/^X\(none\)X$/m, 'echo no argument'); +like(http_get('/test1.html?test='), qr/^XX$/m, 'empty argument'); +like(http_get('/test1.html?test=test'), qr/^XtestX$/m, 'argument'); +like(http_get('/test1.html?test=test&a=b'), qr/^XtestX$/m, 'argument 2'); +like(http_get('/test1.html?a=b&test=test'), qr/^XtestX$/m, 'argument 3'); +like(http_get('/test1.html?a=b&test=test&d=c'), qr/^XtestX$/m, 'argument 4'); +like(http_get('/test1.html?atest=a&testb=b&ctestc=c&test=test'), qr/^XtestX$/m, + 'argument 5'); + +like(http_get('/test2.html'), qr/^XXtestXX$/m, 'argument via include'); + +like(http_get('/test3.html'), qr/^XtestX$/m, 'set'); + +# args should be in subrequest even if original request has no args and that +# was queried somehow (e.g. by server rewrites) + +TODO: { +local $TODO = 'patch under review'; + +like(http_get('/test-args-rewrite.html'), qr/^XX$/m, 'args only subrequest'); + +} + +like(http_get('/test-args-rewrite.html?wasargs'), qr/^XX$/m, + 'args was in main request'); + +# Last-Modified and Accept-Ranges headers should be cleared + +unlike(http_get('/test1.html'), qr/Last-Modified|Accept-Ranges/im, + 'cleared headers'); +unlike(http_get('/proxy/test1.html'), qr/Last-Modified|Accept-Ranges/im, + 'cleared headers from proxy'); + +like(http_get('/test-empty1.html'), qr/HTTP/, 'empty with ssi'); +like(http_get('/test-empty2.html'), qr/HTTP/, 'empty without ssi'); +like(http_get('/test-empty3.html'), qr/HTTP/, 'empty with proxy'); +like(http_get('/test-empty3.html'), qr/HTTP/, 'empty with proxy cached'); + +like(`grep -F '[alert]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no alerts'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/ssi_if.t b/tests/nginx-tests/dso-nginx-tests/ssi_if.t new file mode 100644 index 0000000000..79f362ce92 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/ssi_if.t @@ -0,0 +1,267 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin +# (C) Valentin Bartenev + +# Tests for nginx ssi module, "if" statement. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http ssi/)->plan(44); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + ssi on; + } + } +} + +EOF + + +my $if_elif_else = + 'IF' + . 'ELIF' + . 'ELSE' + . ''; + +my $zig = 'GOOD'; +my $zag = 'GOOD'; + +foreach my $i (reverse 1 .. 15) { + if ($i % 2) { + $zig = + "$i$zig"; + $zag = + "$zag$i"; + } else { + $zig = + "$zig$i"; + $zag = + "$i$zag"; + } +} + +$t->run(); + +############################################################################### + +$t->write_file('if_var.html', 'xOKx'); + +like(http_get('/if_var.html?v=1'), qr/^xOKx$/m, 'if variable exists'); +like(http_get('/if_var.html'), qr/^xx$/m, 'if variable not exists'); + + +$t->write_file('if_eq.html', + 'xOKx'); + +like(http_get('/if_eq.html?v=equal'), qr/^xOKx$/m, 'if var = text'); +like(http_get('/if_eq.html?v=notequal'), qr/^xx$/m, 'if var = text (false)'); + + +$t->write_file('if_neq.html', + 'xOKx'); + +like(http_get('/if_neq.html?v=notequal'), qr/^xOKx$/m, 'if text != var'); +like(http_get('/if_neq.html?v=equal'), qr/^xx$/m, 'if text != var (false)'); + + +$t->write_file('if_eq_re.html', + 'xOKx'); + +like(http_get('/if_eq_re.html?v=XreeeegexX'), qr/^xOKx$/m, 'if var = /regex/'); +like(http_get('/if_eq_re.html?v=XrgxX'), qr/^xx$/m, 'if var = /regex/ (false)'); + + +$t->write_file('if_neq_re.html', + 'xOKx'); + +like(http_get('/if_neq_re.html?v=XrgxX'), qr/^xOKx$/m, 'if var != /regex/'); +like(http_get('/if_neq_re.html?v=XreeeegexX'), qr/^xx$/m, + 'if var != /regex/ (false)'); + + +$t->write_file('if_varvar.html', + 'xOKx'); + +like(http_get('/if_varvar.html?v=varHERE&v2=HERE'), qr/^xOKx$/m, + 'if var = complex'); + + +$t->write_file('if_cap_re.html', + 'x' + . 'x' + . 'x'); + +like(http_get('/if_cap_re.html?v=hereCAP1andCAP2'), qr/^xCAP1xCAP2x$/m, + 'if regex with captures'); + + +$t->write_file('if_ncap_re.html', + 'x' + . '' + . 'x'); + +like(http_get('/if_ncap_re.html?v=captureHEREeee'), qr/^xHEREx$/m, + 'if regex with named capture'); + + +$t->write_file('if.html', 'x' . $if_elif_else . 'x'); + +like(http_get('/if.html?if=1'), qr/^xIFx$/m, 'if'); +like(http_get('/if.html?if=1&elif=1'), qr/^xIFx$/m, 'if suppresses elif'); +like(http_get('/if.html?elif=1'), qr/^xELIFx$/m, 'elif'); +like(http_get('/if.html'), qr/^xELSEx$/m, 'else'); + + +$t->write_file('if_multi.html', + 'xIF1ELSE1' + . 'xIF2ELSE2' + . 'xIF3ELSE3' + . 'xIF4ELSE4' + . 'xIF5ELSE5x'); + +like(http_get('/if_multi.html?1=t&2=t&3=t&4=t&5=t'), + qr/^xIF1xIF2xIF3xIF4xIF5x$/m, 'multiple if (sequentially)'); +like(http_get('/if_multi.html?1=t&3=t&5=t'), qr/^xIF1xELSE2xIF3xELSE4xIF5x$/m, + 'multiple if (interlaced)'); +like(http_get('/if_multi.html?2=t&4=t'), qr/^xELSE1xIF2xELSE3xIF4xELSE5x$/m, + 'multiple if (interlaced reversed)'); + + +$t->write_file('if_in_block.html', + '' . $if_elif_else . '' + . 'xx'); + +like(http_get('/if_in_block.html?if=1'), qr/^xIFx$/m, 'if (in block)'); +like(http_get('/if_in_block.html?if=1&elif=1'), qr/^xIFx$/m, + 'if suppresses elif (in block)'); +like(http_get('/if_in_block.html?elif=1'), qr/^xELIFx$/m, 'elif (in block)'); +like(http_get('/if_in_block.html'), qr/^xELSEx$/m, 'else (in block)'); + + +$t->write_file('if_config_set_echo.html', + 'x' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . 'x'); + +like(http_get('/if_config_set_echo.html?if=1'), qr/^xIFx$/m, + 'if config-set-echo'); +like(http_get('/if_config_set_echo.html'), qr/^xELSEx$/m, + 'else config-set-echo'); + + +$t->write_file('if_include.html', + 'x' + . '' + . '' + . '' + . 'x'); + +like(http_get('/if_include.html?if=1'), qr/^xxIFxx$/m, + 'if include'); +like(http_get('/if_include.html'), qr/^xxELSExx$/m, + 'else include'); + + +$t->write_file('if_block.html', + '' + . 'IF' + . '' + . 'ELSE' + . '' + . 'xx'); + +like(http_get('/if_block.html?if=1'), qr/^xIFx$/m, 'if block'); +like(http_get('/if_block.html'), qr/^xELSEx$/m, 'else block'); + + +TODO: { +local $TODO = 'support for nested ifs'; + +$t->write_file('ifif.html', + 'xIFx' . $if_elif_else + . 'ELIFx' . $if_elif_else + . 'ELSEx' . $if_elif_else + . 'x'); + +like(http_get('/ifif.html?_if=1&if=1'), qr/^xIFxIFx$/m, 'if if'); +like(http_get('/ifif.html?_if=1&elif=1'), qr/^xIFxELIFx$/m, 'if elif'); +like(http_get('/ifif.html?_if=1'), qr/^xIFxELSEx$/m, 'if else'); + +like(http_get('/ifif.html?_elif=1&if=1'), qr/^xELIFxIFx$/m, 'elif if'); +like(http_get('/ifif.html?_elif=1&elif=1'), qr/^xELIFxELIFx$/m, 'elif elif'); +like(http_get('/ifif.html?_elif=1'), qr/^xELIFxELSEx$/m, 'elif else'); + +like(http_get('/ifif.html?if=1'), qr/^xELSExIFx$/m, 'else if'); +like(http_get('/ifif.html?elif=1'), qr/^xELSExELIFx$/m, 'else elif'); +like(http_get('/ifif.html'), qr/^xELSExELSEx$/m, 'else else'); + + +$t->write_file('zigzag.html', + "x$zig$zagx"); + +like(http_get('/zigzag.html?0=t&2=t&4=t&6=t&8=t&10=t&12=t&14=t'), + qr/^xGOODx$/m, 'zigzag'); +like(http_get('/zigzag.html?1=t&3=t&5=t&7=t&9=t&11=t&13=t&15=t'), + qr/^xGOODx$/m, 'zagzig'); + + +$t->write_file('zigzag_block.html', + '' + . "x$zig$zagx" + . '' + . 'xx'); + +like(http_get('/zigzag_block.html?0=t&2=t&4=t&6=t&8=t&10=t&12=t&14=t'), + qr/^xGOODx$/m, 'zigzag block'); +like(http_get('/zigzag_block.html?1=t&3=t&5=t&7=t&9=t&11=t&13=t&15=t'), + qr/^xGOODx$/m, 'zagzig block'); + +} + + +like(`grep -F '[alert]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no alerts'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t b/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t new file mode 100644 index 0000000000..86891e65f3 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t @@ -0,0 +1,95 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx ssi bug with big includes. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx qw/ :DEFAULT :gzip /; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http ssi rewrite gzip proxy/)->plan(8); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + output_buffers 2 512; + ssi on; + gzip on; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /proxy/ { + proxy_pass http://127.0.0.1:8080/local/; + } + location = /local/blah { + return 204; + } + } +} + +EOF + +$t->write_file('c1.html', 'X' x 1023); +$t->write_file('c2.html', 'X' x 1024); +$t->write_file('c3.html', 'X' x 1025); +$t->write_file('test1.html', '' + . ''); +$t->write_file('test2.html', '' + . ''); +$t->write_file('test3.html', '' + . ''); +$t->write_file('test4.html', '' + . ('X' x 1025)); + +$t->run(); + +############################################################################### + +my $t1 = http_gzip_request('/test1.html'); +ok(defined $t1, 'small included file (less than output_buffers)'); +http_gzip_like($t1, qr/^X{1023}\Z/, 'small included file content'); + +my $t2 = http_gzip_request('/test2.html'); +ok(defined $t2, 'small included file (equal to output_buffers)'); +http_gzip_like($t2, qr/^X{1024}\Z/, 'small included file content'); + +my $t3 = http_gzip_request('/test3.html'); +ok(defined $t3, 'big included file (more than output_buffers)'); +http_gzip_like($t3, qr/^X{1025}\Z/, 'big included file content'); + +my $t4 = http_gzip_request('/test4.html'); +ok(defined $t4, 'big ssi main file'); +http_gzip_like($t4, qr/^X{1025}\Z/, 'big ssi main file content'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/ssi_waited.t b/tests/nginx-tests/dso-nginx-tests/ssi_waited.t new file mode 100644 index 0000000000..d88baaba66 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/ssi_waited.t @@ -0,0 +1,70 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx ssi module, waited subrequests. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http ssi/)->plan(2); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + location / { + ssi on; + } + } +} + +EOF + +$t->write_file('index.html', 'x' . + 'xx'); +$t->write_file('first.html', 'FIRST'); +$t->write_file('second.html', + 'xSECOND'); +$t->write_file('waited.html', 'WAITED'); + +$t->run(); + +############################################################################### + +like(http_get('/'), qr/^xFIRSTxWAITEDxSECONDx$/m, 'waited non-active'); + +like(`grep -F '[alert]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no alerts'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/uwsgi.t b/tests/nginx-tests/dso-nginx-tests/uwsgi.t new file mode 100644 index 0000000000..e9a655b85d --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/uwsgi.t @@ -0,0 +1,119 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Test for uwsgi backend. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http uwsgi/)->has_daemon('uwsgi')->plan(3); + +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location / { + uwsgi_pass 127.0.0.1:8081; + uwsgi_param SERVER_PROTOCOL $server_protocol; + uwsgi_param HTTP_X_BLAH "blah"; + } + } +} + +EOF + +$t->write_file('uwsgi_test_app.py', <run_daemon('uwsgi', '--socket', '127.0.0.1:8081', + '--wsgi-file', $t->testdir() . '/uwsgi_test_app.py', + '--logto', $t->testdir() . '/uwsgi_log'); + +$t->run(); + +$t->waitforsocket('127.0.0.1:8081') + or die "Can't start uwsgi"; + +############################################################################### + +like(http_get('/'), qr/SEE-THIS/, 'uwsgi request'); +unlike(http_head('/head'), qr/SEE-THIS/, 'no data in HEAD'); + +SKIP: { +skip 'unsafe', 1 unless $ENV{TEST_NGINX_UNSAFE}; +local $TODO = 'not yet'; + +like(http_get_headers('/headers'), qr/SEE-THIS/, + 'uwsgi request with many ignored headers'); + +} + +############################################################################### + +sub http_get_headers { + my ($url, %extra) = @_; + return http(<new()->has(qw/http xslt/)->plan(5); + +$t->set_dso("ngx_http_xslt_filter_module", "lib_ngx_http_xslt_filter_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + default_type text/xml; + + location /x1 { + xslt_stylesheet %%TESTDIR%%/test.xslt; + } + location /x2 { + xslt_stylesheet %%TESTDIR%%/test.xslt + param1='value1':param2=/root param3='value%33'; + } + location /x3 { + xml_entities %%TESTDIR%%/entities.dtd; + xslt_stylesheet %%TESTDIR%%/test.xslt; + } + location /x4 { + xslt_stylesheet %%TESTDIR%%/first.xslt; + xslt_stylesheet %%TESTDIR%%/test.xslt; + } + } +} + +EOF + +$t->write_file('test.xslt', <<'EOF'); + + + + + + + + + + +test xslt result +param1= +param2= +param3= +data= + + + + +EOF + +$t->write_file('first.xslt', <<'EOF'); + + + + +other + + + + +EOF + +$t->write_file('entities.dtd', '' . "\n"); +$t->write_file('x1', ''); +$t->write_file('x2', 'data'); +$t->write_file('x3', '&test;'); +$t->write_file('x4', 'data'); + +$t->run(); + +############################################################################### + +like(http_get("/x1"), qr!200 OK.*test xslt result!ms, 'simple'); +like(http_get("/x1"), qr!200 OK.*Content-Type: text/html!ms, 'content type'); + +TODO: { +local $TODO = 'broken in 0.7.44 (r2589)'; + +like(http_get("/x2"), qr!200 OK.*param1=value1.*param2=data.*param3=value3!ms, + 'params'); + +} + +like(http_get("/x3"), qr!200 OK.*data=test entity!ms, 'entities'); +like(http_get("/x4"), qr!200 OK.*data=other data!ms, 'several stylesheets'); + +############################################################################### diff --git a/tests/nginx-tests/dso-nginx-tests/xslt_params.t b/tests/nginx-tests/dso-nginx-tests/xslt_params.t new file mode 100644 index 0000000000..a3cb4d19c5 --- /dev/null +++ b/tests/nginx-tests/dso-nginx-tests/xslt_params.t @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +# (C) Maxim Dounin + +# Tests for nginx xslt filter module. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http xslt/); + +$t->set_dso("ngx_http_xslt_module", "lib_ngx_http_xslt_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); + +$t->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +%%TEST_GLOBALS_DSO%% + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + default_type text/xml; + + location /x1 { + xslt_stylesheet %%TESTDIR%%/test.xslt + param1='value1':param2=/root param3='value%33'; + } + location /x2 { + xslt_stylesheet %%TESTDIR%%/test.xslt; + xslt_param param1 "'value1'"; + xslt_param param2 "/root"; + xslt_string_param param3 "value3"; + } + location /x3 { + xslt_stylesheet %%TESTDIR%%/test.xslt + param1='value1':param2=/root; + xslt_string_param param3 "value3"; + } + } +} + +EOF + +$t->write_file('test.xslt', <<'EOF'); + + + + + + + + + + +param1= +param2= +param3= + + + + +EOF + +$t->write_file('x1', 'data'); +$t->write_file('x2', 'data'); +$t->write_file('x3', 'data'); + +eval { + open OLDERR, ">&", \*STDERR; close STDERR; + $t->run(); + open STDERR, ">&", \*OLDERR; +}; + +plan(skip_all => 'no xslt_param') if $@; +$t->plan(3); + +############################################################################### + +like(http_get("/x1"), qr!200 OK.*param1=value1.*param2=data.*param3=value3!ms, + 'params from xslt_stylesheet'); +like(http_get("/x2"), qr!200 OK.*param1=value1.*param2=data.*param3=value3!ms, + 'params from xslt_param/xslt_string_param'); +like(http_get("/x3"), qr!200 OK.*param1=value1.*param2=data.*param3=value3!ms, + 'mixed'); + +############################################################################### diff --git a/tests/test-nginx/README b/tests/test-nginx/README new file mode 100644 index 0000000000..69757e109f --- /dev/null +++ b/tests/test-nginx/README @@ -0,0 +1,15 @@ + +Just test the static modules: + +PATH=/path/to/nginx/sbin:$PATH prove -r cases/footer.t +PATH=/path/to/nginx/sbin:$PATH prove -r cases/syslog.t +PATH=/path/to/nginx/sbin:$PATH prove -r cases/user_agent.t +TEST_NGINX_SLEEP_BEFORE=6 TEST_NGINX_USE_HUP=1 PATH=/path/to/nginx/sbin:$PATH prove -r cases/ngx_http_upstream_check_module + + +Just test the DSO modules. The test script can compile the dso module when testing: + +TEST_NGINX_DSO_PATH=/path/to/dso/module/source/ TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove -r dso_cases/footer.t +TEST_NGINX_DSO_PATH=/path/to/dso/module/source/ TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove -r dso_cases/syslog.t +TEST_NGINX_DSO_PATH=/path/to/dso/module/source/ TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove -r dso_cases/user_agent.t +TEST_NGINX_DSO_PATH=/path/to/dso/module/source/ TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx TEST_NGINX_SLEEP_BEFORE=6 TEST_NGINX_USE_HUP=1 PATH=/path/to/nginx/sbin:$PATH prove -r cases/ngx_http_upstream_check_module diff --git a/tests/test-nginx/dso_cases/footer.t b/tests/test-nginx/dso_cases/footer.t new file mode 100644 index 0000000000..56a053a786 --- /dev/null +++ b/tests/test-nginx/dso_cases/footer.t @@ -0,0 +1,47 @@ +use lib 'lib'; +use Shell; +use Test::Nginx::Socket; +plan tests => blocks() * 2; +run_tests(); + +__DATA__ + +=== TEST 0:0 +--- http_config + footer "taobao\n"; +--- config + location /e { + } +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +--- user_files +>>> a.html +--- request + GET /a.html +--- response_body +taobao + +=== TEST 1:1 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +--- config + location /e { + } +--- user_files +>>> a.html +--- request + GET /a.html +--- response_headers_like +HTTP/1.1 200 OK + +=== TEST 2:2 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +--- config + location /e { + } +--- user_files +>>> a.html +--- request + GET /a.html +--- response_body diff --git a/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/http_check.t b/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/http_check.t new file mode 100644 index 0000000000..9b93d5b00d --- /dev/null +++ b/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/http_check.t @@ -0,0 +1,253 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::LWP; + +plan tests => repeat_each(2) * 2 * blocks(); + +no_root_location(); + +run_tests(); + +__DATA__ + +=== TEST 1: the http_check test-single server +--- http_config + upstream test{ + server blog.163.com:80; + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 2: the http_check test-multi_server +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + + upstream foo{ + server www.taobao.com:80; + server www.taobao.com:81; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 3: the http_check test +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET /foo HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- error_code: 502 +--- response_body_like: ^.*$ + +=== TEST 4: the http_check without check directive +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 5: the http_check which does not use the upstream +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://blog.163.com; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 6: the http_check test-single server +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + ip_hash; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 7: the http_check test-multi_server +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + ip_hash; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 8: the http_check test +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + ip_hash; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET /foo HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- error_code: 502 +--- response_body_like: ^.*$ + +=== TEST 9: the http_check without check directive +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + ip_hash; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 10: the http_check which does not use the upstream +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + ip_hash; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + +--- config + location / { + proxy_pass http://blog.163.com; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 11: the http_check which does not use the upstream, with variable +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + ip_hash; + + check interval=3000 rise=1 fall=5 timeout=2000 type=http; + check_http_send "GET / HTTP/1.0\r\n\r\n"; + check_http_expect_alive http_2xx http_3xx; + } + + resolver 8.8.8.8; + +--- config + location / { + set $test "/"; + proxy_pass http://blog.163.com$test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ diff --git a/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/ssl_hello_check.t b/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/ssl_hello_check.t new file mode 100644 index 0000000000..30eca4fcff --- /dev/null +++ b/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/ssl_hello_check.t @@ -0,0 +1,74 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::LWP; + +plan tests => repeat_each(2) * 2 * blocks(); + +no_root_location(); +#no_diff; + +run_tests(); + +__DATA__ + +=== TEST 1: the ssl_hello_check test +--- http_config + upstream test{ + server www.alipay.com:443; + server www.alipay.com:444; + server www.alipay.com:445; + + check interval=4000 rise=1 fall=5 timeout=2000 type=ssl_hello; + } + +--- config + location / { + proxy_pass https://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>[\r\n\s\t]*$ + +=== TEST 2: the ssl_hello_check test with ip_hash +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server www.alipay.com:443; + server www.alipay.com:444; + server www.alipay.com:445; + ip_hash; + + check interval=4000 rise=1 fall=5 timeout=2000 type=ssl_hello; + } + +--- config + location / { + proxy_pass https://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>[\r\n\s\t]*$ + +=== TEST 3: the ssl_hello_check test with bad ip +--- http_config + upstream test{ + server www.alipay.com:80; + server www.alipay.com:443; + server www.alipay.com:444; + server www.alipay.com:445; + + check interval=4000 rise=1 fall=5 timeout=2000 type=ssl_hello; + } + +--- config + location / { + proxy_pass https://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>[\r\n\s\t]*$ diff --git a/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/tcp_check.t b/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/tcp_check.t new file mode 100644 index 0000000000..b3f874f8d2 --- /dev/null +++ b/tests/test-nginx/dso_cases/ngx_http_upstream_check_module/tcp_check.t @@ -0,0 +1,73 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::LWP; + +plan tests => repeat_each(2) * 2 * blocks(); + +no_root_location(); +#no_diff; + +run_tests(); + +__DATA__ + +=== TEST 1: the tcp_check test +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + server blog.163.com:82; + + check interval=3000 rise=1 fall=5 timeout=1000; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 2: the tcp_check test with ip_hash +--- include_dso_modules +ngx_http_upstream_ip_hash_module ngx_http_upstream_ip_hash_module +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + server blog.163.com:82; + ip_hash; + + check interval=3000 rise=1 fall=5 timeout=1000 type=tcp; + } + +--- config + location / { + proxy_pass http://test; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ + +=== TEST 3: the tcp_check test which don't use the checked upstream +--- http_config + upstream test{ + server blog.163.com:80; + server blog.163.com:81; + server blog.163.com:82; + + check interval=3000 rise=1 fall=5 timeout=1000; + } + +--- config + location / { + proxy_pass http://blog.163.com; + } + +--- request +GET / +--- response_body_like: ^<(.*)>$ diff --git a/tests/test-nginx/dso_cases/syslog.t b/tests/test-nginx/dso_cases/syslog.t new file mode 100644 index 0000000000..dcae8dc08f --- /dev/null +++ b/tests/test-nginx/dso_cases/syslog.t @@ -0,0 +1,223 @@ +use lib 'lib'; +use Test::Nginx::Socket; +plan tests => blocks() + 0; +run_tests(); + +__DATA__ + +=== TEST 1: syslog:user for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 2: syslog:user:info for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user:info; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 3: syslog:user:info:127.0.0.1 for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user:info:127.0.0.1; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 4: syslog:user:info:127.0.0.1:514 for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user:info:127.0.0.1:514; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 5: syslog:user:info:127.0.0.1:514:test.taobao.com for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user:info:127.0.0.1:514:test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 6: syslog:user::127.0.0.1:514:test.taobao.com for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user::127.0.0.1:514:test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 7: syslog:user:info:127.0.0.1::test.taobao.com for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user:info:127.0.0.1::test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 8: syslog:user:info:/dev/log:test.taobao.com for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user::/dev/log:test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 9: syslog:user:info:/dev/log for access log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + access_log syslog:user::/dev/log; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 11: syslog:user for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 12: syslog:user:info for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user:info; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 13: syslog:user:info:127.0.0.1 for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user:info:127.0.0.1; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 14: syslog:user:info:127.0.0.1:514 for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user:info:127.0.0.1:514; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 15: syslog:user:info:127.0.0.1:514:test.taobao.com for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user:info:127.0.0.1:514:test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 16: syslog:user::127.0.0.1:514:test.taobao.com for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user::127.0.0.1:514:test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 17: syslog:user:info:127.0.0.1::test.taobao.com for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user:info:127.0.0.1::test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 18: syslog:user:info:/dev/log:test.taobao.com for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user::/dev/log:test.taobao.com; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + +=== TEST 19: syslog:user:info:/dev/log for error log === +--- include_dso_modules +ngx_http_empty_gif_module ngx_http_empty_gif_module +--- config +location /p { + error_log syslog:user::/dev/log; + empty_gif; +} +--- request +GET /p +--- error_code: 200 + diff --git a/tests/test-nginx/dso_cases/user_agent.t b/tests/test-nginx/dso_cases/user_agent.t new file mode 100644 index 0000000000..b9c0402fc9 --- /dev/null +++ b/tests/test-nginx/dso_cases/user_agent.t @@ -0,0 +1,438 @@ +use lib 'lib'; +use Test::Nginx::Socket; +plan tests => blocks() * 2; +run_tests(); +__DATA__ + +=== TEST 2:2 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0) Gecko/20100101 Firefox/6.0 +--- response_body +Firefox + +=== TEST 3:3 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0) Gecko/20100101 Firefox/4.0 +--- response_body +msie6 + + +=== TEST 4:4 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.6.31 Version/10.70 +--- response_body +Opera + +=== TEST 5:5 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Opera/13.80 (Windows NT 6.1; U; pl) Presto/2.6.31 Version/10.70 +--- response_body +msie6 + +=== TEST 6:6 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 l ibidn/0.6.5 +--- response_body +msie6 + +=== TEST 7:7 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Chrome 6~8 8; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome1"; + } + + if ($browser = 8) { + echo "Chrome2"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Ubuntu/10.04 Chromium/14.0.808.0 Chrome/7.0.808.0 Safari/535.1 +--- response_body +Chrome2 + +=== TEST 8:8 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Chrome 6~8 8; + Chrome 5 9; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome1"; + } + + if ($browser = 8) { + echo "Chrome2"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Mozilla/4.0 (compatible; MSIE 9; Windows NT 6.1; Trident/5.0) +--- response_body +msie9 + +=== TEST 9:9 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Chrome 6~8 8; + Chrome 5 9; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 9.0= 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome1"; + } + + if ($browser = 8) { + echo "Chrome2"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 9) { + echo "Chrome3"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/5 Safari/535.2 +--- response_body +Chrome3 + +=== TEST 10:10 +--- include_dso_modules +nginx-http-footer-filter ngx_http_footer_filter_module +nginx-http-user-agent ngx_http_user_agent_module +echo-nginx-module ngx_http_echo_module +--- http_config + user_agent $browser { + default 1; + greedy safari; + greedy Safari; + + Chrome 12.0.742.112~15.0.872.0 4; + Chrome 6~8 8; + Chrome 5 9; + Firefox 5.0+ 5; + Opera 12.00- 6; + MSIE 7; + } +--- config + location /exact { + if ($browser = 1) { + echo "msie6"; + } + + if ($browser = 4) { + echo "Chrome1"; + } + + if ($browser = 8) { + echo "Chrome2"; + } + + if ($browser = 5) { + echo "Firefox"; + } + + if ($browser = 6) { + echo "Opera"; + } + + if ($browser = 7) { + echo "msie9"; + } + } +--- request + GET /exact +--- more_headers +User-Agent: Mozilla/4.0 (compatible; MSIE 9.0.1.0; Windows NT 6.1; Trident/5.0) +--- response_body +msie9 From 195c6ac584724076f75464c8b529002bf1e8de40 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Fri, 20 Jul 2012 11:56:01 +0800 Subject: [PATCH 08/36] 1 modify some warn message. --- contrib/dso.in | 7 ++++--- src/core/ngx_dso_module.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/contrib/dso.in b/contrib/dso.in index 3c402dec65..0e7b08aa9d 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -27,6 +27,7 @@ do case "$option" in --help) help=yes ;; + --h) help=yes ;; --prefix=) NGX_DSO_PREFIX="!" ;; --prefix=*) NGX_DSO_PREFIX="$value" ;; @@ -54,9 +55,9 @@ cat << END --prefix=PATH set module installation prefix - --add-module=PATH external module of will compile;; + --add-module=PATH external module of will compile - --with-nginx-source=NGX_SOURCE_HOM set nginx source path;; + --with-nginx-source=NGX_SOURCE_HOM set nginx source path END @@ -333,7 +334,7 @@ if test -n "$NGX_DSO_ADDONS"; then fi done else - echo "please assign module path" + echo "please specify the module path" exit 1 fi diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index fd768f9b28..b7744dea4f 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -538,7 +538,7 @@ ngx_show_dso_modules(ngx_conf_t *cf) module_name = dl_m[i].name; module = dl_m[i].module; - ngx_log_stderr(0, " %V (shared), version (%d.%d)", + ngx_log_stderr(0, " %V (shared), require nginx version (%d.%d)", &module_name, module->major_version, module->minor_version); } } From a06106889d6d8cd914f0e648023dca90e8ae10b1 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Fri, 20 Jul 2012 14:41:21 +0800 Subject: [PATCH 09/36] add chinese doc of dso. --- docs/modules/ngx_dso_module_zh.md | 118 ++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 docs/modules/ngx_dso_module_zh.md diff --git a/docs/modules/ngx_dso_module_zh.md b/docs/modules/ngx_dso_module_zh.md new file mode 100644 index 0000000000..5f413a700b --- /dev/null +++ b/docs/modules/ngx_dso_module_zh.md @@ -0,0 +1,118 @@ +模块名 +==== + +* 动态加载模块 + +描述 +=========== + +* 这个模块主要是用来运行时动态加载模块,而不用每次都要重新编译Tengine。 + +* 如果你想要编译官方模块为动态模块,你需要在configure的时候加上类似这样的指令(--with-http\_xxx_module),./configure --help可以看到更多的细节。 + +* 动态加载模块的个数限制为128个。 + +* 模块 在Linux/FreeeBSD/MacOS下测试成功。 + + +例子 +=========== + + dso_path /home/nginx-dso/module/; + + dso_load ngx_http_hat_filter_module lib_ngx_http_hat_filter_module.so; + dso_load ngx_http_lua_module lib_ngx_http_lua_module.so; + dso_load ngx_http_addition_filter_module lib_ngx_http_addition_filter_module.so; + dso_load ngx_http_concat_module lib_ngx_http_concat_module.so; + dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; + dso_load ngx_http_image_filter_module lib_ngx_http_image_filter_module.so; + +指令 +========== + +dso_order +------------- + +**Syntax**: *dso_order {.....}* + +**Default**: *none* + +**Context**: *main* + + +这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个模块要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 + +例子: + + dso_order { + ngx_core_module; + ngx_errlog_module; + ngx_conf_module; + ngx_events_module; + ngx_event_core_module; + ngx_epoll_module; + ngx_openssl_module; + ngx_http_module; + ngx_http_core_module; + ....................... + ngx_http_addition_filter_module; + ngx_http_my_filter_module; + } + +上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 + + +dso_path +------------------------ + +**Syntax**: *dso_path path* + +**Default**: *none* + +**Context**: *main* + +dso_path 主要是设置默认的动态模块加载路径。 + +例子: + + dso_path /home/dso/module/; + +设置默认的动态模块加载路径为/home/dso/module/. + +dso_load +------------------------ + +**Syntax**: *dso_load module_name module_path* + +**Default**: *none* + +**Context**: *main* + +dso_load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。 + +对于module\_path的路径查找,这里是严格按照下面的顺序的 + +1 module\_path指定的是绝对路径。 +2 相对于dso\_path设置的相对路径. +3 相对于默认的加载路径的相对路径(NGX\_PREFIX/modules或者说configure时通过--dso-path设置的路径). + +例子: + + dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; + +将会从lib\_ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。 + + +工具 +=========== + +dso_tools +------------------------ + +这个工具主要是用来编译第三方模块为动态模块. + +例子: + + ./dso_tools --add-module=/home/dso/lua-nginx-module + +将会编译ngx\_lua模块为动态库,然后安装到默认的模块路径. From 85dcf9a965d630ab7e63ee4d951acb0546aed754 Mon Sep 17 00:00:00 2001 From: diaoliang Date: Fri, 27 Jul 2012 17:19:02 +0800 Subject: [PATCH 10/36] 1 modify the name of compiled dso module name. --- auto/make | 6 +- contrib/dso.in | 8 +- docs/modules/ngx_dso_module.md | 14 +- docs/modules/ngx_dso_module_cn.md | 130 ++++++++++++++++++ tests/nginx-tests/README | 2 +- tests/nginx-tests/cases/concat.t | 8 +- tests/nginx-tests/cases/expires_by_types.t | 6 +- .../nginx-tests/cases/http_error_page_merge.t | 6 +- tests/nginx-tests/cases/limit_req_enhance.t | 8 +- tests/nginx-tests/cases/slice.t | 8 +- .../nginx-tests/dso-nginx-tests/auth_basic.t | 8 +- tests/nginx-tests/dso-nginx-tests/autoindex.t | 10 +- tests/nginx-tests/dso-nginx-tests/dav.t | 6 +- tests/nginx-tests/dso-nginx-tests/fastcgi.t | 6 +- .../dso-nginx-tests/fastcgi_cache.t | 6 +- .../dso-nginx-tests/fastcgi_header_params.t | 6 +- .../dso-nginx-tests/fastcgi_merge_params.t | 6 +- .../dso-nginx-tests/fastcgi_merge_params2.t | 6 +- tests/nginx-tests/dso-nginx-tests/gzip.t | 6 +- .../nginx-tests/dso-nginx-tests/gzip_flush.t | 6 +- .../dso-nginx-tests/http_disable_symlinks.t | 6 +- .../dso-nginx-tests/http_error_page.t | 6 +- .../http_expect_100_continue.t | 6 +- tests/nginx-tests/dso-nginx-tests/http_host.t | 6 +- .../dso-nginx-tests/http_location.t | 6 +- .../dso-nginx-tests/http_server_name.t | 6 +- .../dso-nginx-tests/http_try_files.t | 6 +- .../dso-nginx-tests/http_variables.t | 6 +- tests/nginx-tests/dso-nginx-tests/limit_req.t | 8 +- tests/nginx-tests/dso-nginx-tests/mail_imap.t | 6 +- tests/nginx-tests/dso-nginx-tests/mail_pop3.t | 6 +- tests/nginx-tests/dso-nginx-tests/mail_smtp.t | 6 +- .../mail_smtp_greeting_delay.t | 6 +- .../dso-nginx-tests/mail_smtp_xclient.t | 6 +- tests/nginx-tests/dso-nginx-tests/memcached.t | 8 +- .../dso-nginx-tests/memcached_fake.t | 8 +- .../dso-nginx-tests/not_modified.t | 6 +- tests/nginx-tests/dso-nginx-tests/perl.t | 6 +- tests/nginx-tests/dso-nginx-tests/perl_gzip.t | 6 +- tests/nginx-tests/dso-nginx-tests/proxy.t | 6 +- .../nginx-tests/dso-nginx-tests/proxy_cache.t | 6 +- .../dso-nginx-tests/proxy_cache_lock.t | 6 +- .../dso-nginx-tests/proxy_chunked.t | 6 +- .../dso-nginx-tests/proxy_cookie.t | 6 +- .../dso-nginx-tests/proxy_merge_headers.t | 6 +- .../dso-nginx-tests/proxy_noclose.t | 6 +- .../dso-nginx-tests/proxy_redirect.t | 6 +- .../nginx-tests/dso-nginx-tests/proxy_store.t | 6 +- tests/nginx-tests/dso-nginx-tests/proxy_xar.t | 6 +- .../dso-nginx-tests/random_index.t | 8 +- tests/nginx-tests/dso-nginx-tests/range.t | 8 +- tests/nginx-tests/dso-nginx-tests/range_flv.t | 8 +- .../dso-nginx-tests/range_if_range.t | 6 +- tests/nginx-tests/dso-nginx-tests/rewrite.t | 6 +- .../dso-nginx-tests/rewrite_unescape.t | 6 +- tests/nginx-tests/dso-nginx-tests/scgi.t | 6 +- tests/nginx-tests/dso-nginx-tests/scgi_gzip.t | 6 +- .../dso-nginx-tests/scgi_merge_params.t | 6 +- .../nginx-tests/dso-nginx-tests/secure_link.t | 8 +- tests/nginx-tests/dso-nginx-tests/ssi.t | 6 +- tests/nginx-tests/dso-nginx-tests/ssi_if.t | 6 +- .../dso-nginx-tests/ssi_include_big.t | 6 +- .../nginx-tests/dso-nginx-tests/ssi_waited.t | 6 +- tests/nginx-tests/dso-nginx-tests/uwsgi.t | 6 +- tests/nginx-tests/dso-nginx-tests/xslt.t | 8 +- .../nginx-tests/dso-nginx-tests/xslt_params.t | 8 +- .../test-nginx/lib/Test/Nginx/Util.pm | 2 +- 67 files changed, 344 insertions(+), 214 deletions(-) create mode 100644 docs/modules/ngx_dso_module_cn.md diff --git a/auto/make b/auto/make index b9d4a791ed..70c21ea5a6 100644 --- a/auto/make +++ b/auto/make @@ -210,7 +210,7 @@ ngx_link=${CORE_LINK:+`echo $CORE_LINK \ for ngx_shared_modules in $NGX_SHARED_MODULES do - NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}lib_${ngx_shared_modules}${ngx_soext}" + NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}" done if test -n "$NGX_DSO_ALL_TARGETS"; then @@ -523,8 +523,8 @@ END cat << END >> $NGX_MAKEFILE -$NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}lib_${ngx_shared_modules}${ngx_soext}: $ngx_dso_deps$ngx_spacer - \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/dso_modules${ngx_dirsep}lib_${ngx_shared_modules}${ngx_soext}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib +$NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}: $ngx_dso_deps$ngx_spacer + \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/dso_modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib $ngx_rcc ${ngx_long_end} END diff --git a/contrib/dso.in b/contrib/dso.in index 0e7b08aa9d..994c370245 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -153,8 +153,8 @@ END cat << END >> $NGX_DSO_MAKEFILE -$NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext}: $ngx_deps$ngx_spacer - \$(LINK) ${ngx_long_start}${ngx_binout} $NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext}$ngx_long_cont$ngx_objs$ngx_libs$ngx_link +$NGX_OBJS${ngx_dirsep}${dso_binout}${ngx_soext}: $ngx_deps$ngx_spacer + \$(LINK) ${ngx_long_start}${ngx_binout} $NGX_OBJS${ngx_dirsep}${dso_binout}${ngx_soext}$ngx_long_cont$ngx_objs$ngx_libs$ngx_link $ngx_rcc ${ngx_long_end} END @@ -187,9 +187,9 @@ END make -f $NGX_DSO_MAKEFILE if test -n "$NGX_DSO_PREFIX"; then - cp $NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext} $NGX_DSO_PREFIX + cp $NGX_OBJS${ngx_dirsep}${dso_binout}${ngx_soext} $NGX_DSO_PREFIX else - cp $NGX_OBJS${ngx_dirsep}lib_${dso_binout}${ngx_soext} $NGX_PREFIX/$NGX_DSO_PATH + cp $NGX_OBJS${ngx_dirsep}${dso_binout}${ngx_soext} $NGX_PREFIX/$NGX_DSO_PATH fi } diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index 7d0c0225e9..caa28c8121 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -20,12 +20,12 @@ Exampe dso_path /home/nginx-dso/module/; - dso_load ngx_http_hat_filter_module lib_ngx_http_hat_filter_module.so; - dso_load ngx_http_lua_module lib_ngx_http_lua_module.so; - dso_load ngx_http_addition_filter_module lib_ngx_http_addition_filter_module.so; - dso_load ngx_http_concat_module lib_ngx_http_concat_module.so; - dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; - dso_load ngx_http_image_filter_module lib_ngx_http_image_filter_module.so; + dso_load ngx_http_hat_filter_module ngx_http_hat_filter_module.so; + dso_load ngx_http_lua_module ngx_http_lua_module.so; + dso_load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; + dso_load ngx_http_concat_module ngx_http_concat_module.so; + dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + dso_load ngx_http_image_filter_module ngx_http_image_filter_module.so; Directives ========== @@ -99,7 +99,7 @@ There are three possibility with the module_path. It will search the module in b Example: - dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; + dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; load empty_gif module from lib\_ngx\_http\_empty\_gif\_module.so. diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md new file mode 100644 index 0000000000..36e0b83e06 --- /dev/null +++ b/docs/modules/ngx_dso_module_cn.md @@ -0,0 +1,130 @@ +模块名 +==== + +* 动态加载模块 + +描述 +=========== + +* 这个模块主要是用来运行时动态加载模块,而不用每次都要重新编译Tengine. + +* 如果你想要编译官方模块为动态模块,你需要在configure的时候加上类似这样的指令(--with-http\_xxx_module),./configure --help可以看到更多的细节. + +* 如果需要编译第三方模块,可以使用dso\_tools工具(详细使用方法请参加dso_tools章节). + +* 动态加载模块的个数限制为128个. + +* 如果已经加载的动态模块有修改,那么必须重起Tengine. + +* 模块 在Linux/FreeeBSD/MacOS下测试成功. + + +例子 +=========== + + worker_processes 1; + + dso_path /home/nginx-dso/module/; + + dso_load ngx_http_hat_filter_module ngx_http_hat_filter_module.so; + dso_load ngx_http_lua_module ngx_http_lua_module.so; + dso_load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; + dso_load ngx_http_concat_module ngx_http_concat_module.so; + dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + dso_load ngx_http_image_filter_module ngx_http_image_filter_module.so; + + events { + worker_connections 1024; + } + + +指令 +========== + +dso_load +------------------------ + +**Syntax**: *dso_load module_name module_path* + +**Default**: *none* + +**Context**: *main* + +dso_load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。 + +对于module\_path的路径查找,这里是严格按照下面的顺序的 + +1 module\_path指定的是绝对路径。 +2 相对于dso\_path设置的相对路径. +3 相对于默认的加载路径的相对路径(NGX\_PREFIX/modules或者说configure时通过--dso-path设置的路径). + +例子: + + dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + +将会从lib\_ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。 + + +dso_order +------------- + +**Syntax**: *dso_order {.....}* + +**Default**: *none* + +**Context**: *main* + + +这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个模块要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 + +例子: + + dso_order { + ngx_core_module; + ngx_errlog_module; + ngx_conf_module; + ngx_events_module; + ngx_event_core_module; + ngx_epoll_module; + ngx_openssl_module; + ngx_http_module; + ngx_http_core_module; + ....................... + ngx_http_addition_filter_module; + ngx_http_my_filter_module; + } + +上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 + + +dso_path +------------------------ + +**Syntax**: *dso_path path* + +**Default**: *none* + +**Context**: *main* + +dso_path 主要是设置默认的动态模块加载路径。 + +例子: + + dso_path /home/dso/module/; + +设置默认的动态模块加载路径为/home/dso/module/. + + +工具 +=========== + +dso_tools +------------------------ + +这个工具主要是用来编译第三方模块为动态模块. + +例子: + + ./dso_tools --add-module=/home/dso/lua-nginx-module + +将会编译ngx\_lua模块为动态库,然后安装到默认的模块路径. diff --git a/tests/nginx-tests/README b/tests/nginx-tests/README index 6638a43cb0..500aa2ea3c 100644 --- a/tests/nginx-tests/README +++ b/tests/nginx-tests/README @@ -10,6 +10,6 @@ TEST_NGINX_DSO=1 TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove cases TEST_NGINX_DSO=1 TEST_NGINX_BINARY=/path/to/nginx/sbin/nginx prove dso-nginx-tests 2. Add the dso module to the test script (The example module shared library should be under the modules directory): -$t->set_dso("ngx_http_example_module", "lib_ngx_http_example_module.so"); +$t->set_dso("ngx_http_example_module", "ngx_http_example_module.so"); ... %%TEST_GLOBALS_DSO%% diff --git a/tests/nginx-tests/cases/concat.t b/tests/nginx-tests/cases/concat.t index 747ff995fd..811bf471f8 100644 --- a/tests/nginx-tests/cases/concat.t +++ b/tests/nginx-tests/cases/concat.t @@ -21,10 +21,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http/)->plan(58); -$t->set_dso("ngx_http_concat_module", "lib_ngx_http_concat_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_concat_module", "ngx_http_concat_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/cases/expires_by_types.t b/tests/nginx-tests/cases/expires_by_types.t index 74492196c6..9496240a7e 100644 --- a/tests/nginx-tests/cases/expires_by_types.t +++ b/tests/nginx-tests/cases/expires_by_types.t @@ -26,9 +26,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->plan(72); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/cases/http_error_page_merge.t b/tests/nginx-tests/cases/http_error_page_merge.t index 14cf6479e0..95daaf4034 100644 --- a/tests/nginx-tests/cases/http_error_page_merge.t +++ b/tests/nginx-tests/cases/http_error_page_merge.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(16); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/cases/limit_req_enhance.t b/tests/nginx-tests/cases/limit_req_enhance.t index 702fb3b16b..022f3655db 100644 --- a/tests/nginx-tests/cases/limit_req_enhance.t +++ b/tests/nginx-tests/cases/limit_req_enhance.t @@ -23,10 +23,10 @@ use Test::Nginx; my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(27); -$t->set_dso("ngx_http_limit_req_module", "lib_ngx_http_limit_req_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_limit_req_module", "ngx_http_limit_req_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/cases/slice.t b/tests/nginx-tests/cases/slice.t index fbf863010c..5fda517c97 100644 --- a/tests/nginx-tests/cases/slice.t +++ b/tests/nginx-tests/cases/slice.t @@ -21,10 +21,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http/)->plan(23); -$t->set_dso("ngx_http_slice_module", "lib_ngx_http_slice_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_slice_module", "ngx_http_slice_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/auth_basic.t b/tests/nginx-tests/dso-nginx-tests/auth_basic.t index d8f8200582..40f12493e7 100644 --- a/tests/nginx-tests/dso-nginx-tests/auth_basic.t +++ b/tests/nginx-tests/dso-nginx-tests/auth_basic.t @@ -25,10 +25,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http auth_basic/)->plan(11); -#$t->set_dso("ngx_http_auth_basic_module", "lib_ngx_http_auth_basic_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +#$t->set_dso("ngx_http_auth_basic_module", "ngx_http_auth_basic_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/autoindex.t b/tests/nginx-tests/dso-nginx-tests/autoindex.t index fd4a56c52d..9cf4dc3cec 100644 --- a/tests/nginx-tests/dso-nginx-tests/autoindex.t +++ b/tests/nginx-tests/dso-nginx-tests/autoindex.t @@ -23,11 +23,11 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http autoindex/)->plan(16); -$t->set_dso("ngx_http_autoindex_module", "lib_ngx_http_autoindex_module.so"); -$t->set_dso("ngx_http_charset_filter_module", "lib_ngx_http_charset_filter_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_autoindex_module", "ngx_http_autoindex_module.so"); +$t->set_dso("ngx_http_charset_filter_module", "ngx_http_charset_filter_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/dav.t b/tests/nginx-tests/dso-nginx-tests/dav.t index 2fe2d0de81..a0aed04e43 100644 --- a/tests/nginx-tests/dso-nginx-tests/dav.t +++ b/tests/nginx-tests/dso-nginx-tests/dav.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http dav/)->plan(13); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/fastcgi.t b/tests/nginx-tests/dso-nginx-tests/fastcgi.t index bcfc0bd52d..10f3e39b6b 100644 --- a/tests/nginx-tests/dso-nginx-tests/fastcgi.t +++ b/tests/nginx-tests/dso-nginx-tests/fastcgi.t @@ -26,9 +26,9 @@ plan(skip_all => 'FCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http fastcgi/)->plan(5); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/fastcgi_cache.t b/tests/nginx-tests/dso-nginx-tests/fastcgi_cache.t index 2a38c353b9..18bbd598d9 100644 --- a/tests/nginx-tests/dso-nginx-tests/fastcgi_cache.t +++ b/tests/nginx-tests/dso-nginx-tests/fastcgi_cache.t @@ -26,9 +26,9 @@ plan(skip_all => 'FCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(5); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/fastcgi_header_params.t b/tests/nginx-tests/dso-nginx-tests/fastcgi_header_params.t index 4c8b04937c..6b722b8f01 100644 --- a/tests/nginx-tests/dso-nginx-tests/fastcgi_header_params.t +++ b/tests/nginx-tests/dso-nginx-tests/fastcgi_header_params.t @@ -26,9 +26,9 @@ plan(skip_all => 'FCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http fastcgi/)->plan(1); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params.t b/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params.t index 6aa7162dac..d1374f037f 100644 --- a/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params.t +++ b/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params.t @@ -27,9 +27,9 @@ plan(skip_all => 'FCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(9); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params2.t b/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params2.t index 6f91dd1ee1..2a6ffa956e 100644 --- a/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params2.t +++ b/tests/nginx-tests/dso-nginx-tests/fastcgi_merge_params2.t @@ -27,9 +27,9 @@ plan(skip_all => 'FCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(4); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/gzip.t b/tests/nginx-tests/dso-nginx-tests/gzip.t index 2bc43bdc97..d5c0b1af5f 100644 --- a/tests/nginx-tests/dso-nginx-tests/gzip.t +++ b/tests/nginx-tests/dso-nginx-tests/gzip.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy gzip/)->plan(8); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/gzip_flush.t b/tests/nginx-tests/dso-nginx-tests/gzip_flush.t index 4569168b94..f315baef93 100644 --- a/tests/nginx-tests/dso-nginx-tests/gzip_flush.t +++ b/tests/nginx-tests/dso-nginx-tests/gzip_flush.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http gzip perl/)->plan(2); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t b/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t index da7734c8ab..e22f34bd56 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t +++ b/tests/nginx-tests/dso-nginx-tests/http_disable_symlinks.t @@ -25,9 +25,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_error_page.t b/tests/nginx-tests/dso-nginx-tests/http_error_page.t index 2f87c1bf59..9272dd1fd5 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_error_page.t +++ b/tests/nginx-tests/dso-nginx-tests/http_error_page.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(7); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t b/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t index 262756127f..5ea9f2b428 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t +++ b/tests/nginx-tests/dso-nginx-tests/http_expect_100_continue.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(2); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_host.t b/tests/nginx-tests/dso-nginx-tests/http_host.t index c736e0fc51..7c20b07835 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_host.t +++ b/tests/nginx-tests/dso-nginx-tests/http_host.t @@ -24,9 +24,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(35); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_location.t b/tests/nginx-tests/dso-nginx-tests/http_location.t index 5ca38c47bc..572df7a1e7 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_location.t +++ b/tests/nginx-tests/dso-nginx-tests/http_location.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(8); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_server_name.t b/tests/nginx-tests/dso-nginx-tests/http_server_name.t index b8560d1784..e86f05ba9a 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_server_name.t +++ b/tests/nginx-tests/dso-nginx-tests/http_server_name.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(9); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_try_files.t b/tests/nginx-tests/dso-nginx-tests/http_try_files.t index 64ebda2052..443567b809 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_try_files.t +++ b/tests/nginx-tests/dso-nginx-tests/http_try_files.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(4); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/http_variables.t b/tests/nginx-tests/dso-nginx-tests/http_variables.t index 002a629659..13668e7a60 100644 --- a/tests/nginx-tests/dso-nginx-tests/http_variables.t +++ b/tests/nginx-tests/dso-nginx-tests/http_variables.t @@ -24,9 +24,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite proxy/)->plan(3); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/limit_req.t b/tests/nginx-tests/dso-nginx-tests/limit_req.t index bc4e78e19e..da207f6039 100644 --- a/tests/nginx-tests/dso-nginx-tests/limit_req.t +++ b/tests/nginx-tests/dso-nginx-tests/limit_req.t @@ -23,10 +23,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(5); -$t->set_dso("ngx_http_limit_req_module", "lib_ngx_http_limit_req_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_limit_req_module", "ngx_http_limit_req_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/mail_imap.t b/tests/nginx-tests/dso-nginx-tests/mail_imap.t index c5a6f5088c..29aa0b2aaf 100644 --- a/tests/nginx-tests/dso-nginx-tests/mail_imap.t +++ b/tests/nginx-tests/dso-nginx-tests/mail_imap.t @@ -31,9 +31,9 @@ local $SIG{PIPE} = 'IGNORE'; my $t = Test::Nginx->new() ->has(qw/mail imap http rewrite/)->plan(9); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->run_daemon(\&Test::Nginx::IMAP::imap_test_daemon) ->write_file_expand('nginx.conf', <<'EOF')->run(); diff --git a/tests/nginx-tests/dso-nginx-tests/mail_pop3.t b/tests/nginx-tests/dso-nginx-tests/mail_pop3.t index dae8158e0c..86b6568847 100644 --- a/tests/nginx-tests/dso-nginx-tests/mail_pop3.t +++ b/tests/nginx-tests/dso-nginx-tests/mail_pop3.t @@ -31,9 +31,9 @@ local $SIG{PIPE} = 'IGNORE'; my $t = Test::Nginx->new() ->has(qw/mail pop3 http rewrite/)->plan(8); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->run_daemon(\&Test::Nginx::POP3::pop3_test_daemon) ->write_file_expand('nginx.conf', <<'EOF')->run(); diff --git a/tests/nginx-tests/dso-nginx-tests/mail_smtp.t b/tests/nginx-tests/dso-nginx-tests/mail_smtp.t index 36007c9ec0..ff95497590 100644 --- a/tests/nginx-tests/dso-nginx-tests/mail_smtp.t +++ b/tests/nginx-tests/dso-nginx-tests/mail_smtp.t @@ -30,9 +30,9 @@ local $SIG{PIPE} = 'IGNORE'; my $t = Test::Nginx->new() ->has(qw/mail smtp http rewrite/)->plan(25); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon) ->write_file_expand('nginx.conf', <<'EOF')->run(); diff --git a/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t b/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t index 4b098d4c70..a928d0267e 100644 --- a/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t +++ b/tests/nginx-tests/dso-nginx-tests/mail_smtp_greeting_delay.t @@ -24,9 +24,9 @@ local $SIG{PIPE} = 'IGNORE'; my $t = Test::Nginx->new()->has(qw/mail smtp http/)->plan(2); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF')->run(); diff --git a/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t b/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t index d2b655252d..8637c594f5 100644 --- a/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t +++ b/tests/nginx-tests/dso-nginx-tests/mail_smtp_xclient.t @@ -27,9 +27,9 @@ local $SIG{PIPE} = 'IGNORE'; my $t = Test::Nginx->new()->has(qw/mail smtp http rewrite/)->plan(6); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon) ->write_file_expand('nginx.conf', <<'EOF')->run(); diff --git a/tests/nginx-tests/dso-nginx-tests/memcached.t b/tests/nginx-tests/dso-nginx-tests/memcached.t index e2a9dc5716..9fe60f93a7 100644 --- a/tests/nginx-tests/dso-nginx-tests/memcached.t +++ b/tests/nginx-tests/dso-nginx-tests/memcached.t @@ -27,10 +27,10 @@ plan(skip_all => 'Cache::Memcached not installed') if $@; my $t = Test::Nginx->new()->has(qw/http rewrite memcached/) ->has_daemon('memcached')->plan(4); -$t->set_dso("ngx_http_memcached_module", "lib_ngx_http_memcached_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_memcached_module", "ngx_http_memcached_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/memcached_fake.t b/tests/nginx-tests/dso-nginx-tests/memcached_fake.t index e9c79e77da..7a04745fb9 100644 --- a/tests/nginx-tests/dso-nginx-tests/memcached_fake.t +++ b/tests/nginx-tests/dso-nginx-tests/memcached_fake.t @@ -24,10 +24,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite memcached ssi/)->plan(3); -$t->set_dso("ngx_http_memcached_module", "lib_ngx_http_memcached_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_memcached_module", "ngx_http_memcached_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/not_modified.t b/tests/nginx-tests/dso-nginx-tests/not_modified.t index 2229e94c80..f2bdcb41dc 100644 --- a/tests/nginx-tests/dso-nginx-tests/not_modified.t +++ b/tests/nginx-tests/dso-nginx-tests/not_modified.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has('http')->plan(4); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/perl.t b/tests/nginx-tests/dso-nginx-tests/perl.t index 798ecfe982..63c1c7ea80 100644 --- a/tests/nginx-tests/dso-nginx-tests/perl.t +++ b/tests/nginx-tests/dso-nginx-tests/perl.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http perl rewrite/)->plan(1); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/perl_gzip.t b/tests/nginx-tests/dso-nginx-tests/perl_gzip.t index c5e97367a6..74f05e6dae 100644 --- a/tests/nginx-tests/dso-nginx-tests/perl_gzip.t +++ b/tests/nginx-tests/dso-nginx-tests/perl_gzip.t @@ -26,9 +26,9 @@ Test::More::plan(skip_all => "IO::Compress::Gzip not found") if $@; my $t = Test::Nginx->new()->has(qw/http perl gzip/)->plan(2); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy.t b/tests/nginx-tests/dso-nginx-tests/proxy.t index 0f46d4a6c5..14fc7c08ae 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(3); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_cache.t b/tests/nginx-tests/dso-nginx-tests/proxy_cache.t index ac11791802..e83cc3b2e3 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_cache.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_cache.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy cache gzip/)->plan(12); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t b/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t index c8591cc894..0f73757df7 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_cache_lock.t @@ -24,9 +24,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy cache/); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t b/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t index e536105619..2602d57382 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_chunked.t @@ -29,9 +29,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy ssi/)->plan(3); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t b/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t index 8d9599fd0d..fcb47462a9 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_cookie.t @@ -24,9 +24,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy rewrite/); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t b/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t index 1a2b4f99ac..22ba08d1bb 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_merge_headers.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy cache rewrite/)->plan(3); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_noclose.t b/tests/nginx-tests/dso-nginx-tests/proxy_noclose.t index 89ea93e854..db6ed7047a 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_noclose.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_noclose.t @@ -34,9 +34,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(4); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t b/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t index d10b782416..d49d005767 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_redirect.t @@ -24,9 +24,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy rewrite/)->plan(15); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_store.t b/tests/nginx-tests/dso-nginx-tests/proxy_store.t index 35f2565e0e..e375a4d5cc 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_store.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_store.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new(); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF')->has(qw/http proxy ssi/)->plan(7); diff --git a/tests/nginx-tests/dso-nginx-tests/proxy_xar.t b/tests/nginx-tests/dso-nginx-tests/proxy_xar.t index 81e909141f..f0e6e96db1 100644 --- a/tests/nginx-tests/dso-nginx-tests/proxy_xar.t +++ b/tests/nginx-tests/dso-nginx-tests/proxy_xar.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy rewrite/)->plan(8); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/random_index.t b/tests/nginx-tests/dso-nginx-tests/random_index.t index 98ce8de909..d78cfb37e5 100644 --- a/tests/nginx-tests/dso-nginx-tests/random_index.t +++ b/tests/nginx-tests/dso-nginx-tests/random_index.t @@ -23,10 +23,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http random_index/)->plan(1); -$t->set_dso("ngx_http_random_index_module", "lib_ngx_http_random_index_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_random_index_module", "ngx_http_random_index_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/range.t b/tests/nginx-tests/dso-nginx-tests/range.t index 098ee8a235..fdcff05811 100644 --- a/tests/nginx-tests/dso-nginx-tests/range.t +++ b/tests/nginx-tests/dso-nginx-tests/range.t @@ -23,10 +23,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http charset/)->plan(31); -$t->set_dso("ngx_http_charset_filter_module", "lib_ngx_http_charset_filter_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_charset_filter_module", "ngx_http_charset_filter_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/range_flv.t b/tests/nginx-tests/dso-nginx-tests/range_flv.t index 566af98127..3bfab91153 100644 --- a/tests/nginx-tests/dso-nginx-tests/range_flv.t +++ b/tests/nginx-tests/dso-nginx-tests/range_flv.t @@ -23,10 +23,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http flv/)->plan(12); -$t->set_dso("ngx_http_flv_module", "lib_ngx_http_flv_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_flv_module", "ngx_http_flv_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/range_if_range.t b/tests/nginx-tests/dso-nginx-tests/range_if_range.t index 0b6bccf094..9129335beb 100644 --- a/tests/nginx-tests/dso-nginx-tests/range_if_range.t +++ b/tests/nginx-tests/dso-nginx-tests/range_if_range.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http/)->plan(8); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/rewrite.t b/tests/nginx-tests/dso-nginx-tests/rewrite.t index de3139c0fc..2d5fbbe330 100644 --- a/tests/nginx-tests/dso-nginx-tests/rewrite.t +++ b/tests/nginx-tests/dso-nginx-tests/rewrite.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(19); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/rewrite_unescape.t b/tests/nginx-tests/dso-nginx-tests/rewrite_unescape.t index e997cc8ed9..61c6db8174 100644 --- a/tests/nginx-tests/dso-nginx-tests/rewrite_unescape.t +++ b/tests/nginx-tests/dso-nginx-tests/rewrite_unescape.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(9); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/scgi.t b/tests/nginx-tests/dso-nginx-tests/scgi.t index 8f39e064f4..fdc4f00f6a 100644 --- a/tests/nginx-tests/dso-nginx-tests/scgi.t +++ b/tests/nginx-tests/dso-nginx-tests/scgi.t @@ -26,9 +26,9 @@ plan(skip_all => 'SCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http scgi/)->plan(5); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/scgi_gzip.t b/tests/nginx-tests/dso-nginx-tests/scgi_gzip.t index 82d2089c80..b884a30573 100644 --- a/tests/nginx-tests/dso-nginx-tests/scgi_gzip.t +++ b/tests/nginx-tests/dso-nginx-tests/scgi_gzip.t @@ -26,9 +26,9 @@ plan(skip_all => 'SCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http scgi gzip/)->plan(1); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/scgi_merge_params.t b/tests/nginx-tests/dso-nginx-tests/scgi_merge_params.t index 8905291b07..a6739ee313 100644 --- a/tests/nginx-tests/dso-nginx-tests/scgi_merge_params.t +++ b/tests/nginx-tests/dso-nginx-tests/scgi_merge_params.t @@ -26,9 +26,9 @@ plan(skip_all => 'SCGI not installed') if $@; my $t = Test::Nginx->new()->has(qw/http scgi cache/)->plan(9); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/secure_link.t b/tests/nginx-tests/dso-nginx-tests/secure_link.t index a64442e923..fd42e5ea8f 100644 --- a/tests/nginx-tests/dso-nginx-tests/secure_link.t +++ b/tests/nginx-tests/dso-nginx-tests/secure_link.t @@ -26,10 +26,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http secure_link/)->plan(8); -$t->set_dso("ngx_http_secure_link_module", "lib_ngx_http_secure_link_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_secure_link_module", "ngx_http_secure_link_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/ssi.t b/tests/nginx-tests/dso-nginx-tests/ssi.t index bad9ddc16a..c3f9880ba8 100644 --- a/tests/nginx-tests/dso-nginx-tests/ssi.t +++ b/tests/nginx-tests/dso-nginx-tests/ssi.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http ssi cache proxy rewrite/)->plan(18); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/ssi_if.t b/tests/nginx-tests/dso-nginx-tests/ssi_if.t index 79f362ce92..fbf1ae19e0 100644 --- a/tests/nginx-tests/dso-nginx-tests/ssi_if.t +++ b/tests/nginx-tests/dso-nginx-tests/ssi_if.t @@ -24,9 +24,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http ssi/)->plan(44); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t b/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t index 86891e65f3..fb1bd2de06 100644 --- a/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t +++ b/tests/nginx-tests/dso-nginx-tests/ssi_include_big.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http ssi rewrite gzip proxy/)->plan(8); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/ssi_waited.t b/tests/nginx-tests/dso-nginx-tests/ssi_waited.t index d88baaba66..1b941b5862 100644 --- a/tests/nginx-tests/dso-nginx-tests/ssi_waited.t +++ b/tests/nginx-tests/dso-nginx-tests/ssi_waited.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http ssi/)->plan(2); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/uwsgi.t b/tests/nginx-tests/dso-nginx-tests/uwsgi.t index e9a655b85d..46b45e20af 100644 --- a/tests/nginx-tests/dso-nginx-tests/uwsgi.t +++ b/tests/nginx-tests/dso-nginx-tests/uwsgi.t @@ -23,9 +23,9 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http uwsgi/)->has_daemon('uwsgi')->plan(3); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/xslt.t b/tests/nginx-tests/dso-nginx-tests/xslt.t index 34e36fed8c..9b399fd74e 100644 --- a/tests/nginx-tests/dso-nginx-tests/xslt.t +++ b/tests/nginx-tests/dso-nginx-tests/xslt.t @@ -23,10 +23,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http xslt/)->plan(5); -$t->set_dso("ngx_http_xslt_filter_module", "lib_ngx_http_xslt_filter_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_xslt_filter_module", "ngx_http_xslt_filter_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/nginx-tests/dso-nginx-tests/xslt_params.t b/tests/nginx-tests/dso-nginx-tests/xslt_params.t index a3cb4d19c5..928d38cec8 100644 --- a/tests/nginx-tests/dso-nginx-tests/xslt_params.t +++ b/tests/nginx-tests/dso-nginx-tests/xslt_params.t @@ -23,10 +23,10 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http xslt/); -$t->set_dso("ngx_http_xslt_module", "lib_ngx_http_xslt_module.so"); -$t->set_dso("ngx_http_fastcgi_module", "lib_ngx_http_fastcgi_module.so"); -$t->set_dso("ngx_http_uwsgi_module", "lib_ngx_http_uwsgi_module.so"); -$t->set_dso("ngx_http_scgi_module", "lib_ngx_http_scgi_module.so"); +$t->set_dso("ngx_http_xslt_module", "ngx_http_xslt_module.so"); +$t->set_dso("ngx_http_fastcgi_module", "ngx_http_fastcgi_module.so"); +$t->set_dso("ngx_http_uwsgi_module", "ngx_http_uwsgi_module.so"); +$t->set_dso("ngx_http_scgi_module", "ngx_http_scgi_module.so"); $t->write_file_expand('nginx.conf', <<'EOF'); diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm index 6b2f92b973..931a751b08 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm @@ -330,7 +330,7 @@ sub include_dso_modules ($) { } } - my $dso_module_lib = $modules_dir . "/lib_" . $name . ".so"; + my $dso_module_lib = $modules_dir . $name . ".so"; if (-f "$dso_module_lib") { push @DSO_modules, [$name, $dso_module_lib]; From 12fc82b6fc85c4d5e9e149fa0051b67947d649cc Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 31 Jul 2012 11:53:46 +0800 Subject: [PATCH 11/36] 1 modify the name of dso module chinese doc. 2 modify the directives of dso. 3 fix some bug. --- auto/modules | 8 +- auto/options | 24 +- docs/modules/ngx_dso_module.md | 93 ++-- docs/modules/ngx_dso_module_cn.md | 56 ++- docs/modules/ngx_dso_module_zh.md | 118 ----- src/core/ngx_dso_module.c | 464 +++++++++++------- .../nginx-tests/nginx-tests/lib/Test/Nginx.pm | 4 +- .../test-nginx/lib/Test/Nginx/Util.pm | 12 +- 8 files changed, 406 insertions(+), 373 deletions(-) delete mode 100644 docs/modules/ngx_dso_module_zh.md diff --git a/auto/modules b/auto/modules index 81f4e35d1e..725be4afdf 100644 --- a/auto/modules +++ b/auto/modules @@ -779,13 +779,9 @@ if [ $NGX_DSO = YES ] ; then END - - echo 'dso_order {' > $NGX_MODULE_ORDER - - for mod in $NGX_ALL_MODULES +for mod in $NGX_ALL_MODULES do - echo " $mod;" >> $NGX_MODULE_ORDER + echo "$mod;" >> $NGX_MODULE_ORDER done - echo '}' >> $NGX_MODULE_ORDER fi diff --git a/auto/options b/auto/options index 10d1e63cca..8a77403619 100644 --- a/auto/options +++ b/auto/options @@ -58,8 +58,12 @@ NGX_ALL_MODULES=" ngx_conf_module ngx_events_module ngx_event_core_module + ngx_rtsig_module ngx_epoll_module + ngx_select_module + ngx_poll_module ngx_openssl_module + ngx_regex_module ngx_http_module ngx_http_core_module ngx_http_log_module @@ -70,7 +74,6 @@ NGX_ALL_MODULES=" ngx_http_autoindex_module ngx_http_index_module ngx_http_random_index_module - ngx_http_concat_module ngx_http_auth_basic_module ngx_http_access_module ngx_http_limit_conn_module @@ -87,17 +90,17 @@ NGX_ALL_MODULES=" ngx_http_fastcgi_module ngx_http_uwsgi_module ngx_http_scgi_module + ngx_http_perl_module ngx_http_memcached_module ngx_http_empty_gif_module ngx_http_browser_module - ngx_http_user_agent_module ngx_http_secure_link_module ngx_http_degradation_module - ngx_http_sysguard_module ngx_http_flv_module - ngx_http_slice_module ngx_http_mp4_module ngx_http_upstream_ip_hash_module + ngx_http_upstream_least_conn_module + ngx_http_upstream_keepalive_module ngx_http_stub_status_module ngx_http_write_filter_module ngx_http_header_filter_module @@ -112,11 +115,20 @@ NGX_ALL_MODULES=" ngx_http_sub_filter_module ngx_http_addition_filter_module ngx_http_userid_filter_module - ngx_http_footer_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_not_modified_filter_module + ngx_mail_module + ngx_mail_core_module + ngx_mail_ssl_module + ngx_mail_pop3_module + ngx_mail_imap_module + ngx_mail_smtp_module + ngx_mail_auth_http_module + ngx_mail_proxy_module + ngx_google_perftools_module" + # dso shared NGX_SHARED_MODULES= NGX_SHARED_SRCS= diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index caa28c8121..1412bb7c3a 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -12,39 +12,77 @@ Description * DSO loaded module will limit to 128. +* DSO just support HTTP module; + * This module are tested successfully in Linux/FreeeBSD/MacOS. Exampe =========== - dso_path /home/nginx-dso/module/; + worker_processes 1; + + dso { + path /home/nginx-dso/module/; + load ngx_http_lua_module ngx_http_lua_module.so; + load ngx_http_access_module ngx_http_access_module.so; + load ngx_http_flv_module ngx_http_flv_module.so; + load ngx_http_memcached_module ngx_http_memcached_module.so; + load ngx_http_sub_filter_module ngx_http_sub_filter_module.so; + load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; + load ngx_http_footer_filter_module ngx_http_footer_filter_module.so; + } - dso_load ngx_http_hat_filter_module ngx_http_hat_filter_module.so; - dso_load ngx_http_lua_module ngx_http_lua_module.so; - dso_load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; - dso_load ngx_http_concat_module ngx_http_concat_module.so; - dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; - dso_load ngx_http_image_filter_module ngx_http_image_filter_module.so; + events { + worker_connections 1024; + } Directives ========== -dso_order +load +------------------------ + +**Syntax**: *load module_name module_path* + +**Default**: *none* + +**Context**: *dso* + +The load directive links in the object file or library filename and adds the module structure named module to the list of active modules,module\_name is the name of the DSO module, module\_path is the path of the DSO module. + +There are three possibility with the module_path. It will search the module in below order. + +1 absolute path. +2 relative to path that path directive. +3 relative to default path(NGX\_PREFIX/modules or path which is specified with --dso-path when configure). + + +Example: + + load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + +load empty_gif module from lib\_ngx\_http\_empty\_gif\_module.so. + + +order ------------- -**Syntax**: *dso_order {.....}* +**Syntax**: *order file* **Default**: *none* -**Context**: *main* +**Context**: *dso* This directive can insert your module to nginx' module order list(please see conf/module_order). Be careful, it will change the module runtime order. This directive does not need to be set in most cases. Example: - dso_order { + order module_order; + +in module_order file: + ngx_core_module; ngx_errlog_module; ngx_conf_module; @@ -57,52 +95,27 @@ Example: ....................... ngx_http_addition_filter_module; ngx_http_my_filter_module; - } this will insert my\_filter before addition\_filter module. -dso_path +path ------------------------ -**Syntax**: *dso_path path* +**Syntax**: *path path* **Default**: *none* -**Context**: *main* +**Context**: *dso* The dso_path set default path for DSO module Example: - dso_path /home/dso/module/; + path /home/dso/module/; Set default path to /home/dso/module/. -dso_load ------------------------- - -**Syntax**: *dso_load module_name module_path* - -**Default**: *none* - -**Context**: *main* - -The dso_load directive links in the object file or library filename and adds the module structure named module to the list of active modules,module\_name is the name of the DSO module, module\_path is the path of the DSO module. - -There are three possibility with the module_path. It will search the module in below order. - -1 absolute path. -2 relative to path that dso_path directive. -3 relative to default path(NGX\_PREFIX/modules or path which is specified with --dso-path when configure). - - -Example: - - dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; - -load empty_gif module from lib\_ngx\_http\_empty\_gif\_module.so. - Tools =========== diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md index 36e0b83e06..0d29d2c76c 100644 --- a/docs/modules/ngx_dso_module_cn.md +++ b/docs/modules/ngx_dso_module_cn.md @@ -14,7 +14,9 @@ * 动态加载模块的个数限制为128个. -* 如果已经加载的动态模块有修改,那么必须重起Tengine. +* 如果已经加载的动态模块有修改,那么必须重起Tengine才会生效. + +* 只支持HTTP模块. * 模块 在Linux/FreeeBSD/MacOS下测试成功. @@ -23,15 +25,17 @@ =========== worker_processes 1; - - dso_path /home/nginx-dso/module/; - - dso_load ngx_http_hat_filter_module ngx_http_hat_filter_module.so; - dso_load ngx_http_lua_module ngx_http_lua_module.so; - dso_load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; - dso_load ngx_http_concat_module ngx_http_concat_module.so; - dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; - dso_load ngx_http_image_filter_module ngx_http_image_filter_module.so; + + dso { + path /home/nginx-dso/module/; + load ngx_http_lua_module ngx_http_lua_module.so; + load ngx_http_access_module ngx_http_access_module.so; + load ngx_http_flv_module ngx_http_flv_module.so; + load ngx_http_memcached_module ngx_http_memcached_module.so; + load ngx_http_sub_filter_module ngx_http_sub_filter_module.so; + load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; + load ngx_http_footer_filter_module ngx_http_footer_filter_module.so; + } events { worker_connections 1024; @@ -41,16 +45,16 @@ 指令 ========== -dso_load +load ------------------------ -**Syntax**: *dso_load module_name module_path* +**Syntax**: *load module_name module_path* **Default**: *none* -**Context**: *main* +**Context**: *dso* -dso_load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。 +load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。 对于module\_path的路径查找,这里是严格按照下面的顺序的 @@ -60,26 +64,29 @@ dso_load命令用于在指定的路径(module\_path),将指定的模块(module\_ 例子: - dso_load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; 将会从lib\_ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。 -dso_order +order ------------- -**Syntax**: *dso_order {.....}* +**Syntax**: *order file* **Default**: *none* -**Context**: *main* +**Context**: *dso* 这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个模块要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 例子: - dso_order { + order module_order; + + 在 module_order这个文件中: + ngx_core_module; ngx_errlog_module; ngx_conf_module; @@ -92,25 +99,24 @@ dso_order ....................... ngx_http_addition_filter_module; ngx_http_my_filter_module; - } 上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 -dso_path +path ------------------------ -**Syntax**: *dso_path path* +**Syntax**: *path path* **Default**: *none* -**Context**: *main* +**Context**: *dso* -dso_path 主要是设置默认的动态模块加载路径。 +path 主要是设置默认的动态模块加载路径。 例子: - dso_path /home/dso/module/; + path /home/dso/module/; 设置默认的动态模块加载路径为/home/dso/module/. diff --git a/docs/modules/ngx_dso_module_zh.md b/docs/modules/ngx_dso_module_zh.md deleted file mode 100644 index 5f413a700b..0000000000 --- a/docs/modules/ngx_dso_module_zh.md +++ /dev/null @@ -1,118 +0,0 @@ -模块名 -==== - -* 动态加载模块 - -描述 -=========== - -* 这个模块主要是用来运行时动态加载模块,而不用每次都要重新编译Tengine。 - -* 如果你想要编译官方模块为动态模块,你需要在configure的时候加上类似这样的指令(--with-http\_xxx_module),./configure --help可以看到更多的细节。 - -* 动态加载模块的个数限制为128个。 - -* 模块 在Linux/FreeeBSD/MacOS下测试成功。 - - -例子 -=========== - - dso_path /home/nginx-dso/module/; - - dso_load ngx_http_hat_filter_module lib_ngx_http_hat_filter_module.so; - dso_load ngx_http_lua_module lib_ngx_http_lua_module.so; - dso_load ngx_http_addition_filter_module lib_ngx_http_addition_filter_module.so; - dso_load ngx_http_concat_module lib_ngx_http_concat_module.so; - dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; - dso_load ngx_http_image_filter_module lib_ngx_http_image_filter_module.so; - -指令 -========== - -dso_order -------------- - -**Syntax**: *dso_order {.....}* - -**Default**: *none* - -**Context**: *main* - - -这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个模块要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 - -例子: - - dso_order { - ngx_core_module; - ngx_errlog_module; - ngx_conf_module; - ngx_events_module; - ngx_event_core_module; - ngx_epoll_module; - ngx_openssl_module; - ngx_http_module; - ngx_http_core_module; - ....................... - ngx_http_addition_filter_module; - ngx_http_my_filter_module; - } - -上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 - - -dso_path ------------------------- - -**Syntax**: *dso_path path* - -**Default**: *none* - -**Context**: *main* - -dso_path 主要是设置默认的动态模块加载路径。 - -例子: - - dso_path /home/dso/module/; - -设置默认的动态模块加载路径为/home/dso/module/. - -dso_load ------------------------- - -**Syntax**: *dso_load module_name module_path* - -**Default**: *none* - -**Context**: *main* - -dso_load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。 - -对于module\_path的路径查找,这里是严格按照下面的顺序的 - -1 module\_path指定的是绝对路径。 -2 相对于dso\_path设置的相对路径. -3 相对于默认的加载路径的相对路径(NGX\_PREFIX/modules或者说configure时通过--dso-path设置的路径). - -例子: - - dso_load ngx_http_empty_gif_module lib_ngx_http_empty_gif_module.so; - -将会从lib\_ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。 - - -工具 -=========== - -dso_tools ------------------------- - -这个工具主要是用来编译第三方模块为动态模块. - -例子: - - ./dso_tools --add-module=/home/dso/lua-nginx-module - -将会编译ngx\_lua模块为动态库,然后安装到默认的模块路径. diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index b7744dea4f..7a149c3561 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -10,9 +10,6 @@ #include -#define NGX_DSO_MODULE_PREFIX "ngx_" - - typedef struct { ngx_str_t type; ngx_str_t entry; @@ -30,44 +27,28 @@ typedef struct { typedef struct { ngx_str_t path; ngx_int_t flag_postion; + ngx_array_t *order; ngx_array_t *modules; -} ngx_dso_conf_t; +} ngx_dso_conf_ctx_t; -static void *ngx_dso_create_conf(ngx_cycle_t *cycle); -static char *ngx_dso_init_conf(ngx_cycle_t *cycle, void *conf); - -static char *ngx_dso_load(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_dso_load(ngx_conf_t *cf); static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, ngx_str_t *name, ngx_str_t *path); static char *ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_dso_order_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_dso_get_position(ngx_str_t *module_entry); -static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_t *dcf, ngx_str_t module_name); +static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name); static ngx_command_t ngx_dso_module_commands[] = { - { ngx_string("dso_order"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_dso_order_block, - 0, - 0, - NULL }, - - { ngx_string("dso_path"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - 0, - offsetof(ngx_dso_conf_t, path), - NULL }, - - { ngx_string("dso_load"), - NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE2, - ngx_dso_load, + { ngx_string("dso"), + NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_dso_block, 0, 0, NULL }, @@ -78,8 +59,8 @@ static ngx_command_t ngx_dso_module_commands[] = { static ngx_core_module_t ngx_dso_module_ctx = { ngx_string("dso"), - ngx_dso_create_conf, - ngx_dso_init_conf + NULL, + NULL, }; @@ -99,7 +80,8 @@ ngx_module_t ngx_dso_module = { }; -extern ngx_uint_t ngx_max_module; +static ngx_module_t *ngx_old_modules[NGX_DSO_MAX]; +static ngx_module_t *ngx_static_modules[NGX_DSO_MAX]; static ngx_str_t ngx_default_modules_prefix = ngx_string(NGX_DSO_PATH); @@ -133,37 +115,46 @@ ngx_dso_get_position(ngx_str_t *entry) } -static ngx_int_t -ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, - ngx_str_t *name, ngx_str_t *path) +static void +ngx_dso_cleanup(void *data) { - size_t len; - ngx_uint_t i, j; - ngx_dso_module_t *m; - ngx_dso_conf_t *old_dcf; + ngx_cycle_t *cycle = data; + + ngx_uint_t i; ngx_dso_module_t *old_dl_m; + ngx_dso_conf_ctx_t *old_ctx; - if (cycle->old_cycle->conf_ctx != NULL) { - old_dcf = (ngx_dso_conf_t *) ngx_get_conf(cycle->old_cycle->conf_ctx, - ngx_dso_module); - if (old_dcf != NULL) { - old_dl_m = old_dcf->modules->elts; + if (cycle != ngx_cycle) { - for (i = 0; i < old_dcf->modules->nelts; i++) { - if (old_dl_m[i].name.len == 0) { - continue; - } + if (cycle->old_cycle->conf_ctx) { + old_ctx = (ngx_dso_conf_ctx_t *) cycle->old_cycle->conf_ctx[ngx_dso_module.index]; - if ((name->len == old_dl_m[i].name.len - && ngx_strncmp(name->data, old_dl_m[i].name.data, old_dl_m[i].name.len) == 0) - || (path->len == old_dl_m[i].path.len - && ngx_strncmp(path->data, old_dl_m[i].path.data, old_dl_m[i].path.len) == 0)) - { - return NGX_DECLINED; + if (old_ctx != NULL) { + old_dl_m = old_ctx->modules->elts; + + for (i = 0; i < old_ctx->modules->nelts; i++) { + if (old_dl_m[i].name.len == 0) { + continue; + } + + dlclose(old_dl_m[i].dl_handle); } } } + + ngx_memzero(ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + ngx_memcpy(ngx_modules, ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); } +} + + +static ngx_int_t +ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, + ngx_str_t *name, ngx_str_t *path) +{ + size_t len; + ngx_uint_t j; + ngx_dso_module_t *m; for (j = 0; ngx_module_names[j]; j++) { len = ngx_strlen(ngx_module_names[j]); @@ -196,7 +187,7 @@ ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, static ngx_int_t -ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_t *dcf, ngx_str_t *name) +ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) { size_t len, size; u_char *p, *n, *prefix; @@ -205,7 +196,7 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_t *dcf, ngx_str_t *name) return NGX_OK; } - if (dcf->path.data == NULL) { + if (ctx->path.data == NULL) { if (ngx_default_modules_prefix.data[0] != '/') { prefix = cycle->prefix.data; len = cycle->prefix.len; @@ -216,12 +207,14 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_t *dcf, ngx_str_t *name) size = len + name->len + 1; } } else { - if (dcf->path.data[0] != '/') { + if (ctx->path.data[0] != '/') { + ngx_log_stderr(0, "the path(%V) of dso module should be absolute path", + &ctx->path); return NGX_ERROR; } - len = dcf->path.len; - prefix = dcf->path.data; + len = ctx->path.len; + prefix = ctx->path.data; size = len + name->len + 1; } @@ -232,8 +225,9 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_t *dcf, ngx_str_t *name) p = ngx_cpymem(n, prefix, len); - if (dcf->path.data == NULL - && ngx_default_modules_prefix.data[0] != '/') { + if (ctx->path.data == NULL + && ngx_default_modules_prefix.data[0] != '/') + { p = ngx_cpymem(p, ngx_default_modules_prefix.data, ngx_default_modules_prefix.len); } @@ -303,160 +297,313 @@ ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) } + static char * -ngx_dso_order_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - char *rv; - ngx_conf_t save; - ngx_dso_conf_t *dcf; + ngx_int_t rc; + ngx_str_t *value; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; - dcf = conf; + ctx = cf->ctx; + value = cf->args->elts; - if (dcf->order != NULL) { - return "is duplicate"; + if (ctx->modules->nelts >= NGX_DSO_MAX) { + ngx_log_stderr(0, "Module \"%V\" could not be loaded, " + "because the dso module limit(%ui) was reached.", + &value[1], NGX_DSO_MAX); + return NGX_CONF_ERROR; } - if (dcf->modules->nelts > 0) { - return "order block must appear to before load derective"; + rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, + &value[1], &value[2]); + if (rc == NGX_DECLINED) + { + return NGX_CONF_OK; } - dcf->order = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); - if (dcf->order == NULL) { + dl_m = ngx_array_push(ctx->modules); + if (dl_m == NULL) { return NGX_CONF_ERROR; } - save = *cf; - cf->module_type = NGX_CORE_MODULE; + dl_m->name = value[1]; + dl_m->path = value[2]; - cf->handler = ngx_dso_order; - cf->handler_conf = (void *) dcf; + return NGX_CONF_OK; +} - rv = ngx_conf_parse(cf, NULL); - *cf = save; +static char * +ngx_dso_load(ngx_conf_t *cf) +{ + char *rv; + ngx_int_t postion; + ngx_uint_t i; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; - return rv; + ctx = cf->ctx; + dl_m = ctx->modules->elts; + + for (i = 0; i < ctx->modules->nelts; i++) { + if (ngx_dso_full_name(cf->cycle, ctx, &dl_m[i].path) != NGX_OK) { + return NGX_CONF_ERROR; + } + + if (ngx_dso_open(&dl_m[i]) == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + if (dl_m[i].module->type == NGX_CORE_MODULE) { + ngx_log_stderr(0,"dso module not support core module"); + return NGX_CONF_ERROR; + } + + if (dl_m[i].module->major_version != NGX_NUMBER_MAJOR + || dl_m[i].module->minor_version > NGX_NUMBER_MINOR) + { + ngx_log_stderr(0,"Module \"%V\" is not compatible with this " + "version of Tengine (found %d.%d, need %d.%d). Please " + "contact the vendor for the correct version.", + &dl_m[i].name, dl_m[i].module->major_version, + dl_m[i].module->minor_version, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR); + return NGX_CONF_ERROR; + } + + postion = ngx_dso_find_postion(ctx, dl_m[i].name); + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "dso find postion(%i)", postion); + + /* ngx_log_stderr(0, "dso find postion(%i)", postion); */ + rv = ngx_dso_insert_module(dl_m[i].module, postion); + if (rv == NGX_CONF_ERROR) { + ngx_log_stderr(0, "dso find error postion(%i)", postion); + return rv; + } + } + + return NGX_CONF_OK; } static char * -ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, + ngx_str_t *name) { - ngx_dso_conf_t *dcf = conf; - - ngx_str_t *value, *module_name; + char *rv; + ngx_str_t file; + ngx_conf_t pcf; - value = cf->args->elts; + file.len = name->len; + file.data = ngx_pnalloc(cf->temp_pool, name->len + 1); - if (cf->args->nelts != 1 - || ngx_strncasecmp(value[0].data, (u_char *) NGX_DSO_MODULE_PREFIX, - sizeof(NGX_DSO_MODULE_PREFIX) - 1) != 0) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown directive \"%s\"", value[0].data); + if (file.data == NULL) { return NGX_CONF_ERROR; } - module_name = ngx_array_push(dcf->order); - if (module_name == NULL) { + ngx_sprintf(file.data, "%V", name); + + if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { return NGX_CONF_ERROR; } - *module_name = value[0]; + pcf = *cf; + cf->ctx = ctx; + cf->module_type = NGX_CORE_MODULE; + cf->handler = ngx_dso_order; - return NGX_CONF_OK; + rv = ngx_conf_parse(cf, &file); + + *cf = pcf; + + return rv; } static char * -ngx_dso_load(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - ngx_dso_conf_t *dcf = conf; - - char *rv; - ngx_int_t postion; - ngx_str_t *value, module_path, module_name; - ngx_dso_module_t *dl_m; + ngx_str_t *value; + ngx_dso_conf_ctx_t *ctx; value = cf->args->elts; + ctx = cf->ctx; - if (dcf->modules->nelts >= NGX_DSO_MAX) { - ngx_log_stderr(0, "Module \"%V\" could not be loaded, " - "because the dso module limit(%ui) was reached.", - &value[1], NGX_DSO_MAX); - return NGX_CONF_ERROR; + if (ngx_strcmp(value[0].data, "load") == 0) { + + if (cf->args->nelts != 3) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid number of arguments in \"load\" directive"); + return NGX_CONF_ERROR; + } + + return ngx_dso_save(cf, dummy, conf); } - module_name = value[1]; - module_path = value[2]; + if (ngx_strcmp(value[0].data, "path") == 0) { + if (cf->args->nelts != 2) { - if (ngx_dso_check_duplicated(cf->cycle, dcf->modules, - &module_name, &module_path) == NGX_DECLINED) - { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid number of arguments in \"path\" directive"); + return NGX_CONF_ERROR; + } + + if (ctx->path.data != NULL) { + return "is duplicate"; + } + + ctx->path = value[1]; return NGX_CONF_OK; } - ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "load module(%V)", module_path); + if (ngx_strcmp(value[0].data, "order") == 0) { + + if (cf->args->nelts != 2) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid number of arguments in \"sequence\" directive"); + return NGX_CONF_ERROR; + } + + if (ctx->order->nelts != 0) { + return "is duplicate"; + } + + return ngx_dso_template(cf, ctx, &value[1]); + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown directive \"%s\"", value[0].data); + return NGX_CONF_ERROR; +} + + +static char * +ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *rv; + ngx_conf_t pcf; + ngx_dso_conf_ctx_t *ctx; + ngx_pool_cleanup_t *cln; + + ctx = ((void **) cf->ctx)[ngx_dso_module.index]; + if (ctx != NULL) { + return "is duplicate"; + } - dl_m = ngx_array_push(dcf->modules); + ctx = ngx_pcalloc(cf->pool, sizeof(ngx_dso_conf_ctx_t)); - if (ngx_dso_full_name(cf->cycle, dcf, &module_path) != NGX_OK) { + if (ctx == NULL) { return NGX_CONF_ERROR; } - dl_m->name = module_name; - dl_m->path = module_path; + *(ngx_dso_conf_ctx_t **) conf = ctx; - if (ngx_dso_open(dl_m) == NGX_ERROR) { + ctx->modules = ngx_array_create(cf->pool, 10, sizeof(ngx_dso_module_t)); + if (ctx->modules == NULL) { return NGX_CONF_ERROR; } - if (dl_m->module->type == NGX_CORE_MODULE) { - ngx_log_stderr(0,"dso module not support core module"); + ctx->flag_postion = ngx_dso_get_position(&module_flagpole[0].entry); + if (ctx->flag_postion == NGX_ERROR) { return NGX_CONF_ERROR; } - if (dl_m->module->major_version != NGX_NUMBER_MAJOR - || dl_m->module->minor_version > NGX_NUMBER_MINOR) - { - ngx_log_stderr(0,"Module \"%V\" is not compatible with this " - "version of Tengine (found %d.%d, need %d.%d). Please " - "contact the vendor for the correct version.", - &module_name, dl_m->module->major_version, - dl_m->module->minor_version, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR); + ctx->order = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); + if (ctx->order == NULL) { return NGX_CONF_ERROR; } - postion = ngx_dso_find_postion(dcf, module_name); + if (ngx_is_init_cycle(cf->cycle->old_cycle)) { + ngx_memzero(ngx_static_modules, sizeof(ngx_module_t *) * ngx_max_module); + ngx_memcpy(ngx_static_modules, ngx_modules, sizeof(ngx_module_t *) * ngx_max_module); + } else { + ngx_memzero(ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + ngx_memcpy(ngx_old_modules, ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + ngx_memcpy(ngx_modules, ngx_static_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + } - ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "dso find postion(%i)", postion); + pcf = *cf; + cf->ctx = ctx; + cf->module_type = NGX_CORE_MODULE; + cf->handler = ngx_dso_parse; + cf->handler_conf = conf; + + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + *cf = pcf; + return NGX_CONF_ERROR; + } + + cln->handler = ngx_dso_cleanup; + cln->data = cf->cycle; + + rv = ngx_conf_parse(cf, NULL); + if (rv != NGX_CONF_OK) { + *cf = pcf; + return rv; + } + + rv = ngx_dso_load(cf); - rv = ngx_dso_insert_module(dl_m->module, postion); if (rv == NGX_CONF_ERROR) { return rv; } + *cf = pcf; + + return NGX_CONF_OK; +} + + +static char * +ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_str_t *value, *module_name; + ngx_dso_conf_ctx_t *ctx; + + value = cf->args->elts; + ctx = cf->ctx; + + if (cf->args->nelts != 1) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown directive \"%s\"", value[0].data); + return NGX_CONF_ERROR; + } + + module_name = ngx_array_push(ctx->order); + if (module_name == NULL) { + return NGX_CONF_ERROR; + } + + *module_name = value[0]; + return NGX_CONF_OK; } static ngx_int_t -ngx_dso_find_postion(ngx_dso_conf_t *dcf, ngx_str_t module_name) +ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) { size_t len1, len2, len3; ngx_int_t near; ngx_uint_t i, k; ngx_str_t *name; - near = dcf->flag_postion; + near = ctx->flag_postion; - if (dcf->order == NULL || dcf->order->nelts == 0) { + if (ctx->order == NULL || ctx->order->nelts == 0) { for (i = 0; ngx_all_module_names[i]; i++) { len1 = ngx_strlen(ngx_all_module_names[i]); if (len1 == module_name.len && ngx_strncmp(ngx_all_module_names[i], module_name.data, len1) == 0) { + if (near < ctx->flag_postion) { + ++ctx->flag_postion; + } + return near; } @@ -478,17 +625,21 @@ ngx_dso_find_postion(ngx_dso_conf_t *dcf, ngx_str_t module_name) } if (ngx_all_module_names[i] == NULL) { - return ++dcf->flag_postion; + return ++ctx->flag_postion; } } - name = dcf->order->elts; - near = dcf->flag_postion; + name = ctx->order->elts; + near = ctx->flag_postion; - for (i = 0; i < dcf->order->nelts; i++) { + for (i = 0; i < ctx->order->nelts; i++) { if (name[i].len == module_name.len && ngx_strncmp(name[i].data, module_name.data, name[i].len) == 0) { + if (near < ctx->flag_postion) { + ++ctx->flag_postion; + } + return near; } @@ -508,7 +659,7 @@ ngx_dso_find_postion(ngx_dso_conf_t *dcf, ngx_str_t module_name) } } - return ++dcf->flag_postion; + return ++ctx->flag_postion; } @@ -518,19 +669,19 @@ ngx_show_dso_modules(ngx_conf_t *cf) ngx_str_t module_name; ngx_uint_t i; ngx_module_t *module; - ngx_dso_conf_t *dcf; ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; - dcf = (ngx_dso_conf_t *) ngx_get_conf(cf->cycle->conf_ctx, + ctx = (ngx_dso_conf_ctx_t *) ngx_get_conf(cf->cycle->conf_ctx, ngx_dso_module); - if (dcf == NULL) { + if (ctx == NULL) { return; } - dl_m = dcf->modules->elts; + dl_m = ctx->modules->elts; - for (i = 0; i < dcf->modules->nelts; i++) { + for (i = 0; i < ctx->modules->nelts; i++) { if (dl_m[i].name.len == 0) { continue; } @@ -542,34 +693,3 @@ ngx_show_dso_modules(ngx_conf_t *cf) &module_name, module->major_version, module->minor_version); } } - - -static char * -ngx_dso_init_conf(ngx_cycle_t *cycle, void *conf) -{ - return NGX_CONF_OK; -} - - -static void * -ngx_dso_create_conf(ngx_cycle_t *cycle) -{ - ngx_dso_conf_t *conf; - - conf = ngx_pcalloc(cycle->pool, sizeof(ngx_dso_conf_t)); - if (conf == NULL) { - return NGX_CONF_ERROR; - } - - conf->flag_postion = ngx_dso_get_position(&module_flagpole[0].entry); - if (conf->flag_postion == NGX_ERROR) { - return NGX_CONF_ERROR; - } - - conf->modules = ngx_array_create(cycle->pool, 10, sizeof(ngx_dso_module_t)); - if (conf->modules == NULL) { - return NGX_CONF_ERROR; - } - - return conf; -} diff --git a/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm b/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm index 0b341f7cd7..efeeb50009 100644 --- a/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm +++ b/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm @@ -299,9 +299,11 @@ sub test_globals_dso() { my $s = ''; + $s .= "dso {\n"; while ( my ($key, $value) = each(%{$self->{_dso_module}}) ) { - $s .= "dso_load $key $value;\n"; + $s .= "load $key $value;\n"; } + $s .= "}\n"; $self->{_test_globals_dso} = $s; } diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm index 931a751b08..6dd503084b 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm @@ -341,17 +341,19 @@ sub include_dso_modules ($) { } sub write_dso_config () { - my $content = < Date: Mon, 6 Aug 2012 15:44:19 +0800 Subject: [PATCH 12/36] fixed test-nginx with new dso module --- tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm index 6dd503084b..b14ef106a2 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm @@ -330,7 +330,7 @@ sub include_dso_modules ($) { } } - my $dso_module_lib = $modules_dir . $name . ".so"; + my $dso_module_lib = $modules_dir . "/" . $name . ".so"; if (-f "$dso_module_lib") { push @DSO_modules, [$name, $dso_module_lib]; @@ -341,17 +341,13 @@ sub include_dso_modules ($) { } sub write_dso_config () { -# my $content = < Date: Tue, 7 Aug 2012 12:24:54 +0800 Subject: [PATCH 13/36] to make right for compute of the flag_postion. --- src/core/ngx_dso_module.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 7a149c3561..7b5ac19e18 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -595,22 +595,18 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) if (ctx->order == NULL || ctx->order->nelts == 0) { - for (i = 0; ngx_all_module_names[i]; i++) { + for (i = 1; ngx_all_module_names[i]; i++) { len1 = ngx_strlen(ngx_all_module_names[i]); if (len1 == module_name.len && ngx_strncmp(ngx_all_module_names[i], module_name.data, len1) == 0) { - if (near < ctx->flag_postion) { + if (near <= ctx->flag_postion) { ++ctx->flag_postion; } return near; } - if (i == 0) { - continue; - } - len2 = ngx_strlen(ngx_all_module_names[i - 1]); for (k = 0; ngx_module_names[k]; k++) { len3 = ngx_strlen(ngx_module_names[k]); @@ -632,21 +628,17 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) name = ctx->order->elts; near = ctx->flag_postion; - for (i = 0; i < ctx->order->nelts; i++) { + for (i = 1; i < ctx->order->nelts; i++) { if (name[i].len == module_name.len && ngx_strncmp(name[i].data, module_name.data, name[i].len) == 0) { - if (near < ctx->flag_postion) { + if (near <= ctx->flag_postion) { ++ctx->flag_postion; } return near; } - if (i == 0) { - continue; - } - for (k = 0; ngx_module_names[k]; k++) { len1 = ngx_strlen(ngx_module_names[k]); From 78ad1d8964e5b571815e4ee0b96db0baef6a0f20 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Thu, 9 Aug 2012 15:57:06 +0800 Subject: [PATCH 14/36] 1 fix some code style 2 fix bug of dso cleanup --- src/core/ngx_dso_module.c | 51 ++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 7b5ac19e18..47dd13742c 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -41,7 +41,8 @@ static char *ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_dso_get_position(ngx_str_t *module_entry); -static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name); +static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, + ngx_str_t module_name); static ngx_command_t ngx_dso_module_commands[] = { @@ -88,7 +89,7 @@ static ngx_str_t ngx_default_modules_prefix = ngx_string(NGX_DSO_PATH); static ngx_dso_flagpole_t module_flagpole[] = { { ngx_string("filter"), ngx_string("ngx_http_copy_filter_module")}, - {ngx_null_string, ngx_null_string} + { ngx_null_string, ngx_null_string} }; @@ -121,29 +122,31 @@ ngx_dso_cleanup(void *data) ngx_cycle_t *cycle = data; ngx_uint_t i; - ngx_dso_module_t *old_dl_m; - ngx_dso_conf_ctx_t *old_ctx; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; if (cycle != ngx_cycle) { - if (cycle->old_cycle->conf_ctx) { - old_ctx = (ngx_dso_conf_ctx_t *) cycle->old_cycle->conf_ctx[ngx_dso_module.index]; + if (cycle->conf_ctx) { + ctx = (ngx_dso_conf_ctx_t *) + cycle->conf_ctx[ngx_dso_module.index]; - if (old_ctx != NULL) { - old_dl_m = old_ctx->modules->elts; + if (ctx != NULL) { + dl_m = ctx->modules->elts; - for (i = 0; i < old_ctx->modules->nelts; i++) { - if (old_dl_m[i].name.len == 0) { + for (i = 0; i < ctx->modules->nelts; i++) { + if (dl_m[i].name.len == 0) { continue; } - dlclose(old_dl_m[i].dl_handle); + dlclose(dl_m[i].dl_handle); } } } ngx_memzero(ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); - ngx_memcpy(ngx_modules, ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + ngx_memcpy(ngx_modules, ngx_old_modules, + sizeof(ngx_module_t *) * NGX_DSO_MAX); } } @@ -318,8 +321,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, &value[1], &value[2]); - if (rc == NGX_DECLINED) - { + if (rc == NGX_DECLINED) { return NGX_CONF_OK; } @@ -365,10 +367,11 @@ ngx_dso_load(ngx_conf_t *cf) || dl_m[i].module->minor_version > NGX_NUMBER_MINOR) { ngx_log_stderr(0,"Module \"%V\" is not compatible with this " - "version of Tengine (found %d.%d, need %d.%d). Please " - "contact the vendor for the correct version.", + "version of Tengine (found %d.%d, need %d.%d)." + " Please contact the vendor for the correct version.", &dl_m[i].name, dl_m[i].module->major_version, - dl_m[i].module->minor_version, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR); + dl_m[i].module->minor_version, NGX_NUMBER_MAJOR, + NGX_NUMBER_MINOR); return NGX_CONF_ERROR; } @@ -376,7 +379,6 @@ ngx_dso_load(ngx_conf_t *cf) ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "dso find postion(%i)", postion); - /* ngx_log_stderr(0, "dso find postion(%i)", postion); */ rv = ngx_dso_insert_module(dl_m[i].module, postion); if (rv == NGX_CONF_ERROR) { ngx_log_stderr(0, "dso find error postion(%i)", postion); @@ -517,11 +519,15 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (ngx_is_init_cycle(cf->cycle->old_cycle)) { ngx_memzero(ngx_static_modules, sizeof(ngx_module_t *) * ngx_max_module); - ngx_memcpy(ngx_static_modules, ngx_modules, sizeof(ngx_module_t *) * ngx_max_module); + ngx_memcpy(ngx_static_modules, ngx_modules, + sizeof(ngx_module_t *) * ngx_max_module); } else { ngx_memzero(ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); - ngx_memcpy(ngx_old_modules, ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); - ngx_memcpy(ngx_modules, ngx_static_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + + ngx_memcpy(ngx_old_modules, ngx_modules, + sizeof(ngx_module_t *) * NGX_DSO_MAX); + ngx_memcpy(ngx_modules, ngx_static_modules, + sizeof(ngx_module_t *) * NGX_DSO_MAX); } pcf = *cf; @@ -612,7 +618,8 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) len3 = ngx_strlen(ngx_module_names[k]); if (len2 == len3 - && ngx_strncmp(ngx_all_module_names[i - 1], ngx_module_names[k], len2) == 0) + && ngx_strncmp(ngx_all_module_names[i - 1], + ngx_module_names[k], len2) == 0) { near = k + 1; break; From a46cad072b4f91c64e6ce3613a01a6907b6347a7 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 15 Aug 2012 18:39:19 +0800 Subject: [PATCH 15/36] 1 modify help message of configure. 2 modify load directives. --- auto/options | 60 +++++++++++++++++++-------------------- src/core/ngx_dso_module.c | 30 ++++++++++++++++---- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/auto/options b/auto/options index 8a77403619..902cdbd892 100644 --- a/auto/options +++ b/auto/options @@ -615,51 +615,51 @@ cat << END --with-http_stub_status_module enable ngx_http_stub_status_module --with-http_upstream_check_module enable ngx_http_upstream_check_module - --with-http_addition_module=shared enable ngx_http_addition_filter_module(shared) - --with-http_xslt_module=shared enable ngx_http_xslt_filter_module(shared) + --with-http_addition_module=shared enable ngx_http_addition_filter_module (shared) + --with-http_xslt_module=shared enable ngx_http_xslt_filter_module (shared) --with-http_image_filter_module=shared - enable ngx_http_image_filter_module(shared) + enable ngx_http_image_filter_module (shared) --with-http_geoip_module=shared enable ngx_http_geoip_module - --with-http_sub_module=shared enable ngx_http_sub_filter_module(shared) - --with-http_flv_module=shared enable ngx_http_flv_module(shared) - --with-http_slice_module=shared enable ngx_http_slice_module(shared) - --with-http_mp4_module=shared enable ngx_http_mp4_module(shared) - --with-http_concat_module=shared enable ngx_http_concat_module(shared) + --with-http_sub_module=shared enable ngx_http_sub_filter_module (shared) + --with-http_flv_module=shared enable ngx_http_flv_module (shared) + --with-http_slice_module=shared enable ngx_http_slice_module (shared) + --with-http_mp4_module=shared enable ngx_http_mp4_module (shared) + --with-http_concat_module=shared enable ngx_http_concat_module (shared) --with-http_random_index_module=shared - enable ngx_http_random_index_module(shared) + enable ngx_http_random_index_module (shared) --with-http_secure_link_module=shared - enable ngx_http_secure_link_module(shared) - --with-http_sysguard_module=shared enable ngx_http_sysguard_module(shared) + enable ngx_http_secure_link_module (shared) + --with-http_sysguard_module=shared enable ngx_http_sysguard_module (shared) --with-http_charset_filter_module=shared - enable ngx_http_charset_filter_module(shared) + enable ngx_http_charset_filter_module (shared) --with-http_userid_filter_module=shared - enable ngx_http_userid_filter_module(shared) + enable ngx_http_userid_filter_module (shared) --with-http_footer_filter_module=shared - enable ngx_http_footer_filter_module(shared) - --with-http_access_module=shared enable ngx_http_access_module(shared) + enable ngx_http_footer_filter_module (shared) + --with-http_access_module=shared enable ngx_http_access_module (shared) --with-http_autoindex_module=shared - enable ngx_http_autoindex_module(shared) - --with-http_map_module=shared enable ngx_http_map_module(shared) + enable ngx_http_autoindex_module (shared) + --with-http_map_module=shared enable ngx_http_map_module (shared) --with-http_split_clients_module=shared - enable ngx_http_split_clients_module(shared) - --with-http_referer_module=shared enable ngx_http_referer_module(shared) - --with-http_rewrite_module=shared enable ngx_http_rewrite_module(shared) - --with-http_fastcgi_module=shared enable ngx_http_fastcgi_module(shared) - --with-http_uwsgi_module=shared enable ngx_http_uwsgi_module(shared) - --with-http_scgi_module=shared enable ngx_http_scgi_module(shared) + enable ngx_http_split_clients_module (shared) + --with-http_referer_module=shared enable ngx_http_referer_module (shared) + --with-http_rewrite_module=shared enable ngx_http_rewrite_module (shared) + --with-http_fastcgi_module=shared enable ngx_http_fastcgi_module (shared) + --with-http_uwsgi_module=shared enable ngx_http_uwsgi_module (shared) + --with-http_scgi_module=shared enable ngx_http_scgi_module (shared) --with-http_memcached_module=shared - enable ngx_http_memcached_module(shared) + enable ngx_http_memcached_module (shared) --with-http_limit_conn_module=shared - enable ngx_http_limit_conn_module(shared) + enable ngx_http_limit_conn_module (shared) --with-http_limit_req_module=shared - enable ngx_http_limit_req_module(shared) + enable ngx_http_limit_req_module (shared) --with-http_empty_gif_module=shared - enable ngx_http_empty_gif_module(shared) - --with-http_browser_module=shared enable ngx_http_browser_module(shared) + enable ngx_http_empty_gif_module (shared) + --with-http_browser_module=shared enable ngx_http_browser_module (shared) --with-http_user_agent_module=shared - enable ngx_http_user_agent_module(shared) + enable ngx_http_user_agent_module (shared) --with-http_upstream_ip_hash_module=shared - enable ngx_http_upstream_ip_hash_module(shared) + enable ngx_http_upstream_ip_hash_module (shared) --without-http_charset_module disable ngx_http_charset_filter_module --without-http_gzip_module disable ngx_http_gzip_filter_module diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 47dd13742c..ee546fc9e9 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -10,6 +10,9 @@ #include +#define NGX_DSO_EXT ".so" + + typedef struct { ngx_str_t type; ngx_str_t entry; @@ -304,8 +307,9 @@ ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) static char * ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + u_char *p; ngx_int_t rc; - ngx_str_t *value; + ngx_str_t *value, module_path; ngx_dso_module_t *dl_m; ngx_dso_conf_ctx_t *ctx; @@ -319,8 +323,24 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, - &value[1], &value[2]); + if (cf->args->nelts == 3) { + rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, + &value[1], &value[2]); + module_path = value[2]; + } else { + /* cf->args->nelts == 2 */ + module_path.len = value[1].len + sizeof(NGX_DSO_EXT); + module_path.data = ngx_pcalloc(cf->pool, module_path.len); + if (module_path.data == NULL) { + return NGX_CONF_ERROR; + } + + p = ngx_cpymem(module_path.data, value[1].data, value[1].len); + ngx_memcpy(p, NGX_DSO_EXT, sizeof(NGX_DSO_EXT) - 1); + rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, + &value[1], &module_path); + } + if (rc == NGX_DECLINED) { return NGX_CONF_OK; } @@ -331,7 +351,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } dl_m->name = value[1]; - dl_m->path = value[2]; + dl_m->path = module_path; return NGX_CONF_OK; } @@ -435,7 +455,7 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) if (ngx_strcmp(value[0].data, "load") == 0) { - if (cf->args->nelts != 3) { + if (cf->args->nelts != 2 && cf->args->nelts != 3) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of arguments in \"load\" directive"); return NGX_CONF_ERROR; From 871b4597046af007e4ec97d012dddac93fa0c045 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 15 Aug 2012 18:44:58 +0800 Subject: [PATCH 16/36] update doc of dso module. --- docs/modules/ngx_dso_module.md | 10 ++++++---- docs/modules/ngx_dso_module_cn.md | 10 +++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index 1412bb7c3a..e35abbf796 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -24,7 +24,7 @@ Exampe dso { path /home/nginx-dso/module/; - load ngx_http_lua_module ngx_http_lua_module.so; + load ngx_http_lua_module; load ngx_http_access_module ngx_http_access_module.so; load ngx_http_flv_module ngx_http_flv_module.so; load ngx_http_memcached_module ngx_http_memcached_module.so; @@ -43,7 +43,7 @@ Directives load ------------------------ -**Syntax**: *load module_name module_path* +**Syntax**: *load module_name [module_path]* **Default**: *none* @@ -51,6 +51,8 @@ load The load directive links in the object file or library filename and adds the module structure named module to the list of active modules,module\_name is the name of the DSO module, module\_path is the path of the DSO module. +If module_path is miss, default module\_path is $(module_name).so. + There are three possibility with the module_path. It will search the module in below order. 1 absolute path. @@ -61,9 +63,9 @@ There are three possibility with the module_path. It will search the module in b Example: load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + load ngx_http_test_module; -load empty_gif module from lib\_ngx\_http\_empty\_gif\_module.so. - +load ngx_http_empty_gif_module module from ngx\_http\_empty\_gif\_module.so, and load ngx_http_test_module module from ngx\_http\_test\_module.so. order ------------- diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md index 0d29d2c76c..56ab07245c 100644 --- a/docs/modules/ngx_dso_module_cn.md +++ b/docs/modules/ngx_dso_module_cn.md @@ -28,7 +28,7 @@ dso { path /home/nginx-dso/module/; - load ngx_http_lua_module ngx_http_lua_module.so; + load ngx_http_lua_module; load ngx_http_access_module ngx_http_access_module.so; load ngx_http_flv_module ngx_http_flv_module.so; load ngx_http_memcached_module ngx_http_memcached_module.so; @@ -48,13 +48,13 @@ load ------------------------ -**Syntax**: *load module_name module_path* +**Syntax**: *load module_name [module_path]* **Default**: *none* **Context**: *dso* -load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。 +load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。其中module\_path是可选的,如果没有module\_path参数,那么默认path是 $(modulename).so. 对于module\_path的路径查找,这里是严格按照下面的顺序的 @@ -65,9 +65,9 @@ load命令用于在指定的路径(module\_path),将指定的模块(module\_name 例子: load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + load ngx_http_test_module; -将会从lib\_ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。 - +将会从ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。以及从ngx\_http\_test\_module.so加载ngx\_http\_test\_module模块. order ------------- From ff13cc8e5dcf42ff39af7b32629e32c4ef0ea579 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 21 Aug 2012 15:47:16 +0800 Subject: [PATCH 17/36] modify doc of dso module (via shudu). --- docs/modules/ngx_dso_module.md | 65 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index e35abbf796..74272825ca 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -1,36 +1,37 @@ Name ==== -* dso module +* Dynamic Module Loading Support (DSO) Description =========== -* On selected operating systems this module can be used to load modules into Tengine at runtime via the DSO (Dynamic Shared Object) mechanism, rather than requiring a recompilation. +* You can choose which functionalities to include by selecting a set of modules. A module will be compiled as a Dynamic Shared Object (DSO) that exists from the main Tengine binary. So you don't have to recompile Tengine when you want to add or enable a functionality to it. -* If you want to compile official module with DSO, you should add the configure argument named --with-http\_xxx_module, see the ./configure --help for detail. +* If you want to enable an standard module, you should enable it via configure's option while compiling Tengine, for instance, --with-http\_example_module or --with-http\_example_module=shared. Run ./configure --help for more details. -* DSO loaded module will limit to 128. +* The maximum of dynamic loaded modules is limited to 128. -* DSO just support HTTP module; +* For now, only HTTP modules are dynamic-loaded supported. -* This module are tested successfully in Linux/FreeeBSD/MacOS. +* This feature is tested only on Linux/FreeBSD/MacOS. -Exampe +Example =========== worker_processes 1; dso { - path /home/nginx-dso/module/; - load ngx_http_lua_module; - load ngx_http_access_module ngx_http_access_module.so; - load ngx_http_flv_module ngx_http_flv_module.so; - load ngx_http_memcached_module ngx_http_memcached_module.so; - load ngx_http_sub_filter_module ngx_http_sub_filter_module.so; - load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; - load ngx_http_footer_filter_module ngx_http_footer_filter_module.so; + path /home/nginx-dso/module; + + load ngx_http_lua_module.so; + load ngx_http_access_module.so; + load ngx_http_flv_module.so; + load ngx_http_memcached_module.so; + load ngx_http_sub_filter_module.so; + load ngx_http_addition_filter_module.so; + load ngx_http_footer_filter_module.so; } events { @@ -43,29 +44,27 @@ Directives load ------------------------ -**Syntax**: *load module_name [module_path]* +**Syntax**: *load [module_name] [module_path]* **Default**: *none* **Context**: *dso* -The load directive links in the object file or library filename and adds the module structure named module to the list of active modules,module\_name is the name of the DSO module, module\_path is the path of the DSO module. +The load directive loads the object file or library file and adds the specified module to the list of active modules. module\_name is the name of the DSO module, and module\_path is the path of the DSO module. -If module_path is miss, default module\_path is $(module_name).so. +The order in which the module is searched is as follows: -There are three possibility with the module_path. It will search the module in below order. - -1 absolute path. -2 relative to path that path directive. -3 relative to default path(NGX\_PREFIX/modules or path which is specified with --dso-path when configure). +* the absolute path. +* relative path to the prefix specified by the 'path' directive. +* relative path to the default path (NGX\_PREFIX/modules or path which is specified by the '--dso-path' configure option). Example: load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; - load ngx_http_test_module; -load ngx_http_empty_gif_module module from ngx\_http\_empty\_gif\_module.so, and load ngx_http_test_module module from ngx\_http\_test\_module.so. +It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so. + order ------------- @@ -77,13 +76,13 @@ order **Context**: *dso* -This directive can insert your module to nginx' module order list(please see conf/module_order). Be careful, it will change the module runtime order. This directive does not need to be set in most cases. +This directive can insert a module into Nginx's module array in order (see conf/module_order for more details). Note it will change the module runtime order. This directive does not need to be used in most cases. Example: order module_order; -in module_order file: +in the 'module_order' file: ngx_core_module; ngx_errlog_module; @@ -98,7 +97,7 @@ in module_order file: ngx_http_addition_filter_module; ngx_http_my_filter_module; -this will insert my\_filter before addition\_filter module. +It will insert ngx\_http\_my\_filter\_module before ngx\_http\_addition\_filter\_module. path @@ -110,13 +109,13 @@ path **Context**: *dso* -The dso_path set default path for DSO module +This directive specifies the default path (prefix) for DSO modules. Example: - path /home/dso/module/; + path /home/dso/module; -Set default path to /home/dso/module/. +Sets the default path to /home/dso/module. Tools @@ -125,10 +124,10 @@ Tools dso_tools ------------------------ -This tools is used to compile the third nginx'module. +This tools can be used to compile a third party nginx module. Example: ./dso_tools --add-module=/home/dso/lua-nginx-module -This will compile ngx_lua module to dso, and install dso to default module path. +It will compile the ngx_lua module into a shared object, and install it to the default module path. From 1107b2ebd594fd762862fa5556473aef918cd502 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 22 Aug 2012 17:41:58 +0800 Subject: [PATCH 18/36] 1 modify order directive of dso module. 2 add include directive of dso module. 3 modify document of dso module. --- auto/modules | 2 +- docs/modules/ngx_dso_module.md | 47 ++++++++++++++++++----------- docs/modules/ngx_dso_module_cn.md | 50 ++++++++++++++++++++----------- src/core/ngx_dso_module.c | 18 ++++++++--- 4 files changed, 77 insertions(+), 40 deletions(-) diff --git a/auto/modules b/auto/modules index 725be4afdf..a968a8188a 100644 --- a/auto/modules +++ b/auto/modules @@ -781,7 +781,7 @@ END for mod in $NGX_ALL_MODULES do - echo "$mod;" >> $NGX_MODULE_ORDER + echo "module_order $mod;" >> $NGX_MODULE_ORDER done fi diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index 74272825ca..6e9ece7ade 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -41,6 +41,23 @@ Example Directives ========== +include +------------- + +**Syntax**: *include file_name* + +**Default**: *none* + +**Context**: *dso* + +Specifies a file contain order of module(via module_order directive). + +Example: + + include module_order + +It will load conf/module_order file and define order of module(via module\_order directive). + load ------------------------ @@ -66,10 +83,10 @@ Example: It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so. -order +module_order ------------- -**Syntax**: *order file* +**Syntax**: *module_order module_name* **Default**: *none* @@ -80,22 +97,18 @@ This directive can insert a module into Nginx's module array in order (see conf/ Example: - order module_order; - -in the 'module_order' file: - - ngx_core_module; - ngx_errlog_module; - ngx_conf_module; - ngx_events_module; - ngx_event_core_module; - ngx_epoll_module; - ngx_openssl_module; - ngx_http_module; - ngx_http_core_module; + module_order ngx_core_module; + module_order ngx_errlog_module; + module_order ngx_conf_module; + module_order ngx_events_module; + module_order ngx_event_core_module; + module_order ngx_epoll_module; + module_order ngx_openssl_module; + module_order ngx_http_module; + module_order ngx_http_core_module; ....................... - ngx_http_addition_filter_module; - ngx_http_my_filter_module; + module_order ngx_http_addition_filter_module; + module_order ngx_http_my_filter_module; It will insert ngx\_http\_my\_filter\_module before ngx\_http\_addition\_filter\_module. diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md index 56ab07245c..a54dc016c2 100644 --- a/docs/modules/ngx_dso_module_cn.md +++ b/docs/modules/ngx_dso_module_cn.md @@ -45,6 +45,24 @@ 指令 ========== +include +------------- + +**Syntax**: *include file_name* + +**Default**: *none* + +**Context**: *dso* + +include命令主要用于指定一个文件,这个文件里面包含了对应模块顺序(module_order指令),有关于module\_order指令可以看下面的module\_order部分. + +例子: + + include module_order + +将会加载conf/module_order这个文件,这个文件主要是由(module_order指令组成). + + load ------------------------ @@ -69,36 +87,32 @@ load命令用于在指定的路径(module\_path),将指定的模块(module\_name 将会从ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。以及从ngx\_http\_test\_module.so加载ngx\_http\_test\_module模块. -order +module_order ------------- -**Syntax**: *order file* +**Syntax**: *module_order module_name* **Default**: *none* **Context**: *dso* -这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个模块要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 +这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个命令要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 例子: - - order module_order; - - 在 module_order这个文件中: - ngx_core_module; - ngx_errlog_module; - ngx_conf_module; - ngx_events_module; - ngx_event_core_module; - ngx_epoll_module; - ngx_openssl_module; - ngx_http_module; - ngx_http_core_module; + module_order ngx_core_module; + module_order ngx_errlog_module; + module_order ngx_conf_module; + module_order ngx_events_module; + module_order ngx_event_core_module; + module_order ngx_epoll_module; + module_order ngx_openssl_module; + module_order ngx_http_module; + module_order ngx_http_core_module; ....................... - ngx_http_addition_filter_module; - ngx_http_my_filter_module; + module_order ngx_http_addition_filter_module; + module_order ngx_http_my_filter_module; 上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index ee546fc9e9..079b43c489 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -434,7 +434,6 @@ ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_CORE_MODULE; - cf->handler = ngx_dso_order; rv = ngx_conf_parse(cf, &file); @@ -480,7 +479,18 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) return NGX_CONF_OK; } - if (ngx_strcmp(value[0].data, "order") == 0) { + if (ngx_strcmp(value[0].data, "module_order") == 0) { + + if (cf->args->nelts != 2) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid number of arguments in \"sequence\" directive"); + return NGX_CONF_ERROR; + } + + return ngx_dso_order(cf, dummy, conf); + } + + if (ngx_strcmp(value[0].data, "include") == 0) { if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -592,7 +602,7 @@ ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) value = cf->args->elts; ctx = cf->ctx; - if (cf->args->nelts != 1) { + if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown directive \"%s\"", value[0].data); return NGX_CONF_ERROR; @@ -603,7 +613,7 @@ ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - *module_name = value[0]; + *module_name = value[1]; return NGX_CONF_OK; } From b16d884dec1c7216ef4e87467d1630f66f100282 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 28 Aug 2012 16:52:53 +0800 Subject: [PATCH 19/36] modify module_order command to module_stub. --- auto/init | 2 +- auto/install | 6 +++--- auto/modules | 2 +- docs/modules/ngx_dso_module.md | 34 +++++++++++++++---------------- docs/modules/ngx_dso_module_cn.md | 34 +++++++++++++++---------------- src/core/ngx_dso_module.c | 24 +++++++++++----------- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/auto/init b/auto/init index 904065596f..87d4c2c8c8 100644 --- a/auto/init +++ b/auto/init @@ -18,7 +18,7 @@ MAKEFILE=$NGX_OBJS/Makefile #dso NGX_DSO_COMPILE=$NGX_OBJS/dso_tools -NGX_MODULE_ORDER=$NGX_OBJS/module_order +NGX_MODULE_STUBS=$NGX_OBJS/module_stubs NGX_PCH= NGX_USE_PCH= diff --git a/auto/install b/auto/install index 04469103f7..3a77575d61 100644 --- a/auto/install +++ b/auto/install @@ -220,9 +220,9 @@ END cat << END >> $NGX_MAKEFILE - test -f '\$(DESTDIR)$NGX_CONF_PREFIX/module_order' \ - || cp $NGX_MODULE_ORDER '\$(DESTDIR)$NGX_CONF_PREFIX' - cp $NGX_MODULE_ORDER '\$(DESTDIR)$NGX_CONF_PREFIX/module_order' + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/module_stubs' \ + || cp $NGX_MODULE_STUBS '\$(DESTDIR)$NGX_CONF_PREFIX' + cp $NGX_MODULE_STUBS '\$(DESTDIR)$NGX_CONF_PREFIX/module_stubs' chmod 0755 $NGX_DSO_COMPILE cp $NGX_DSO_COMPILE '$NGX_PREFIX/sbin' END diff --git a/auto/modules b/auto/modules index a968a8188a..13e924fe65 100644 --- a/auto/modules +++ b/auto/modules @@ -781,7 +781,7 @@ END for mod in $NGX_ALL_MODULES do - echo "module_order $mod;" >> $NGX_MODULE_ORDER + echo "module_stub $mod;" >> $NGX_MODULE_STUBS done fi diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index 6e9ece7ade..d7bc2f7aaa 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -50,13 +50,13 @@ include **Context**: *dso* -Specifies a file contain order of module(via module_order directive). +Specifies a file contain order of module(via module_stub directive). Example: - include module_order + include module_stubs -It will load conf/module_order file and define order of module(via module\_order directive). +It will load conf/module_stubs file and define order of module(via module\_stub directive). load ------------------------ @@ -83,32 +83,32 @@ Example: It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so. -module_order +module_stub ------------- -**Syntax**: *module_order module_name* +**Syntax**: *module_stub module_name* **Default**: *none* **Context**: *dso* -This directive can insert a module into Nginx's module array in order (see conf/module_order for more details). Note it will change the module runtime order. This directive does not need to be used in most cases. +This directive can insert a module into Nginx's module array in order (see conf/module_stubs for more details). Note it will change the module runtime order. This directive does not need to be used in most cases. Example: - module_order ngx_core_module; - module_order ngx_errlog_module; - module_order ngx_conf_module; - module_order ngx_events_module; - module_order ngx_event_core_module; - module_order ngx_epoll_module; - module_order ngx_openssl_module; - module_order ngx_http_module; - module_order ngx_http_core_module; + module_stub ngx_core_module; + module_stub ngx_errlog_module; + module_stub ngx_conf_module; + module_stub ngx_events_module; + module_stub ngx_event_core_module; + module_stub ngx_epoll_module; + module_stub ngx_openssl_module; + module_stub ngx_http_module; + module_stub ngx_http_core_module; ....................... - module_order ngx_http_addition_filter_module; - module_order ngx_http_my_filter_module; + module_stub ngx_http_addition_filter_module; + module_stub ngx_http_my_filter_module; It will insert ngx\_http\_my\_filter\_module before ngx\_http\_addition\_filter\_module. diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md index a54dc016c2..7f296fd247 100644 --- a/docs/modules/ngx_dso_module_cn.md +++ b/docs/modules/ngx_dso_module_cn.md @@ -54,13 +54,13 @@ include **Context**: *dso* -include命令主要用于指定一个文件,这个文件里面包含了对应模块顺序(module_order指令),有关于module\_order指令可以看下面的module\_order部分. +include命令主要用于指定一个文件,这个文件里面包含了对应模块顺序(module_stub指令),有关于module\_stub指令可以看下面的module\_stubs部分. 例子: - include module_order + include module_stubs -将会加载conf/module_order这个文件,这个文件主要是由(module_order指令组成). +将会加载conf/module_stubs这个文件,这个文件主要是由(module_stub指令组成). load @@ -87,32 +87,32 @@ load命令用于在指定的路径(module\_path),将指定的模块(module\_name 将会从ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。以及从ngx\_http\_test\_module.so加载ngx\_http\_test\_module模块. -module_order +module_stub ------------- -**Syntax**: *module_order module_name* +**Syntax**: *module_stub module_name* **Default**: *none* **Context**: *dso* -这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_order这个文件),这个命令要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 +这个指令主要是将你需要的动态模块插入到你所需要的位置(可以看conf/module\_stubs这个文件),这个命令要很小心使用,因为它将会改变你的模块的运行时顺序(在Nginx中模块都是有严格顺序的).而大多数时候这个命令都是不需要设置的。 例子: - module_order ngx_core_module; - module_order ngx_errlog_module; - module_order ngx_conf_module; - module_order ngx_events_module; - module_order ngx_event_core_module; - module_order ngx_epoll_module; - module_order ngx_openssl_module; - module_order ngx_http_module; - module_order ngx_http_core_module; + module_stub ngx_core_module; + module_stub ngx_errlog_module; + module_stub ngx_conf_module; + module_stub ngx_events_module; + module_stub ngx_event_core_module; + module_stub ngx_epoll_module; + module_stub ngx_openssl_module; + module_stub ngx_http_module; + module_stub ngx_http_core_module; ....................... - module_order ngx_http_addition_filter_module; - module_order ngx_http_my_filter_module; + module_stub ngx_http_addition_filter_module; + module_stub ngx_http_my_filter_module; 上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 079b43c489..663a670f60 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -31,7 +31,7 @@ typedef struct { ngx_str_t path; ngx_int_t flag_postion; - ngx_array_t *order; + ngx_array_t *stubs; ngx_array_t *modules; } ngx_dso_conf_ctx_t; @@ -40,7 +40,7 @@ static char *ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_dso_load(ngx_conf_t *cf); static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, ngx_str_t *name, ngx_str_t *path); -static char *ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_dso_get_position(ngx_str_t *module_entry); @@ -479,7 +479,7 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) return NGX_CONF_OK; } - if (ngx_strcmp(value[0].data, "module_order") == 0) { + if (ngx_strcmp(value[0].data, "module_stub") == 0) { if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -487,7 +487,7 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) return NGX_CONF_ERROR; } - return ngx_dso_order(cf, dummy, conf); + return ngx_dso_stub(cf, dummy, conf); } if (ngx_strcmp(value[0].data, "include") == 0) { @@ -498,7 +498,7 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) return NGX_CONF_ERROR; } - if (ctx->order->nelts != 0) { + if (ctx->stubs->nelts != 0) { return "is duplicate"; } @@ -542,8 +542,8 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - ctx->order = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); - if (ctx->order == NULL) { + ctx->stubs = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); + if (ctx->stubs == NULL) { return NGX_CONF_ERROR; } @@ -594,7 +594,7 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static char * -ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value, *module_name; ngx_dso_conf_ctx_t *ctx; @@ -608,7 +608,7 @@ ngx_dso_order(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - module_name = ngx_array_push(ctx->order); + module_name = ngx_array_push(ctx->stubs); if (module_name == NULL) { return NGX_CONF_ERROR; } @@ -629,7 +629,7 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) near = ctx->flag_postion; - if (ctx->order == NULL || ctx->order->nelts == 0) { + if (ctx->stubs == NULL || ctx->stubs->nelts == 0) { for (i = 1; ngx_all_module_names[i]; i++) { len1 = ngx_strlen(ngx_all_module_names[i]); @@ -662,10 +662,10 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) } } - name = ctx->order->elts; + name = ctx->stubs->elts; near = ctx->flag_postion; - for (i = 1; i < ctx->order->nelts; i++) { + for (i = 1; i < ctx->stubs->nelts; i++) { if (name[i].len == module_name.len && ngx_strncmp(name[i].data, module_name.data, name[i].len) == 0) { From 2885aae57a27b51c1d2f2deef837a3bc3fc30bb7 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 29 Aug 2012 17:32:38 +0800 Subject: [PATCH 20/36] add command of dso module in show directive(nginx -l). --- src/core/nginx.c | 23 ++-------------------- src/core/ngx_cycle.c | 25 ++++++++++++++++++++++++ src/core/ngx_cycle.h | 1 + src/core/ngx_dso_module.c | 41 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 21 deletions(-) diff --git a/src/core/nginx.c b/src/core/nginx.c index 16b77974ea..de70c8af66 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -191,7 +191,6 @@ ngx_uint_t ngx_dump_config; static ngx_uint_t ngx_show_help; static ngx_uint_t ngx_show_version; static ngx_uint_t ngx_show_configure; -static ngx_uint_t ngx_show_directives; static u_char *ngx_prefix; static u_char *ngx_conf_file; static u_char *ngx_conf_params; @@ -207,7 +206,6 @@ main(int argc, char *const *argv) ngx_int_t i; ngx_log_t *log; ngx_cycle_t *cycle, init_cycle; - ngx_command_t *cmd; ngx_core_conf_t *ccf; ngx_debug_init(); @@ -270,24 +268,7 @@ main(int argc, char *const *argv) "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } - if (ngx_show_directives) { - ngx_log_stderr(0, "all available directives:"); - - for (i = 0; ngx_modules[i]; i++) { - ngx_log_stderr(0, "%s:", ngx_module_names[i]); - - cmd = ngx_modules[i]->commands; - if(cmd == NULL) { - continue; - } - - for ( /* void */ ; cmd->name.len; cmd++) { - ngx_log_stderr(0, " %V", &cmd->name); - } - } - } - - if(!ngx_test_config && !ngx_show_modules) { + if(!ngx_test_config && !ngx_show_modules && !ngx_show_directives) { return 0; } } @@ -374,7 +355,7 @@ main(int argc, char *const *argv) return 0; } - if (ngx_show_modules) { + if (ngx_show_modules || ngx_show_directives) { return 0; } diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index e8b1ef98de..bf2ea666f1 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -12,6 +12,7 @@ #if (NGX_DSO) void ngx_show_dso_modules(ngx_conf_t *cf); +void ngx_show_dso_directives(ngx_conf_t *cf); #endif @@ -32,6 +33,7 @@ static ngx_event_t ngx_cleaner_event; ngx_uint_t ngx_test_config; ngx_uint_t ngx_quiet_mode; ngx_uint_t ngx_show_modules; +ngx_uint_t ngx_show_directives; #if (NGX_THREADS) ngx_tls_key_t ngx_core_tls_key; @@ -58,6 +60,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_conf_t conf; ngx_pool_t *pool; ngx_cycle_t *cycle, **old; + ngx_command_t *cmd; ngx_shm_zone_t *shm_zone, *oshm_zone; ngx_list_part_t *part, *opart; ngx_open_file_t *file; @@ -281,6 +284,28 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) return NULL; } + if (ngx_show_directives) { + ngx_log_stderr(0, "all available directives:"); + + for (i = 0; ngx_module_names[i]; i++) { + ngx_log_stderr(0, "%s:", ngx_module_names[i]); + + cmd = ngx_modules[i]->commands; + if(cmd == NULL) { + continue; + } + + for ( /* void */ ; cmd->name.len; cmd++) { + ngx_log_stderr(0, " %V", &cmd->name); + } + } + +#if (NGX_DSO) + ngx_show_dso_directives(&conf); +#endif + return cycle; + } + if (ngx_show_modules) { ngx_log_stderr(0, "loaded modules:"); diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h index 5339a6b927..6b93c758f3 100644 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -139,6 +139,7 @@ extern ngx_array_t ngx_old_cycles; extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_test_config; extern ngx_uint_t ngx_show_modules; +extern ngx_uint_t ngx_show_directives; extern ngx_uint_t ngx_quiet_mode; #if (NGX_THREADS) extern ngx_tls_key_t ngx_core_tls_key; diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 663a670f60..bd543ec037 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -722,3 +722,44 @@ ngx_show_dso_modules(ngx_conf_t *cf) &module_name, module->major_version, module->minor_version); } } + + +void +ngx_show_dso_directives(ngx_conf_t *cf) +{ + ngx_str_t module_name; + ngx_uint_t i; + ngx_module_t *module; + ngx_command_t *cmd; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; + + ctx = (ngx_dso_conf_ctx_t *) ngx_get_conf(cf->cycle->conf_ctx, + ngx_dso_module); + + if (ctx == NULL) { + return; + } + + dl_m = ctx->modules->elts; + + for (i = 0; i < ctx->modules->nelts; i++) { + if (dl_m[i].name.len == 0) { + continue; + } + + module_name = dl_m[i].name; + module = dl_m[i].module; + + ngx_log_stderr(0, "%V (shared):", &module_name); + + cmd = module->commands; + if(cmd == NULL) { + continue; + } + + for ( /* void */ ; cmd->name.len; cmd++) { + ngx_log_stderr(0, " %V", &cmd->name); + } + } +} From cc279d918c4929459aceb9e0b38ebcf4c4f85f37 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 29 Aug 2012 18:56:08 +0800 Subject: [PATCH 21/36] 1 fix code style. 2 modify for some review opinion. --- src/core/ngx_dso_module.c | 282 +++++++++++++++++++------------------- 1 file changed, 143 insertions(+), 139 deletions(-) diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index bd543ec037..e4c04ba0c2 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -37,7 +37,12 @@ typedef struct { static char *ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); +static char *ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, + ngx_str_t *name); static char *ngx_dso_load(ngx_conf_t *cf); +static void ngx_dso_cleanup(void *data); + static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, ngx_str_t *name, ngx_str_t *path); static char *ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -96,13 +101,95 @@ static ngx_dso_flagpole_t module_flagpole[] = { }; +static char * +ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *rv; + ngx_conf_t pcf; + ngx_dso_conf_ctx_t *ctx; + ngx_pool_cleanup_t *cln; + + ctx = ((void **) cf->ctx)[ngx_dso_module.index]; + if (ctx != NULL) { + return "is duplicate"; + } + + ctx = ngx_pcalloc(cf->pool, sizeof(ngx_dso_conf_ctx_t)); + + if (ctx == NULL) { + return NGX_CONF_ERROR; + } + + *(ngx_dso_conf_ctx_t **) conf = ctx; + + ctx->modules = ngx_array_create(cf->pool, 10, sizeof(ngx_dso_module_t)); + if (ctx->modules == NULL) { + return NGX_CONF_ERROR; + } + + ctx->flag_postion = ngx_dso_get_position(&module_flagpole[0].entry); + if (ctx->flag_postion == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + ctx->stubs = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); + if (ctx->stubs == NULL) { + return NGX_CONF_ERROR; + } + + if (ngx_is_init_cycle(cf->cycle->old_cycle)) { + ngx_memzero(ngx_static_modules, sizeof(ngx_module_t *) * ngx_max_module); + ngx_memcpy(ngx_static_modules, ngx_modules, + sizeof(ngx_module_t *) * ngx_max_module); + } else { + ngx_memzero(ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + + ngx_memcpy(ngx_old_modules, ngx_modules, + sizeof(ngx_module_t *) * NGX_DSO_MAX); + ngx_memcpy(ngx_modules, ngx_static_modules, + sizeof(ngx_module_t *) * NGX_DSO_MAX); + } + + pcf = *cf; + cf->ctx = ctx; + cf->module_type = NGX_CORE_MODULE; + cf->handler = ngx_dso_parse; + cf->handler_conf = conf; + + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + *cf = pcf; + return NGX_CONF_ERROR; + } + + cln->handler = ngx_dso_cleanup; + cln->data = cf->cycle; + + rv = ngx_conf_parse(cf, NULL); + if (rv != NGX_CONF_OK) { + *cf = pcf; + return rv; + } + + rv = ngx_dso_load(cf); + + if (rv == NGX_CONF_ERROR) { + return rv; + } + + *cf = pcf; + + return NGX_CONF_OK; +} + + static ngx_int_t ngx_dso_get_position(ngx_str_t *entry) { - size_t len; - ngx_int_t i; + size_t len; + ngx_int_t i; - /* start insert filter list */ + /* start to insert */ for (i = 0; ngx_module_names[i]; i++) { len = ngx_strlen(ngx_module_names[i]); @@ -124,9 +211,9 @@ ngx_dso_cleanup(void *data) { ngx_cycle_t *cycle = data; - ngx_uint_t i; - ngx_dso_module_t *dl_m; - ngx_dso_conf_ctx_t *ctx; + ngx_uint_t i; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; if (cycle != ngx_cycle) { @@ -158,9 +245,9 @@ static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, ngx_str_t *name, ngx_str_t *path) { - size_t len; - ngx_uint_t j; - ngx_dso_module_t *m; + size_t len; + ngx_uint_t j; + ngx_dso_module_t *m; for (j = 0; ngx_module_names[j]; j++) { len = ngx_strlen(ngx_module_names[j]); @@ -195,8 +282,8 @@ ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, static ngx_int_t ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) { - size_t len, size; - u_char *p, *n, *prefix; + size_t len, size; + u_char *p, *n, *prefix; if (name->data[0] == '/') { return NGX_OK; @@ -251,9 +338,9 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) static ngx_int_t ngx_dso_open(ngx_dso_module_t *dl_m) { - void *dl_handle; - ngx_str_t module_name, module_path; - ngx_module_t *module; + void *dl_handle; + ngx_str_t module_name, module_path; + ngx_module_t *module; module_name = dl_m->name; module_path = dl_m->path; @@ -280,11 +367,11 @@ ngx_dso_open(ngx_dso_module_t *dl_m) static char * ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) { - ngx_uint_t j; - ngx_module_t *m; + ngx_uint_t j; + ngx_module_t *m; m = NULL; - /* start insert filter list */ + /* start to insert */ for (j = flag_postion; ngx_modules[j]; j++) { m = ngx_modules[j]; @@ -303,22 +390,21 @@ ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) } - static char * ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - u_char *p; - ngx_int_t rc; - ngx_str_t *value, module_path; - ngx_dso_module_t *dl_m; - ngx_dso_conf_ctx_t *ctx; + u_char *p; + ngx_int_t rc; + ngx_str_t *value, module_path; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; ctx = cf->ctx; value = cf->args->elts; if (ctx->modules->nelts >= NGX_DSO_MAX) { - ngx_log_stderr(0, "Module \"%V\" could not be loaded, " - "because the dso module limit(%ui) was reached.", + ngx_log_stderr(0, "module \"%V\" could not be loaded, " + "because the dso module limit(%ui) is reached.", &value[1], NGX_DSO_MAX); return NGX_CONF_ERROR; } @@ -360,11 +446,11 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static char * ngx_dso_load(ngx_conf_t *cf) { - char *rv; - ngx_int_t postion; - ngx_uint_t i; - ngx_dso_module_t *dl_m; - ngx_dso_conf_ctx_t *ctx; + char *rv; + ngx_int_t postion; + ngx_uint_t i; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; ctx = cf->ctx; dl_m = ctx->modules->elts; @@ -387,7 +473,7 @@ ngx_dso_load(ngx_conf_t *cf) || dl_m[i].module->minor_version > NGX_NUMBER_MINOR) { ngx_log_stderr(0,"Module \"%V\" is not compatible with this " - "version of Tengine (found %d.%d, need %d.%d)." + "version of Tengine (found %ui.%ui, need %ui.%ui)." " Please contact the vendor for the correct version.", &dl_m[i].name, dl_m[i].module->major_version, dl_m[i].module->minor_version, NGX_NUMBER_MAJOR, @@ -410,44 +496,11 @@ ngx_dso_load(ngx_conf_t *cf) } -static char * -ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, - ngx_str_t *name) -{ - char *rv; - ngx_str_t file; - ngx_conf_t pcf; - - file.len = name->len; - file.data = ngx_pnalloc(cf->temp_pool, name->len + 1); - - if (file.data == NULL) { - return NGX_CONF_ERROR; - } - - ngx_sprintf(file.data, "%V", name); - - if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { - return NGX_CONF_ERROR; - } - - pcf = *cf; - cf->ctx = ctx; - cf->module_type = NGX_CORE_MODULE; - - rv = ngx_conf_parse(cf, &file); - - *cf = pcf; - - return rv; -} - - static char * ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - ngx_str_t *value; - ngx_dso_conf_ctx_t *ctx; + ngx_str_t *value; + ngx_dso_conf_ctx_t *ctx; value = cf->args->elts; ctx = cf->ctx; @@ -512,92 +565,43 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) static char * -ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, + ngx_str_t *name) { - char *rv; - ngx_conf_t pcf; - ngx_dso_conf_ctx_t *ctx; - ngx_pool_cleanup_t *cln; - - ctx = ((void **) cf->ctx)[ngx_dso_module.index]; - if (ctx != NULL) { - return "is duplicate"; - } - - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_dso_conf_ctx_t)); - - if (ctx == NULL) { - return NGX_CONF_ERROR; - } + char *rv; + ngx_str_t file; + ngx_conf_t pcf; - *(ngx_dso_conf_ctx_t **) conf = ctx; + file.len = name->len; + file.data = ngx_pnalloc(cf->temp_pool, name->len + 1); - ctx->modules = ngx_array_create(cf->pool, 10, sizeof(ngx_dso_module_t)); - if (ctx->modules == NULL) { + if (file.data == NULL) { return NGX_CONF_ERROR; } - ctx->flag_postion = ngx_dso_get_position(&module_flagpole[0].entry); - if (ctx->flag_postion == NGX_ERROR) { - return NGX_CONF_ERROR; - } + ngx_sprintf(file.data, "%V", name); - ctx->stubs = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); - if (ctx->stubs == NULL) { + if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { return NGX_CONF_ERROR; } - if (ngx_is_init_cycle(cf->cycle->old_cycle)) { - ngx_memzero(ngx_static_modules, sizeof(ngx_module_t *) * ngx_max_module); - ngx_memcpy(ngx_static_modules, ngx_modules, - sizeof(ngx_module_t *) * ngx_max_module); - } else { - ngx_memzero(ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); - - ngx_memcpy(ngx_old_modules, ngx_modules, - sizeof(ngx_module_t *) * NGX_DSO_MAX); - ngx_memcpy(ngx_modules, ngx_static_modules, - sizeof(ngx_module_t *) * NGX_DSO_MAX); - } - pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_CORE_MODULE; - cf->handler = ngx_dso_parse; - cf->handler_conf = conf; - - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) { - *cf = pcf; - return NGX_CONF_ERROR; - } - cln->handler = ngx_dso_cleanup; - cln->data = cf->cycle; - - rv = ngx_conf_parse(cf, NULL); - if (rv != NGX_CONF_OK) { - *cf = pcf; - return rv; - } - - rv = ngx_dso_load(cf); - - if (rv == NGX_CONF_ERROR) { - return rv; - } + rv = ngx_conf_parse(cf, &file); *cf = pcf; - return NGX_CONF_OK; + return rv; } static char * ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_str_t *value, *module_name; - ngx_dso_conf_ctx_t *ctx; + ngx_str_t *value, *module_name; + ngx_dso_conf_ctx_t *ctx; value = cf->args->elts; ctx = cf->ctx; @@ -622,10 +626,10 @@ ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) { - size_t len1, len2, len3; - ngx_int_t near; - ngx_uint_t i, k; - ngx_str_t *name; + size_t len1, len2, len3; + ngx_int_t near; + ngx_str_t *name; + ngx_uint_t i, k; near = ctx->flag_postion; @@ -695,11 +699,11 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) void ngx_show_dso_modules(ngx_conf_t *cf) { - ngx_str_t module_name; - ngx_uint_t i; - ngx_module_t *module; - ngx_dso_module_t *dl_m; - ngx_dso_conf_ctx_t *ctx; + ngx_str_t module_name; + ngx_uint_t i; + ngx_module_t *module; + ngx_dso_module_t *dl_m; + ngx_dso_conf_ctx_t *ctx; ctx = (ngx_dso_conf_ctx_t *) ngx_get_conf(cf->cycle->conf_ctx, ngx_dso_module); @@ -718,7 +722,7 @@ ngx_show_dso_modules(ngx_conf_t *cf) module_name = dl_m[i].name; module = dl_m[i].module; - ngx_log_stderr(0, " %V (shared), require nginx version (%d.%d)", + ngx_log_stderr(0, " %V (shared), nginx dso version (%ui.%ui)", &module_name, module->major_version, module->minor_version); } } From 8dd2239025cdf14386688f4f50f3e638a25fd001 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Thu, 30 Aug 2012 17:14:33 +0800 Subject: [PATCH 22/36] modify error message --- auto/make | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auto/make b/auto/make index 70c21ea5a6..af381859fa 100644 --- a/auto/make +++ b/auto/make @@ -7,7 +7,7 @@ if test -n "$NGX_SHARED_MODULES"; then if [ $NGX_DSO != YES ]; then cat << END -when you use shared modules, you should enable dso module. +you should enable the dso module, if you want to use a dynamic loaded module. END exit 1 fi From 6ce5137cc43a241b3b26e08739e6245217d4903f Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Thu, 30 Aug 2012 19:01:52 +0800 Subject: [PATCH 23/36] merge 1.2.3 for dso patch --- auto/modules | 5 +++++ auto/options | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/auto/modules b/auto/modules index 13e924fe65..64965922ff 100644 --- a/auto/modules +++ b/auto/modules @@ -588,6 +588,11 @@ if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_LEAST_CONN_SRCS" fi +if [ $HTTP_UPSTREAM_LEAST_CONN_SHARED = YES ]; then + NGX_SHARED_MODULES="$NGX_SHARED_MODULES $HTTP_UPSTREAM_LEAST_CONN_MODULE" + NGX_SHARED_SRCS="$NGX_SHARED_SRCS|$HTTP_UPSTREAM_LEAST_CONN_SRCS" +fi + if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_KEEPALIVE_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS" diff --git a/auto/options b/auto/options index 902cdbd892..c441b1a822 100644 --- a/auto/options +++ b/auto/options @@ -233,6 +233,7 @@ HTTP_EMPTY_GIF_SHARED=NO HTTP_BROWSER_SHARED=NO HTTP_USER_AGENT_SHARED=NO HTTP_UPSTREAM_IP_HASH_SHARED=NO +HTTP_UPSTREAM_LEAST_CONN_SHARED=NO MAIL=NO MAIL_SSL=NO @@ -445,6 +446,9 @@ do --with-http_upstream_ip_hash_module=shared) HTTP_UPSTREAM_IP_HASH_SHARED=YES HTTP_UPSTREAM_IP_HASH=NO ;; + --with-http_upstream_least_conn_module=shared) + HTTP_UPSTREAM_LEAST_CONN_SHARED=YES + HTTP_UPSTREAM_LEAST_CONN=NO ;; --without-http_charset_module) HTTP_CHARSET=NO ;; --without-http_gzip_module) HTTP_GZIP=NO ;; @@ -660,6 +664,8 @@ cat << END enable ngx_http_user_agent_module (shared) --with-http_upstream_ip_hash_module=shared enable ngx_http_upstream_ip_hash_module (shared) + --with-http_upstream_least_conn_module=shared + enable ngx_http_upstream_least_conn_module (shared) --without-http_charset_module disable ngx_http_charset_filter_module --without-http_gzip_module disable ngx_http_gzip_filter_module From c3d638f3c7b15510869dbc1e37574eacf4d36025 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Fri, 31 Aug 2012 16:36:01 +0800 Subject: [PATCH 24/36] 1 remove some dead code. 2 fix bug for zls0424's review. --- src/core/ngx_dso_module.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index e4c04ba0c2..01841b4f76 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -138,12 +138,9 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } if (ngx_is_init_cycle(cf->cycle->old_cycle)) { - ngx_memzero(ngx_static_modules, sizeof(ngx_module_t *) * ngx_max_module); ngx_memcpy(ngx_static_modules, ngx_modules, sizeof(ngx_module_t *) * ngx_max_module); } else { - ngx_memzero(ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); - ngx_memcpy(ngx_old_modules, ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); ngx_memcpy(ngx_modules, ngx_static_modules, @@ -158,8 +155,8 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { - *cf = pcf; - return NGX_CONF_ERROR; + rv = NGX_CONF_ERROR; + goto failed; } cln->handler = ngx_dso_cleanup; @@ -167,19 +164,23 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) rv = ngx_conf_parse(cf, NULL); if (rv != NGX_CONF_OK) { - *cf = pcf; - return rv; + goto failed; } rv = ngx_dso_load(cf); if (rv == NGX_CONF_ERROR) { - return rv; + goto failed; } *cf = pcf; return NGX_CONF_OK; + +failed: + + *cf = pcf; + return rv; } @@ -234,7 +235,6 @@ ngx_dso_cleanup(void *data) } } - ngx_memzero(ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); ngx_memcpy(ngx_modules, ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); } @@ -559,7 +559,7 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown directive \"%s\"", value[0].data); + "unknown directive \"%V\"", &value[0]); return NGX_CONF_ERROR; } From a9e8d1af303ac581744ee0dcb2fe58e5a981c96c Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Fri, 31 Aug 2012 18:34:29 +0800 Subject: [PATCH 25/36] fix code style. --- auto/make | 3 + auto/unix | 2 +- contrib/dso.in | 2 +- src/core/ngx_dso_module.c | 189 ++++++++++++++++++++------------------ 4 files changed, 107 insertions(+), 89 deletions(-) diff --git a/auto/make b/auto/make index af381859fa..526d67a2c5 100644 --- a/auto/make +++ b/auto/make @@ -588,6 +588,9 @@ END cat << END > $NGX_DSO_COMPILE #!/bin/sh +#Copyright (C) 2010-2012 Alibaba Group Holding Limited + + ngx_soext='.so' CC=$CC CFLAGS='$CFLAGS -fPIC' diff --git a/auto/unix b/auto/unix index 4bde743fd2..2e89611aef 100755 --- a/auto/unix +++ b/auto/unix @@ -275,7 +275,7 @@ if [ $ngx_found != yes ]; then else if [ $NGX_DSO = YES] ; then cat << END -dlopen(3) required by dso not found, please disable dso (--without-dso). +dlopen(3) required by dso was not found, please disable dso (--without-dso). END fi diff --git a/contrib/dso.in b/contrib/dso.in index 994c370245..f0685902e9 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -55,7 +55,7 @@ cat << END --prefix=PATH set module installation prefix - --add-module=PATH external module of will compile + --add-module=PATH external module which will be compiled --with-nginx-source=NGX_SOURCE_HOM set nginx source path diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 01841b4f76..2d9ba6c469 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -43,8 +43,8 @@ static char *ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, static char *ngx_dso_load(ngx_conf_t *cf); static void ngx_dso_cleanup(void *data); -static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, - ngx_str_t *name, ngx_str_t *path); +static ngx_int_t ngx_dso_check_duplicated(ngx_cycle_t *cycle, + ngx_array_t *modules, ngx_str_t *name, ngx_str_t *path); static char *ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_dso_get_position(ngx_str_t *module_entry); @@ -122,7 +122,7 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) *(ngx_dso_conf_ctx_t **) conf = ctx; - ctx->modules = ngx_array_create(cf->pool, 10, sizeof(ngx_dso_module_t)); + ctx->modules = ngx_array_create(cf->pool, 50, sizeof(ngx_dso_module_t)); if (ctx->modules == NULL) { return NGX_CONF_ERROR; } @@ -132,7 +132,7 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - ctx->stubs = ngx_array_create(cf->pool, 10, sizeof(ngx_str_t)); + ctx->stubs = ngx_array_create(cf->pool, 50, sizeof(ngx_str_t)); if (ctx->stubs == NULL) { return NGX_CONF_ERROR; } @@ -140,6 +140,7 @@ ngx_dso_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (ngx_is_init_cycle(cf->cycle->old_cycle)) { ngx_memcpy(ngx_static_modules, ngx_modules, sizeof(ngx_module_t *) * ngx_max_module); + } else { ngx_memcpy(ngx_old_modules, ngx_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); @@ -195,8 +196,11 @@ ngx_dso_get_position(ngx_str_t *entry) len = ngx_strlen(ngx_module_names[i]); - if (len == entry->len - && ngx_strncasecmp((u_char *) ngx_module_names[i], + if (len != entry->len) { + continue; + } + + if (ngx_strncasecmp((u_char *) ngx_module_names[i], entry->data, len) == 0) { return i; @@ -213,7 +217,7 @@ ngx_dso_cleanup(void *data) ngx_cycle_t *cycle = data; ngx_uint_t i; - ngx_dso_module_t *dl_m; + ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; if (cycle != ngx_cycle) { @@ -223,14 +227,14 @@ ngx_dso_cleanup(void *data) cycle->conf_ctx[ngx_dso_module.index]; if (ctx != NULL) { - dl_m = ctx->modules->elts; + dm = ctx->modules->elts; for (i = 0; i < ctx->modules->nelts; i++) { - if (dl_m[i].name.len == 0) { + if (dm[i].name.len == 0) { continue; } - dlclose(dl_m[i].dl_handle); + dlclose(dm[i].dl_handle); } } } @@ -246,31 +250,31 @@ ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, ngx_str_t *name, ngx_str_t *path) { size_t len; - ngx_uint_t j; + ngx_uint_t i; ngx_dso_module_t *m; - for (j = 0; ngx_module_names[j]; j++) { - len = ngx_strlen(ngx_module_names[j]); + for (i = 0; ngx_module_names[i]; i++) { + len = ngx_strlen(ngx_module_names[i]); - if (len == name->len && ngx_strncmp(ngx_module_names[j], + if (len == name->len && ngx_strncmp(ngx_module_names[i], name->data, name->len) == 0) { - ngx_log_stderr(0, "module %V is already static loaded, skipping", - name); + ngx_log_stderr(0, "module %V is already static loaded, " + "skipping", name); return NGX_DECLINED; } } m = modules->elts; - for (j = 0; j < modules->nelts; j++) { - if ((m[j].name.len == name->len - && ngx_strncmp(m[j].name.data, name->data, name->len) == 0) - || (m[j].path.len == path->len - && ngx_strncmp(m[j].path.data, path->data, path->len) == 0)) + for (i = 0; i < modules->nelts; i++) { + if ((m[i].name.len == name->len + && ngx_strncmp(m[i].name.data, name->data, name->len) == 0) + || (m[i].path.len == path->len + && ngx_strncmp(m[i].path.data, path->data, path->len) == 0)) { - ngx_log_stderr(0, "module %V/%V is already dynamic loaded, skipping", - path, name); - m[j].name.len = 0; + ngx_log_stderr(0, "module %V/%V is already dynamic loaded, " + "skipping", path, name); + m[i].name.len = 0; return NGX_DECLINED; } } @@ -280,7 +284,8 @@ ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, static ngx_int_t -ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) +ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, + ngx_str_t *name) { size_t len, size; u_char *p, *n, *prefix; @@ -294,15 +299,17 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) prefix = cycle->prefix.data; len = cycle->prefix.len; size = len + ngx_default_modules_prefix.len + name->len + 1; + } else { prefix = ngx_default_modules_prefix.data; len = ngx_default_modules_prefix.len; size = len + name->len + 1; } + } else { if (ctx->path.data[0] != '/') { - ngx_log_stderr(0, "the path(%V) of dso module should be absolute path", - &ctx->path); + ngx_log_stderr(0, "the path(%V) of dso module " + "should be absolute path", &ctx->path); return NGX_ERROR; } @@ -336,29 +343,29 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) static ngx_int_t -ngx_dso_open(ngx_dso_module_t *dl_m) +ngx_dso_open(ngx_dso_module_t *dm) { - void *dl_handle; - ngx_str_t module_name, module_path; + void *handle; + ngx_str_t name, path; ngx_module_t *module; - module_name = dl_m->name; - module_path = dl_m->path; + name = dm->name; + path = dm->path; - dl_handle = dlopen((char *) module_path.data, RTLD_NOW | RTLD_GLOBAL); - if (dl_handle == NULL) { + handle = dlopen((char *) path.data, RTLD_NOW | RTLD_GLOBAL); + if (handle == NULL) { ngx_log_stderr(errno, "load module failed %s", dlerror()); return NGX_ERROR; } - module = dlsym(dl_handle, (const char *) module_name.data); + module = dlsym(handle, (const char *) name.data); if (module == NULL) { - ngx_log_stderr(errno, "Can't locate sym in module(%V)", &module_name); + ngx_log_stderr(errno, "Can't locate sym in module(%V)", &name); return NGX_ERROR; } - dl_m->dl_handle = dl_handle; - dl_m->module = module; + dm->dl_handle = handle; + dm->module = module; return NGX_OK; } @@ -367,15 +374,15 @@ ngx_dso_open(ngx_dso_module_t *dl_m) static char * ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) { - ngx_uint_t j; + ngx_uint_t i; ngx_module_t *m; m = NULL; /* start to insert */ - for (j = flag_postion; ngx_modules[j]; j++) { - m = ngx_modules[j]; + for (i = flag_postion; ngx_modules[i]; i++) { + m = ngx_modules[i]; - ngx_modules[j] = module; + ngx_modules[i] = module; module = m; } @@ -384,7 +391,7 @@ ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) return NGX_CONF_ERROR; } - ngx_modules[j] = module; + ngx_modules[i] = module; return NGX_CONF_OK; } @@ -396,7 +403,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) u_char *p; ngx_int_t rc; ngx_str_t *value, module_path; - ngx_dso_module_t *dl_m; + ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; ctx = cf->ctx; @@ -404,8 +411,8 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (ctx->modules->nelts >= NGX_DSO_MAX) { ngx_log_stderr(0, "module \"%V\" could not be loaded, " - "because the dso module limit(%ui) is reached.", - &value[1], NGX_DSO_MAX); + "because the dso module limit(%ui) is reached.", + &value[1], NGX_DSO_MAX); return NGX_CONF_ERROR; } @@ -413,6 +420,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, &value[1], &value[2]); module_path = value[2]; + } else { /* cf->args->nelts == 2 */ module_path.len = value[1].len + sizeof(NGX_DSO_EXT); @@ -431,13 +439,13 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_OK; } - dl_m = ngx_array_push(ctx->modules); - if (dl_m == NULL) { + dm = ngx_array_push(ctx->modules); + if (dm == NULL) { return NGX_CONF_ERROR; } - dl_m->name = value[1]; - dl_m->path = module_path; + dm->name = value[1]; + dm->path = module_path; return NGX_CONF_OK; } @@ -449,45 +457,45 @@ ngx_dso_load(ngx_conf_t *cf) char *rv; ngx_int_t postion; ngx_uint_t i; - ngx_dso_module_t *dl_m; + ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; ctx = cf->ctx; - dl_m = ctx->modules->elts; + dm = ctx->modules->elts; for (i = 0; i < ctx->modules->nelts; i++) { - if (ngx_dso_full_name(cf->cycle, ctx, &dl_m[i].path) != NGX_OK) { + if (ngx_dso_full_name(cf->cycle, ctx, &dm[i].path) != NGX_OK) { return NGX_CONF_ERROR; } - if (ngx_dso_open(&dl_m[i]) == NGX_ERROR) { + if (ngx_dso_open(&dm[i]) == NGX_ERROR) { return NGX_CONF_ERROR; } - if (dl_m[i].module->type == NGX_CORE_MODULE) { + if (dm[i].module->type == NGX_CORE_MODULE) { ngx_log_stderr(0,"dso module not support core module"); return NGX_CONF_ERROR; } - if (dl_m[i].module->major_version != NGX_NUMBER_MAJOR - || dl_m[i].module->minor_version > NGX_NUMBER_MINOR) + if (dm[i].module->major_version != NGX_NUMBER_MAJOR + || dm[i].module->minor_version > NGX_NUMBER_MINOR) { - ngx_log_stderr(0,"Module \"%V\" is not compatible with this " - "version of Tengine (found %ui.%ui, need %ui.%ui)." - " Please contact the vendor for the correct version.", - &dl_m[i].name, dl_m[i].module->major_version, - dl_m[i].module->minor_version, NGX_NUMBER_MAJOR, - NGX_NUMBER_MINOR); + ngx_log_stderr(0, "module \"%V\" is not compatible with this " + "version of nginx (require %ui.%ui, found %ui.%ui).", + &dm[i].name, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR, + dm[i].module->major_version, + dm[i].module->minor_version); return NGX_CONF_ERROR; } - postion = ngx_dso_find_postion(ctx, dl_m[i].name); + postion = ngx_dso_find_postion(ctx, dm[i].name); - ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "dso find postion(%i)", postion); + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, + "dso find postion (%i)", postion); - rv = ngx_dso_insert_module(dl_m[i].module, postion); + rv = ngx_dso_insert_module(dm[i].module, postion); if (rv == NGX_CONF_ERROR) { - ngx_log_stderr(0, "dso find error postion(%i)", postion); + ngx_log_stderr(0, "dso failed to find position (%i)", postion); return rv; } } @@ -509,7 +517,8 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) if (cf->args->nelts != 2 && cf->args->nelts != 3) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of arguments in \"load\" directive"); + "invalid number of arguments " + "in \"load\" directive"); return NGX_CONF_ERROR; } @@ -520,7 +529,8 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of arguments in \"path\" directive"); + "invalid number of arguments " + "in \"path\" directive"); return NGX_CONF_ERROR; } @@ -536,7 +546,8 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of arguments in \"sequence\" directive"); + "invalid number of arguments " + "in \"sequence\" directive"); return NGX_CONF_ERROR; } @@ -547,7 +558,8 @@ ngx_dso_parse(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid number of arguments in \"sequence\" directive"); + "invalid number of arguments " + "in \"sequence\" directive"); return NGX_CONF_ERROR; } @@ -608,7 +620,7 @@ ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (cf->args->nelts != 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown directive \"%s\"", value[0].data); + "unknown directive \"%V\"", &value[0]); return NGX_CONF_ERROR; } @@ -638,7 +650,8 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) for (i = 1; ngx_all_module_names[i]; i++) { len1 = ngx_strlen(ngx_all_module_names[i]); if (len1 == module_name.len - && ngx_strncmp(ngx_all_module_names[i], module_name.data, len1) == 0) + && ngx_strncmp(ngx_all_module_names[i], + module_name.data, len1) == 0) { if (near <= ctx->flag_postion) { ++ctx->flag_postion; @@ -684,7 +697,8 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) len1 = ngx_strlen(ngx_module_names[k]); if (len1 == name[i].len - && ngx_strncmp(name[i].data, ngx_module_names[k], name[i].len) == 0) + && ngx_strncmp(name[i].data, ngx_module_names[k], + name[i].len) == 0) { near = k + 1; break; @@ -702,28 +716,29 @@ ngx_show_dso_modules(ngx_conf_t *cf) ngx_str_t module_name; ngx_uint_t i; ngx_module_t *module; - ngx_dso_module_t *dl_m; + ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; ctx = (ngx_dso_conf_ctx_t *) ngx_get_conf(cf->cycle->conf_ctx, - ngx_dso_module); + ngx_dso_module); if (ctx == NULL) { return; } - dl_m = ctx->modules->elts; + dm = ctx->modules->elts; for (i = 0; i < ctx->modules->nelts; i++) { - if (dl_m[i].name.len == 0) { + if (dm[i].name.len == 0) { continue; } - module_name = dl_m[i].name; - module = dl_m[i].module; + module_name = dm[i].name; + module = dm[i].module; - ngx_log_stderr(0, " %V (shared), nginx dso version (%ui.%ui)", - &module_name, module->major_version, module->minor_version); + ngx_log_stderr(0, " %V (shared, %ui.%ui)", + &module_name, module->major_version, + module->minor_version); } } @@ -735,7 +750,7 @@ ngx_show_dso_directives(ngx_conf_t *cf) ngx_uint_t i; ngx_module_t *module; ngx_command_t *cmd; - ngx_dso_module_t *dl_m; + ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; ctx = (ngx_dso_conf_ctx_t *) ngx_get_conf(cf->cycle->conf_ctx, @@ -745,15 +760,15 @@ ngx_show_dso_directives(ngx_conf_t *cf) return; } - dl_m = ctx->modules->elts; + dm = ctx->modules->elts; for (i = 0; i < ctx->modules->nelts; i++) { - if (dl_m[i].name.len == 0) { + if (dm[i].name.len == 0) { continue; } - module_name = dl_m[i].name; - module = dl_m[i].module; + module_name = dm[i].name; + module = dm[i].module; ngx_log_stderr(0, "%V (shared):", &module_name); From e80b4c2d443a3ec572120a19d75d5d177558f746 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Mon, 3 Sep 2012 17:17:22 +0800 Subject: [PATCH 26/36] 1 fix code style. 2 fix core dump when load failed. --- auto/install | 17 ++++++ auto/make | 8 +-- contrib/dso.in | 2 +- docs/modules/ngx_dso_module.md | 6 +- docs/modules/ngx_dso_module_cn.md | 9 ++- src/core/ngx_dso_module.c | 97 ++++++++++++++++++------------- 6 files changed, 90 insertions(+), 49 deletions(-) diff --git a/auto/install b/auto/install index c294b3aee0..51e1730eef 100644 --- a/auto/install +++ b/auto/install @@ -110,6 +110,20 @@ END if test -n "$NGX_SHARED_MODULES"; then + cat << END >> $NGX_MAKEFILE + +dso_install: all +END + + for ngx_dso_module in $NGX_DSO_ALL_TARGETS + do + cat << END >> $NGX_MAKEFILE + + cp $ngx_dso_module \$(DESTDIR)$NGX_DSO_PATH + +END + done + cat << END >> $NGX_MAKEFILE install: all \ @@ -241,6 +255,9 @@ build: install: \$(MAKE) -f $NGX_MAKEFILE install +dso_install: + \$(MAKE) -f $NGX_MAKEFILE dso_install + upgrade: $NGX_SBIN_PATH -t diff --git a/auto/make b/auto/make index 526d67a2c5..c2d38ed86f 100644 --- a/auto/make +++ b/auto/make @@ -24,7 +24,7 @@ mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \ $NGX_OBJS/src/mail \ $NGX_OBJS/src/misc \ $NGX_OBJS/src/proc \ - $NGX_OBJS/dso_modules + $NGX_OBJS/modules ngx_objs_dir=$NGX_OBJS$ngx_regex_dirsep @@ -210,7 +210,7 @@ ngx_link=${CORE_LINK:+`echo $CORE_LINK \ for ngx_shared_modules in $NGX_SHARED_MODULES do - NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}" + NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}" done if test -n "$NGX_DSO_ALL_TARGETS"; then @@ -523,8 +523,8 @@ END cat << END >> $NGX_MAKEFILE -$NGX_OBJS${ngx_dirsep}dso_modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}: $ngx_dso_deps$ngx_spacer - \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/dso_modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib +$NGX_OBJS${ngx_dirsep}modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}: $ngx_dso_deps$ngx_spacer + \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib $ngx_rcc ${ngx_long_end} END diff --git a/contrib/dso.in b/contrib/dso.in index f0685902e9..9a1de3cf5c 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -27,7 +27,7 @@ do case "$option" in --help) help=yes ;; - --h) help=yes ;; + -h) help=yes ;; --prefix=) NGX_DSO_PREFIX="!" ;; --prefix=*) NGX_DSO_PREFIX="$value" ;; diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index d7bc2f7aaa..f6efe61f97 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -61,7 +61,7 @@ It will load conf/module_stubs file and define order of module(via module\_stub load ------------------------ -**Syntax**: *load [module_name] [module_path]* +**Syntax**: *load [module_name] \[module_path]* **Default**: *none* @@ -79,8 +79,10 @@ The order in which the module is searched is as follows: Example: load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; + load ngx_http_test_module; + load ngx_http_test2_module.so; -It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so. +It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so. and will load ngx\_http\_test_module and ngx\_http\_test2\_module form ngx\_http\_test\_module.so and ngx\_http\_test2\_module.so module_stub diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md index 7f296fd247..6661079ae4 100644 --- a/docs/modules/ngx_dso_module_cn.md +++ b/docs/modules/ngx_dso_module_cn.md @@ -10,6 +10,8 @@ * 如果你想要编译官方模块为动态模块,你需要在configure的时候加上类似这样的指令(--with-http\_xxx_module),./configure --help可以看到更多的细节. +* 如果只想要安装官方模块为动态模块(不安装Nginx),那么就只需要configure之后,执行 make dso_install命令. + * 如果需要编译第三方模块,可以使用dso\_tools工具(详细使用方法请参加dso_tools章节). * 动态加载模块的个数限制为128个. @@ -66,13 +68,13 @@ include命令主要用于指定一个文件,这个文件里面包含了对应 load ------------------------ -**Syntax**: *load module_name [module_path]* +**Syntax**: *load [module_name] \[module_path]* **Default**: *none* **Context**: *dso* -load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。其中module\_path是可选的,如果没有module\_path参数,那么默认path是 $(modulename).so. +load命令用于在指定的路径(module\_path),将指定的模块(module\_name)动态加载到Nginx中。其中module\_path和module\_name可以只写一个,如果没有module\_path参数,那么默认path是 $(modulename).so.如果没有module\_name参数,那么默认name就是module\_path删除掉".so"后缀. 对于module\_path的路径查找,这里是严格按照下面的顺序的 @@ -84,8 +86,9 @@ load命令用于在指定的路径(module\_path),将指定的模块(module\_name load ngx_http_empty_gif_module ngx_http_empty_gif_module.so; load ngx_http_test_module; + load ngx_http_test2_module.so; -将会从ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。以及从ngx\_http\_test\_module.so加载ngx\_http\_test\_module模块. +将会从ngx\_http\_empty\_gif\_module.so.加载empty\_gif模块。以及从ngx\_http\_test\_module.so加载ngx\_http\_test\_module模块.第三条指令是从ngx\_http\_test2\_module.so加载ngx\_http\_test2\_module模块. module_stub ------------- diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 2d9ba6c469..8eeade3acf 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -22,7 +22,7 @@ typedef struct { typedef struct { ngx_str_t name; ngx_str_t path; - void *dl_handle; + void *handle; ngx_module_t *module; } ngx_dso_module_t; @@ -217,30 +217,37 @@ ngx_dso_cleanup(void *data) ngx_cycle_t *cycle = data; ngx_uint_t i; + ngx_cycle_t *clean_cycle; ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; if (cycle != ngx_cycle) { - if (cycle->conf_ctx) { - ctx = (ngx_dso_conf_ctx_t *) - cycle->conf_ctx[ngx_dso_module.index]; + clean_cycle = cycle; + ngx_memcpy(ngx_modules, ngx_old_modules, + sizeof(ngx_module_t *) * NGX_DSO_MAX); + } else { + if (cycle->old_cycle == NULL) { + return; + } + clean_cycle = cycle->old_cycle; + } - if (ctx != NULL) { - dm = ctx->modules->elts; + if (clean_cycle->conf_ctx) { + ctx = (ngx_dso_conf_ctx_t *) + clean_cycle->conf_ctx[ngx_dso_module.index]; - for (i = 0; i < ctx->modules->nelts; i++) { - if (dm[i].name.len == 0) { - continue; - } + if (ctx != NULL) { + dm = ctx->modules->elts; - dlclose(dm[i].dl_handle); + for (i = 0; i < ctx->modules->nelts; i++) { + if (dm[i].name.len == 0 || dm[i].handle == NULL) { + continue; } + + dlclose(dm[i].handle); } } - - ngx_memcpy(ngx_modules, ngx_old_modules, - sizeof(ngx_module_t *) * NGX_DSO_MAX); } } @@ -345,28 +352,23 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, static ngx_int_t ngx_dso_open(ngx_dso_module_t *dm) { - void *handle; ngx_str_t name, path; - ngx_module_t *module; name = dm->name; path = dm->path; - handle = dlopen((char *) path.data, RTLD_NOW | RTLD_GLOBAL); - if (handle == NULL) { - ngx_log_stderr(errno, "load module failed %s", dlerror()); + dm->handle = dlopen((char *) path.data, RTLD_NOW | RTLD_GLOBAL); + if (dm->handle == NULL) { + ngx_log_stderr(errno, "load module \" %V \" failed (%s)", &path, dlerror()); return NGX_ERROR; } - module = dlsym(handle, (const char *) name.data); - if (module == NULL) { - ngx_log_stderr(errno, "Can't locate sym in module(%V)", &name); + dm->module = dlsym(dm->handle, (const char *) name.data); + if (dm->module == NULL) { + ngx_log_stderr(errno, "can't locate symbol in module (%V)", &name); return NGX_ERROR; } - dm->dl_handle = handle; - dm->module = module; - return NGX_OK; } @@ -402,7 +404,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; ngx_int_t rc; - ngx_str_t *value, module_path; + ngx_str_t *value, module_path, module_name; ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; @@ -417,24 +419,40 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } if (cf->args->nelts == 3) { - rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, - &value[1], &value[2]); + module_name = value[1]; module_path = value[2]; } else { /* cf->args->nelts == 2 */ - module_path.len = value[1].len + sizeof(NGX_DSO_EXT); - module_path.data = ngx_pcalloc(cf->pool, module_path.len); - if (module_path.data == NULL) { - return NGX_CONF_ERROR; - } + if (value[1].len > 3 && + value[1].data[value[1].len - 3] == '.' && + value[1].data[value[1].len - 2] == 's' && + value[1].data[value[1].len - 1] == 'o') + { + module_path = value[1]; + module_name.data = ngx_pcalloc(cf->pool, value[1].len - 2); + if (module_path.data == NULL) { + return NGX_CONF_ERROR; + } - p = ngx_cpymem(module_path.data, value[1].data, value[1].len); - ngx_memcpy(p, NGX_DSO_EXT, sizeof(NGX_DSO_EXT) - 1); - rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, - &value[1], &module_path); + module_name.len = value[1].len - 3; + ngx_memcpy(module_name.data, module_path.data, module_name.len); + } else { + + module_path.len = value[1].len + sizeof(NGX_DSO_EXT); + module_path.data = ngx_pcalloc(cf->pool, module_path.len); + if (module_path.data == NULL) { + return NGX_CONF_ERROR; + } + + p = ngx_cpymem(module_path.data, value[1].data, value[1].len); + ngx_memcpy(p, NGX_DSO_EXT, sizeof(NGX_DSO_EXT) - 1); + module_name = value[1]; + } } + rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, + &value[1], &module_path); if (rc == NGX_DECLINED) { return NGX_CONF_OK; } @@ -444,8 +462,9 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - dm->name = value[1]; + dm->name = module_name; dm->path = module_path; + dm->handle = NULL; return NGX_CONF_OK; } @@ -591,7 +610,7 @@ ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, return NGX_CONF_ERROR; } - ngx_sprintf(file.data, "%V", name); + ngx_sprintf(file.data, "%V%Z", name); if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { return NGX_CONF_ERROR; From 94ffb5042ed476da059927b6163068c0c41b6645 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 4 Sep 2012 15:55:42 +0800 Subject: [PATCH 27/36] 1 modify document. 2 fix code style. --- auto/init | 2 +- auto/options | 27 +++++----- contrib/dso.in | 20 ++++---- docs/modules/ngx_dso_module.md | 84 ++++++++++++++++++------------- docs/modules/ngx_dso_module_cn.md | 69 ++++++++++++++----------- src/core/ngx_dso_module.c | 17 ++++--- 6 files changed, 125 insertions(+), 94 deletions(-) diff --git a/auto/init b/auto/init index 87d4c2c8c8..ca42e17993 100644 --- a/auto/init +++ b/auto/init @@ -17,7 +17,7 @@ NGX_ERR=$NGX_OBJS/autoconf.err MAKEFILE=$NGX_OBJS/Makefile #dso -NGX_DSO_COMPILE=$NGX_OBJS/dso_tools +NGX_DSO_COMPILE=$NGX_OBJS/dso_tool NGX_MODULE_STUBS=$NGX_OBJS/module_stubs NGX_PCH= diff --git a/auto/options b/auto/options index c441b1a822..a3fba0e11e 100644 --- a/auto/options +++ b/auto/options @@ -149,7 +149,7 @@ NGX_HTTP_SCGI_TEMP_PATH= HTTP_CACHE=YES HTTP_CHARSET=YES HTTP_GZIP=YES -HTTP_SSL=NO +HTTP_SSL=YES HTTP_SSI=YES HTTP_POSTPONE=NO HTTP_REALIP=NO @@ -192,12 +192,12 @@ HTTP_GZIP_STATIC=NO HTTP_UPSTREAM_IP_HASH=YES HTTP_FOOTER=YES HTTP_USER_AGENT=YES -HTTP_UPSTREAM_CHECK=NO +HTTP_UPSTREAM_CHECK=YES HTTP_UPSTREAM_LEAST_CONN=YES HTTP_UPSTREAM_KEEPALIVE=YES # STUB -HTTP_STUB_STATUS=NO +HTTP_STUB_STATUS=YES #shared module HTTP_XSLT_SHARED=NO @@ -289,7 +289,7 @@ NGX_LIBATOMIC=NO NGX_CPU_CACHE_LINE= -NGX_SYSLOG=NO +NGX_SYSLOG=YES NGX_POST_CONF_MSG= @@ -338,7 +338,8 @@ do --with-file-aio) NGX_FILE_AIO=YES ;; --with-ipv6) NGX_IPV6=YES ;; - --with-syslog) NGX_SYSLOG=YES ;; + + --without-syslog) NGX_SYSLOG=NO ;; --without-dso) NGX_DSO=NO ;; @@ -352,7 +353,6 @@ do --http-uwsgi-temp-path=*) NGX_HTTP_UWSGI_TEMP_PATH="$value" ;; --http-scgi-temp-path=*) NGX_HTTP_SCGI_TEMP_PATH="$value" ;; - --with-http_ssl_module) HTTP_SSL=YES ;; --with-http_realip_module) HTTP_REALIP=YES ;; --with-http_addition_module) HTTP_ADDITION=YES HTTP_ADDITION_SHARED=NO ;; @@ -381,7 +381,6 @@ do --with-http_degradation_module) HTTP_DEGRADATION=YES ;; --with-http_sysguard_module) HTTP_SYSGUARD=YES HTTP_SYSGUARD_SHARED=NO ;; - --with-http_upstream_check_module) HTTP_UPSTREAM_CHECK=YES ;; --with-http_addition_module=shared) HTTP_ADDITION_SHARED=YES HTTP_ADDITION=NO ;; @@ -453,6 +452,7 @@ do --without-http_charset_module) HTTP_CHARSET=NO ;; --without-http_gzip_module) HTTP_GZIP=NO ;; --without-http_ssi_module) HTTP_SSI=NO ;; + --without-http_ssl_module) HTTP_SSL=NO ;; --without-http_userid_module) HTTP_USERID=NO ;; --without-http_footer_module) HTTP_FOOTER=NO ;; --without-http_access_module) HTTP_ACCESS=NO ;; @@ -481,6 +481,7 @@ use the \"--without-http_limit_conn_module\" option instead" --without-http_browser_module) HTTP_BROWSER=NO ;; --without-http_user_agent_module) HTTP_USER_AGENT=NO ;; --without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;; + --without-http_upstream_check_module) HTTP_UPSTREAM_CHECK=NO ;; --without-http_upstream_least_conn_module) HTTP_UPSTREAM_LEAST_CONN=NO ;; --without-http_upstream_keepalive_module) HTTP_UPSTREAM_KEEPALIVE=NO ;; @@ -498,7 +499,7 @@ use the \"--without-http_limit_conn_module\" option instead" --with-lua-lib=*) LUA_LIB="$value" ;; # STUB - --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;; + --without-http_stub_status_module) HTTP_STUB_STATUS=NO ;; --with-mail) MAIL=YES ;; --with-mail_ssl_module) MAIL_SSL=YES ;; @@ -595,11 +596,11 @@ cat << END --with-file-aio enable file AIO support --with-ipv6 enable IPv6 support - --with-syslog enable syslog logging + + --without-syslog disable syslog logging --without-dso disable dso module load - --with-http_ssl_module enable ngx_http_ssl_module --with-http_realip_module enable ngx_http_realip_module --with-http_addition_module enable ngx_http_addition_filter_module --with-http_xslt_module enable ngx_http_xslt_filter_module @@ -616,8 +617,6 @@ cat << END --with-http_secure_link_module enable ngx_http_secure_link_module --with-http_degradation_module enable ngx_http_degradation_module --with-http_sysguard_module enable ngx_http_sysguard_module - --with-http_stub_status_module enable ngx_http_stub_status_module - --with-http_upstream_check_module enable ngx_http_upstream_check_module --with-http_addition_module=shared enable ngx_http_addition_filter_module (shared) --with-http_xslt_module=shared enable ngx_http_xslt_filter_module (shared) @@ -670,6 +669,7 @@ cat << END --without-http_charset_module disable ngx_http_charset_filter_module --without-http_gzip_module disable ngx_http_gzip_filter_module --without-http_ssi_module disable ngx_http_ssi_module + --without-http_ssl_module disable ngx_http_ssl_module --without-http_userid_module disable ngx_http_userid_filter_module --without-http_footer_filter_module disable ngx_http_footer_filter_module @@ -691,9 +691,12 @@ cat << END --without-http_limit_req_module disable ngx_http_limit_req_module --without-http_empty_gif_module disable ngx_http_empty_gif_module --without-http_browser_module disable ngx_http_browser_module + --without-http_upstream_check_module + disable ngx_http_upstream_check_module --without-http_upstream_ip_hash_module disable ngx_http_upstream_ip_hash_module --without-http_user_agent_module disable ngx_http_user_agent_module + --without-http_stub_status_module disable ngx_http_stub_status_module --with-http_perl_module enable ngx_http_perl_module --with-perl_modules_path=PATH set Perl modules path diff --git a/contrib/dso.in b/contrib/dso.in index 9a1de3cf5c..cf51531eb9 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -27,14 +27,17 @@ do case "$option" in --help) help=yes ;; - -h) help=yes ;; + -h) help=yes ;; - --prefix=) NGX_DSO_PREFIX="!" ;; - --prefix=*) NGX_DSO_PREFIX="$value" ;; + --dst=) NGX_DSO_PREFIX="!" ;; + --dst=*) NGX_DSO_PREFIX="$value" ;; + -d=*) NGX_DSO_PREFIX="$value" ;; --add-module=*) NGX_DSO_ADDONS="$NGX_DSO_ADDONS $value" ;; + -a=*) NGX_DSO_ADDONS="$NGX_DSO_ADDONS $value" ;; --with-nginx-source=*) NGX_SOURCE_HOME="$value" ;; + -s=*) NGX_SOURCE_HOME="$value" ;; *) echo "$0: error: invalid option \"$option\"" @@ -51,13 +54,10 @@ if [ $help = yes ]; then cat << END - --help print this message - - --prefix=PATH set module installation prefix - - --add-module=PATH external module which will be compiled - - --with-nginx-source=NGX_SOURCE_HOM set nginx source path +-h, --help display this help and exit +-d, --dst=PATH set module installation prefix +-a, --add-module=PATH external module which will be compiled +-s, --with-nginx-source=SOURCE set nginx source root END diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index f6efe61f97..359734189a 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -1,18 +1,18 @@ Name ==== -* Dynamic Module Loading Support (DSO) +* Dynamic Module Loading Support (**DSO**) Description =========== -* You can choose which functionalities to include by selecting a set of modules. A module will be compiled as a Dynamic Shared Object (DSO) that exists from the main Tengine binary. So you don't have to recompile Tengine when you want to add or enable a functionality to it. +* You can choose which functionalities to include by selecting a set of modules. A module will be compiled as a Dynamic Shared Object (**DSO**) that exists from the main tengine binary. So you don't have to recompile tengine when you want to add or enable a functionality to it. -* If you want to enable an standard module, you should enable it via configure's option while compiling Tengine, for instance, --with-http\_example_module or --with-http\_example_module=shared. Run ./configure --help for more details. +* If you want to enable a standard module, you can enable it via configure's option while compiling tengine, for instance, --with-http\_example_module or --with-http\_example\_module=shared. Run *./configure --help* for more details. * The maximum of dynamic loaded modules is limited to 128. -* For now, only HTTP modules are dynamic-loaded supported. +* For now, only HTTP modules can be dynamic-loaded. * This feature is tested only on Linux/FreeBSD/MacOS. @@ -23,15 +23,8 @@ Example worker_processes 1; dso { - path /home/nginx-dso/module; - load ngx_http_lua_module.so; - load ngx_http_access_module.so; - load ngx_http_flv_module.so; load ngx_http_memcached_module.so; - load ngx_http_sub_filter_module.so; - load ngx_http_addition_filter_module.so; - load ngx_http_footer_filter_module.so; } events { @@ -41,22 +34,24 @@ Example Directives ========== -include -------------- -**Syntax**: *include file_name* +path +------------------------ -**Default**: *none* +**Syntax**: *path path* + +**Default**: *NGX\_PREFIX/modules* **Context**: *dso* -Specifies a file contain order of module(via module_stub directive). +This directive specifies the default path (prefix) of DSO modules. Example: - - include module_stubs -It will load conf/module_stubs file and define order of module(via module\_stub directive). + path /home/dso/module; + +Sets the default path to */home/dso/module*. + load ------------------------ @@ -67,7 +62,7 @@ load **Context**: *dso* -The load directive loads the object file or library file and adds the specified module to the list of active modules. module\_name is the name of the DSO module, and module\_path is the path of the DSO module. +The **load** directive loads the shared object file and enables the module. *module\_name* is the name of the DSO module, and *module\_path* is the path of the DSO module. The order in which the module is searched is as follows: @@ -82,7 +77,7 @@ Example: load ngx_http_test_module; load ngx_http_test2_module.so; -It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so. and will load ngx\_http\_test_module and ngx\_http\_test2\_module form ngx\_http\_test\_module.so and ngx\_http\_test2\_module.so +It will load the ngx\_http\_empty\_gif\_module from ngx\_http\_empty\_gif\_module.so, ngx\_http\_test_module and ngx\_http\_test2\_module from ngx\_http\_test\_module.so and ngx\_http\_test2\_module.so. module_stub @@ -95,7 +90,7 @@ module_stub **Context**: *dso* -This directive can insert a module into Nginx's module array in order (see conf/module_stubs for more details). Note it will change the module runtime order. This directive does not need to be used in most cases. +This directive can insert a module into nginx's module array in order (see conf/module\_stubs for more details). Note it will change the module runtime order. This directive does not need to be used in most cases. Don't use it or edit the *conf/module\_stubs* file unless you know what you are doing. Example: @@ -112,37 +107,56 @@ Example: module_stub ngx_http_addition_filter_module; module_stub ngx_http_my_filter_module; -It will insert ngx\_http\_my\_filter\_module before ngx\_http\_addition\_filter\_module. +It will place ngx\_http\_my\_filter\_module before ngx\_http\_addition\_filter\_module. -path ------------------------- +include +------------- -**Syntax**: *path path* +**Syntax**: *include file_name* **Default**: *none* **Context**: *dso* -This directive specifies the default path (prefix) for DSO modules. +Specifies a file which contains the module stubs (via the **module_stub** directive). Example: + + include module_stubs; - path /home/dso/module; - -Sets the default path to /home/dso/module. +It will load conf/module_stubs and define the loading order of the modules (via the **module\_stub** directive). -Tools +How to compile a module =========== -dso_tools +Standard module +------------------------ +If you want to enable a standard module after you compiled and installed tengine, you can take these steps as following. + +* enable the standard module you wanted in shared mode, for example: + + $ ./configure --with-http_sub_module=shared + +* compile it: + + $ make + +* install the shared object (*.so): + + $ make dso_install + +It will copy the *.so files to the destination, or you can copy the files you want (in objs/modules) manually to the modules directory. + +Third party module ------------------------ -This tools can be used to compile a third party nginx module. +You can use the __dso_tool__ located in the directory of nginx binary to compile a third party module. Example: - ./dso_tools --add-module=/home/dso/lua-nginx-module + ./dso_tool --add-module=/home/dso/lua-nginx-module + +It will compile the ngx_lua module into a shared object, and install it to the default module path. You can specify the destination directory you want install to by the **--dst** option. -It will compile the ngx_lua module into a shared object, and install it to the default module path. diff --git a/docs/modules/ngx_dso_module_cn.md b/docs/modules/ngx_dso_module_cn.md index 6661079ae4..0bfe8c93d9 100644 --- a/docs/modules/ngx_dso_module_cn.md +++ b/docs/modules/ngx_dso_module_cn.md @@ -12,7 +12,7 @@ * 如果只想要安装官方模块为动态模块(不安装Nginx),那么就只需要configure之后,执行 make dso_install命令. -* 如果需要编译第三方模块,可以使用dso\_tools工具(详细使用方法请参加dso_tools章节). +* 如果需要编译第三方模块,可以使用dso\_tools工具(详细使用方法请参加dso_tool章节). * 动态加载模块的个数限制为128个. @@ -29,14 +29,8 @@ worker_processes 1; dso { - path /home/nginx-dso/module/; - load ngx_http_lua_module; - load ngx_http_access_module ngx_http_access_module.so; - load ngx_http_flv_module ngx_http_flv_module.so; - load ngx_http_memcached_module ngx_http_memcached_module.so; - load ngx_http_sub_filter_module ngx_http_sub_filter_module.so; - load ngx_http_addition_filter_module ngx_http_addition_filter_module.so; - load ngx_http_footer_filter_module ngx_http_footer_filter_module.so; + load ngx_http_lua_module.so; + load ngx_http_memcached_module.so; } events { @@ -47,22 +41,22 @@ 指令 ========== -include -------------- +path +------------------------ -**Syntax**: *include file_name* +**Syntax**: *path path* **Default**: *none* **Context**: *dso* -include命令主要用于指定一个文件,这个文件里面包含了对应模块顺序(module_stub指令),有关于module\_stub指令可以看下面的module\_stubs部分. +path 主要是设置默认的动态模块加载路径。 例子: - include module_stubs - -将会加载conf/module_stubs这个文件,这个文件主要是由(module_stub指令组成). + path /home/dso/module/; + +设置默认的动态模块加载路径为/home/dso/module/. load @@ -120,34 +114,53 @@ module_stub 上面这个例子将会插入my\_filter模块到addition\_filter之前执行。 -path ------------------------- +include +------------- -**Syntax**: *path path* +**Syntax**: *include file_name* **Default**: *none* **Context**: *dso* -path 主要是设置默认的动态模块加载路径。 +include命令主要用于指定一个文件,这个文件里面包含了对应模块顺序(module_stub指令),有关于module\_stub指令可以看下面的module\_stubs部分. 例子: - path /home/dso/module/; - -设置默认的动态模块加载路径为/home/dso/module/. + include module_stubs + +将会加载conf/module_stubs这个文件,这个文件主要是由(module_stub指令组成). -工具 +如何编译动态模块 =========== -dso_tools +官方模块 +------------------------ + +如果你想要在安装完Tengine之后,编译官方模块为动态模块,那么你需要按照如下的步骤: + +* 在configure的时候打开你想要编译的模块. + + $ ./configure --with-http_sub_module=shared + +* 编译它. + + $ make + +* 安装动态模块. + + $ make dso_install + +它将会复制动态库文件到你的动态模块目录,或者你也可以手工拷贝动态模块文件(文件是在objs/modules)到你想要加载的目录. + +第三方模块 ------------------------ -这个工具主要是用来编译第三方模块为动态模块. +你能够使用dso_tool(在Nginx安装目录的sbin下)这个工具来编译第三方模块. 例子: - ./dso_tools --add-module=/home/dso/lua-nginx-module + ./dso_tool --add-module=/home/dso/lua-nginx-module -将会编译ngx\_lua模块为动态库,然后安装到默认的模块路径. +将会编译ngx\_lua模块为动态库,然后安装到默认的模块路径.如果你想要安装到指定位置,那么需要指定--dst选项(更多的选项请使用dso_tool -h查看). diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 8eeade3acf..4c38a82d81 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -226,6 +226,7 @@ ngx_dso_cleanup(void *data) clean_cycle = cycle; ngx_memcpy(ngx_modules, ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); + } else { if (cycle->old_cycle == NULL) { return; @@ -359,7 +360,7 @@ ngx_dso_open(ngx_dso_module_t *dm) dm->handle = dlopen((char *) path.data, RTLD_NOW | RTLD_GLOBAL); if (dm->handle == NULL) { - ngx_log_stderr(errno, "load module \" %V \" failed (%s)", &path, dlerror()); + ngx_log_stderr(errno, "load module \"%V\" failed (%s)", &path, dlerror()); return NGX_ERROR; } @@ -437,8 +438,8 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) module_name.len = value[1].len - 3; ngx_memcpy(module_name.data, module_path.data, module_name.len); - } else { + } else { module_path.len = value[1].len + sizeof(NGX_DSO_EXT); module_path.data = ngx_pcalloc(cf->pool, module_path.len); if (module_path.data == NULL) { @@ -732,7 +733,7 @@ ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) void ngx_show_dso_modules(ngx_conf_t *cf) { - ngx_str_t module_name; + ngx_str_t name; ngx_uint_t i; ngx_module_t *module; ngx_dso_module_t *dm; @@ -752,11 +753,11 @@ ngx_show_dso_modules(ngx_conf_t *cf) continue; } - module_name = dm[i].name; + name = dm[i].name; module = dm[i].module; ngx_log_stderr(0, " %V (shared, %ui.%ui)", - &module_name, module->major_version, + &name, module->major_version, module->minor_version); } } @@ -765,7 +766,7 @@ ngx_show_dso_modules(ngx_conf_t *cf) void ngx_show_dso_directives(ngx_conf_t *cf) { - ngx_str_t module_name; + ngx_str_t name; ngx_uint_t i; ngx_module_t *module; ngx_command_t *cmd; @@ -786,10 +787,10 @@ ngx_show_dso_directives(ngx_conf_t *cf) continue; } - module_name = dm[i].name; + name = dm[i].name; module = dm[i].module; - ngx_log_stderr(0, "%V (shared):", &module_name); + ngx_log_stderr(0, "%V (shared):", &name); cmd = module->commands; if(cmd == NULL) { From 02c1c817a0cb6be15750d609794cf63fd73dabbf Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 4 Sep 2012 17:56:51 +0800 Subject: [PATCH 28/36] 1 compatible with nginx config option. --- auto/options | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/auto/options b/auto/options index a3fba0e11e..7ca00266f8 100644 --- a/auto/options +++ b/auto/options @@ -339,6 +339,7 @@ do --with-file-aio) NGX_FILE_AIO=YES ;; --with-ipv6) NGX_IPV6=YES ;; + --with-syslog) NGX_SYSLOG=YES ;; --without-syslog) NGX_SYSLOG=NO ;; --without-dso) NGX_DSO=NO ;; @@ -353,6 +354,7 @@ do --http-uwsgi-temp-path=*) NGX_HTTP_UWSGI_TEMP_PATH="$value" ;; --http-scgi-temp-path=*) NGX_HTTP_SCGI_TEMP_PATH="$value" ;; + --with-http_ssl_module) HTTP_SSL=YES ;; --with-http_realip_module) HTTP_REALIP=YES ;; --with-http_addition_module) HTTP_ADDITION=YES HTTP_ADDITION_SHARED=NO ;; @@ -381,6 +383,7 @@ do --with-http_degradation_module) HTTP_DEGRADATION=YES ;; --with-http_sysguard_module) HTTP_SYSGUARD=YES HTTP_SYSGUARD_SHARED=NO ;; + --with-http_upstream_check_module) HTTP_UPSTREAM_CHECK=YES ;; --with-http_addition_module=shared) HTTP_ADDITION_SHARED=YES HTTP_ADDITION=NO ;; @@ -499,6 +502,7 @@ use the \"--without-http_limit_conn_module\" option instead" --with-lua-lib=*) LUA_LIB="$value" ;; # STUB + --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;; --without-http_stub_status_module) HTTP_STUB_STATUS=NO ;; --with-mail) MAIL=YES ;; From 9bf0f59f7503c21e2d68dfead19f467dd693c75e Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 4 Sep 2012 19:28:47 +0800 Subject: [PATCH 29/36] modify test nginx. --- tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm index b14ef106a2..d1992701ad 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm @@ -307,7 +307,7 @@ sub include_dso_modules ($) { my $dso_compile_script; - $dso_compile_script = $dso_compile_dir . "dso_tools"; + $dso_compile_script = $dso_compile_dir . "dso_tool"; for my $module (@modules) { my ($dir, $name) = @$module; From 7a9f8d0dd27f6c743a76a84512081fa341bb7600 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 11:55:42 +0800 Subject: [PATCH 30/36] 1 modify dso_tool 2 delete some dead code --- auto/make | 2 +- contrib/dso.in | 20 +++++++++++++------ .../test-nginx/lib/Test/Nginx/Util.pm | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/auto/make b/auto/make index c2d38ed86f..3db45e06c1 100644 --- a/auto/make +++ b/auto/make @@ -620,11 +620,11 @@ ngx_spacer='$ngx_spacer' ngx_objext='$ngx_objext' ngx_regex_cont='$ngx_regex_cont' ngx_binout='$ngx_binout' -ngx_binout='$ngx_binout' NGX_DSO_PATH=$NGX_DSO_PATH NGX_AUTOCONF_ERR=$NGX_AUTOCONF_ERR NGX_AUTOTEST=$NGX_AUTOTEST NGX_AUTO_CONFIG_H=$NGX_AUTO_CONFIG_H +NGX_CONFIGURE='$NGX_CONFIGURE' END diff --git a/contrib/dso.in b/contrib/dso.in index cf51531eb9..0cbd86bbc0 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -36,7 +36,7 @@ do --add-module=*) NGX_DSO_ADDONS="$NGX_DSO_ADDONS $value" ;; -a=*) NGX_DSO_ADDONS="$NGX_DSO_ADDONS $value" ;; - --with-nginx-source=*) NGX_SOURCE_HOME="$value" ;; + --nginx-source=*) NGX_SOURCE_HOME="$value" ;; -s=*) NGX_SOURCE_HOME="$value" ;; *) @@ -47,17 +47,19 @@ do done -NGX_CONFIGURE="$opt" +if ! test -n "$option" ; then + help=yes +fi if [ $help = yes ]; then cat << END --h, --help display this help and exit --d, --dst=PATH set module installation prefix --a, --add-module=PATH external module which will be compiled --s, --with-nginx-source=SOURCE set nginx source root + -h, --help display this help and exit + -d, --dst=PATH set module installation prefix + -a, --add-module=PATH external module which will be compiled + -s, --nginx-source=SOURCE set nginx source root END @@ -196,6 +198,12 @@ END if test -n "$NGX_DSO_ADDONS"; then + # compile nginx + cd $NGX_SOURCE_HOME + ./configure $NGX_CONFIGURE + make + cd - + echo configuring additional modules for dai in $DSO_ALL_INCS diff --git a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm index d1992701ad..5c1e681a9c 100644 --- a/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm +++ b/tests/test-nginx/test-nginx/lib/Test/Nginx/Util.pm @@ -316,7 +316,7 @@ sub include_dso_modules ($) { if (-d $dir) { $modules_dir = $DsoDir; - system("$dso_compile_script --prefix=$DsoDir --add-module=\"$dir\"") == 0 + system("$dso_compile_script --dst=$DsoDir --add-module=\"$dir\"") == 0 or die "Can't compile dso module $dir"; } else { From 375f1ff3a76ab8fb78c5a692e309414b63f056f3 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 17:11:47 +0800 Subject: [PATCH 31/36] 1 fix compile error in Darwin. 2 delete some dead code. --- auto/cc/conf | 1 - auto/make | 16 ++++++++++------ auto/modules | 5 ++++- auto/os/conf | 2 ++ contrib/dso.in | 1 - src/core/ngx_dso_module.c | 7 ++----- tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm | 2 +- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/auto/cc/conf b/auto/cc/conf index 4e7f6bde67..d0b0d228aa 100644 --- a/auto/cc/conf +++ b/auto/cc/conf @@ -11,7 +11,6 @@ ngx_objout="-o " ngx_binout="-o " ngx_objext="o" ngx_binext= -ngx_soext=".so" ngx_long_start= ngx_long_end= diff --git a/auto/make b/auto/make index 3db45e06c1..0ba44837eb 100644 --- a/auto/make +++ b/auto/make @@ -210,7 +210,7 @@ ngx_link=${CORE_LINK:+`echo $CORE_LINK \ for ngx_shared_modules in $NGX_SHARED_MODULES do - NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}" + NGX_DSO_ALL_TARGETS="$NGX_DSO_ALL_TARGETS $NGX_OBJS${ngx_dirsep}modules${ngx_dirsep}${ngx_shared_modules}${NGX_SOEXT}" done if test -n "$NGX_DSO_ALL_TARGETS"; then @@ -464,6 +464,11 @@ if [ $NGX_DSO = YES ] ; then ngx_dso_link_flag=" -shared " ngx_dso_index=2 + case "$NGX_PLATFORM" in + Darwin:*) + ngx_dso_link_flag="$ngx_dso_link_flag -undefined dynamic_lookup " + esac + ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)" for ngx_shared_modules in $NGX_SHARED_MODULES @@ -523,8 +528,8 @@ END cat << END >> $NGX_MAKEFILE -$NGX_OBJS${ngx_dirsep}modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}: $ngx_dso_deps$ngx_spacer - \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/modules${ngx_dirsep}${ngx_shared_modules}${ngx_soext}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib +$NGX_OBJS${ngx_dirsep}modules${ngx_dirsep}${ngx_shared_modules}${NGX_SOEXT}: $ngx_dso_deps$ngx_spacer + \$(LINK)${ngx_dso_link_flag} ${ngx_long_start}${ngx_binout} $NGX_OBJS/modules${ngx_dirsep}${ngx_shared_modules}${NGX_SOEXT}$ngx_long_cont$ngx_dso_objs$ngx_libs$ngx_dso_link $ngx_dso_feture_lib $ngx_rcc ${ngx_long_end} END @@ -591,11 +596,11 @@ END #Copyright (C) 2010-2012 Alibaba Group Holding Limited -ngx_soext='.so' +ngx_soext='$NGX_SOEXT' CC=$CC CFLAGS='$CFLAGS -fPIC' CPP='$CPP' -LINK='$LINK -fPIC -shared' +LINK='$LINK -fPIC $ngx_dso_link_flag' CORE_LIBS='$CORE_LIBS' @@ -634,6 +639,5 @@ END -e "s|%%HTTP_DEPS%%|'$http_deps_temp'|g" \ -e "s|%%HTTP_INCS%%|'$http_incs_temp'|g" \ -e "s|%%NGX_SOURCE_HOME%%|`pwd`|g" \ - -e "s|%%ngx_soext%%|'\.so'|g" \ contrib/dso.in >> $NGX_DSO_COMPILE fi diff --git a/auto/modules b/auto/modules index 64965922ff..94bb6b8481 100644 --- a/auto/modules +++ b/auto/modules @@ -65,6 +65,7 @@ if [ $NGX_DSO = YES ] ; then have=NGX_DSO . auto/have have=NGX_DSO_MAX value="$NGX_DSO_MAX" . auto/define have=NGX_DSO_PATH value="\"$NGX_DSO_PATH\"" . auto/define + have=NGX_SOEXT value="\"$NGX_SOEXT\"" . auto/define CORE_MODULES="$CORE_MODULES $DSO_MODULE" CORE_SRCS="$CORE_SRCS $DSO_SRCS" CORE_LIBS="$CORE_LIBS $NGX_LIBDL" @@ -717,7 +718,9 @@ fi if [ $NGX_BACKTRACE = YES ]; then modules="$modules $NGX_BACKTRACE_MODULE" NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_BACKTRACE_SRCS" - LINK="$LINK -rdynamic" + if ! [ $NGX_DSO = YES ] ; then + LINK="$LINK -rdynamic" + fi fi diff --git a/auto/os/conf b/auto/os/conf index fe720160ad..b494a91479 100644 --- a/auto/os/conf +++ b/auto/os/conf @@ -3,6 +3,8 @@ # Copyright (C) Nginx, Inc. +NGX_SOEXT=".so" + echo "checking for $NGX_SYSTEM specific features" case "$NGX_PLATFORM" in diff --git a/contrib/dso.in b/contrib/dso.in index 0cbd86bbc0..2bb716f879 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -201,7 +201,6 @@ if test -n "$NGX_DSO_ADDONS"; then # compile nginx cd $NGX_SOURCE_HOME ./configure $NGX_CONFIGURE - make cd - echo configuring additional modules diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 4c38a82d81..fc4466e7d5 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -10,9 +10,6 @@ #include -#define NGX_DSO_EXT ".so" - - typedef struct { ngx_str_t type; ngx_str_t entry; @@ -440,14 +437,14 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_memcpy(module_name.data, module_path.data, module_name.len); } else { - module_path.len = value[1].len + sizeof(NGX_DSO_EXT); + module_path.len = value[1].len + sizeof(NGX_SOEXT); module_path.data = ngx_pcalloc(cf->pool, module_path.len); if (module_path.data == NULL) { return NGX_CONF_ERROR; } p = ngx_cpymem(module_path.data, value[1].data, value[1].len); - ngx_memcpy(p, NGX_DSO_EXT, sizeof(NGX_DSO_EXT) - 1); + ngx_memcpy(p, NGX_SOEXT, sizeof(NGX_SOEXT) - 1); module_name = value[1]; } } diff --git a/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm b/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm index a4bbe21e32..b6f6c4526e 100644 --- a/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm +++ b/tests/nginx-tests/nginx-tests/lib/Test/Nginx.pm @@ -310,7 +310,7 @@ sub test_globals() { sub test_globals_dso() { my ($self) = @_; - return unless defined $ENV{TEST_NGINX_DSO}; + return "" unless defined $ENV{TEST_NGINX_DSO}; return $self->{_test_globals_dso} if defined $self->{_test_globals_dso}; From 8b1e249fc50a7e396402ed6b84cfe36b13f07674 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 20:27:33 +0800 Subject: [PATCH 32/36] fix bug for duplicate load. --- contrib/dso.in | 2 +- src/core/ngx_dso_module.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/dso.in b/contrib/dso.in index 2bb716f879..f3d52e9a70 100644 --- a/contrib/dso.in +++ b/contrib/dso.in @@ -57,7 +57,7 @@ if [ $help = yes ]; then cat << END -h, --help display this help and exit - -d, --dst=PATH set module installation prefix + -d, --dst=PATH set module installation path -a, --add-module=PATH external module which will be compiled -s, --nginx-source=SOURCE set nginx source root diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index fc4466e7d5..5a29ee10a3 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -450,7 +450,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, - &value[1], &module_path); + &module_name, &module_path); if (rc == NGX_DECLINED) { return NGX_CONF_OK; } @@ -629,7 +629,7 @@ ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, static char * ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_str_t *value, *module_name; + ngx_str_t *value, *name; ngx_dso_conf_ctx_t *ctx; value = cf->args->elts; @@ -641,12 +641,12 @@ ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - module_name = ngx_array_push(ctx->stubs); - if (module_name == NULL) { + name = ngx_array_push(ctx->stubs); + if (name == NULL) { return NGX_CONF_ERROR; } - *module_name = value[1]; + *name = value[1]; return NGX_CONF_OK; } From 4efe3439a02016b9ab94aa20fe8d294d22f456c7 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 21:47:58 +0800 Subject: [PATCH 33/36] fix some code style --- auto/make | 4 +- docs/modules/ngx_dso_module.md | 4 +- src/core/ngx_dso_module.c | 90 +++++++++++++++++----------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/auto/make b/auto/make index 0ba44837eb..e57323b936 100644 --- a/auto/make +++ b/auto/make @@ -7,7 +7,7 @@ if test -n "$NGX_SHARED_MODULES"; then if [ $NGX_DSO != YES ]; then cat << END -you should enable the dso module, if you want to use a dynamic loaded module. +you should enable dso, if you want to use a dynamically loaded module. END exit 1 fi @@ -593,7 +593,7 @@ END cat << END > $NGX_DSO_COMPILE #!/bin/sh -#Copyright (C) 2010-2012 Alibaba Group Holding Limited +# Copyright (C) 2010-2012 Alibaba Group Holding Limited ngx_soext='$NGX_SOEXT' diff --git a/docs/modules/ngx_dso_module.md b/docs/modules/ngx_dso_module.md index 359734189a..742f87d8ab 100644 --- a/docs/modules/ngx_dso_module.md +++ b/docs/modules/ngx_dso_module.md @@ -10,9 +10,9 @@ Description * If you want to enable a standard module, you can enable it via configure's option while compiling tengine, for instance, --with-http\_example_module or --with-http\_example\_module=shared. Run *./configure --help* for more details. -* The maximum of dynamic loaded modules is limited to 128. +* The maximum of dynamically loaded modules is limited to 128. -* For now, only HTTP modules can be dynamic-loaded. +* For now, only HTTP modules can be dynamically loaded. * This feature is tested only on Linux/FreeBSD/MacOS. diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 5a29ee10a3..41b04d7ed2 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -88,11 +88,10 @@ ngx_module_t ngx_dso_module = { static ngx_module_t *ngx_old_modules[NGX_DSO_MAX]; static ngx_module_t *ngx_static_modules[NGX_DSO_MAX]; -static ngx_str_t ngx_default_modules_prefix = ngx_string(NGX_DSO_PATH); +static ngx_str_t ngx_default_module_prefix = ngx_string(NGX_DSO_PATH); static ngx_dso_flagpole_t module_flagpole[] = { - { ngx_string("filter"), ngx_string("ngx_http_copy_filter_module")}, { ngx_null_string, ngx_null_string} }; @@ -188,7 +187,6 @@ ngx_dso_get_position(ngx_str_t *entry) size_t len; ngx_int_t i; - /* start to insert */ for (i = 0; ngx_module_names[i]; i++) { len = ngx_strlen(ngx_module_names[i]); @@ -198,7 +196,7 @@ ngx_dso_get_position(ngx_str_t *entry) } if (ngx_strncasecmp((u_char *) ngx_module_names[i], - entry->data, len) == 0) + entry->data, len) == 0) { return i; } @@ -261,10 +259,10 @@ ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, for (i = 0; ngx_module_names[i]; i++) { len = ngx_strlen(ngx_module_names[i]); - if (len == name->len && ngx_strncmp(ngx_module_names[i], - name->data, name->len) == 0) + if (len == name->len + && ngx_strncmp(ngx_module_names[i], name->data, name->len) == 0) { - ngx_log_stderr(0, "module %V is already static loaded, " + ngx_log_stderr(0, "module %V is already statically loaded, " "skipping", name); return NGX_DECLINED; } @@ -277,7 +275,7 @@ ngx_dso_check_duplicated(ngx_cycle_t *cycle, ngx_array_t *modules, || (m[i].path.len == path->len && ngx_strncmp(m[i].path.data, path->data, path->len) == 0)) { - ngx_log_stderr(0, "module %V/%V is already dynamic loaded, " + ngx_log_stderr(0, "module \"%V/%V\" is already dynamically loaded, " "skipping", path, name); m[i].name.len = 0; return NGX_DECLINED; @@ -300,21 +298,21 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, } if (ctx->path.data == NULL) { - if (ngx_default_modules_prefix.data[0] != '/') { + if (ngx_default_module_prefix.data[0] != '/') { prefix = cycle->prefix.data; len = cycle->prefix.len; - size = len + ngx_default_modules_prefix.len + name->len + 1; + size = len + ngx_default_module_prefix.len + name->len + 1; } else { - prefix = ngx_default_modules_prefix.data; - len = ngx_default_modules_prefix.len; + prefix = ngx_default_module_prefix.data; + len = ngx_default_module_prefix.len; size = len + name->len + 1; } } else { if (ctx->path.data[0] != '/') { - ngx_log_stderr(0, "the path(%V) of dso module " - "should be absolute path", &ctx->path); + ngx_log_stderr(0, "the path (\"%V\") of dso module " + "should be an absolute path", &ctx->path); return NGX_ERROR; } @@ -331,10 +329,10 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, p = ngx_cpymem(n, prefix, len); if (ctx->path.data == NULL - && ngx_default_modules_prefix.data[0] != '/') + && ngx_default_module_prefix.data[0] != '/') { - p = ngx_cpymem(p, ngx_default_modules_prefix.data, - ngx_default_modules_prefix.len); + p = ngx_cpymem(p, ngx_default_module_prefix.data, + ngx_default_module_prefix.len); } p = ngx_cpymem(p, "/", 1); @@ -350,14 +348,15 @@ ngx_dso_full_name(ngx_cycle_t *cycle, ngx_dso_conf_ctx_t *ctx, static ngx_int_t ngx_dso_open(ngx_dso_module_t *dm) { - ngx_str_t name, path; + ngx_str_t name, path; name = dm->name; path = dm->path; dm->handle = dlopen((char *) path.data, RTLD_NOW | RTLD_GLOBAL); if (dm->handle == NULL) { - ngx_log_stderr(errno, "load module \"%V\" failed (%s)", &path, dlerror()); + ngx_log_stderr(errno, "load module \"%V\" failed (%s)", + &path, dlerror()); return NGX_ERROR; } @@ -378,6 +377,7 @@ ngx_dso_insert_module(ngx_module_t *module, ngx_int_t flag_postion) ngx_module_t *m; m = NULL; + /* start to insert */ for (i = flag_postion; ngx_modules[i]; i++) { m = ngx_modules[i]; @@ -402,7 +402,7 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; ngx_int_t rc; - ngx_str_t *value, module_path, module_name; + ngx_str_t *value, path, name; ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; @@ -410,15 +410,15 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) value = cf->args->elts; if (ctx->modules->nelts >= NGX_DSO_MAX) { - ngx_log_stderr(0, "module \"%V\" could not be loaded, " - "because the dso module limit(%ui) is reached.", + ngx_log_stderr(0, "module \"%V\" can not be loaded, " + "because the dso module limit (%ui) is reached.", &value[1], NGX_DSO_MAX); return NGX_CONF_ERROR; } if (cf->args->nelts == 3) { - module_name = value[1]; - module_path = value[2]; + name = value[1]; + path = value[2]; } else { /* cf->args->nelts == 2 */ @@ -427,30 +427,30 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) value[1].data[value[1].len - 2] == 's' && value[1].data[value[1].len - 1] == 'o') { - module_path = value[1]; - module_name.data = ngx_pcalloc(cf->pool, value[1].len - 2); - if (module_path.data == NULL) { + path = value[1]; + name.data = ngx_pcalloc(cf->pool, value[1].len - 2); + if (path.data == NULL) { return NGX_CONF_ERROR; } - module_name.len = value[1].len - 3; - ngx_memcpy(module_name.data, module_path.data, module_name.len); + name.len = value[1].len - 3; + ngx_memcpy(name.data, path.data, name.len); } else { - module_path.len = value[1].len + sizeof(NGX_SOEXT); - module_path.data = ngx_pcalloc(cf->pool, module_path.len); - if (module_path.data == NULL) { + path.len = value[1].len + sizeof(NGX_SOEXT); + path.data = ngx_pcalloc(cf->pool, path.len); + if (path.data == NULL) { return NGX_CONF_ERROR; } - p = ngx_cpymem(module_path.data, value[1].data, value[1].len); + p = ngx_cpymem(path.data, value[1].data, value[1].len); ngx_memcpy(p, NGX_SOEXT, sizeof(NGX_SOEXT) - 1); - module_name = value[1]; + name = value[1]; } } rc = ngx_dso_check_duplicated(cf->cycle, ctx->modules, - &module_name, &module_path); + &name, &path); if (rc == NGX_DECLINED) { return NGX_CONF_OK; } @@ -460,8 +460,8 @@ ngx_dso_save(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - dm->name = module_name; - dm->path = module_path; + dm->name = name; + dm->path = path; dm->handle = NULL; return NGX_CONF_OK; @@ -490,7 +490,7 @@ ngx_dso_load(ngx_conf_t *cf) } if (dm[i].module->type == NGX_CORE_MODULE) { - ngx_log_stderr(0,"dso module not support core module"); + ngx_log_stderr(0, "core modules can not be dynamically loaded"); return NGX_CONF_ERROR; } @@ -597,9 +597,9 @@ static char * ngx_dso_template(ngx_conf_t *cf, ngx_dso_conf_ctx_t *ctx, ngx_str_t *name) { - char *rv; - ngx_str_t file; - ngx_conf_t pcf; + char *rv; + ngx_str_t file; + ngx_conf_t pcf; file.len = name->len; file.data = ngx_pnalloc(cf->temp_pool, name->len + 1); @@ -655,10 +655,10 @@ ngx_dso_stub(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static ngx_int_t ngx_dso_find_postion(ngx_dso_conf_ctx_t *ctx, ngx_str_t module_name) { - size_t len1, len2, len3; - ngx_int_t near; - ngx_str_t *name; - ngx_uint_t i, k; + size_t len1, len2, len3; + ngx_int_t near; + ngx_str_t *name; + ngx_uint_t i, k; near = ctx->flag_postion; From a62ae88a968c04e4bab06845815cca00c40d20cd Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 22:10:28 +0800 Subject: [PATCH 34/36] modify comment --- auto/init | 2 +- auto/options | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/auto/init b/auto/init index ca42e17993..db90e62bdc 100644 --- a/auto/init +++ b/auto/init @@ -16,7 +16,7 @@ NGX_AUTOCONF_ERR=$NGX_OBJS/autoconf.err NGX_ERR=$NGX_OBJS/autoconf.err MAKEFILE=$NGX_OBJS/Makefile -#dso +# dso NGX_DSO_COMPILE=$NGX_OBJS/dso_tool NGX_MODULE_STUBS=$NGX_OBJS/module_stubs diff --git a/auto/options b/auto/options index 7ca00266f8..7611ee6ce9 100644 --- a/auto/options +++ b/auto/options @@ -16,7 +16,6 @@ NGX_USER= NGX_GROUP= NGX_DSO_PATH= -NGX_SOURCE_PATH=`pwd` CC=${CC:-gcc} CPP= @@ -199,7 +198,7 @@ HTTP_UPSTREAM_KEEPALIVE=YES # STUB HTTP_STUB_STATUS=YES -#shared module +# shared modules HTTP_XSLT_SHARED=NO HTTP_IMAGE_FILTER_SHARED=NO HTTP_SUB_SHARED=NO From f81ecb29425f6e0492eda2b3830db6d9a2d5f19e Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 22:33:50 +0800 Subject: [PATCH 35/36] fix bug for reload. --- src/core/ngx_dso_module.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index 41b04d7ed2..a7352cb7f7 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -212,26 +212,18 @@ ngx_dso_cleanup(void *data) ngx_cycle_t *cycle = data; ngx_uint_t i; - ngx_cycle_t *clean_cycle; ngx_dso_module_t *dm; ngx_dso_conf_ctx_t *ctx; if (cycle != ngx_cycle) { - clean_cycle = cycle; ngx_memcpy(ngx_modules, ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); - - } else { - if (cycle->old_cycle == NULL) { - return; - } - clean_cycle = cycle->old_cycle; } - if (clean_cycle->conf_ctx) { + if (cycle->conf_ctx) { ctx = (ngx_dso_conf_ctx_t *) - clean_cycle->conf_ctx[ngx_dso_module.index]; + cycle->conf_ctx[ngx_dso_module.index]; if (ctx != NULL) { dm = ctx->modules->elts; From e167210b9e26c4aa4a26d7499afe9dd247e38b4b Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Wed, 5 Sep 2012 22:46:31 +0800 Subject: [PATCH 36/36] fix code style. --- src/core/ngx_dso_module.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/ngx_dso_module.c b/src/core/ngx_dso_module.c index a7352cb7f7..c581e1fc47 100644 --- a/src/core/ngx_dso_module.c +++ b/src/core/ngx_dso_module.c @@ -216,14 +216,12 @@ ngx_dso_cleanup(void *data) ngx_dso_conf_ctx_t *ctx; if (cycle != ngx_cycle) { - ngx_memcpy(ngx_modules, ngx_old_modules, sizeof(ngx_module_t *) * NGX_DSO_MAX); } if (cycle->conf_ctx) { - ctx = (ngx_dso_conf_ctx_t *) - cycle->conf_ctx[ngx_dso_module.index]; + ctx = (ngx_dso_conf_ctx_t *) cycle->conf_ctx[ngx_dso_module.index]; if (ctx != NULL) { dm = ctx->modules->elts;