nginx-0.0.3-2004-04-26-00:13:21 import

This commit is contained in:
Igor Sysoev 2004-04-25 20:13:21 +00:00
parent a040f00167
commit 3f4685f3de
20 changed files with 383 additions and 49 deletions

View File

@ -78,8 +78,9 @@ if [ $HTTP_PROXY = YES ]; then
fi
modules="$CORE_MODULES $EVENT_MODULES $HTTP_MODULES \
$HTTP_FILTER_MODULES $HTTP_NOT_MODIFIED_FILTER_MODULE"
modules="$CORE_MODULES $EVENT_MODULES $HTTP_MODULES $HTTP_FILTER_MODULES \
$HTTP_HEADERS_FILTER_MODULE \
$HTTP_NOT_MODIFIED_FILTER_MODULE"
echo "#include <ngx_config.h>" > $NGX_MODULES_C

View File

@ -179,6 +179,7 @@ HTTP_FILTER_MODULES="ngx_http_write_filter_module \
HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module
HTTP_RANGE_FILTER_MODULE=ngx_http_range_filter_module
HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module
HTTP_HEADERS_FILTER_MODULE=ngx_http_headers_filter_module
HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module
HTTP_STATIC_MODULE=ngx_http_static_module
@ -212,6 +213,7 @@ HTTP_SRCS="src/http/ngx_http.c \
src/http/modules/ngx_http_chunked_filter.c \
src/http/modules/ngx_http_range_filter.c \
src/http/modules/ngx_http_charset_filter.c \
src/http/modules/ngx_http_headers_filter.c \
src/http/modules/ngx_http_not_modified_filter.c"
# STUB

View File

@ -70,12 +70,9 @@ ngx_module_t ngx_core_module = {
};
ngx_int_t ngx_max_module;
ngx_uint_t ngx_max_module;
ngx_int_t ngx_process;
ngx_pid_t ngx_pid;
ngx_pid_t ngx_new_binary;
ngx_int_t ngx_inherited;
ngx_uint_t ngx_inherited;
int main(int argc, char *const *argv)

View File

@ -274,7 +274,7 @@ char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
extern ngx_int_t ngx_max_module;
extern ngx_uint_t ngx_max_module;
extern ngx_module_t *ngx_modules[];

View File

@ -77,7 +77,10 @@ typedef int ngx_flag_t;
/* TODO: auto */
#define NGX_INT32_LEN sizeof("-2147483648") - 1
#define NGX_INT64_LEN sizeof("-9223372036854775808") - 1
#if 0
#define NGX_TIME_T_LEN sizeof("-2147483648") - 1
#endif
#define NGX_TIME_T_LEN sizeof("-9223372036854775808") - 1
#define NGX_OFF_T_LEN sizeof("-9223372036854775808") - 1

View File

@ -76,11 +76,12 @@ int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
continue;
}
if (err != NGX_ENOENT
if ((path->level[0] == 0)
|| (err != NGX_ENOENT
#if (WIN32)
&& err != NGX_ENOTDIR
&& err != NGX_ENOTDIR
#endif
) {
)) {
ngx_log_error(NGX_LOG_CRIT, file->log, err,
ngx_open_tempfile_n " \"%s\" failed",
file->name.data);

View File

@ -31,7 +31,7 @@ static u_char cached_http_log_time0[] = "28/Sep/1970:12:00:00 +0600";
static u_char cached_http_log_time1[] = "28/Sep/1970:12:00:00 +0600";
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fir", "Sat" };
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

View File

@ -51,7 +51,9 @@ typedef struct {
unsigned flush:4;
unsigned redo:1;
unsigned pass:1;
unsigned done:1;
unsigned blocked:1;
size_t zin;
size_t zout;
@ -493,8 +495,8 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (ctx->zstream.avail_in == 0
&& ctx->flush == Z_NO_FLUSH
&& !ctx->redo) {
&& !ctx->redo)
{
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"gzip in: " PTR_FMT, ctx->in);
@ -517,6 +519,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (ctx->in_hunk->last < ctx->in_hunk->pos) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"zstream.avail_in is huge");
ctx->done = 1;
return NGX_ERROR;
}
@ -555,9 +558,11 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->hunks++;
} else {
ctx->blocked = 1;
break;
}
ctx->blocked = 0;
ctx->zstream.next_out = ctx->out_hunk->pos;
ctx->zstream.avail_out = conf->bufs.size;
}
@ -585,8 +590,16 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
"gzip in_hunk:" PTR_FMT " pos:" PTR_FMT,
ctx->in_hunk, ctx->in_hunk->pos);
#if 0
if (!ctx->redo) {
ctx->in_hunk->pos = ctx->zstream.next_in;
ctx->out_hunk->last = ctx->zstream.next_out;
}
#else
ctx->in_hunk->pos = ctx->zstream.next_in;
ctx->out_hunk->last = ctx->zstream.next_out;
#endif
if (ctx->zstream.avail_out == 0) {
ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool,
@ -608,6 +621,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_http_gzip_error(ctx));
*ctx->last_out = cl;
ctx->last_out = &cl->next;
ctx->pass = 1;
break;
}
@ -665,6 +679,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->zstream.avail_out = 0;
ctx->done = 1;
ctx->pass = 1;
break;
}
@ -674,13 +689,22 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_http_gzip_error(ctx));
*ctx->last_out = cl;
ctx->last_out = &cl->next;
ctx->pass = 1;
break;
}
}
if (ctx->out) {
if (last == NGX_AGAIN) {
if (ctx->pass) {
ctx->pass = 0;
} else if (last == NGX_AGAIN) {
return last;
}
} else if (ctx->blocked) {
if (last != NGX_NONE) {
return last;
}
@ -804,6 +828,8 @@ ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx)
ctx->zstream.avail_in = 0;
ctx->zstream.avail_out = 0;
ctx->done = 1;
return NGX_ERROR;
}

