summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES29
-rw-r--r--CHANGES.ru25
-rw-r--r--auto/headers1
-rw-r--r--auto/options4
-rw-r--r--auto/summary18
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_conf_file.c8
-rw-r--r--src/core/ngx_log.h3
-rw-r--r--src/core/ngx_output_chain.c20
-rw-r--r--src/core/ngx_parse.c112
-rw-r--r--src/core/ngx_parse.h2
-rw-r--r--src/core/ngx_resolver.c92
-rw-r--r--src/core/ngx_resolver.h4
-rw-r--r--src/core/ngx_string.c18
-rw-r--r--src/core/ngx_string.h2
-rw-r--r--src/core/ngx_times.c85
-rw-r--r--src/event/ngx_event_openssl.c29
-rw-r--r--src/http/modules/ngx_http_sub_filter_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http.c4
-rw-r--r--src/http/ngx_http_core_module.c24
-rw-r--r--src/http/ngx_http_core_module.h1
-rw-r--r--src/http/ngx_http_parse_time.c19
-rw-r--r--src/http/ngx_http_request.c9
-rw-r--r--src/http/ngx_http_special_response.c4
-rw-r--r--src/http/ngx_http_upstream.c13
-rw-r--r--src/http/ngx_http_upstream_round_robin.c5
-rw-r--r--src/mail/ngx_mail.c4
-rw-r--r--src/mail/ngx_mail_proxy_module.c2
-rw-r--r--src/os/unix/ngx_files.c10
-rw-r--r--src/os/unix/ngx_files.h19
-rw-r--r--src/os/unix/ngx_posix_config.h2
-rw-r--r--src/os/unix/ngx_process.c7
33 files changed, 389 insertions, 192 deletions
diff --git a/CHANGES b/CHANGES
index 0b3087de3..4c3671c84 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,15 +1,37 @@
+Changes with nginx 0.6.30 29 Apr 2008
+
+ *) Change: now if an "include" directive pattern does not match any
+ file, then nginx does not issue an error.
+
+ *) Feature: now the time in directives may be specified without spaces,
+ for example, "1h50m".
+
+ *) Bugfix: memory leaks if the "ssl_verify_client" directive was on.
+ Thanks to Chavelle Vincent.
+
+ *) Bugfix: the "sub_filter" directive might set text to change into
+ output.
+
+ *) Bugfix: the "error_page" directive did not take into account
+ arguments in redirected URI.
+
+ *) Bugfix: now nginx always opens files in binary mode under Cygwin.
+
+ *) Bugfix: nginx could not be built on OpenBSD; bug appeared in 0.6.15.
+
+
Changes with nginx 0.6.29 18 Mar 2008
*) Feature: the ngx_google_perftools_module.
- *) Bugfix: the ngx_http_perl_module could be not built on 64-bit
+ *) Bugfix: the ngx_http_perl_module could not be built on 64-bit
platforms; bug appeared in 0.6.27.
Changes with nginx 0.6.28 13 Mar 2008
- *) Bugfix: the rtsig method could be not built; bug appeared in 0.6.27.
+ *) Bugfix: the rtsig method could not be built; bug appeared in 0.6.27.
Changes with nginx 0.6.27 12 Mar 2008
@@ -665,7 +687,8 @@ Changes with nginx 0.5.20 07 May 2007
Studio.
Thanks to Andrei Nigmatulin.
- *) Bugfix: the ngx_http_perl_module could not built by Solaris make.
+ *) Bugfix: the ngx_http_perl_module could not be built by Solaris
+ make.
Thanks to Andrei Nigmatulin.
diff --git a/CHANGES.ru b/CHANGES.ru
index 25e21b171..5bf68083c 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,29 @@
+Изменения в nginx 0.6.30 29.04.2008
+
+ *) Изменение: теперь, если маске, заданной в директиве include, не
+ соответствует ни один файл, то nginx не выдаёт ошибку.
+
+ *) Добавление: теперь время в директивах можно задавать без пробела,
+ например, "1h50m".
+
+ *) Исправление: утечек памяти, если директива ssl_verify_client имела
+ значение on.
+ Спасибо Chavelle Vincent.
+
+ *) Исправление: директива sub_filter могла вставлять заменяемый текст в
+ вывод.
+
+ *) Исправление: директива error_page не воспринимала параметры в
+ перенаправляемом URI.
+
+ *) Исправление: теперь при сборке с Cygwin nginx всегда открывает файлы
+ в бинарном режиме.
+
+ *) Исправление: nginx не собирался под OpenBSD; ошибка появилась в
+ 0.6.15.
+
+
Изменения в nginx 0.6.29 18.03.2008
*) Добавление: модуль ngx_google_perftools_module.
diff --git a/auto/headers b/auto/headers
index d41d95a75..542b757c1 100644
--- a/auto/headers
+++ b/auto/headers
@@ -7,4 +7,3 @@ ngx_include="inttypes.h"; . auto/include
ngx_include="limits.h"; . auto/include
ngx_include="sys/filio.h"; . auto/include
ngx_include="crypt.h"; . auto/include
-ngx_include="malloc.h"; . auto/include
diff --git a/auto/options b/auto/options
index 65fd360de..e00bf9764 100644
--- a/auto/options
+++ b/auto/options
@@ -150,8 +150,8 @@ do
--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" ;;
--without-http) HTTP=NO ;;
--http-log-path=*) NGX_HTTP_LOG_PATH="$value" ;;
diff --git a/auto/summary b/auto/summary
index c220c7123..a8ed45446 100644
--- a/auto/summary
+++ b/auto/summary
@@ -21,15 +21,15 @@ echo
echo "Configuration summary"
-case $USE_THREADS in
- rfork) echo " + using rfork()ed threads" ;;
- pthreads) echo " + using libpthread threads library" ;;
- libthr) echo " + using FreeBSD libthr threads library" ;;
- libc_r) echo " + using FreeBSD libc_r threads library" ;;
- linuxthreads) echo " + using FreeBSD LinuxThreads port library" ;;
- NO) echo " + threads are not used" ;;
- *) echo " + using lib$USE_THREADS threads library" ;;
-esac
+#case $USE_THREADS in
+# rfork) echo " + using rfork()ed threads" ;;
+# pthreads) echo " + using libpthread threads library" ;;
+# libthr) echo " + using FreeBSD libthr threads library" ;;
+# libc_r) echo " + using FreeBSD libc_r threads library" ;;
+# linuxthreads) echo " + using FreeBSD LinuxThreads port library" ;;
+# NO) echo " + threads are not used" ;;
+# *) echo " + using lib$USE_THREADS threads library" ;;
+#esac
if [ $USE_PCRE = DISABLED ]; then
echo " + PCRE library is disabled"
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 5a2e64dbc..1a0d3c437 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.29"
+#define NGINX_VERSION "0.6.30"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index 54769fbe0..6efcd8b7d 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -645,10 +645,18 @@ ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
+ if (strpbrk((char *) file.data, "*?[") == NULL) {
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
+
+ return ngx_conf_parse(cf, &file);
+ }
+
ngx_memzero(&gl, sizeof(ngx_glob_t));
gl.pattern = file.data;
gl.log = cf->log;
+ gl.test = 1;
if (ngx_open_glob(&gl) != NGX_OK) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h
index e58834d5f..1fd1ad8ad 100644
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -195,9 +195,6 @@ void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err,
/*********************************/
-#define ngx_log_alloc_log(pool, log) ngx_palloc(pool, log, sizeof(ngx_log_t))
-#define ngx_log_copy_log(new, old) ngx_memcpy(new, old, sizeof(ngx_log_t))
-
ngx_log_t *ngx_log_init(void);
ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args);
char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log);
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 5e6773e60..423a650d3 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -433,8 +433,11 @@ ngx_chain_writer(void *data, ngx_chain_t *in)
{
ngx_chain_writer_ctx_t *ctx = data;
- off_t size;
- ngx_chain_t *cl;
+ off_t size;
+ ngx_chain_t *cl;
+ ngx_connection_t *c;
+
+ c = ctx->connection;
for (size = 0; in; in = in->next) {
@@ -446,7 +449,7 @@ ngx_chain_writer(void *data, ngx_chain_t *in)
size += ngx_buf_size(in->buf);
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
"chain writer buf fl:%d s:%uO",
in->buf->flush, ngx_buf_size(in->buf));
@@ -461,7 +464,7 @@ ngx_chain_writer(void *data, ngx_chain_t *in)
ctx->last = &cl->next;
}
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
"chain writer in: %p", ctx->out);
for (cl = ctx->out; cl; cl = cl->next) {
@@ -476,14 +479,13 @@ ngx_chain_writer(void *data, ngx_chain_t *in)
size += ngx_buf_size(cl->buf);
}
- if (size == 0 && !ctx->connection->buffered) {
+ if (size == 0 && !c->buffered) {
return NGX_OK;
}
- ctx->out = ctx->connection->send_chain(ctx->connection, ctx->out,
- ctx->limit);
+ ctx->out = c->send_chain(c, ctx->out, ctx->limit);
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
"chain writer out: %p", ctx->out);
if (ctx->out == NGX_CHAIN_ERROR) {
@@ -493,7 +495,7 @@ ngx_chain_writer(void *data, ngx_chain_t *in)
if (ctx->out == NULL) {
ctx->last = &ctx->out;
- if (!ctx->connection->buffered) {
+ if (!c->buffered) {
return NGX_OK;
}
}
diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c
index 786824562..6c4640cf7 100644
--- a/src/core/ngx_parse.c
+++ b/src/core/ngx_parse.c
@@ -11,15 +11,15 @@
ssize_t
ngx_parse_size(ngx_str_t *line)
{
- u_char last;
+ u_char unit;
size_t len;
ssize_t size;
ngx_int_t scale;
len = line->len;
- last = line->data[len - 1];
+ unit = line->data[len - 1];
- switch (last) {
+ switch (unit) {
case 'K':
case 'k':
len--;
@@ -50,15 +50,15 @@ ngx_parse_size(ngx_str_t *line)
off_t
ngx_parse_offset(ngx_str_t *line)
{
- u_char last;
+ u_char unit;
off_t offset;
size_t len;
ngx_int_t scale;
len = line->len;
- last = line->data[len - 1];
+ unit = line->data[len - 1];
- switch (last) {
+ switch (unit) {
case 'K':
case 'k':
len--;
@@ -93,12 +93,11 @@ ngx_parse_offset(ngx_str_t *line)
ngx_int_t
-ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
+ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
{
- size_t len;
- u_char *start, last;
+ u_char *p, *last;
ngx_int_t value, total, scale;
- ngx_uint_t max, i;
+ ngx_uint_t max, valid;
enum {
st_start = 0,
st_year,
@@ -112,39 +111,30 @@ ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
st_last
} step;
-
- start = line->data;
- len = 0;
+ valid = 0;
+ value = 0;
total = 0;
step = sec ? st_start : st_month;
+ scale = sec ? 1 : 1000;
- for (i = 0; /* void */ ; i++) {
-
- if (i < line->len) {
- if (line->data[i] != ' ') {
- len++;
- continue;
- }
+ p = line->data;
+ last = p + line->len;
- if (line->data[i] == ' ' && len == 0) {
- start = &line->data[i + 1];
- continue;
- }
- }
+ while (p < last) {
- if (len == 0) {
- break;
+ if (*p >= '0' && *p <= '9') {
+ value = value * 10 + (*p++ - '0');
+ valid = 1;
+ continue;
}
- last = line->data[i - 1];
+ switch (*p++) {
- switch (last) {
case 'y':
if (step > st_start) {
return NGX_ERROR;
}
step = st_year;
- len--;
max = 68;
scale = 60 * 60 * 24 * 365;
break;
@@ -154,7 +144,6 @@ ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
return NGX_ERROR;
}
step = st_month;
- len--;
max = 828;
scale = 60 * 60 * 24 * 30;
break;
@@ -164,7 +153,6 @@ ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
return NGX_ERROR;
}
step = st_week;
- len--;
max = 3550;
scale = 60 * 60 * 24 * 7;
break;
@@ -174,7 +162,6 @@ ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
return NGX_ERROR;
}
step = st_day;
- len--;
max = 24855;
scale = 60 * 60 * 24;
break;
@@ -184,52 +171,49 @@ ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
return NGX_ERROR;
}
step = st_hour;
- len--;
max = 596523;
scale = 60 * 60;
break;
case 'm':
- if (step > st_hour) {
- return NGX_ERROR;
- }
- step = st_min;
- len--;
- max = 35791394;
- scale = 60;
- break;
-
- case 's':
- len--;
-
- if (line->data[i - 2] == 'm') {
+ if (*p == 's') {
if (sec || step > st_sec) {
return NGX_ERROR;
}
+ p++;
step = st_msec;
- len--;
max = 2147483647;
scale = 1;
break;
}
- if (step > st_min) {
+ if (step > st_hour) {
return NGX_ERROR;
}
+ step = st_min;
+ max = 35791394;
+ scale = 60;
+ break;
+ case 's':
+ if (step > st_min) {
+ return NGX_ERROR;
+ }
step = st_sec;
max = 2147483647;
scale = 1;
break;
- default:
+ case ' ':
+ if (step > st_min) {
+ return NGX_ERROR;
+ }
step = st_last;
max = 2147483647;
scale = 1;
- }
+ break;
- value = ngx_atoi(start, len);
- if (value == NGX_ERROR) {
+ default:
return NGX_ERROR;
}
@@ -238,23 +222,27 @@ ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
max /= 1000;
}
- if ((u_int) value > max) {
- return NGX_PARSE_LARGE_TIME;
+ if ((ngx_uint_t) value > max) {
+ return NGX_ERROR;
}
total += value * scale;
- if ((u_int) total > 2147483647) {
- return NGX_PARSE_LARGE_TIME;
+ if ((ngx_uint_t) total > 2147483647) {
+ return NGX_ERROR;
}
- if (i >= line->len) {
- break;
+ value = 0;
+ scale = sec ? 1 : 1000;
+
+ while (p < last && *p == ' ') {
+ p++;
}
+ }
- len = 0;
- start = &line->data[i + 1];
+ if (valid) {
+ return total + value * scale;
}
- return total;
+ return NGX_ERROR;
}
diff --git a/src/core/ngx_parse.h b/src/core/ngx_parse.h
index cf3f0b2be..c25a3a023 100644
--- a/src/core/ngx_parse.h
+++ b/src/core/ngx_parse.h
@@ -17,7 +17,7 @@
ssize_t ngx_parse_size(ngx_str_t *line);
off_t ngx_parse_offset(ngx_str_t *line);
-ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_int_t sec);
+ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t sec);
#endif /* _NGX_PARSE_H_INCLUDED_ */
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index bbc40bae0..a5b8efbf6 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -369,6 +369,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
{
uint32_t hash;
in_addr_t addr, *addrs;
+ ngx_int_t rc;
ngx_uint_t naddrs;
ngx_resolver_ctx_t *next;
ngx_resolver_node_t *rn;
@@ -434,10 +435,29 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
/* NGX_RESOLVE_CNAME */
- ctx->name.len = rn->cnlen;
- ctx->name.data = rn->u.cname;
+ if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
+
+ ctx->name.len = rn->cnlen;
+ ctx->name.data = rn->u.cname;
+
+ return ngx_resolve_name_locked(r, ctx);
+ }
+
+ ctx->next = rn->waiting;
+ rn->waiting = NULL;
+
+ /* unlock name mutex */
+
+ do {
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
+ next = ctx->next;
+
+ ctx->handler(ctx);
- return ngx_resolve_name_locked(r, ctx);
+ ctx = next;
+ } while (ctx);
+
+ return NGX_OK;
}
if (rn->waiting) {
@@ -453,6 +473,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
/* lock alloc mutex */
ngx_resolver_free_locked(r, rn->query);
+ rn->query = NULL;
if (rn->cnlen) {
ngx_resolver_free_locked(r, rn->u.cname);
@@ -479,14 +500,30 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
rn->node.key = hash;
rn->nlen = (u_short) ctx->name.len;
+ rn->query = NULL;
ngx_rbtree_insert(&r->name_rbtree, &rn->node);
}
- if (ngx_resolver_create_name_query(rn, ctx) != NGX_OK) {
+ rc = ngx_resolver_create_name_query(rn, ctx);
+
+ if (rc == NGX_ERROR) {
goto failed;
}
+ if (rc == NGX_DECLINED) {
+ ngx_rbtree_delete(&r->name_rbtree, &rn->node);
+
+ ngx_resolver_free(r, rn->query);
+ ngx_resolver_free(r, rn->name);
+ ngx_resolver_free(r, rn);
+
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
+ ctx->handler(ctx);
+
+ return NGX_OK;
+ }
+
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
goto failed;
}
@@ -526,6 +563,10 @@ failed:
ngx_rbtree_delete(&r->name_rbtree, &rn->node);
+ if (rn->query) {
+ ngx_resolver_free(r, rn->query);
+ }
+
ngx_resolver_free(r, rn->name);
ngx_resolver_free(r, rn);
@@ -588,6 +629,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
ngx_queue_remove(&rn->queue);
ngx_resolver_free(r, rn->query);
+ rn->query = NULL;
} else {
rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
@@ -596,6 +638,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
}
rn->node.key = ctx->addr;
+ rn->query = NULL;
ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
}
@@ -646,6 +689,10 @@ failed:
if (rn) {
ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
+ if (rn->query) {
+ ngx_resolver_free(r, rn->query);
+ }
+
ngx_resolver_free(r, rn);
}
@@ -925,14 +972,14 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
nan = (query->nan_hi << 8) + query->nan_lo;
ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver DNS response %d fl:%04Xud %d/%d/%d/%d",
+ "resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui",
ident, flags, nqs, nan,
(query->nns_hi << 8) + query->nns_lo,
(query->nar_hi << 8) + query->nar_lo);
if (!(flags & 0x8000)) {
ngx_log_error(r->log_level, r->log, 0,
- "invalid DNS response %d fl:%04Xud", ident, flags);
+ "invalid DNS response %ui fl:%04Xui", ident, flags);
return;
}
@@ -940,7 +987,7 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
if (code == NGX_RESOLVE_FORMERR || code > NGX_RESOLVE_REFUSED) {
ngx_log_error(r->log_level, r->log, 0,
- "DNS error (%d: %s), query id:%d",
+ "DNS error (%ui: %s), query id:%ui",
code, ngx_resolver_strerror(code), ident);
return;
}
@@ -982,11 +1029,11 @@ found:
qclass = (qs->class_hi << 8) + qs->class_lo;
ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver DNS response qt:%d cl:%d", qtype, qclass);
+ "resolver DNS response qt:%ui cl:%ui", qtype, qclass);
if (qclass != 1) {
ngx_log_error(r->log_level, r->log, 0,
- "unknown query class %d in DNS response", qclass);
+ "unknown query class %ui in DNS response", qclass);
return;
}
@@ -1007,7 +1054,7 @@ found:
default:
ngx_log_error(r->log_level, r->log, 0,
- "unknown query type %d in DNS response", qtype);
+ "unknown query type %ui in DNS response", qtype);
return;
}
@@ -1062,7 +1109,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
if (ident != qident) {
ngx_log_error(r->log_level, r->log, 0,
- "wrong ident %d response for %V, expect %d",
+ "wrong ident %ui response for %V, expect %ui",
ident, &name, qident);
goto failed;
}
@@ -1158,6 +1205,13 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
} else if (qtype == NGX_RESOLVE_CNAME) {
cname = &buf[i] + sizeof(ngx_resolver_an_t);
i += sizeof(ngx_resolver_an_t) + len;
+
+ } else if (qtype == NGX_RESOLVE_DNAME) {
+ i += sizeof(ngx_resolver_an_t) + len;
+
+ } else {
+ ngx_log_error(r->log_level, r->log, 0,
+ "unexpected qtype %ui", qtype);
}
}
@@ -1291,8 +1345,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
}
ngx_log_error(r->log_level, r->log, 0,
- "no A or CNAME types in DNS responses, unknown query type: %d",
- qtype);
+ "no A or CNAME types in DNS responses, unknown query type: %ui",
+ qtype);
return;
short_response:
@@ -1368,9 +1422,9 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
if (ident != qident) {
ngx_log_error(r->log_level, r->log, 0,
- "wrong ident %d response for %ud.%ud.%ud.%ud, expect %d",
- ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
- (addr >> 8) & 0xff, addr & 0xff, qident);
+ "wrong ident %ui response for %ud.%ud.%ud.%ud, expect %ui",
+ ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
+ (addr >> 8) & 0xff, addr & 0xff, qident);
goto failed;
}
@@ -1421,7 +1475,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
len = (an->len_hi << 8) + an->len_lo;
ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver qt:%d cl:%d len:%uz", qtype, qclass, len);
+ "resolver qt:%ui cl:%ui len:%uz", qtype, qclass, len);
i += 2 + sizeof(ngx_resolver_an_t);
@@ -1684,6 +1738,10 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
len++;
} else {
+ if (len == 0) {
+ return NGX_DECLINED;
+ }
+
*p = (u_char) len;
len = 0;
}
diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h
index 8f8b06055..6c4afac97 100644
--- a/src/core/ngx_resolver.h
+++ b/src/core/ngx_resolver.h
@@ -17,6 +17,7 @@
#define NGX_RESOLVE_PTR 12
#define NGX_RESOLVE_MX 15
#define NGX_RESOLVE_TXT 16
+#define NGX_RESOLVE_DNAME 39
#define NGX_RESOLVE_FORMERR 1
#define NGX_RESOLVE_SERVFAIL 2
@@ -28,6 +29,8 @@
#define NGX_NO_RESOLVER (void *) -1
+#define NGX_RESOLVER_MAX_RECURSION 50
+
typedef struct {
ngx_connection_t *connection;
@@ -127,6 +130,7 @@ struct ngx_resolver_ctx_s {
ngx_msec_t timeout;
ngx_uint_t quick; /* unsigned quick:1; */
+ ngx_uint_t recursion;
ngx_event_t *event;
};
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index acd9382dd..01d792f36 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1430,26 +1430,32 @@ ngx_escape_html(u_char *dst, u_char *src, size_t size)
void
ngx_sort(void *base, size_t n, size_t size,
- int (*cmp)(const void *, const void *))
+ ngx_int_t (*cmp)(const void *, const void *))
{
- u_char *p1, *p2;
- u_char buf[256];
+ u_char *p1, *p2, *p;
+
+ p = ngx_alloc(size, ngx_cycle->log);
+ if (p == NULL) {
+ return;
+ }
for (p1 = (u_char *) base + size;
p1 < (u_char *) base + n * size;
p1 += size)
{
- ngx_memcpy(buf, p1, size);
+ ngx_memcpy(p, p1, size);
for (p2 = p1;
- p2 > (u_char *) base && cmp(p2 - size, buf) > 0;
+ p2 > (u_char *) base && cmp(p2 - size, p) > 0;
p2 -= size)
{
ngx_memcpy(p2, p2 - size, size);
}
- ngx_memcpy(p2, buf, size);
+ ngx_memcpy(p2, p, size);
}
+
+ ngx_free(p);
}
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 4fe5cb604..00617f3b2 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -173,7 +173,7 @@ uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
void ngx_sort(void *base, size_t n, size_t size,
- int (*cmp)(const void *, const void *));
+ ngx_int_t (*cmp)(const void *, const void *));
#define ngx_qsort qsort
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 1ba1210f0..c1798b5bc 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -203,14 +203,17 @@ ngx_http_cookie_time(u_char *buf, time_t t)
void
ngx_gmtime(time_t t, ngx_tm_t *tp)
{
- ngx_uint_t n, sec, min, hour, mday, mon, year, wday, yday, days;
+ ngx_int_t yday;
+ ngx_uint_t n, sec, min, hour, mday, mon, year, wday, days, leap;
/* the calculation is valid for positive time_t only */
+
n = (ngx_uint_t) t;
days = n / 86400;
/* Jaunary 1, 1970 was Thursday */
+
wday = (4 + days) % 7;
n %= 86400;
@@ -219,57 +222,65 @@ ngx_gmtime(time_t t, ngx_tm_t *tp)
min = n / 60;
sec = n % 60;
- /* the algorithm based on Gauss's formula */
+ /*
+ * the algorithm based on Gauss' formula,
+ * see src/http/ngx_http_parse_time.c
+ */
+ /* days since March 1, 1 BC */
days = days - (31 + 28) + 719527;
- year = days * 400 / (365 * 400 + 100 - 4 + 1);
+ /*
+ * The "days" should be adjusted to 1 only, however, some March 1st's go
+ * to previous year, so we adjust them to 2. This causes also shift of the
+ * last Feburary days to next year, but we catch the case when "yday"
+ * becomes negative.
+ */
+
+ year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1);
+
yday = days - (365 * year + year / 4 - year / 100 + year / 400);
- mon = (yday + 31) * 12 / 367;
- mday = yday - (mon * 367 / 12 - 31);
+ if (yday < 0) {
+ leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0));
+ yday = 365 + leap + yday;
+ year--;
+ }
+
+ /*
+ * The empirical formula that maps "yday" to month.
+ * There are at least 10 variants, some of them are:
+ * mon = (yday + 31) * 15 / 459
+ * mon = (yday + 31) * 17 / 520
+ * mon = (yday + 31) * 20 / 612
+ */
+
+ mon = (yday + 31) * 10 / 306;
- mon += 2;
+ /* the Gauss' formula that evaluates days before the month */
+
+ mday = yday - (367 * mon / 12 - 30) + 1;
if (yday >= 306) {
+ year++;
+ mon -= 10;
+
/*
* there is no "yday" in Win32 SYSTEMTIME
*
* yday -= 306;
*/
- year++;
- mon -= 12;
-
- if (mday == 0) {
- /* Jaunary 31 */
- mon = 1;
- mday = 31;
-
- } else if (mon == 2) {
-
- if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) {
- if (mday > 29) {
- mon = 3;
- mday -= 29;
- }
-
- } else if (mday > 28) {
- mon = 3;
- mday -= 28;
- }
- }
-/*
- * there is no "yday" in Win32 SYSTEMTIME
- *
- * } else {
- * yday += 31 + 28;
- *
- * if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) {
- * yday++;
- * }
- */
+ } else {
+
+ mon += 2;
+
+ /*
+ * there is no "yday" in Win32 SYSTEMTIME
+ *
+ * yday += 31 + 28 + leap;
+ */
}
tp->ngx_tm_sec = (ngx_tm_sec_t) sec;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 436237857..559c00772 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -285,10 +285,11 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
static int
ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
{
+#if (NGX_DEBUG)
char *subject, *issuer;
int err, depth;
X509 *cert;
- X509_NAME *name;
+ X509_NAME *sname, *iname;
ngx_connection_t *c;
ngx_ssl_conn_t *ssl_conn;
@@ -301,17 +302,26 @@ ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
err = X509_STORE_CTX_get_error(x509_store);
depth = X509_STORE_CTX_get_error_depth(x509_store);
- name = X509_get_subject_name(cert);
- subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
+ sname = X509_get_subject_name(cert);
+ subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";
- name = X509_get_issuer_name(cert);
- issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
+ iname = X509_get_issuer_name(cert);
+ issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
"verify:%d, error:%d, depth:%d, "
"subject:\"%s\",issuer: \"%s\"",
ok, err, depth, subject, issuer);
+ if (sname) {
+ OPENSSL_free(subject);
+ }
+
+ if (iname) {
+ OPENSSL_free(issuer);
+ }
+#endif
+
return 1;
}
@@ -1778,6 +1788,7 @@ ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
name = X509_get_subject_name(cert);
if (name == NULL) {
+ X509_free(cert);
return NGX_ERROR;
}
@@ -1789,12 +1800,14 @@ ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
s->data = ngx_palloc(pool, len);
if (s->data == NULL) {
OPENSSL_free(p);
+ X509_free(cert);
return NGX_ERROR;
}
ngx_memcpy(s->data, p, len);
OPENSSL_free(p);
+ X509_free(cert);
return NGX_OK;
}
@@ -1817,6 +1830,7 @@ ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
name = X509_get_issuer_name(cert);
if (name == NULL) {
+ X509_free(cert);
return NGX_ERROR;
}
@@ -1828,12 +1842,14 @@ ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
s->data = ngx_palloc(pool, len);
if (s->data == NULL) {
OPENSSL_free(p);
+ X509_free(cert);
return NGX_ERROR;
}
ngx_memcpy(s->data, p, len);
OPENSSL_free(p);
+ X509_free(cert);
return NGX_OK;
}
@@ -1855,6 +1871,7 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
bio = BIO_new(BIO_s_mem());
if (bio == NULL) {
+ X509_free(cert);
return NGX_ERROR;
}
@@ -1865,11 +1882,13 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
s->data = ngx_palloc(pool, len);
if (s->data == NULL) {
BIO_free(bio);
+ X509_free(cert);
return NGX_ERROR;
}
BIO_read(bio, s->data, len);
BIO_free(bio);
+ X509_free(cert);
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c
index 93d1b36ef..663a9f5b7 100644
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -590,7 +590,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
ctx->state = sub_start_state;
ctx->pos = p + 1;
- ctx->looked = looked;
+ ctx->looked = 0;
ctx->copy_end = copy_end;
if (ctx->copy_start == NULL && copy_end) {
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 822ae81ea..7f781a10e 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.6.29';
+our $VERSION = '0.6.30';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 22866639a..3ef1dcbc8 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -19,7 +19,7 @@ static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
static char *ngx_http_merge_locations(ngx_conf_t *cf,
ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module,
ngx_uint_t ctx_index);
-static int ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
+static ngx_int_t ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
const void *two);
@@ -1089,7 +1089,7 @@ ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations,
}
-static int
+static ngx_int_t
ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
{
ngx_http_conf_in_addr_t *first, *second;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 08c1d352b..f57db3622 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -45,7 +45,8 @@ static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
-static int ngx_http_core_cmp_locations(const void *first, const void *second);
+static ngx_int_t ngx_http_core_cmp_locations(const void *first,
+ const void *second);
static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -2297,7 +2298,7 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
}
-static int
+static ngx_int_t
ngx_http_core_cmp_locations(const void *one, const void *two)
{
ngx_int_t rc;
@@ -2361,7 +2362,7 @@ ngx_http_core_cmp_locations(const void *one, const void *two)
return 1;
}
- return (int) rc;
+ return rc;
}
@@ -3470,6 +3471,7 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_loc_conf_t *lcf = conf;
+ u_char *args;
ngx_int_t overwrite;
ngx_str_t *value, uri;
ngx_uint_t i, n, nvar;
@@ -3538,6 +3540,8 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
+ args = (u_char *) ngx_strchr(uri.data, '?');
+
for (i = 1; i < cf->args->nelts - n; i++) {
err = ngx_array_push(lcf->error_pages);
if (err == NULL) {
@@ -3576,7 +3580,19 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
- err->uri = uri;
+ if (args) {
+ err->uri.len = args - uri.data;
+ err->uri.data = uri.data;
+ args++;
+ err->args.len = (uri.data + uri.len) - args;
+ err->args.data = args;
+
+ } else {
+ err->uri = uri;
+ err->args.len = 0;
+ err->args.data = NULL;
+ }
+
err->uri_lengths = uri_lengths;
err->uri_values = uri_values;
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index e11d82941..9a9f97bdd 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -225,6 +225,7 @@ typedef struct {
ngx_int_t status;
ngx_int_t overwrite;
ngx_str_t uri;
+ ngx_str_t args;
ngx_array_t *uri_lengths;
ngx_array_t *uri_values;
} ngx_http_err_page_t;
diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c
index 115508954..eac23f2f9 100644
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -240,7 +240,7 @@ ngx_http_parse_time(u_char *value, size_t len)
/*
* shift new year to March 1 and start months from 1 (not 0),
- * it is needed for Gauss's formula
+ * it is needed for Gauss' formula
*/
if (--month <= 0) {
@@ -248,11 +248,20 @@ ngx_http_parse_time(u_char *value, size_t len)
year -= 1;
}
- /* Gauss's formula for Grigorian days from March 1, 1 BC */
+ /* Gauss' formula for Grigorian days since March 1, 1 BC */
- return (365 * year + year / 4 - year / 100 + year / 400
- + 367 * month / 12 - 31
- + day
+ return (
+ /* days in years including leap years since March 1, 1 BC */
+
+ 365 * year + year / 4 - year / 100 + year / 400
+
+ /* days before the month */
+
+ + 367 * month / 12 - 30
+
+ /* days before the day */
+
+ + day - 1
/*
* 719527 days were between March 1, 1 BC and March 1, 1970,
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index d87f77d54..b248321e2 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1419,6 +1419,7 @@ ngx_http_process_request(ngx_http_request_t *r)
if (c->ssl) {
long rc;
+ X509 *cert;
ngx_http_ssl_srv_conf_t *sscf;
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
@@ -1438,9 +1439,9 @@ ngx_http_process_request(ngx_http_request_t *r)
return;
}
- if (SSL_get_peer_certificate(c->ssl->connection)
- == NULL)
- {
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+
+ if (cert == NULL) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent no required SSL certificate");
@@ -1450,6 +1451,8 @@ ngx_http_process_request(ngx_http_request_t *r)
ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
return;
}
+
+ X509_free(cert);
}
}
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 741a9b1d4..306944b61 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -441,8 +441,6 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
r->zero_in_uri = 0;
- args = NULL;
-
if (err_page->uri_lengths) {
if (ngx_http_script_run(r, &u, err_page->uri_lengths->elts, 0,
err_page->uri_values->elts)
@@ -453,6 +451,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
p = u.data;
uri = &u;
+ args = NULL;
if (*p == '/') {
@@ -488,6 +487,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
} else {
uri = &err_page->uri;
+ args = &err_page->args;
}
if (uri->data[0] == '/') {
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index be30b8862..9ec861cfa 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -333,7 +333,6 @@ ngx_http_upstream_init(ngx_http_request_t *r)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- u->output.sendfile = c->sendfile;
u->output.pool = r->pool;
u->output.bufs.num = 1;
u->output.bufs.size = clcf->client_body_buffer_size;
@@ -422,13 +421,14 @@ ngx_http_upstream_init(ngx_http_request_t *r)
ctx->data = r;
ctx->timeout = clcf->resolver_timeout;
+ u->resolved->ctx = ctx;
+
if (ngx_resolve_name(ctx) != NGX_OK) {
+ u->resolved->ctx = NULL;
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
- u->resolved->ctx = ctx;
-
return;
}
@@ -702,6 +702,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
c->read->handler = ngx_http_upstream_process_header;
c->sendfile &= r->connection->sendfile;
+ u->output.sendfile = c->sendfile;
c->pool = r->pool;
c->read->log = c->write->log = c->log = r->connection->log;
@@ -2612,6 +2613,10 @@ ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
while (*++p == ' ') { /* void */ }
+ if (*p == '\0') {
+ return NGX_OK;
+ }
+
if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
continue;
}
@@ -3200,7 +3205,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
fail_timeout = ngx_parse_time(&s, 1);
- if (fail_timeout < 0) {
+ if (fail_timeout == NGX_ERROR) {
goto invalid;
}
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index c25c076b4..062137158 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -9,7 +9,8 @@
#include <ngx_http.h>
-static int ngx_http_upstream_cmp_servers(const void *one, const void *two);
+static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,
+ const void *two);
static ngx_uint_t
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers);
@@ -185,7 +186,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
}
-static int
+static ngx_int_t
ngx_http_upstream_cmp_servers(const void *one, const void *two)
{
ngx_http_upstream_rr_peer_t *first, *second;
diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c
index 95d29e893..00c255040 100644
--- a/src/mail/ngx_mail.c
+++ b/src/mail/ngx_mail.c
@@ -11,7 +11,7 @@
static char *ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static int ngx_mail_cmp_conf_in_addrs(const void *one, const void *two);
+static ngx_int_t ngx_mail_cmp_conf_in_addrs(const void *one, const void *two);
ngx_uint_t ngx_mail_max_module;
@@ -388,7 +388,7 @@ ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
-static int
+static ngx_int_t
ngx_mail_cmp_conf_in_addrs(const void *one, const void *two)
{
ngx_mail_conf_in_addr_t *first, *second;
diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c
index 9f5a2f6cb..3cac329b7 100644
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -171,6 +171,8 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_peer_addr_t *peer)
return;
}
+ s->out.len = 0;
+
switch (s->protocol) {
case NGX_MAIL_POP3_PROTOCOL:
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index a091b9b77..7ee8cbd84 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -257,7 +257,15 @@ ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
ngx_int_t
ngx_open_glob(ngx_glob_t *gl)
{
- if (glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob) == 0) {
+ int n;
+
+ n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
+
+ if (n == 0) {
+ return NGX_OK;
+ }
+
+ if (n == GLOB_NOMATCH && gl->test) {
return NGX_OK;
}
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index aa7311d72..a223b34e8 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -17,8 +17,18 @@
+#ifdef __CYGWIN__
+
+#define ngx_open_file(name, mode, create, access) \
+ open((const char *) name, mode|create|O_BINARY, access)
+
+#else
+
#define ngx_open_file(name, mode, create, access) \
open((const char *) name, mode|create, access)
+
+#endif
+
#define ngx_open_file_n "open()"
#define NGX_FILE_RDONLY O_RDONLY
@@ -144,10 +154,11 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
typedef struct {
- size_t n;
- glob_t pglob;
- u_char *pattern;
- ngx_log_t *log;
+ size_t n;
+ glob_t pglob;
+ u_char *pattern;
+ ngx_log_t *log;
+ ngx_uint_t test;
} ngx_glob_t;
diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h
index 37176e0d2..ae6f70f6a 100644
--- a/src/os/unix/ngx_posix_config.h
+++ b/src/os/unix/ngx_posix_config.h
@@ -70,7 +70,7 @@
#include <limits.h> /* IOV_MAX */
#endif
-#if (NGX_HAVE_MALLOC_H)
+#ifdef __CYGWIN__
#include <malloc.h> /* memalign() */
#endif
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index 9bd78f78e..ca3eae108 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -452,7 +452,7 @@ ngx_process_get_status(void)
*
* When several processes exit at the same time FreeBSD may
* erroneously call the signal handler for exited process
- * despite waitpid() may be already called for this process
+ * despite waitpid() may be already called for this process.
*/
if (err == NGX_ECHILD) {
@@ -507,8 +507,9 @@ ngx_process_get_status(void)
if (WEXITSTATUS(status) == 2 && ngx_processes[i].respawn) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "%s %P exited with fatal code %d and could not respawn",
- process, pid, WEXITSTATUS(status));
+ "%s %P exited with fatal code %d "
+ "and can not be respawn",
+ process, pid, WEXITSTATUS(status));
ngx_processes[i].respawn = 0;
}
}