summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES25
-rw-r--r--CHANGES.ru25
-rw-r--r--src/core/nginx.c220
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_cycle.h4
-rw-r--r--src/core/ngx_file.c6
-rw-r--r--src/core/ngx_file.h4
-rw-r--r--src/core/ngx_palloc.c26
-rw-r--r--src/core/ngx_palloc.h2
-rw-r--r--src/http/modules/ngx_http_dav_module.c2
-rw-r--r--src/http/modules/ngx_http_log_module.c131
-rw-r--r--src/http/modules/ngx_http_memcached_module.c45
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c25
-rw-r--r--src/http/ngx_http_core_module.c22
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/http/ngx_http_request_body.c29
-rw-r--r--src/os/unix/ngx_process_cycle.c17
19 files changed, 436 insertions, 155 deletions
diff --git a/CHANGES b/CHANGES
index 7128432ec..4c5dc34a1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,25 @@
+Changes with nginx 0.5.9 25 Jan 2007
+
+ *) Change: now the ngx_http_memcached_module uses the $memcached_key
+ variable value as a key.
+
+ *) Feature: the $memcached_key variable.
+
+ *) Feature: the "clean" parameter in the "client_body_in_file_only"
+ directive.
+
+ *) Feature: the "env" directive.
+
+ *) Feature: the "sendfile" directive is available inside the "if" block.
+
+ *) Feature: now on failure of the writing to access nginx logs a
+ message to error_log, but not more often than once a minute.
+
+ *) Bugfix: the "access_log off" directive did not always turn off the
+ logging.
+
+
Changes with nginx 0.5.8 19 Jan 2007
*) Bugfix: a segmentation fault might occur if
@@ -737,7 +758,7 @@ Changes with nginx 0.3.38 14 Apr 2006
*) Feature: the "client_body_in_file_only" directive.
- *) Workaround: no on disk overflow nginx tries to write access logs
+ *) Workaround: now on disk overflow nginx tries to write access logs
once a second only.
Thanks to Anton Yuzhaninov and Maxim Dounin.
@@ -834,7 +855,7 @@ Changes with nginx 0.3.31 10 Mar 2006
*) Workaround: for MacOSX 64-bit kernel kqueue millisecond timeout
bug.
- Thanks Andrei Nigmatulin.
+ Thanks to Andrei Nigmatulin.
*) Bugfix: if there were several "listen" directives listening one
various addresses inside one server, then server names like
diff --git a/CHANGES.ru b/CHANGES.ru
index f9fc09a60..49c6dc0eb 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,24 @@
+Изменения в nginx 0.5.9 25.01.2007
+
+ *) Изменение: модуль ngx_http_memcached_module теперь в качестве ключа
+ использует значение переменной $memcached_key.
+
+ *) Добавление: переменная $memcached_key.
+
+ *) Добавление: параметр clean в директиве client_body_in_file_only.
+
+ *) Добавление: директива env.
+
+ *) Добавление: директива sendfile работает внутри блока if.
+
+ *) Добавление: теперь при ошибке записи в access_log nginx записывает
+ сообщение в error_log, но не чаще одного раза в минуту.
+
+ *) Исправление: директива "access_log off" не всегда запрещала запись в
+ лог.
+
+
Изменения в nginx 0.5.8 19.01.2007
*) Исправление: если использовалась директива
@@ -11,8 +31,9 @@
делался переход к следующему бэкенду.
*) Исправление: если при использовании директивы "proxy_buffering off"
- соединение с клиентом было неактивно, то оно закрывалось по таймуту,
- заданному директивой send_timeout; ошибка появилась в 0.4.7.
+ соединение с клиентом было неактивно, то оно закрывалось по
+ таймауту, заданному директивой send_timeout; ошибка появилась в
+ 0.4.7.
*) Исправление: если при использовании метода epoll клиент закрывал
преждевременно соединение со своей стороны, то nginx закрывал это
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 47dafe141..c251ff56a 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -16,6 +16,7 @@ static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static char *ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -128,6 +129,13 @@ static ngx_command_t ngx_core_commands[] = {
offsetof(ngx_core_conf_t, working_directory),
NULL },
+ { ngx_string("env"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+ ngx_set_env,
+ 0,
+ 0,
+ NULL },
+
#if (NGX_THREADS)
{ ngx_string("worker_threads"),
@@ -178,7 +186,7 @@ ngx_uint_t ngx_max_module;
static ngx_uint_t ngx_show_version;
static ngx_uint_t ngx_show_configure;
-static char *ngx_null_environ = NULL;
+static char **ngx_os_environ;
int ngx_cdecl
@@ -275,8 +283,6 @@ main(int argc, char *const *argv)
return 1;
}
- environ = &ngx_null_environ;
-
ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++;
@@ -407,21 +413,128 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
}
+char **
+ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
+{
+ char **p, **env;
+ ngx_str_t *var;
+ ngx_uint_t i, n;
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ if (last) {
+ n = *last;
+
+ } else {
+ if (ccf->environment) {
+ return ccf->environment;
+ }
+
+ n = 0;
+ }
+
+ var = ccf->env.elts;
+
+ for (i = 0; i < ccf->env.nelts; i++) {
+ if (ngx_strcmp(var[i].data, "TZ") == 0
+ || ngx_strncmp(var[i].data, "TZ=", 3) == 0)
+ {
+ goto tz_found;
+ }
+ }
+
+ var = ngx_array_push(&ccf->env);
+
+ var->len = 2;
+ var->data = (u_char *) "TZ";
+
+ var = ccf->env.elts;
+
+tz_found:
+
+ for (i = 0; i < ccf->env.nelts; i++) {
+
+ if (var[i].data[var[i].len] == '=') {
+ n++;
+ continue;
+ }
+
+ for (p = ngx_os_environ; *p; p++) {
+
+ if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
+ && (*p)[var[i].len] == '=')
+ {
+ n++;
+ break;
+ }
+ }
+ }
+
+ if (last) {
+ *last = n;
+ env = ngx_alloc((n + 1) * sizeof(char *), cycle->log);
+
+ } else {
+ env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *));
+ }
+
+ if (env == NULL) {
+ return NULL;
+ }
+
+ n = 0;
+
+ for (i = 0; i < ccf->env.nelts; i++) {
+
+ if (var[i].data[var[i].len] == '=') {
+ env[n++] = (char *) var[i].data;
+ continue;
+ }
+
+ for (p = ngx_os_environ; *p; p++) {
+
+ if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
+ && (*p)[var[i].len] == '=')
+ {
+ env[n++] = *p;
+ break;
+ }
+ }
+ }
+
+ env[n] = NULL;
+
+ if (last == NULL) {
+ ccf->environment = env;
+ environ = env;
+ }
+
+ return env;
+}
+
+
ngx_pid_t
ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
{
- char *env[3], *var;
- u_char *p;
- ngx_uint_t i;
- ngx_pid_t pid;
- ngx_exec_ctx_t ctx;
- ngx_core_conf_t *ccf;
- ngx_listening_t *ls;
+ char **env, *var;
+ u_char *p;
+ ngx_uint_t i, n;
+ ngx_pid_t pid;
+ ngx_exec_ctx_t ctx;
+ ngx_core_conf_t *ccf;
+ ngx_listening_t *ls;
ctx.path = argv[0];
ctx.name = "new binary process";
ctx.argv = argv;
+ n = 2;
+ env = ngx_set_environment(cycle, &n);
+ if (env == NULL) {
+ return NGX_INVALID_PID;
+ }
+
var = ngx_alloc(sizeof(NGINX_VAR)
+ cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
cycle->log);
@@ -435,40 +548,42 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
*p = '\0';
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "inherited: %s", var);
-
- env[0] = var;
+ env[n++] = var;
#if (NGX_SETPROCTITLE_USES_ENV)
/* allocate the spare 300 bytes for the new binary process title */
- env[1] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+ env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
- env[2] = NULL;
-
-#else
+#endif
- env[1] = NULL;
+ env[n] = NULL;
+#if (NGX_DEBUG)
+ {
+ char **e;
+ for (e = env; *e; e++) {
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "env: %s", *e);
+ }
+ }
#endif
- ctx.envp = (char *const *) &env;
+ ctx.envp = (char *const *) env;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
- if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data)
- != NGX_OK)
- {
+ if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) != NGX_OK) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_rename_file_n " %s to %s failed "
"before executing new binary process \"%s\"",
ccf->pid.data, ccf->oldpid.data, argv[0]);
+ ngx_free(env);
ngx_free(var);
return NGX_INVALID_PID;
@@ -477,16 +592,15 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
pid = ngx_execute(cycle, &ctx);
if (pid == NGX_INVALID_PID) {
- if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
- != NGX_OK)
- {
+ if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data) != NGX_OK) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_rename_file_n " %s back to %s failed "
- "after try to executing new binary process \"%s\"",
+ ngx_rename_file_n " %s back to %s failed after "
+ "the try to execute the new binary process \"%s\"",
ccf->oldpid.data, ccf->pid.data, argv[0]);
}
}
+ ngx_free(env);
ngx_free(var);
return pid;
@@ -588,6 +702,8 @@ ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
#endif
+ ngx_os_environ = environ;
+
return NGX_OK;
}
@@ -631,6 +747,12 @@ ngx_core_module_create_conf(ngx_cycle_t *cycle)
ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
#endif
+ if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
+ != NGX_OK)
+ {
+ return NULL;
+ }
+
return ccf;
}
@@ -641,9 +763,9 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_core_conf_t *ccf = conf;
#if !(NGX_WIN32)
- ngx_str_t lock_file;
- struct passwd *pwd;
- struct group *grp;
+ ngx_str_t lock_file;
+ struct group *grp;
+ struct passwd *pwd;
#endif
ngx_conf_init_value(ccf->daemon, 1);
@@ -830,6 +952,36 @@ ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
+ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_core_conf_t *ccf = conf;
+
+ ngx_str_t *value, *var;
+ ngx_uint_t i;
+
+ var = ngx_array_push(&ccf->env);
+ if (var == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ value = cf->args->elts;
+ *var = value[1];
+
+ for (i = 0; i < value[1].len; i++) {
+
+ if (value[1].data[i] == '=') {
+
+ var->len = i;
+
+ return NGX_CONF_OK;
+ }
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_core_conf_t *ccf = conf;
diff --git a/src/core/nginx.h b/src/core/nginx.h
index a4204d13b..89e1c9409 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.5.8"
+#define NGINX_VERSION "0.5.9"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 21fb86acf..820ebbe0d 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -93,6 +93,9 @@ typedef struct {
ngx_str_t pid;
ngx_str_t oldpid;
+ ngx_array_t env;
+ char **environment;
+
#if (NGX_THREADS)
ngx_int_t worker_threads;
size_t thread_stack_size;
@@ -113,6 +116,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);
ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log);
void ngx_delete_pidfile(ngx_cycle_t *cycle);
void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
+char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
u_long ngx_get_cpu_affinity(ngx_uint_t n);
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 4be17ec9a..876541551 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -19,7 +19,7 @@ ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
if (tf->file.fd == NGX_INVALID_FILE) {
rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool,
- tf->persistent, tf->access);
+ tf->persistent, tf->clean, tf->access);
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
return rc;
@@ -37,7 +37,7 @@ ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
ngx_int_t
ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
- ngx_uint_t persistent, ngx_uint_t access)
+ ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access)
{
ngx_err_t err;
ngx_atomic_uint_t n;
@@ -79,7 +79,7 @@ ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
if (file->fd != NGX_INVALID_FILE) {
- cln->handler = ngx_pool_cleanup_file;
+ cln->handler = clean ? ngx_pool_delete_file : ngx_pool_cleanup_file;
clnf = cln->data;
clnf->fd = file->fd;
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
index 80dbd3319..e42489d8d 100644
--- a/src/core/ngx_file.h
+++ b/src/core/ngx_file.h
@@ -53,6 +53,7 @@ typedef struct {
unsigned log_level:8;
unsigned persistent:1;
+ unsigned clean:1;
} ngx_temp_file_t;
@@ -81,7 +82,8 @@ struct ngx_tree_ctx_s {
ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain);
ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
- ngx_pool_t *pool, ngx_uint_t persistent,ngx_uint_t access);
+ ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean,
+ ngx_uint_t access);
void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path);
ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path);
ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access);
diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c
index 109b6e3cc..4288bf10a 100644
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -243,6 +243,32 @@ ngx_pool_cleanup_file(void *data)
}
+void
+ngx_pool_delete_file(void *data)
+{
+ ngx_pool_cleanup_file_t *c = data;
+
+ ngx_err_t err;
+
+ ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, c->log, 0, "run cleanup: %p, fd:%d %s",
+ c, c->fd, c->name);
+
+ if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
+ err = ngx_errno;
+
+ if (err != NGX_ENOENT) {
+ ngx_log_error(NGX_LOG_CRIT, c->log, err,
+ ngx_delete_file_n " \"%s\" failed", c->name);
+ }
+ }
+
+ if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", c->name);
+ }
+}
+
+
#if 0
static void *
diff --git a/src/core/ngx_palloc.h b/src/core/ngx_palloc.h
index 239728102..76c6af15a 100644
--- a/src/core/ngx_palloc.h
+++ b/src/core/ngx_palloc.h
@@ -60,7 +60,6 @@ typedef struct {
} ngx_pool_cleanup_file_t;
-
void *ngx_alloc(size_t size, ngx_log_t *log);
void *ngx_calloc(size_t size, ngx_log_t *log);
@@ -74,6 +73,7 @@ ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);
ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);
void ngx_pool_cleanup_file(void *data);
+void ngx_pool_delete_file(void *data);
#endif /* _NGX_PALLOC_H_INCLUDED_ */
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 277a5bfc9..5a2f0cacb 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -135,7 +135,7 @@ ngx_http_dav_handler(ngx_http_request_t *r)
r->request_body_in_file_only = 1;
r->request_body_in_persistent_file = 1;
- r->request_body_delete_incomplete_file = 1;
+ r->request_body_in_clean_file = 1;
r->request_body_file_group_access = 1;
r->request_body_file_log_level = 0;
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 04ba03bff..55328312c 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -42,6 +42,7 @@ typedef struct {
typedef struct {
ngx_open_file_t *file;
time_t disk_full_time;
+ time_t error_log_time;
ngx_array_t *ops; /* array of ngx_http_log_op_t */
} ngx_http_log_t;
@@ -59,6 +60,9 @@ typedef struct {
} ngx_http_log_var_t;
+static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
+ u_char *buf, size_t len);
+
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op);
static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
@@ -151,7 +155,7 @@ ngx_module_t ngx_http_log_module = {
};
-static ngx_str_t http_access_log = ngx_string(NGX_HTTP_LOG_PATH);
+static ngx_str_t ngx_http_access_log = ngx_string(NGX_HTTP_LOG_PATH);
static ngx_str_t ngx_http_combined_fmt =
@@ -183,9 +187,9 @@ static ngx_http_log_var_t ngx_http_log_vars[] = {
ngx_int_t
ngx_http_log_handler(ngx_http_request_t *r)
{
- ngx_uint_t i, l;
u_char *line, *p;
size_t len;
+ ngx_uint_t i, l;
ngx_http_log_t *log;
ngx_open_file_t *file;
ngx_http_log_op_t *op;
@@ -206,9 +210,9 @@ ngx_http_log_handler(ngx_http_request_t *r)
if (ngx_time() == log[l].disk_full_time) {
/*
- * On FreeBSD writing to a full filesystem with enabled softupdates
+ * on FreeBSD writing to a full filesystem with enabled softupdates
* may block process for much longer time than writing to non-full
- * filesystem, so we skip writing the log for one second.
+ * filesystem, so we skip writing to a log for one second
*/
continue;
@@ -233,13 +237,8 @@ ngx_http_log_handler(ngx_http_request_t *r)
if (len > (size_t) (file->last - file->pos)) {
- if (ngx_write_fd(file->fd, file->buffer,
- file->pos - file->buffer)
- == -1
- && ngx_errno == NGX_ENOSPC)
- {
- log[l].disk_full_time = ngx_time();
- }
+ ngx_http_log_write(r, &log[l], file->buffer,
+ file->pos - file->buffer);
file->pos = file->buffer;
}
@@ -273,17 +272,57 @@ ngx_http_log_handler(ngx_http_request_t *r)
ngx_linefeed(p);
- if (ngx_write_fd(file->fd, line, p - line) == -1
- && ngx_errno == NGX_ENOSPC)
- {
- log[l].disk_full_time = ngx_time();
- }
+ ngx_http_log_write(r, &log[l], line, p - line);
}
return NGX_OK;
}
+static void
+ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
+ size_t len)
+{
+ time_t now;
+ ssize_t n;
+ ngx_err_t err;
+
+ n = ngx_write_fd(log->file->fd, buf, len);
+
+ if (n == (ssize_t) len) {
+ return;
+ }
+
+ now = ngx_time();
+
+ if (n == -1) {
+ err = ngx_errno;
+
+ if (err == NGX_ENOSPC) {
+ log->disk_full_time = now;
+ }
+
+ if (now - log->error_log_time > 60) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
+ ngx_write_fd_n " to \"%V\" failed",
+ &log->file->name);
+
+ log->error_log_time = now;
+ }
+
+ return;
+ }
+
+ if (now - log->error_log_time > 60) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ ngx_write_fd_n " to \"%V\" was incomplete: %z of %uz",
+ &log->file->name, n, len);
+
+ log->error_log_time = now;
+ }
+}
+
+
static u_char *
ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)
@@ -515,47 +554,40 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_log_fmt_t *fmt;
ngx_http_log_main_conf_t *lmcf;
- if (conf->logs == NULL) {
-
- if (conf->off) {
- return NGX_CONF_OK;
- }
-
- if (prev->logs) {
- conf->logs = prev->logs;
+ if (conf->logs || conf->off) {
+ return NGX_CONF_OK;
+ }
- } else {
+ *conf = *prev;
- if (prev->off) {
- conf->off = prev->off;
- return NGX_CONF_OK;
- }
+ if (conf->logs || conf->off) {
+ return NGX_CONF_OK;
+ }
- conf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t));
- if (conf->logs == NULL) {
- return NGX_CONF_ERROR;
- }
+ conf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t));
+ if (conf->logs == NULL) {
+ return NGX_CONF_ERROR;
+ }
- log = ngx_array_push(conf->logs);
- if (log == NULL) {
- return NGX_CONF_ERROR;
- }
+ log = ngx_array_push(conf->logs);
+ if (log == NULL) {
+ return NGX_CONF_ERROR;
+ }
- log->file = ngx_conf_open_file(cf->cycle, &http_access_log);
- if (log->file == NULL) {
- return NGX_CONF_ERROR;
- }
+ log->file = ngx_conf_open_file(cf->cycle, &ngx_http_access_log);
+ if (log->file == NULL) {
+ return NGX_CONF_ERROR;
+ }
- log->disk_full_time = 0;
+ log->disk_full_time = 0;
+ log->error_log_time = 0;
- lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
- fmt = lmcf->formats.elts;
+ lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
+ fmt = lmcf->formats.elts;
- /* the default "combined" format */
- log->ops = fmt[0].ops;
- lmcf->combined_used = 1;
- }
- }
+ /* the default "combined" format */
+ log->ops = fmt[0].ops;
+ lmcf->combined_used = 1;
return NGX_CONF_OK;
}
@@ -600,6 +632,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
log->disk_full_time = 0;
+ log->error_log_time = 0;
if (cf->args->nelts >= 3) {
name = value[2];
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index bd8b83716..8894410ab 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -12,6 +12,7 @@
typedef struct {
ngx_http_upstream_conf_t upstream;
+ ngx_int_t index;
} ngx_http_memcached_loc_conf_t;
@@ -147,6 +148,9 @@ ngx_module_t ngx_http_memcached_module = {
};
+static ngx_str_t ngx_http_memcached_key = ngx_string("memcached_key");
+
+
#define NGX_HTTP_MEMCACHED_END (sizeof(ngx_http_memcached_end) - 1)
static u_char ngx_http_memcached_end[] = CRLF "END" CRLF;
@@ -221,14 +225,26 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
static ngx_int_t
ngx_http_memcached_create_request(ngx_http_request_t *r)
{
- size_t len;
- ngx_buf_t *b;
- ngx_chain_t *cl;
- ngx_http_memcached_ctx_t *ctx;
+ size_t len;
+ ngx_buf_t *b;
+ ngx_chain_t *cl;
+ ngx_http_memcached_ctx_t *ctx;
+ ngx_http_variable_value_t *vv;
+ ngx_http_memcached_loc_conf_t *mlcf;
- len = sizeof("get ") - 1 + r->uri.len + sizeof(" " CRLF) - 1;
- if (r->args.len) {
- len += 1 + r->args.len;
+ mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
+
+ vv = ngx_http_get_indexed_variable(r, mlcf->index);
+
+ if (vv == NULL || vv->not_found || vv->len == 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "the \"$memcached_key\" variable is not set");
+ return NGX_ERROR;
+ }
+
+ len = sizeof("get ") - 1 + vv->len + sizeof(" " CRLF) - 1;
+ if (vv->len) {
+ len += 1 + vv->len;
}
b = ngx_create_temp_buf(r->pool, len);
@@ -252,12 +268,7 @@ ngx_http_memcached_create_request(ngx_http_request_t *r)
ctx->key.data = b->last;
- b->last = ngx_copy(b->last, r->uri.data, r->uri.len);
-
- if (r->args.len) {
- *b->last++ = '?';
- b->last = ngx_copy(b->last, r->args.data, r->args.len);
- }
+ b->last = ngx_copy(b->last, vv->data, vv->len);
ctx->key.len = b->last - ctx->key.data;
@@ -504,7 +515,7 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
*
- * conf->peers = NULL;
+ * conf->index = 0;
*/
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
@@ -604,6 +615,12 @@ ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
clcf->auto_redirect = 1;
}
+ lcf->index = ngx_http_get_variable_index(cf, &ngx_http_memcached_key);
+
+ if (lcf->index == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
return NGX_CONF_OK;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index d674b0ea3..74703a29c 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.5.8';
+our $VERSION = '0.5.9';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index f13ce0f46..421fa7e8e 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -363,7 +363,7 @@ has_request_body(r, next)
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
- r->request_body_delete_incomplete_file = 1;
+ r->request_body_in_clean_file = 1;
if (r->request_body_in_file_only) {
r->request_body_file_log_level = 0;
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index a33a9f7ee..bfdcb647c 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -44,9 +44,8 @@ static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
static void ngx_http_perl_sleep_handler(ngx_http_request_t *r);
static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf,
ngx_http_perl_main_conf_t *pmcf);
-static PerlInterpreter *
- ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
- ngx_log_t *log);
+static PerlInterpreter *ngx_http_perl_create_interpreter(ngx_conf_t *cf,
+ ngx_http_perl_main_conf_t *pmcf);
static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires,
ngx_log_t *log);
static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r,
@@ -475,7 +474,7 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
PERL_SYS_INIT(&ngx_argc, &ngx_argv);
- pmcf->perl = ngx_http_perl_create_interpreter(pmcf, cf->log);
+ pmcf->perl = ngx_http_perl_create_interpreter(cf, pmcf);
if (pmcf->perl == NULL) {
PERL_SYS_TERM();
@@ -500,8 +499,8 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
static PerlInterpreter *
-ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
- ngx_log_t *log)
+ngx_http_perl_create_interpreter(ngx_conf_t *cf,
+ ngx_http_perl_main_conf_t *pmcf)
{
int n;
STRLEN len;
@@ -509,11 +508,15 @@ ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
char *ver, *embedding[6];
PerlInterpreter *perl;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "create perl interpreter");
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");
+
+ if (ngx_set_environment(cf->cycle, NULL) == NULL) {
+ return NULL;
+ }
perl = perl_alloc();
if (perl == NULL) {
- ngx_log_error(NGX_LOG_ALERT, log, 0, "perl_alloc() failed");
+ ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_alloc() failed");
return NULL;
}
@@ -546,7 +549,7 @@ ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
n = perl_parse(perl, ngx_http_perl_xs_init, n, embedding, NULL);
if (n != 0) {
- ngx_log_error(NGX_LOG_ALERT, log, 0, "perl_parse() failed: %d", n);
+ ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_parse() failed: %d", n);
goto fail;
}
@@ -554,13 +557,13 @@ ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
ver = SvPV(sv, len);
if (ngx_strcmp(ver, NGINX_VERSION) != 0) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
+ ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
"version " NGINX_VERSION " of nginx.pm is required, "
"but %s was found", ver);
goto fail;
}
- if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, log) != NGX_OK) {
+ if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) {
goto fail;
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 2bff24560..c35ccacda 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -23,6 +23,11 @@ typedef struct {
#define NGX_HTTP_LOCATION_REGEX 4
+#define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
+#define NGX_HTTP_REQUEST_BODY_FILE_ON 1
+#define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
+
+
static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
ngx_array_t *locations, size_t len);
@@ -74,6 +79,14 @@ static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = {
};
+static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
+ { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
+ { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
+ { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
+ { ngx_null_string, 0 }
+};
+
+
static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("variables_hash_max_size"),
@@ -269,13 +282,14 @@ static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("client_body_in_file_only"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
+ ngx_conf_set_enum_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
- NULL },
+ &ngx_http_core_request_body_in_file },
{ ngx_string("sendfile"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
+ |NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, sendfile),
@@ -876,6 +890,8 @@ ngx_http_update_location_config(ngx_http_request_t *r)
if (clcf->client_body_in_file_only) {
r->request_body_in_file_only = 1;
r->request_body_in_persistent_file = 1;
+ r->request_body_in_clean_file =
+ clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
r->request_body_file_log_level = NGX_LOG_NOTICE;
} else {
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 0c7f5cb5f..787b36155 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -409,7 +409,7 @@ struct ngx_http_request_s {
unsigned request_body_in_single_buf:1;
unsigned request_body_in_file_only:1;
unsigned request_body_in_persistent_file:1;
- unsigned request_body_delete_incomplete_file:1;
+ unsigned request_body_in_clean_file:1;
unsigned request_body_file_group_access:1;
unsigned request_body_file_log_level:3;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 11f82dbd4..16d60a00b 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -14,7 +14,6 @@ static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r,
ngx_chain_t *body);
-static void ngx_http_finalize_request_body(ngx_http_request_t *r, ngx_int_t rc);
static void ngx_http_read_discarded_body_handler(ngx_http_request_t *r);
static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r);
@@ -72,6 +71,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
tf->warn = "a client request body is buffered to a temporary file";
tf->log_level = r->request_body_file_log_level;
tf->persistent = r->request_body_in_persistent_file;
+ tf->clean = r->request_body_in_clean_file;
if (r->request_body_file_group_access) {
tf->access = 0660;
@@ -80,7 +80,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
rb->temp_file = tf;
if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
- tf->persistent, tf->access)
+ tf->persistent, tf->clean, tf->access)
!= NGX_OK)
{
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -238,14 +238,14 @@ ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
if (r->connection->read->timedout) {
r->connection->timedout = 1;
- ngx_http_finalize_request_body(r, NGX_HTTP_REQUEST_TIME_OUT);
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
return;
}
rc = ngx_http_do_read_client_request_body(r);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- ngx_http_finalize_request_body(r, rc);
+ ngx_http_finalize_request(r, rc);
}
}
@@ -400,6 +400,7 @@ ngx_http_write_request_body(ngx_http_request_t *r, ngx_chain_t *body)
tf->warn = "a client request body is buffered to a temporary file";
tf->log_level = r->request_body_file_log_level;
tf->persistent = r->request_body_in_persistent_file;
+ tf->clean = r->request_body_in_clean_file;
if (r->request_body_file_group_access) {
tf->access = 0660;
@@ -422,26 +423,6 @@ ngx_http_write_request_body(ngx_http_request_t *r, ngx_chain_t *body)
}
-static void
-ngx_http_finalize_request_body(ngx_http_request_t *r, ngx_int_t rc)
-{
- if (r->request_body->temp_file
- && r->request_body_in_persistent_file
- && r->request_body_delete_incomplete_file)
- {
- if (ngx_delete_file(r->request_body->temp_file->file.name.data)
- == NGX_FILE_ERROR)
- {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed",
- r->request_body->temp_file->file.name.data);
- }
- }
-
- ngx_http_finalize_request(r, rc);
-}
-
-
ngx_int_t
ngx_http_discard_body(ngx_http_request_t *r)
{
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index da4828f88..c8586f6e4 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -757,15 +757,20 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
static void
ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
{
- sigset_t set;
- ngx_int_t n;
- ngx_uint_t i;
- struct rlimit rlmt;
- ngx_core_conf_t *ccf;
- ngx_listening_t *ls;
+ sigset_t set;
+ ngx_int_t n;
+ ngx_uint_t i;
+ struct rlimit rlmt;
+ ngx_core_conf_t *ccf;
+ ngx_listening_t *ls;
ngx_process = NGX_PROCESS_WORKER;
+ if (ngx_set_environment(cycle, NULL) == NULL) {
+ /* fatal */
+ exit(2);
+ }
+
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (geteuid() == 0) {