View File

@ -0,0 +1,237 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
typedef struct {
time_t expires;
} ngx_http_headers_conf_t;
#define NGX_HTTP_EXPIRES_UNSET -2147483647
#define NGX_HTTP_EXPIRES_OFF -2147483646
#define NGX_HTTP_EXPIRES_EPOCH -2147483645
static int ngx_http_headers_filter_init(ngx_cycle_t *cycle);
static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_command_t ngx_http_headers_filter_commands[] = {
{ ngx_string("expires"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_headers_expires,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL},
ngx_null_command
};
static ngx_http_module_t ngx_http_headers_filter_module_ctx = {
NULL, /* pre conf */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_http_headers_create_conf, /* create location configuration */
ngx_http_headers_merge_conf /* merge location configuration */
};
ngx_module_t ngx_http_headers_filter_module = {
NGX_MODULE,
&ngx_http_headers_filter_module_ctx, /* module context */
ngx_http_headers_filter_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
ngx_http_headers_filter_init, /* init module */
NULL /* init child */
};
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static int ngx_http_headers_filter(ngx_http_request_t *r)
{
size_t len;
ngx_table_elt_t *expires, *cc;
ngx_http_headers_conf_t *conf;
if (r->headers_out.status != NGX_HTTP_OK) {
return ngx_http_next_header_filter(r);
}
conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
expires = ngx_http_add_header(&r->headers_out, ngx_http_headers_out);
if (expires == NULL) {
return NGX_ERROR;
}
r->headers_out.expires = expires;
cc = ngx_http_add_header(&r->headers_out, ngx_http_headers_out);
if (cc == NULL) {
return NGX_ERROR;
}
r->headers_out.cache_control = cc;
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
expires->key.len = sizeof("Expires") - 1;
expires->key.data = (u_char *) "Expires";
expires->value.len = len - 1;
cc->key.len = sizeof("Cache-Control") - 1;
cc->key.data = (u_char *) "Cache-Control";
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
} else {
expires->value.data = ngx_palloc(r->pool, len);
if (expires->value.data == NULL) {
return NGX_ERROR;
}
if (conf->expires == 0) {
ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
ngx_cached_http_time.len + 1);
cc->value.len = sizeof("max-age=0") - 1;
cc->value.data = (u_char *) "max-age=0";
} else {
ngx_http_time(expires->value.data,
ngx_cached_time + conf->expires);
if (conf->expires < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
} else {
cc->value.data = ngx_palloc(r->pool, NGX_TIME_T_LEN + 1);
if (cc->value.data == NULL) {
return NGX_ERROR;
}
cc->value.len = ngx_snprintf((char *) cc->value.data,
sizeof("max-age=")
+ NGX_TIME_T_LEN,
"max-age=" TIME_T_FMT,
conf->expires);
}
}
}
}
return ngx_http_next_header_filter(r);
}
static int ngx_http_headers_filter_init(ngx_cycle_t *cycle)
{
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_headers_filter;
return NGX_OK;
}
static void *ngx_http_headers_create_conf(ngx_conf_t *cf)
{
ngx_http_headers_conf_t *conf;
if (!(conf = ngx_palloc(cf->pool, sizeof(ngx_http_headers_conf_t)))) {
return NGX_CONF_ERROR;
}
conf->expires = NGX_HTTP_EXPIRES_UNSET;
return conf;
}
static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
void *parent, void *child)
{
ngx_http_headers_conf_t *prev = parent;
ngx_http_headers_conf_t *conf = child;
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ?
NGX_HTTP_EXPIRES_OFF : prev->expires;
}
return NGX_CONF_OK;
}
char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_headers_conf_t *hcf = conf;
ngx_uint_t minus;
ngx_str_t *value;
if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) {
return "is duplicate";
}
value = cf->args->elts;
if (ngx_strcmp(value[1].data, "epoch") == 0) {
hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
return NGX_CONF_OK;
}
if (ngx_strcmp(value[1].data, "off") == 0) {
hcf->expires = NGX_HTTP_EXPIRES_OFF;
return NGX_CONF_OK;
}
if (value[1].data[0] == '+') {
value[1].data++;
value[1].len--;
minus = 0;
} else if (value[1].data[0] == '-') {
value[1].data++;
value[1].len--;
minus = 1;
} else {
minus = 0;
}
hcf->expires = ngx_parse_time(&value[1], 1);
if (hcf->expires == NGX_ERROR) {
return "invalid value";
}
if (hcf->expires == NGX_PARSE_LARGE_TIME) {
return "value must be less than 68 years";
}
if (minus) {
hcf->expires = - hcf->expires;
}
return NGX_CONF_OK;
}

