nginx-0.3.53-RELEASE import
*) Change: the "add_header" directive adds the string to 204, 301, and
302 responses.
*) Feature: the "server" directive in the "upstream" context supports
the "weight" parameter.
*) Feature: the "server_name" directive supports the "*" wildcard.
*) Feature: nginx supports the request body size more than 2G.
*) Bugfix: if a client was successfully authorized using "satisfy_any
on", then anyway the message "access forbidden by rule" was written
in the log.
*) Bugfix: the "PUT" method may erroneously not create a file and
return the 409 code.
*) Bugfix: if the IMAP/POP3 backend returned an error, then nginx
continued proxying anyway.
diff --git a/src/core/nginx.h b/src/core/nginx.h
index ad8c768..50746ae 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VER "nginx/0.3.52"
+#define NGINX_VER "nginx/0.3.53"
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index 94dfe62..b5d8b16 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -1036,6 +1036,37 @@
char *
+ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ char *p = conf;
+
+ off_t *op;
+ ngx_str_t *value;
+ ngx_conf_post_t *post;
+
+
+ op = (off_t *) (p + cmd->offset);
+ if (*op != NGX_CONF_UNSET) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ *op = ngx_parse_offset(&value[1]);
+ if (*op == (off_t) NGX_ERROR) {
+ return "invalid value";
+ }
+
+ if (cmd->post) {
+ post = cmd->post;
+ return post->post_handler(cf, post, op);
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+char *
ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index 17c24c7..7d51129 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -236,8 +236,8 @@
conf = default; \
}
-#define ngx_conf_init_unsigned_value(conf, default) \
- if (conf == (unsigned) NGX_CONF_UNSET) { \
+#define ngx_conf_init_uint_value(conf, default) \
+ if (conf == NGX_CONF_UNSET_UINT) { \
conf = default; \
}
@@ -261,7 +261,7 @@
conf = (prev == NULL) ? default : prev; \
}
-#define ngx_conf_merge_unsigned_value(conf, prev, default) \
+#define ngx_conf_merge_uint_value(conf, prev, default) \
if (conf == NGX_CONF_UNSET_UINT) { \
conf = (prev == NGX_CONF_UNSET_UINT) ? default : prev; \
}
@@ -281,6 +281,11 @@
conf = (prev == NGX_CONF_UNSET_SIZE) ? default : prev; \
}
+#define ngx_conf_merge_off_value(conf, prev, default) \
+ if (conf == NGX_CONF_UNSET) { \
+ conf = (prev == NGX_CONF_UNSET) ? default : prev; \
+ }
+
#define ngx_conf_merge_str_value(conf, prev, default) \
if (conf.data == NULL) { \
if (prev.data) { \
@@ -328,6 +333,7 @@
char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index f2b0cf7..7b3fef3 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -479,7 +479,6 @@
}
peers->number = i;
- peers->weight = 1;
for (i = 0; h->h_addr_list[i] != NULL; i++) {
@@ -511,6 +510,10 @@
- peers->peer[i].name.data;
peers->peer[i].uri_separator = "";
+
+ peers->peer[i].weight = NGX_CONF_UNSET_UINT;
+ peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
+ peers->peer[i].fail_timeout = NGX_CONF_UNSET;
}
} else {
@@ -643,7 +646,6 @@
}
peers->number = i;
- peers->weight = 1;
for (i = 0; h->h_addr_list[i] != NULL; i++) {
@@ -677,6 +679,10 @@
peers->peer[i].name.len = len + u->port_text.len;
peers->peer[i].uri_separator = "";
+
+ peers->peer[i].weight = NGX_CONF_UNSET_UINT;
+ peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
+ peers->peer[i].fail_timeout = NGX_CONF_UNSET;
}
} else {
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
index 7600ed8..3014023 100644
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -29,6 +29,7 @@
ngx_str_t name;
char *uri_separator;
+ ngx_uint_t current_weight;
ngx_uint_t weight;
ngx_uint_t fails;
@@ -45,7 +46,6 @@
struct ngx_peers_s {
ngx_uint_t current;
- ngx_uint_t weight;
ngx_uint_t number;
ngx_uint_t last_cached;
diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c
index 28e5d96..7868245 100644
--- a/src/core/ngx_parse.c
+++ b/src/core/ngx_parse.c
@@ -47,6 +47,51 @@
}
+off_t
+ngx_parse_offset(ngx_str_t *line)
+{
+ u_char last;
+ off_t offset;
+ size_t len;
+ ngx_int_t scale;
+
+ len = line->len;
+ last = line->data[len - 1];
+
+ switch (last) {
+ case 'K':
+ case 'k':
+ len--;
+ scale = 1024;
+ break;
+
+ case 'M':
+ case 'm':
+ len--;
+ scale = 1024 * 1024;
+ break;
+
+ case 'G':
+ case 'g':
+ len--;
+ scale = 1024 * 1024 * 1024;
+ break;
+
+ default:
+ scale = 1;
+ }
+
+ offset = ngx_atoof(line->data, len);
+ if (offset == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ offset *= scale;
+
+ return offset;
+}
+
+
ngx_int_t
ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
{
diff --git a/src/core/ngx_parse.h b/src/core/ngx_parse.h
index 464cefc..cf3f0b2 100644
--- a/src/core/ngx_parse.h
+++ b/src/core/ngx_parse.h
@@ -16,6 +16,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);
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index b149bfe..1ea51f9 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -510,8 +510,8 @@
{
ngx_devpoll_conf_t *dpcf = conf;
- ngx_conf_init_unsigned_value(dpcf->changes, 32);
- ngx_conf_init_unsigned_value(dpcf->events, 32);
+ ngx_conf_init_uint_value(dpcf->changes, 32);
+ ngx_conf_init_uint_value(dpcf->events, 32);
return NGX_CONF_OK;
}
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index e476667..184346a 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -479,11 +479,13 @@
c->fd, revents);
}
+#if 0
if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"strange epoll_wait() events fd:%d ev:%04XD",
c->fd, revents);
}
+#endif
if ((revents & (EPOLLERR|EPOLLHUP))
&& (revents & (EPOLLIN|EPOLLOUT)) == 0)
@@ -564,7 +566,7 @@
{
ngx_epoll_conf_t *epcf = conf;
- ngx_conf_init_unsigned_value(epcf->events, 512);
+ ngx_conf_init_uint_value(epcf->events, 512);
return NGX_CONF_OK;
}
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 4fc98e9..7dc1562 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -1205,10 +1205,10 @@
return NGX_CONF_ERROR;
}
- ngx_conf_init_unsigned_value(ecf->connections, connections);
+ ngx_conf_init_uint_value(ecf->connections, connections);
cycle->connection_n = ecf->connections;
- ngx_conf_init_unsigned_value(ecf->use, module->ctx_index);
+ ngx_conf_init_uint_value(ecf->use, module->ctx_index);
event_module = module->ctx;
ngx_conf_init_ptr_value(ecf->name, event_module->name->data);
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index 157c480..2b4c08d 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -81,8 +81,6 @@
pc->peers->current = 0;
}
- pc->peers->weight = pc->peers->peer[pc->peers->current].weight;
-
pc->tries--;
if (pc->tries) {
@@ -92,16 +90,16 @@
goto failed;
}
- pc->peers->weight--;
+ peer->current_weight--;
- if (pc->peers->weight == 0) {
+ if (peer->current_weight == 0) {
+ peer->current_weight = peer->weight;
+
pc->peers->current++;
if (pc->peers->current >= pc->peers->number) {
pc->peers->current = 0;
}
-
- pc->peers->weight = pc->peers->peer[pc->peers->current].weight;
}
} else {
@@ -131,6 +129,20 @@
goto failed;
}
+
+ peer->current_weight--;
+
+ if (peer->current_weight == 0) {
+ peer->current_weight = peer->weight;
+
+ if (pc->cur_peer == pc->peers->current) {
+ pc->peers->current++;
+
+ if (pc->peers->current >= pc->peers->number) {
+ pc->peers->current = 0;
+ }
+ }
+ }
}
}
@@ -358,15 +370,22 @@
void
ngx_event_connect_peer_failed(ngx_peer_connection_t *pc, ngx_uint_t down)
{
- time_t now;
+ time_t now;
+ ngx_peer_t *peer;
if (down) {
now = ngx_time();
/* ngx_lock_mutex(pc->peers->mutex); */
- pc->peers->peer[pc->cur_peer].fails++;
- pc->peers->peer[pc->cur_peer].accessed = now;
+ peer = &pc->peers->peer[pc->cur_peer];
+
+ peer->fails++;
+ peer->accessed = now;
+
+ if (peer->current_weight > 1) {
+ peer->current_weight /= 2;
+ }
/* ngx_unlock_mutex(pc->peers->mutex); */
}
diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c
index 710dd24..b8aa3aa 100644
--- a/src/http/modules/ngx_http_access_module.c
+++ b/src/http/modules/ngx_http_access_module.c
@@ -92,6 +92,7 @@
ngx_uint_t i;
struct sockaddr_in *sin;
ngx_http_access_rule_t *rule;
+ ngx_http_core_loc_conf_t *clcf;
ngx_http_access_loc_conf_t *alcf;
alcf = ngx_http_get_module_loc_conf(r, ngx_http_access_module);
@@ -113,8 +114,12 @@
if ((sin->sin_addr.s_addr & rule[i].mask) == rule[i].addr) {
if (rule[i].deny) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "access forbidden by rule");
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (!clcf->satisfy_any) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "access forbidden by rule");
+ }
return NGX_HTTP_FORBIDDEN;
}
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index d33e7f6..5dd2876 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -136,7 +136,7 @@
fd = ngx_open_file(alcf->user_file.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
if (fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_open_file_n " \"%s\" failed", alcf->user_file.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 41a0e57..0bc31bc 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -188,7 +188,7 @@
{
u_char *ct;
ngx_int_t charset, source_charset;
- ngx_str_t *mc;
+ ngx_str_t *mc, *from, *to;
ngx_uint_t n;
ngx_http_charset_t *charsets;
ngx_http_charset_ctx_t *ctx;
@@ -288,13 +288,10 @@
return ngx_http_next_header_filter(r);
}
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no \"charset_map\" between the charsets "
- "\"%V\" and \"%V\"",
- &charsets[lcf->source_charset].name,
- &r->main->headers_out.charset);
+ from = &charsets[lcf->source_charset].name;
+ to = &r->main->headers_out.charset;
- return ngx_http_next_header_filter(r);
+ goto no_charset_map;
}
source_charset = ngx_http_charset_get_charset(charsets, n,
@@ -308,11 +305,12 @@
r->headers_out.charset.data)
!= 0)
{
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no \"charset_map\" between the charsets "
- "\"%V\" and \"%V\"",
- &r->headers_out.charset,
- &r->main->headers_out.charset);
+ from = &r->headers_out.charset;
+ to = (charset == NGX_HTTP_NO_CHARSET) ?
+ &r->main->headers_out.charset:
+ &charsets[charset].name;
+
+ goto no_charset_map;
}
return ngx_http_next_header_filter(r);
@@ -322,18 +320,24 @@
&& (charsets[source_charset].tables == NULL
|| charsets[source_charset].tables[charset] == NULL))
{
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no \"charset_map\" between the charsets "
- "\"%V\" and \"%V\"",
- &charsets[source_charset].name, &charsets[charset].name);
+ from = &charsets[source_charset].name;
+ to = &charsets[charset].name;
- return ngx_http_next_header_filter(r);
+ goto no_charset_map;
}
r->headers_out.content_type.len = r->headers_out.content_type_len;
return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset,
source_charset);
+
+no_charset_map:
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "no \"charset_map\" between the charsets "
+ "\"%V\" and \"%V\"", from, to);
+
+ return ngx_http_next_header_filter(r);
}
@@ -392,11 +396,14 @@
ctx->from_utf8 = charsets[source_charset].utf8;
ctx->to_utf8 = charsets[charset].utf8;
+ r->filter_need_in_memory = 1;
+
if ((ctx->to_utf8 || ctx->from_utf8) && r == r->main) {
ngx_http_clear_content_length(r);
- }
- r->filter_need_in_memory = 1;
+ } else {
+ r->filter_need_temporary = 1;
+ }
return ngx_http_next_header_filter(r);
}
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 7f61774..53ef21c 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -251,17 +251,20 @@
} else {
status = NGX_HTTP_NO_CONTENT;
- }
- if (ngx_is_dir(&fi)) {
- if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed",
- temp->data);
+ if (ngx_is_dir(&fi)) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EISDIR,
+ "\"%s\" could not be created", path.data);
+
+ if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed",
+ temp->data);
+ }
+
+ ngx_http_finalize_request(r, NGX_HTTP_CONFLICT);
+ return;
}
-
- ngx_http_finalize_request(r, NGX_HTTP_CONFLICT);
- return;
}
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 085fb47..172a1a7 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -1565,6 +1565,7 @@
uintptr_t *code;
ngx_str_t *header;
ngx_uint_t i, j;
+ ngx_peer_t *peer;
ngx_array_t hide_headers;
ngx_keyval_t *src;
ngx_hash_key_t *hk;
@@ -1693,20 +1694,23 @@
|NGX_HTTP_UPSTREAM_FT_ERROR
|NGX_HTTP_UPSTREAM_FT_TIMEOUT));
- ngx_conf_merge_unsigned_value(conf->upstream.max_fails,
+ ngx_conf_merge_uint_value(conf->upstream.max_fails,
prev->upstream.max_fails, 1);
ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
prev->upstream.fail_timeout, 10);
- if (conf->upstream_peers && !conf->upstream_peers->balanced) {
+ if (conf->upstream_peers) {
+ peer = conf->upstream_peers->peers->peer;
for (i = 0; i < conf->upstream_peers->peers->number; i++) {
- conf->upstream_peers->peers->peer[i].weight = 1;
- conf->upstream_peers->peers->peer[i].max_fails =
- conf->upstream.max_fails;
- conf->upstream_peers->peers->peer[i].fail_timeout =
- conf->upstream.fail_timeout;
+ ngx_conf_init_uint_value(peer[i].weight, 1);
+ peer[i].current_weight = peer[i].weight;
+ ngx_conf_init_uint_value(peer[i].max_fails,
+ conf->upstream.max_fails);
+ ngx_conf_init_value(peer[i].fail_timeout,
+ conf->upstream.fail_timeout);
}
+
}
ngx_conf_merge_path_value(conf->upstream.temp_path,
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index a08f31c..26c1649 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -1087,7 +1087,7 @@
ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
- ngx_conf_merge_unsigned_value(conf->http_version, prev->http_version,
+ ngx_conf_merge_uint_value(conf->http_version, prev->http_version,
NGX_HTTP_VERSION_11);
ngx_conf_merge_bitmask_value(conf->proxied, prev->proxied,
(NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index 8ced8e0..8065742 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -103,9 +103,12 @@
ngx_http_header_val_t *h;
ngx_http_headers_conf_t *conf;
- if ((r->headers_out.status != NGX_HTTP_OK
- && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)
- || r != r->main)
+ if (r != r->main
+ || (r->headers_out.status != NGX_HTTP_OK
+ && r->headers_out.status != NGX_HTTP_NO_CONTENT
+ && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
+ && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY
+ && r->headers_out.status != NGX_HTTP_NOT_MODIFIED))
{
return ngx_http_next_header_filter(r);
}
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 5e16363..f85a6c8 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -478,7 +478,7 @@
ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)
{
- return ngx_sprintf(buf, "%z", r->request_length);
+ return ngx_sprintf(buf, "%O", r->request_length);
}
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index 5b07dbc..000622d 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -560,7 +560,7 @@
|NGX_HTTP_UPSTREAM_FT_ERROR
|NGX_HTTP_UPSTREAM_FT_TIMEOUT));
- ngx_conf_merge_unsigned_value(conf->upstream.max_fails,
+ ngx_conf_merge_uint_value(conf->upstream.max_fails,
prev->upstream.max_fails, 1);
ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index f14151a..ff5b129 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1520,6 +1520,7 @@
uintptr_t *code;
ngx_str_t *header;
ngx_uint_t i, j;
+ ngx_peer_t *peer;
ngx_array_t hide_headers;
ngx_keyval_t *src, *s, *h;
ngx_hash_key_t *hk;
@@ -1647,19 +1648,21 @@
|NGX_HTTP_UPSTREAM_FT_ERROR
|NGX_HTTP_UPSTREAM_FT_TIMEOUT));
- ngx_conf_merge_unsigned_value(conf->upstream.max_fails,
+ ngx_conf_merge_uint_value(conf->upstream.max_fails,
prev->upstream.max_fails, 1);
ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
prev->upstream.fail_timeout, 10);
- if (conf->upstream_peers && !conf->upstream_peers->balanced) {
+ if (conf->upstream_peers) {
+ peer = conf->upstream_peers->peers->peer;
for (i = 0; i < conf->upstream_peers->peers->number; i++) {
- conf->upstream_peers->peers->peer[i].weight = 1;
- conf->upstream_peers->peers->peer[i].max_fails =
- conf->upstream.max_fails;
- conf->upstream_peers->peers->peer[i].fail_timeout =
- conf->upstream.fail_timeout;
+ ngx_conf_init_uint_value(peer[i].weight, 1);
+ peer[i].current_weight = peer[i].weight;
+ ngx_conf_init_uint_value(peer[i].max_fails,
+ conf->upstream.max_fails);
+ ngx_conf_init_value(peer[i].fail_timeout,
+ conf->upstream.fail_timeout);
}
}
diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c
index 210bbf6..3940ee4 100644
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -243,7 +243,7 @@
conf->from = prev->from;
}
- ngx_conf_merge_unsigned_value(conf->xfwd, prev->xfwd, 0);
+ ngx_conf_merge_uint_value(conf->xfwd, prev->xfwd, 0);
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index c557314..88988bd 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -245,7 +245,7 @@
ngx_conf_merge_value(conf->log, prev->log, 0);
ngx_conf_merge_value(conf->uninitialized_variable_warn,
prev->uninitialized_variable_warn, 1);
- ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10);
+ ngx_conf_merge_uint_value(conf->stack_size, prev->stack_size, 10);
if (conf->codes == NULL) {
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index 92c53f8..bdad35d 100644
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -670,8 +670,8 @@
ngx_http_userid_conf_t *prev = parent;
ngx_http_userid_conf_t *conf = child;
- ngx_conf_merge_unsigned_value(conf->enable, prev->enable,
- NGX_HTTP_USERID_OFF);
+ ngx_conf_merge_uint_value(conf->enable, prev->enable,
+ NGX_HTTP_USERID_OFF);
ngx_conf_merge_str_value(conf->name, prev->name, "uid");
ngx_conf_merge_str_value(conf->domain, prev->domain, "");
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 91a9c85..bf976e9 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -833,9 +833,9 @@
ngx_http_perl_main_conf_t *pmcf = conf;
#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
- ngx_conf_init_unsigned_value(pmcf->interp_max, 10);
+ ngx_conf_init_uint_value(pmcf->interp_max, 10);
#else
- ngx_conf_init_unsigned_value(pmcf->interp_max, 1);
+ ngx_conf_init_uint_value(pmcf->interp_max, 1);
#endif
pmcf->free_perls = ngx_pcalloc(cf->pool,
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index ca963ab..b417f41 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -242,7 +242,7 @@
{ ngx_string("client_max_body_size"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
+ ngx_conf_set_off_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
NULL },
@@ -634,6 +634,12 @@
}
if (r->phase == NGX_HTTP_ACCESS_PHASE && r->access_code) {
+
+ if (r->access_code == NGX_HTTP_FORBIDDEN) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "access forbidden by rule");
+ }
+
ngx_http_finalize_request(r, r->access_code);
return;
}
@@ -690,15 +696,15 @@
ngx_http_update_location_config(r);
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http cl:%z max:%uz",
+ "http cl:%O max:%O",
r->headers_in.content_length_n, clcf->client_max_body_size);
if (r->headers_in.content_length_n != -1
&& clcf->client_max_body_size
- && clcf->client_max_body_size < (size_t) r->headers_in.content_length_n)
+ && clcf->client_max_body_size < r->headers_in.content_length_n)
{
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client intented to send too large body: %z bytes",
+ "client intented to send too large body: %O bytes",
r->headers_in.content_length_n);
return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
@@ -2015,7 +2021,7 @@
* lcf->alias = 0;
*/
- lcf->client_max_body_size = NGX_CONF_UNSET_SIZE;
+ lcf->client_max_body_size = NGX_CONF_UNSET;
lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
lcf->satisfy_any = NGX_CONF_UNSET;
@@ -2086,12 +2092,12 @@
conf->post_action = prev->post_action;
}
- ngx_conf_merge_unsigned_value(conf->types_hash_max_size,
- prev->types_hash_max_size, 1024);
+ ngx_conf_merge_uint_value(conf->types_hash_max_size,
+ prev->types_hash_max_size, 1024);
- ngx_conf_merge_unsigned_value(conf->types_hash_bucket_size,
- prev->types_hash_bucket_size,
- ngx_cacheline_size);
+ ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
+ prev->types_hash_bucket_size,
+ ngx_cacheline_size);
conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
ngx_cacheline_size);
@@ -2175,7 +2181,7 @@
ngx_conf_merge_str_value(conf->default_type,
prev->default_type, "text/plain");
- ngx_conf_merge_size_value(conf->client_max_body_size,
+ ngx_conf_merge_off_value(conf->client_max_body_size,
prev->client_max_body_size, 1 * 1024 * 1024);
ngx_conf_merge_size_value(conf->client_body_buffer_size,
prev->client_body_buffer_size,
@@ -2451,6 +2457,11 @@
ch = value[i].data[0];
+ if (value[i].len == 1 && ch == '*') {
+ cscf->wildcard = 1;
+ continue;
+ }
+
if (value[i].len == 0
|| (ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
|| (ch == '.' && value[i].len < 2))
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 4f7823d..661f1b9 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -116,6 +116,8 @@
ngx_flag_t optimize_server_names;
ngx_flag_t ignore_invalid_headers;
+
+ ngx_uint_t wildcard; /* unsigned wildcard:1 */
} ngx_http_core_srv_conf_t;
@@ -213,7 +215,8 @@
ngx_hash_t types_hash;
ngx_str_t default_type;
- size_t client_max_body_size; /* client_max_body_size */
+ off_t client_max_body_size; /* client_max_body_size */
+
size_t client_body_buffer_size; /* client_body_buffer_size */
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 36ed6e1..c6ecd3a 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -84,7 +84,7 @@
ngx_string("406 Not Acceptable"),
ngx_null_string, /* "407 Proxy Authentication Required" */
ngx_string("408 Request Time-out"),
- ngx_null_string, /* "409 Conflict" */
+ ngx_string("409 Conflict"),
ngx_string("410 Gone"),
ngx_string("411 Length Required"),
ngx_null_string, /* "412 Precondition Failed" */
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 5b947ff..bf3b0ed 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1235,7 +1235,7 @@
if (r->headers_in.content_length) {
r->headers_in.content_length_n =
- ngx_atosz(r->headers_in.content_length->value.data,
+ ngx_atoof(r->headers_in.content_length->value.data,
r->headers_in.content_length->value.len);
if (r->headers_in.content_length_n == NGX_ERROR) {
@@ -1395,6 +1395,13 @@
}
}
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+ if (cscf->wildcard) {
+ r->server_name.len = len;
+ r->server_name.data = host;
+ }
+
return;
found:
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 0bec204..b2d4184 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -192,7 +192,7 @@
ngx_array_t cookies;
size_t host_name_len;
- ssize_t content_length_n;
+ off_t content_length_n;
time_t keep_alive_n;
unsigned connection_type:2;
@@ -250,7 +250,7 @@
ngx_temp_file_t *temp_file;
ngx_chain_t *bufs;
ngx_buf_t *buf;
- size_t rest;
+ off_t rest;
ngx_chain_t *to_write;
ngx_http_client_body_handler_pt post_handler;
} ngx_http_request_body_t;
@@ -366,7 +366,7 @@
/* used to learn the Apache compatible response length without a header */
size_t header_size;
- size_t request_length;
+ off_t request_length;
void **err_ctx;
ngx_uint_t err_status;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 605c8ad..c6fa3fc 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -30,7 +30,8 @@
ngx_http_read_client_request_body(ngx_http_request_t *r,
ngx_http_client_body_handler_pt post_handler)
{
- ssize_t size, preread;
+ size_t preread;
+ ssize_t size;
ngx_buf_t *b;
ngx_chain_t *cl, **next;
ngx_http_request_body_t *rb;
@@ -95,7 +96,7 @@
/* the whole request body was pre-read */
- r->header_in->pos += r->headers_in.content_length_n;
+ r->header_in->pos += (size_t) r->headers_in.content_length_n;
r->request_length += r->headers_in.content_length_n;
if (r->request_body_in_file_only) {
@@ -143,8 +144,8 @@
size = clcf->client_body_buffer_size;
size += size >> 2;
- if (rb->rest < (size_t) size) {
- size = rb->rest;
+ if (rb->rest < size) {
+ size = (ssize_t) rb->rest;
if (r->request_body_in_single_buf) {
size += preread;
@@ -242,7 +243,7 @@
size = rb->buf->end - rb->buf->last;
if (size > rb->rest) {
- size = rb->rest;
+ size = (size_t) rb->rest;
}
n = c->recv(c, rb->buf->last, size);
@@ -429,7 +430,7 @@
r->headers_in.content_length_n -= size;
} else {
- r->header_in->pos += r->headers_in.content_length_n;
+ r->header_in->pos += (size_t) r->headers_in.content_length_n;
r->headers_in.content_length_n = 0;
return NGX_OK;
}
@@ -468,7 +469,8 @@
static ngx_int_t
ngx_http_read_discarded_body(ngx_http_request_t *r)
{
- ssize_t size, n;
+ size_t size;
+ ssize_t n;
u_char buffer[NGX_HTTP_DISCARD_BUFFER_SIZE];
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -478,12 +480,9 @@
return NGX_OK;
}
-
- size = r->headers_in.content_length_n;
-
- if (size > NGX_HTTP_DISCARD_BUFFER_SIZE) {
- size = NGX_HTTP_DISCARD_BUFFER_SIZE;
- }
+ size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
+ NGX_HTTP_DISCARD_BUFFER_SIZE:
+ (size_t) r->headers_in.content_length_n;
n = r->connection->recv(r->connection, buffer, size);
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index a8c557a..782c14b 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -226,7 +226,7 @@
NULL },
{ ngx_string("server"),
- NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
+ NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
ngx_http_upstream_server,
NGX_HTTP_SRV_CONF_OFFSET,
0,
@@ -2729,7 +2729,6 @@
}
uscf->peers->number = n;
- uscf->peers->weight = 1;
n = 0;
@@ -2750,6 +2749,8 @@
ngx_str_t *value;
ngx_url_t u;
+ ngx_int_t weight;
+ ngx_uint_t i;
ngx_peers_t **peers;
if (uscf->servers == NULL) {
@@ -2780,9 +2781,41 @@
return NGX_CONF_ERROR;
}
+ weight = 1;
+
+ if (cf->args->nelts == 3) {
+
+ value = &value[2];
+
+ if (ngx_strncmp(value->data, "weight=", 7) == 0) {
+
+ weight = ngx_atoi(&value->data[7], value->len - 7);
+
+ if (weight == NGX_ERROR || weight == 0) {
+ goto invalid;
+ }
+
+ } else {
+ goto invalid;
+ }
+ }
+
+ for (i = 0; i < u.peers->number; i++) {
+ u.peers->peer[i].weight = weight;
+ u.peers->peer[i].current_weight = weight;
+ u.peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
+ u.peers->peer[i].fail_timeout = NGX_CONF_UNSET;
+ }
+
*peers = u.peers;
return NGX_CONF_OK;
+
+invalid:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", value);
+
+ return NGX_CONF_ERROR;
}
@@ -2893,8 +2926,7 @@
}
uscfp[i]->peers = ngx_inet_resolve_peer(cf, &uscfp[i]->host,
- uscfp[i]->port);
-
+ uscfp[i]->port);
if (uscfp[i]->peers == NULL) {
return NGX_CONF_ERROR;
}
@@ -2908,6 +2940,7 @@
}
}
+
if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 53705fc..086d184 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -56,8 +56,6 @@
ngx_str_t file_name;
ngx_uint_t line;
in_port_t port;
-
- ngx_uint_t balanced; /* unsigned balanced:1; */
} ngx_http_upstream_srv_conf_t;
diff --git a/src/imap/ngx_imap.h b/src/imap/ngx_imap.h
index e4928be..a55ad8c 100644
--- a/src/imap/ngx_imap.h
+++ b/src/imap/ngx_imap.h
@@ -109,7 +109,7 @@
ngx_imap_start = 0,
ngx_imap_login,
ngx_imap_user,
- ngx_imap_passwd,
+ ngx_imap_passwd
} ngx_imap_state_e;
diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c
index c76ad6c..af50ad6 100644
--- a/src/imap/ngx_imap_core_module.c
+++ b/src/imap/ngx_imap_core_module.c
@@ -205,7 +205,7 @@
prev->imap_client_buffer_size,
(size_t) ngx_pagesize);
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
- ngx_conf_merge_unsigned_value(conf->protocol, prev->protocol,
+ ngx_conf_merge_uint_value(conf->protocol, prev->protocol,
NGX_IMAP_IMAP_PROTOCOL);
ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
diff --git a/src/imap/ngx_imap_proxy_module.c b/src/imap/ngx_imap_proxy_module.c
index 97df382..6ab225b 100644
--- a/src/imap/ngx_imap_proxy_module.c
+++ b/src/imap/ngx_imap_proxy_module.c
@@ -23,7 +23,7 @@
static void ngx_imap_proxy_pop3_handler(ngx_event_t *rev);
static void ngx_imap_proxy_dummy_handler(ngx_event_t *ev);
static ngx_int_t ngx_imap_proxy_read_response(ngx_imap_session_t *s,
- ngx_uint_t what);
+ ngx_uint_t state);
static void ngx_imap_proxy_handler(ngx_event_t *ev);
static void ngx_imap_proxy_internal_server_error(ngx_imap_session_t *s);
static void ngx_imap_proxy_close_session(ngx_imap_session_t *s);
@@ -32,10 +32,6 @@
void *child);
-#define NGX_IMAP_WAIT_OK 0
-#define NGX_IMAP_WAIT_NEXT 1
-
-
static ngx_command_t ngx_imap_proxy_commands[] = {
{ ngx_string("proxy"),
@@ -201,8 +197,7 @@
}
}
- rc = ngx_imap_proxy_read_response(s, s->imap_state == ngx_imap_start ?
- NGX_IMAP_WAIT_OK : NGX_IMAP_WAIT_NEXT);
+ rc = ngx_imap_proxy_read_response(s, s->imap_state);
if (rc == NGX_AGAIN) {
return;
@@ -274,6 +269,23 @@
s->imap_state = ngx_imap_passwd;
break;
+ case ngx_imap_passwd:
+ s->connection->read->handler = ngx_imap_proxy_handler;
+ s->connection->write->handler = ngx_imap_proxy_handler;
+ rev->handler = ngx_imap_proxy_handler;
+ c->write->handler = ngx_imap_proxy_handler;
+
+ pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
+ ngx_add_timer(s->connection->read, pcf->timeout);
+ ngx_del_timer(c->read);
+
+ c->log->action = NULL;
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
+
+ ngx_imap_proxy_handler(s->connection->write);
+
+ return;
+
default:
#if (NGX_SUPPRESS_WARN)
line.len = 0;
@@ -293,20 +305,6 @@
s->proxy->buffer->pos = s->proxy->buffer->start;
s->proxy->buffer->last = s->proxy->buffer->start;
-
- if (s->imap_state == ngx_imap_passwd) {
- s->connection->read->handler = ngx_imap_proxy_handler;
- s->connection->write->handler = ngx_imap_proxy_handler;
- rev->handler = ngx_imap_proxy_handler;
- c->write->handler = ngx_imap_proxy_handler;
-
- pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
- ngx_add_timer(s->connection->read, pcf->timeout);
- ngx_del_timer(c->read);
-
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
- }
}
@@ -344,7 +342,7 @@
}
}
- rc = ngx_imap_proxy_read_response(s, NGX_IMAP_WAIT_OK);
+ rc = ngx_imap_proxy_read_response(s, 0);
if (rc == NGX_AGAIN) {
return;
@@ -395,6 +393,23 @@
s->imap_state = ngx_pop3_passwd;
break;
+ case ngx_pop3_passwd:
+ s->connection->read->handler = ngx_imap_proxy_handler;
+ s->connection->write->handler = ngx_imap_proxy_handler;
+ rev->handler = ngx_imap_proxy_handler;
+ c->write->handler = ngx_imap_proxy_handler;
+
+ pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
+ ngx_add_timer(s->connection->read, pcf->timeout);
+ ngx_del_timer(c->read);
+
+ c->log->action = NULL;
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
+
+ ngx_imap_proxy_handler(s->connection->write);
+
+ return;
+
default:
#if (NGX_SUPPRESS_WARN)
line.len = 0;
@@ -414,20 +429,6 @@
s->proxy->buffer->pos = s->proxy->buffer->start;
s->proxy->buffer->last = s->proxy->buffer->start;
-
- if (s->imap_state == ngx_pop3_passwd) {
- s->connection->read->handler = ngx_imap_proxy_handler;
- s->connection->write->handler = ngx_imap_proxy_handler;
- rev->handler = ngx_imap_proxy_handler;
- c->write->handler = ngx_imap_proxy_handler;
-
- pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
- ngx_add_timer(s->connection->read, pcf->timeout);
- ngx_del_timer(c->read);
-
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
- }
}
@@ -449,7 +450,7 @@
static ngx_int_t
-ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t what)
+ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t state)
{
u_char *p;
ssize_t n;
@@ -496,15 +497,29 @@
}
} else {
- if (what == NGX_IMAP_WAIT_OK) {
+ switch (state) {
+
+ case ngx_imap_start:
if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') {
return NGX_OK;
}
+ break;
- } else {
+ case ngx_imap_login:
+ case ngx_imap_user:
if (p[0] == '+') {
return NGX_OK;
}
+ break;
+
+ case ngx_imap_passwd:
+ if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) {
+ p += s->tag.len;
+ if (p[0] == 'O' && p[1] == 'K') {
+ return NGX_OK;
+ }
+ }
+ break;
}
}
diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h
index e0c4a19..b941a43 100644
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -24,6 +24,7 @@
#define NGX_EBUSY EBUSY
#define NGX_EEXIST EEXIST
#define NGX_ENOTDIR ENOTDIR
+#define NGX_EISDIR EISDIR
#define NGX_EINVAL EINVAL
#define NGX_ENOSPC ENOSPC
#define NGX_EPIPE EPIPE
diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h
index 9b6c7b5..5f1fab2 100644
--- a/src/os/win32/ngx_errno.h
+++ b/src/os/win32/ngx_errno.h
@@ -27,6 +27,7 @@
#endif
#define NGX_EEXIST ERROR_ALREADY_EXISTS
#define NGX_ENOTDIR ERROR_PATH_NOT_FOUND
+#define NGX_EISDIR ERROR_CANNOT_MAKE
#define NGX_ENOSPC ERROR_DISK_FULL
#define NGX_EPIPE EPIPE
#define NGX_EAGAIN WSAEWOULDBLOCK