summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto/feature3
-rw-r--r--auto/include4
-rw-r--r--conf/koi-win14
-rw-r--r--conf/nginx.conf6
-rw-r--r--docs/xml/nginx/changes.xml33
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_buf.c6
-rw-r--r--src/core/ngx_conf_file.c184
-rw-r--r--src/core/ngx_conf_file.h1
-rw-r--r--src/core/ngx_log.h1
-rw-r--r--src/http/modules/ngx_http_addition_filter_module.c6
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c2
-rw-r--r--src/http/modules/ngx_http_empty_gif_module.c2
-rw-r--r--src/http/modules/ngx_http_index_module.c2
-rw-r--r--src/http/modules/ngx_http_log_module.c3
-rw-r--r--src/http/modules/ngx_http_memcached_module.c2
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c73
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.h1
-rw-r--r--src/http/modules/ngx_http_static_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c22
-rw-r--r--src/http/ngx_http_request.c17
-rw-r--r--src/mysql/ngx_mysql.c136
-rw-r--r--src/mysql/ngx_mysql.h36
-rw-r--r--src/os/unix/ngx_socket.c2
-rw-r--r--src/os/unix/ngx_socket.h5
26 files changed, 438 insertions, 129 deletions
diff --git a/auto/feature b/auto/feature
index 15da5bde3..6ad008ae0 100644
--- a/auto/feature
+++ b/auto/feature
@@ -14,7 +14,8 @@ END
ngx_found=no
if test -n "$ngx_feature_name"; then
- ngx_have_feature=`echo $ngx_feature_name | tr '[a-z]' '[A-Z]'`
+ ngx_have_feature=`echo $ngx_feature_name \
+ | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
fi
cat << END > $NGX_AUTOTEST.c
diff --git a/auto/include b/auto/include
index 7a098d9d0..4139238ca 100644
--- a/auto/include
+++ b/auto/include
@@ -35,8 +35,8 @@ if [ -x $NGX_AUTOTEST ]; then
echo " found"
- ngx_name=`echo $ngx_include | sed -e 's/\./_/' -e 's/\//_/' \
- | tr '[a-z]' '[A-Z]'`
+ ngx_name=`echo $ngx_include \
+ | tr abcdefghijklmnopqrstuvwxyz/. ABCDEFGHIJKLMNOPQRSTUVWXYZ__`
have=NGX_HAVE_$ngx_name . auto/have_headers
diff --git a/conf/koi-win b/conf/koi-win
index 92cabb140..2b12b8da1 100644
--- a/conf/koi-win
+++ b/conf/koi-win
@@ -10,8 +10,22 @@ charset_map koi8-r windows-1251 {
9E B7 ; # &middot;
A3 B8 ; # small yo
+ A4 BA ; # small Ukrainian ye
+
+ A6 B3 ; # small Ukrainian i
+ A7 BF ; # small Ukrainian j
+
+ AD B4 ; # small Ukrainian soft g
+ AE A2 ; # small Byelorussian short u
B3 A8 ; # capital YO
+ B4 AA ; # capital Ukrainian YE
+
+ B6 B2 ; # capital Ukrainian I
+ B7 AF ; # capital Ukrainian J
+
+ BD A5 ; # capital Ukrainian soft G
+ BE A1 ; # capital Byelorussian short U
BF A9 ; # (C)
diff --git a/conf/nginx.conf b/conf/nginx.conf
index 11404add4..2f5785a02 100644
--- a/conf/nginx.conf
+++ b/conf/nginx.conf
@@ -26,9 +26,10 @@ http {
sendfile on;
#tcp_nopush on;
- #tcp_nodelay on;
#keepalive_timeout 0;
+ keepalive_timeout 65;
+ tcp_nodelay on;
#gzip on;
@@ -60,7 +61,8 @@ http {
# include conf/fastcgi_params;
#}
- # deny access to .htaccess files
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index d13e61582..92fefa4db 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -9,6 +9,39 @@
<title lang="en">nginx changelog</title>
+<changes ver="0.3.44" date="04.05.2006">
+
+<change type="feature">
+<para lang="ru">
+параметр wait в команде SSI inlcude.
+</para>
+<para lang="en">
+the "wait" parameter in the SSI "include" command.
+</para>
+</change>
+
+<change type="feature">
+<para lang="ru">
+в таблицу перекодировки koi-win добавлены украинские и белорусские символы.
+</para>
+<para lang="en">
+the Ukrainian and Byelorussian characters were added to koi-win conversion
+table.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в SSI.
+</para>
+<para lang="en">
+in the SSI.
+</para>
+</change>
+
+</changes>
+
+
<changes ver="0.3.43" date="26.04.2006">
<change type="bugfix">
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 9a08f130f..7fd9d7286 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.43"
+#define NGINX_VER "nginx/0.3.44"
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
diff --git a/src/core/ngx_buf.c b/src/core/ngx_buf.c
index 901c3f540..31d990315 100644
--- a/src/core/ngx_buf.c
+++ b/src/core/ngx_buf.c
@@ -134,12 +134,6 @@ ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in)
}
while (in) {
-
- if (ngx_buf_sync_only(in->buf)) {
- in = in->next;
- continue;
- }
-
cl = ngx_alloc_chain_link(pool);
if (cl == NULL) {
return NGX_ERROR;
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index 7c22948a3..b895910d5 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -221,12 +221,14 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{
char *rv;
void *conf, **confp;
- ngx_uint_t i, valid;
+ ngx_uint_t i, multi;
ngx_str_t *name;
ngx_command_t *cmd;
name = cf->args->elts;
+ multi = 0;
+
for (i = 0; ngx_modules[i]; i++) {
/* look up the directive in the appropriate modules */
@@ -242,132 +244,138 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
continue;
}
- while (cmd->name.len) {
+ for ( /* void */ ; cmd->name.len; cmd++) {
- if (name->len == cmd->name.len
- && ngx_strcmp(name->data, cmd->name.data) == 0)
- {
- /* is the directive's location right ? */
+ if (name->len != cmd->name.len) {
+ continue;
+ }
- if (!(cmd->type & cf->cmd_type)) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "directive \"%s\" in %s:%ui "
- "is not allowed here",
- name->data, cf->conf_file->file.name.data,
- cf->conf_file->line);
- return NGX_ERROR;
- }
+ if (ngx_strcmp(name->data, cmd->name.data) != 0) {
+ continue;
+ }
- if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "directive \"%s\" in %s:%ui "
- "is not terminated by \";\"",
- name->data, cf->conf_file->file.name.data,
- cf->conf_file->line);
- return NGX_ERROR;
- }
- if ((cmd->type & NGX_CONF_BLOCK)
- && last != NGX_CONF_BLOCK_START)
- {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "directive \"%s\" in %s:%ui "
- "has not the opening \"{\"",
- name->data, cf->conf_file->file.name.data,
- cf->conf_file->line);
- return NGX_ERROR;
+ /* is the directive's location right ? */
+
+ if (!(cmd->type & cf->cmd_type)) {
+ if (cmd->type & NGX_CONF_MULTI) {
+ multi = 1;
+ continue;
}
- /* is the directive's argument count right ? */
+ goto not_allowed;
+ }
+
+ if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "directive \"%s\" in %s:%ui "
+ "is not terminated by \";\"",
+ name->data, cf->conf_file->file.name.data,
+ cf->conf_file->line);
+ return NGX_ERROR;
+ }
+
+ if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "directive \"%s\" in %s:%ui "
+ "has not the opening \"{\"",
+ name->data, cf->conf_file->file.name.data,
+ cf->conf_file->line);
+ return NGX_ERROR;
+ }
+
+ /* is the directive's argument count right ? */
- if (cmd->type & NGX_CONF_ANY) {
- valid = 1;
+ if (!(cmd->type & NGX_CONF_ANY)) {
- } else if (cmd->type & NGX_CONF_FLAG) {
+ if (cmd->type & NGX_CONF_FLAG) {
- if (cf->args->nelts == 2) {
- valid = 1;
- } else {
- valid = 0;
+ if (cf->args->nelts != 2) {
+ goto invalid;
}
} else if (cmd->type & NGX_CONF_1MORE) {
- if (cf->args->nelts > 1) {
- valid = 1;
- } else {
- valid = 0;
+ if (cf->args->nelts < 2) {
+ goto invalid;
}
} else if (cmd->type & NGX_CONF_2MORE) {
- if (cf->args->nelts > 2) {
- valid = 1;
- } else {
- valid = 0;
+ if (cf->args->nelts < 3) {
+ goto invalid;
}
- } else if (cf->args->nelts <= NGX_CONF_MAX_ARGS
- && (cmd->type
- & argument_number[cf->args->nelts - 1]))
- {
- valid = 1;
+ } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {
- } else {
- valid = 0;
- }
+ goto invalid;
- if (!valid) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "invalid number arguments in "
- "directive \"%s\" in %s:%ui",
- name->data, cf->conf_file->file.name.data,
- cf->conf_file->line);
- return NGX_ERROR;
+ } else if (!(cmd->type & argument_number[cf->args->nelts - 1]))
+ {
+ goto invalid;
}
+ }
- /* set up the directive's configuration context */
-
- conf = NULL;
-
- if (cmd->type & NGX_DIRECT_CONF) {
- conf = ((void **) cf->ctx)[ngx_modules[i]->index];
+ /* set up the directive's configuration context */
- } else if (cmd->type & NGX_MAIN_CONF) {
- conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
+ conf = NULL;
- } else if (cf->ctx) {
- confp = *(void **) ((char *) cf->ctx + cmd->conf);
+ if (cmd->type & NGX_DIRECT_CONF) {
+ conf = ((void **) cf->ctx)[ngx_modules[i]->index];
- if (confp) {
- conf = confp[ngx_modules[i]->ctx_index];
- }
- }
+ } else if (cmd->type & NGX_MAIN_CONF) {
+ conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
- rv = cmd->set(cf, cmd, conf);
+ } else if (cf->ctx) {
+ confp = *(void **) ((char *) cf->ctx + cmd->conf);
- if (rv == NGX_CONF_OK) {
- return NGX_OK;
+ if (confp) {
+ conf = confp[ngx_modules[i]->ctx_index];
}
+ }
- if (rv == NGX_CONF_ERROR) {
- return NGX_ERROR;
- }
+ rv = cmd->set(cf, cmd, conf);
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "the \"%s\" directive %s in %s:%ui",
- name->data, rv, cf->conf_file->file.name.data,
- cf->conf_file->line);
+ if (rv == NGX_CONF_OK) {
+ return NGX_OK;
+ }
+ if (rv == NGX_CONF_ERROR) {
return NGX_ERROR;
}
- cmd++;
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "the \"%s\" directive %s in %s:%ui",
+ name->data, rv, cf->conf_file->file.name.data,
+ cf->conf_file->line);
+
+ return NGX_ERROR;
}
}
+ if (multi == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "unknown directive \"%s\" in %s:%ui",
+ name->data, cf->conf_file->file.name.data,
+ cf->conf_file->line);
+
+ return NGX_ERROR;
+ }
+
+not_allowed:
+
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "directive \"%s\" in %s:%ui "
+ "is not allowed here",
+ name->data, cf->conf_file->file.name.data,
+ cf->conf_file->line);
+ return NGX_ERROR;
+
+invalid:
+
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unknown directive \"%s\" in %s:%ui",
+ "invalid number arguments in "
+ "directive \"%s\" in %s:%ui",
name->data, cf->conf_file->file.name.data,
cf->conf_file->line);
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index a183a5747..37d36d62e 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -44,6 +44,7 @@
#define NGX_CONF_ANY 0x00000400
#define NGX_CONF_1MORE 0x00000800
#define NGX_CONF_2MORE 0x00001000
+#define NGX_CONF_MULTI 0x00002000
#define NGX_DIRECT_CONF 0x00010000
diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h
index 290ca74e3..d49f9d1fe 100644
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -28,6 +28,7 @@
#define NGX_LOG_DEBUG_EVENT 0x080
#define NGX_LOG_DEBUG_HTTP 0x100
#define NGX_LOG_DEBUG_IMAP 0x200
+#define NGX_LOG_DEBUG_MYSQL 0x400
/*
* do not forget to update debug_levels[] in src/core/ngx_log.c
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index 842124d91..15231ce98 100644
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -143,7 +143,9 @@ ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->before_body_sent = 1;
if (conf->before_body.len) {
- if (ngx_http_subrequest(r, &conf->before_body, NULL, 0) != NGX_OK) {
+ if (ngx_http_subrequest(r, &conf->before_body, NULL, 0)
+ == NGX_ERROR)
+ {
return NGX_ERROR;
}
}
@@ -165,7 +167,7 @@ ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
return rc;
}
- if (ngx_http_subrequest(r, &conf->after_body, NULL, 0) != NGX_OK) {
+ if (ngx_http_subrequest(r, &conf->after_body, NULL, 0) == NGX_ERROR) {
return NGX_ERROR;
}
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index e1a0e86c6..b1ba178b9 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -162,7 +162,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_empty_gif_module.c b/src/http/modules/ngx_http_empty_gif_module.c
index d72983ad4..82bf8c5e2 100644
--- a/src/http/modules/ngx_http_empty_gif_module.c
+++ b/src/http/modules/ngx_http_empty_gif_module.c
@@ -112,7 +112,7 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r)
ngx_buf_t *b;
ngx_chain_t out;
- if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 4326e7399..d4bed45cc 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -143,7 +143,7 @@ ngx_http_index_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 07ac113a4..3afb6a3db 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -128,7 +128,8 @@ static ngx_command_t ngx_http_log_commands[] = {
NULL },
{ ngx_string("access_log"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
+ |NGX_CONF_TAKE123,
ngx_http_log_set_log,
NGX_HTTP_LOC_CONF_OFFSET,
0,
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index 73c018ed9..ace8723e2 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -154,7 +154,7 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
ngx_http_memcached_ctx_t *ctx;
ngx_http_memcached_loc_conf_t *mlcf;
- if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 82ee7ac33..5024d0021 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -188,6 +188,7 @@ static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
#define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0
#define NGX_HTTP_SSI_INCLUDE_FILE 1
+#define NGX_HTTP_SSI_INCLUDE_WAIT 2
#define NGX_HTTP_SSI_ECHO_VAR 0
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
@@ -204,6 +205,7 @@ static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
{ ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 },
{ ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 },
+ { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 },
{ ngx_null_string, 0, 0, 0 }
};
@@ -361,7 +363,12 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
- if (ctx == NULL || (in == NULL && ctx->in == NULL && ctx->busy == NULL)) {
+ if (ctx == NULL
+ || (in == NULL
+ && ctx->buf == NULL
+ && ctx->in == NULL
+ && ctx->busy == NULL))
+ {
return ngx_http_next_body_filter(r, in);
}
@@ -373,6 +380,19 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
+ if (ctx->wait) {
+ if (r->connection->data != r) {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http ssi filter \"%V\" wait", &r->uri);
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http ssi filter \"%V\" continue", &r->uri);
+
+ ctx->wait = 0;
+ }
+
slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -632,6 +652,10 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
continue;
}
+ if (rc == NGX_AGAIN) {
+ return NGX_AGAIN;
+ }
+
if (rc == NGX_ERROR) {
return NGX_ERROR;
}
@@ -782,8 +806,13 @@ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
cl = ctx->busy;
ctx->busy = cl->next;
- cl->next = ctx->free;
- ctx->free = cl;
+
+ if (ngx_buf_in_memory(b) || b->in_file) {
+ /* add data bufs only to the free buf chain */
+
+ cl->next = ctx->free;
+ ctx->free = cl;
+ }
}
return rc;
@@ -1626,11 +1655,13 @@ static ngx_int_t
ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ngx_str_t **params)
{
- ngx_str_t *uri, *file, args;
+ ngx_int_t rc;
+ ngx_str_t *uri, *file, *wait, args;
ngx_uint_t flags;
uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
file = params[NGX_HTTP_SSI_INCLUDE_FILE];
+ wait = params[NGX_HTTP_SSI_INCLUDE_WAIT];
if (uri && file) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -1645,6 +1676,26 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
return NGX_HTTP_SSI_ERROR;
}
+ if (wait) {
+ if (uri == NULL) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "\"wait\" may not be used with file=\"%V\"",
+ uri, file);
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ if (wait->len == 2 && ngx_strncasecmp(wait->data, "no", 2) == 0) {
+ wait = NULL;
+
+ } else if (wait->len != 3 || ngx_strncasecmp(wait->data, "yes", 3) != 0)
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "invalid value \"%V\" in the \"wait\" parameter",
+ &wait);
+ return NGX_HTTP_SSI_ERROR;
+ }
+ }
+
if (uri == NULL) {
uri = file;
}
@@ -1666,11 +1717,21 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
return NGX_HTTP_SSI_ERROR;
}
- if (ngx_http_subrequest(r, uri, &args, flags) != NGX_OK) {
+ rc = ngx_http_subrequest(r, uri, &args, flags);
+
+ if (rc == NGX_ERROR) {
return NGX_HTTP_SSI_ERROR;
}
- return NGX_OK;
+ if (wait == NULL) {
+ return NGX_OK;
+ }
+
+ if (rc == NGX_AGAIN) {
+ ctx->wait = 1;
+ }
+
+ return rc;
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.h b/src/http/modules/ngx_http_ssi_filter_module.h
index eff236050..0d9618b00 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.h
+++ b/src/http/modules/ngx_http_ssi_filter_module.h
@@ -61,6 +61,7 @@ typedef struct {
unsigned conditional:2;
unsigned output:1;
unsigned output_chosen:1;
+ unsigned wait:1;
void *value_buf;
ngx_str_t timefmt;
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index 3399e5098..ad0885217 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -86,7 +86,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
ngx_pool_cleanup_file_t *clnf;
ngx_http_core_loc_conf_t *clcf;
- if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+ if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index d87b2ec78..badd494b4 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -17,7 +17,7 @@ our @EXPORT = qw(
HTTP_SERVER_ERROR
);
-our $VERSION = '0.3.23';
+our $VERSION = '0.3.43';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 6279f3465..931be888f 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1168,7 +1168,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
if (sr == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
sr->signature = NGX_HTTP_MODULE;
@@ -1178,14 +1178,14 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
if (sr->ctx == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
sizeof(ngx_table_elt_t))
== NGX_ERROR)
{
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@@ -1228,7 +1228,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr->http_protocol = r->http_protocol;
if (ngx_http_set_exten(sr) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
sr->main = r->main;
@@ -1251,7 +1251,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
if (pr == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ return NGX_ERROR;
}
pr->request = sr;
@@ -1275,10 +1275,18 @@ ngx_http_subrequest(ngx_http_request_t *r,
ngx_http_handler(sr);
if (!c->destroyed) {
- sr->fast_subrequest = 0;
-
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http subrequest done \"%V?%V\"", uri, &sr->args);
+
+ if (sr->fast_subrequest) {
+ sr->fast_subrequest = 0;
+
+ if (sr->done) {
+ return NGX_OK;
+ }
+ }
+
+ return NGX_AGAIN;
}
return NGX_OK;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index d801e2ce5..680b3bd45 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -958,7 +958,7 @@ ngx_http_read_request_header(ngx_http_request_t *r)
}
if (n == 0 || n == NGX_ERROR) {
- ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
@@ -1480,17 +1480,24 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
}
if (r->fast_subrequest) {
+
+ if (rc == NGX_AGAIN) {
+ r->fast_subrequest = 0;
+ }
+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http fast subrequest: \"%V?%V\" done",
&r->uri, &r->args);
return;
}
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http wake parent request: \"%V?%V\"",
- &pr->uri, &pr->args);
+ if (rc != NGX_AGAIN) {
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http wake parent request: \"%V?%V\"",
+ &pr->uri, &pr->args);
- pr->write_event_handler(pr);
+ pr->write_event_handler(pr);
+ }
}
return;
diff --git a/src/mysql/ngx_mysql.c b/src/mysql/ngx_mysql.c
new file mode 100644
index 000000000..1e008b5e4
--- /dev/null
+++ b/src/mysql/ngx_mysql.c
@@ -0,0 +1,136 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+#include <ngx_mysql.h>
+
+
+/* the library supports the subset of the MySQL 4.1+ protocol (version 10) */
+
+
+ngx_int_t
+ngx_mysql_connect(ngx_mysql_t *m)
+{
+ ngx_int_t rc;
+
+#if 0
+ if (cached) {
+ return NGX_OK;
+ }
+#endif
+
+ m->peer.log->action = "connecting to mysql server";
+
+ rc = ngx_event_connect_peer(&m->peer);
+
+ if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
+ return rc;
+ }
+
+ m->peer.connection->read->handler = ngx_mysql_read_server_greeting;
+ m->peer.connection->write->handler = ngx_mysql_emtpy_handler;
+
+ ngx_add_timer(m->peer.connection->read, /* STUB */ 5000);
+ ngx_add_timer(m->peer.connection->write, /* STUB */ 5000);
+
+ return NGX_OK;
+}
+
+
+static void
+ngx_mysql_read_server_greeting(ngx_event_t *rev)
+{
+ size_t len;
+ u_char *p, *t;
+ ngx_mysql_t *m;
+ ngx_connection_t *c;
+
+ c = rev->data;
+ m = c->data;
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
+ "mysql server %V timed out",
+ &ctx->peer.peers->peer[0].name);
+
+ ngx_mysql_close(m, NGX_ERROR);
+ return;
+ }
+
+ if (m->buf == NULL) {
+ m->peer.log->action = "reading to mysql server greeting";
+
+ m->buf = ngx_create_temp(m->pool, /* STUB */ 1024);
+ if (m->buf == NULL) {
+ ngx_mysql_close(m, NGX_ERROR);
+ return;
+ }
+ }
+
+ n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024);
+
+ if (n == NGX_AGAIN) {
+ return;
+ }
+
+ if (n < 5) {
+ ngx_mysql_close(m, NGX_ERROR);
+ return;
+ }
+
+ p = m->buf->pos;
+
+ if (ngx_m24toh(p) > n - 4) {
+ ngx_log_error(NGX_LOG_ERR, rev->log, 0,
+ "mysql server %V sent incomplete greeting packet",
+ &ctx->peer.peers->peer[0].name);
+
+ ngx_mysql_close(m, NGX_ERROR);
+ return;
+ }
+
+ if (p[4]) < 10) {
+ ngx_log_error(NGX_LOG_ERR, rev->log, 0,
+ "mysql server %V sent unsupported protocol version %ud",
+ &ctx->peer.peers->peer[0].name, p[4]);
+
+ ngx_mysql_close(m, NGX_ERROR);
+ return;
+ }
+
+ len = ngx_strlen(&p[5]);
+ t = p + 5 + len + 1;
+
+ capacity = ngx_m16toh((&t[4 + 9]));
+
+ ngx_log_debug8(NGX_LOG_DEBUG_MYSQL, rev->log, 0,
+ "mysql version: %ud, \"%s\", thread: %ud, salt: \"%s\", ",
+ "capacity: %Xd, charset: %ud, status: %ud, salt rest \"%s\"",
+ p[4], &p[5], ngx_m32toh(t), &t[4],
+ capacity, t[4 + 9 + 2],
+ ngx_m16toh((&t[4 + 9 + 2 + 1])),
+ t[4 + 9 + 2 + 1 + 2 + 13]);
+
+ capacity &= NGX_MYSQL_LONG_PASSWORD
+ | NGX_MYSQL_CONNECT_WITH_DB
+ | NGX_MYSQL_PROTOCOL_41;
+
+}
+
+
+static void
+ngx_mysql_close(ngx_mysql_t *m, ngx_int_t rc)
+{
+ if (rc == NGX_ERROR) {
+ ngx_close_connection(m->peer.connection);
+ }
+
+ m->state = rc;
+
+ m->handler(m);
+}
diff --git a/src/mysql/ngx_mysql.h b/src/mysql/ngx_mysql.h
new file mode 100644
index 000000000..99f10396b
--- /dev/null
+++ b/src/mysql/ngx_mysql.h
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_MYSQL_H_INCLUDED_
+#define _NGX_MYSQL_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+typedef struct {
+ ngx_peer_connection_t peer;
+} ngx_mysql_t;
+
+
+#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED && 0)
+
+#define ngx_m16toh(n) (*(uint32_t *) n & 0x0000ffff)
+#define ngx_m24toh(n) (*(uint32_t *) n & 0x00ffffff)
+#define ngx_m32toh(n) *(uint32_t *) n
+
+#else
+
+#define ngx_m16toh(n) (n[0] | n[1] << 8)
+#define ngx_m24toh(n) (n[0] | n[1] << 8 | n[2] << 16)
+#define ngx_m32toh(n) (n[0] | n[1] << 8 | n[2] << 16 | n[3] << 24)
+
+#endif
+
+
+#endif /* _NGX_MYSQL_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c
index 60885ddd5..a93679f64 100644
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -10,7 +10,7 @@
/*
* ioctl(FIONBIO) sets a blocking mode with the single syscall
- * while fcntl(F_SETFL, ~O_NONBLOCK) needs to learn before
+ * while fcntl(F_SETFL, !O_NONBLOCK) needs to learn before
* the previous state using fcntl(F_GETFL).
*
* ioctl() and fcntl() are syscalls at least in FreeBSD 2.x, Linux 2.2
diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h
index b381967e6..9e6a859bb 100644
--- a/src/os/unix/ngx_socket.h
+++ b/src/os/unix/ngx_socket.h
@@ -29,9 +29,12 @@ int ngx_blocking(ngx_socket_t s);
#else
-#define ngx_nonblocking(s) fcntl(s, F_SETFL, O_NONBLOCK)
+#define ngx_nonblocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK)
#define ngx_nonblocking_n "fcntl(O_NONBLOCK)"
+#define ngx_blocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK)
+#define ngx_blocking_n "fcntl(!O_NONBLOCK)"
+
#endif
int ngx_tcp_nopush(ngx_socket_t s);