View File

@ -26,6 +26,7 @@ typedef struct {
ngx_str_t re_name;
ngx_str_t s_name;
ngx_uint_t status;
unsigned last:1;
} ngx_http_rewrite_rule_t;
@ -123,7 +124,8 @@ static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r)
if (rc == NGX_DECLINED) {
if (scf->log) {
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
"\"%s\" does not match", rule[i].re_name.data);
"\"%s\" does not match \"%s\"",
rule[i].re_name.data, r->uri.data);
}
continue;
@ -139,7 +141,12 @@ static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r)
if (scf->log) {
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
"\"%s\" matches", rule[i].re_name.data);
"\"%s\" matches \"%s\"",
rule[i].re_name.data, r->uri.data);
}
if (rule[i].status) {
return rule[i].status;
}
uri.len = rule[i].size;
@ -247,6 +254,8 @@ static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd,
rule->msize = 0;
rule->size = 0;
rule->status = 0;
rule->last = 0;
value = cf->args->elts;
@ -264,6 +273,19 @@ static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd,
rule->re_name = value[1];
rule->s_name = value[2];
if (ngx_strcasecmp(value[2].data, "forbidden:") == 0) {
if (cf->args->nelts == 3) {
rule->status = NGX_HTTP_FORBIDDEN;
rule->last = 1;
return NGX_CONF_OK;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%s\"", value[3].data);
return NGX_CONF_ERROR;
}
for (i = 0; i < value[2].len; /* void */) {
if (!(op = ngx_push_array(&rule->ops))) {

View File

@ -96,8 +96,6 @@ int ngx_http_discard_body(ngx_http_request_t *r);
extern ngx_module_t ngx_http_module;
extern int ngx_max_module;
extern ngx_uint_t ngx_http_total_requests;
extern uint64_t ngx_http_total_sent;

View File

@ -1493,14 +1493,14 @@ static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
err->code = ngx_atoi(value[i].data, value[i].len);
if (err->code == NGX_ERROR) {
err->status = ngx_atoi(value[i].data, value[i].len);
if (err->status == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid value \"%s\"", value[i].data);
return NGX_CONF_ERROR;
}
if (err->code < 400 || err->code > 599) {
if (err->status < 400 || err->status > 599) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"value \"%s\" must be between 400 and 599",
value[i].data);

View File

@ -105,8 +105,8 @@ typedef struct {
typedef struct {
int code;
int overwrite;
ngx_int_t status;
ngx_int_t overwrite;
ngx_str_t uri;
} ngx_http_err_page_t;

View File

@ -52,8 +52,9 @@ ngx_module_t ngx_http_output_filter_module = {
int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
ngx_int_t rc;
ngx_output_chain_ctx_t *ctx;
ngx_http_output_filter_conf_t *conf;
@ -81,7 +82,16 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
return ngx_output_chain(ctx, in);
rc = ngx_output_chain(ctx, in);
if (rc == NGX_ERROR) {
/* NGX_ERROR could be returned by any filter */
r->connection->write->error = 1;
}
return rc;
}

View File

@ -991,7 +991,7 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (!ngx_terminate
&& !ngx_quit
&& !ngx_exiting
&& r->keepalive != 0
&& clcf->keepalive_timeout > 0)
{
@ -1582,6 +1582,19 @@ void ngx_http_close_request(ngx_http_request_t *r, int error)
}
}
if (r->request_body
&& r->request_body->temp_file
&& r->request_body->temp_file->file.fd != NGX_INVALID_FILE)
{
if (ngx_close_file(r->request_body->temp_file->file.fd)
== NGX_FILE_ERROR)
{
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_close_file_n " deleted file \"%s\" failed",
r->request_body->temp_file->file.name.data);
}
}
/* ctx->url was allocated from r->pool */
ctx = log->data;
ctx->url = NULL;

View File

@ -213,7 +213,7 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
if (r->err_ctx == NULL && clcf->error_pages) {
err_page = clcf->error_pages->elts;
for (i = 0; i < clcf->error_pages->nelts; i++) {
if (err_page[i].code == error) {
if (err_page[i].status == error) {
if (err_page[i].overwrite) {
r->err_status = err_page[i].overwrite;
} else {

View File

@ -16,28 +16,35 @@ static int ngx_worker_thread_cycle(void *data);
#endif
ngx_int_t ngx_process;
ngx_uint_t ngx_process;
ngx_pid_t ngx_pid;
ngx_int_t ngx_threaded;
ngx_uint_t ngx_threaded;
sig_atomic_t ngx_reap;
sig_atomic_t ngx_timer;
sig_atomic_t ngx_terminate;
sig_atomic_t ngx_quit;
ngx_uint_t ngx_exiting;
sig_atomic_t ngx_reconfigure;
sig_atomic_t ngx_reopen;
sig_atomic_t ngx_change_binary;
ngx_pid_t ngx_new_binary;
ngx_int_t ngx_inherited;
ngx_uint_t ngx_inherited;
sig_atomic_t ngx_noaccept;
ngx_uint_t ngx_noaccepting;
ngx_uint_t ngx_restart;
u_char master_process[] = "master process";
void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
{
char *title, *p;
size_t size;
ngx_int_t n;
ngx_uint_t i;
sigset_t set;
struct timeval tv;
@ -64,7 +71,23 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
sigemptyset(&set);
ngx_setproctitle("master process");
size = sizeof(master_process);
for (n = 0; n < ctx->argc; n++) {
size += ngx_strlen(ctx->argv[n]) + 1;
}
title = ngx_palloc(cycle->pool, size);
p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
for (n = 0; n < ctx->argc; n++) {
*p++ = ' ';
p = ngx_cpystrn(p, ctx->argv[n], size);
}
ngx_setproctitle(title);
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@ -386,7 +409,7 @@ static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
sigset_t set;
ngx_uint_t i, exiting;
ngx_uint_t i;
ngx_listening_t *ls;
ngx_core_conf_t *ccf;
#if (NGX_THREADS)
@ -474,10 +497,10 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
#endif
exiting = 0;
for ( ;; ) {
if (exiting && ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
if (ngx_exiting
&& ngx_event_timer_rbtree == &ngx_event_timer_sentinel)
{
ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
ngx_destroy_pool(cycle->pool);
exit(0);
@ -499,9 +522,9 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
"gracefully shutting down");
ngx_setproctitle("worker process is shutting down");
if (!exiting) {
if (!ngx_exiting) {
ngx_close_listening_sockets(cycle);
exiting = 1;
ngx_exiting = 1;
}
}

View File

@ -21,11 +21,12 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
extern ngx_int_t ngx_process;
extern ngx_uint_t ngx_process;
extern ngx_pid_t ngx_pid;
extern ngx_pid_t ngx_new_binary;
extern ngx_int_t ngx_inherited;
extern ngx_int_t ngx_threaded;
extern ngx_uint_t ngx_inherited;
extern ngx_uint_t ngx_threaded;
extern ngx_uint_t ngx_exiting;
extern sig_atomic_t ngx_reap;
extern sig_atomic_t ngx_timer;

View File

@ -5,21 +5,20 @@
#if 0
ngx_int_t ngx_process;
ngx_pid_t ngx_pid;
ngx_pid_t ngx_new_binary;
ngx_int_t ngx_inherited;
sig_atomic_t ngx_reap;
sig_atomic_t ngx_timer;
#endif
ngx_int_t ngx_threaded;
ngx_uint_t ngx_process;
ngx_pid_t ngx_pid;
ngx_uint_t ngx_threaded;
sig_atomic_t ngx_terminate;
sig_atomic_t ngx_quit;
ngx_uint_t ngx_exiting;
#if 0

View File

@ -23,11 +23,12 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx);
extern ngx_int_t ngx_process;
extern ngx_uint_t ngx_process;
extern ngx_pid_t ngx_pid;
extern ngx_pid_t ngx_new_binary;
extern ngx_int_t ngx_inherited;
extern ngx_int_t ngx_threaded;
extern ngx_uint_t ngx_inherited;
extern ngx_uint_t ngx_threaded;
extern ngx_uint_t ngx_exiting;
extern sig_atomic_t ngx_reap;
extern sig_atomic_t ngx_timer;