From 160d774afcf3cdd4f999489211eb9d78bf82439a Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Wed, 19 Nov 2003 16:26:41 +0000 Subject: [PATCH] nginx-0.0.1-2003-11-19-19:26:41 import --- src/core/nginx.c | 78 ++++++----- src/core/nginx.h | 6 +- src/core/ngx_conf_file.h | 6 +- src/core/ngx_core.h | 1 + src/core/ngx_log.c | 9 ++ src/core/ngx_log.h | 4 +- src/event/ngx_event_accept.c | 126 +++++++++++------- src/event/ngx_event_connect.c | 16 ++- .../modules/proxy/ngx_http_proxy_handler.c | 16 ++- .../modules/proxy/ngx_http_proxy_handler.h | 6 + .../modules/proxy/ngx_http_proxy_upstream.c | 18 ++- src/http/ngx_http.h | 8 +- src/http/ngx_http_cache.c | 2 +- src/http/ngx_http_core_module.c | 2 +- src/http/ngx_http_request.c | 34 ++--- src/os/unix/ngx_daemon.c | 15 ++- src/os/unix/ngx_errno.h | 1 + src/os/unix/ngx_files.c | 14 +- src/os/unix/ngx_freebsd_config.h | 1 + src/os/unix/ngx_posix_init.c | 13 +- src/os/unix/ngx_process.c | 112 ++++++++++++++++ src/os/unix/ngx_process.h | 6 + 22 files changed, 348 insertions(+), 146 deletions(-) create mode 100644 src/os/unix/ngx_process.c diff --git a/src/core/nginx.c b/src/core/nginx.c index b5e4392c0..ca056bd18 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -50,18 +50,19 @@ ngx_module_t ngx_core_module = { }; -int ngx_max_module; -ngx_os_io_t ngx_io; +int ngx_max_module; +ngx_os_io_t ngx_io; -ngx_cycle_t *ngx_cycle; -ngx_pool_t *ngx_temp_pool; -ngx_array_t ngx_old_cycles; -ngx_event_t ngx_cleaner_event; +volatile ngx_cycle_t *ngx_cycle; +ngx_array_t ngx_old_cycles; + +static ngx_pool_t *ngx_temp_pool; +static ngx_event_t ngx_cleaner_event; /* STUB NAME */ -ngx_connection_t dumb; +static ngx_connection_t dumb; -int ngx_connection_counter; +u_int ngx_connection_counter; int restart; @@ -112,17 +113,16 @@ int main(int argc, char *const *argv) #if !(WIN32) - ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, - ngx_core_module); + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->daemon != 0) { - if (ngx_daemon(ngx_cycle->log) == NGX_ERROR) { + if (ngx_daemon(cycle->log) == NGX_ERROR) { return 1; } } - if (dup2(ngx_cycle->log->file->fd, STDERR_FILENO) == -1) { - ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, + if (dup2(cycle->log->file->fd, STDERR_FILENO) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "dup2(STDERR) failed"); return 1; } @@ -132,22 +132,31 @@ int main(int argc, char *const *argv) /* life cycle */ for ( ;; ) { - /* STUB */ ngx_cycle->log->log_level = NGX_LOG_DEBUG; + /* STUB */ cycle->log->log_level = NGX_LOG_DEBUG; - /* forks */ +#if 0 + +#if !(WIN32) + ngx_spawn_process(cycle->log); +#endif + + stub_init(cycle); +#endif + + /* TODO: forks */ ngx_init_temp_number(); for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_child) { - if (ngx_modules[i]->init_child(ngx_cycle) == NGX_ERROR) { + if (ngx_modules[i]->init_child(cycle) == NGX_ERROR) { /* fatal */ exit(1); } } } - /* threads */ + /* TODO: threads */ restart = 0; rotate = 0; @@ -155,12 +164,12 @@ int main(int argc, char *const *argv) for ( ;; ) { for ( ;; ) { - ngx_log_debug(ngx_cycle->log, "worker cycle"); + ngx_log_debug(cycle->log, "worker cycle"); - ngx_process_events(ngx_cycle->log); + ngx_process_events(cycle->log); if (rotate) { - ngx_log_debug(ngx_cycle->log, "rotate"); + ngx_log_debug(cycle->log, "rotate"); file = cycle->open_files.elts; for (i = 0; i < cycle->open_files.nelts; i++) { @@ -176,7 +185,7 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ fd _ file[i].fd _ file[i].name.data); if (fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_EMERG, - ngx_cycle->log, ngx_errno, + cycle->log, ngx_errno, ngx_open_file_n " \"%s\" failed", file[i].name.data); continue; @@ -185,14 +194,14 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ fd _ file[i].fd _ file[i].name.data); #if (WIN32) if (ngx_file_append_mode(fd) == NGX_ERROR) { ngx_log_error(NGX_LOG_EMERG, - ngx_cycle->log, ngx_errno, + cycle->log, ngx_errno, ngx_file_append_mode_n " \"%s\" failed", file[i].name.data); if (ngx_close_file(fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, - ngx_cycle->log, ngx_errno, + cycle->log, ngx_errno, ngx_close_file_n " \"%s\" failed", file[i].name.data); } @@ -203,7 +212,7 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ fd _ file[i].fd _ file[i].name.data); if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, - ngx_cycle->log, ngx_errno, + cycle->log, ngx_errno, ngx_close_file_n " \"%s\" failed", file[i].name.data); } @@ -213,14 +222,15 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ fd _ file[i].fd _ file[i].name.data); } if (restart) { - ngx_log_debug(ngx_cycle->log, "restart"); + ngx_log_debug(cycle->log, "restart"); break; } } - cycle = ngx_init_cycle(ngx_cycle, ngx_cycle->log); + cycle = ngx_init_cycle(cycle, cycle->log); if (cycle == NULL) { + cycle = (ngx_cycle_t*) ngx_cycle; continue; } @@ -464,8 +474,6 @@ ngx_log_debug(log, "OPEN: %d:%s" _ file[i].fd _ file[i].name.data); } } - stub_init(cycle); - if (old_cycle == NULL) { return cycle; } @@ -681,11 +689,13 @@ static int ngx_open_listening_sockets(ngx_cycle_t *cycle, ngx_log_t *log) static void ngx_clean_old_cycles(ngx_event_t *ev) { int i, n, found, live; + ngx_log_t *log; ngx_cycle_t **cycle; - ngx_temp_pool->log = ngx_cycle->log; + log = ngx_cycle->log; + ngx_temp_pool->log = log; - ngx_log_debug(ngx_cycle->log, "clean old cycles"); + ngx_log_debug(log, "clean old cycles"); live = 0; @@ -701,7 +711,7 @@ static void ngx_clean_old_cycles(ngx_event_t *ev) for (n = 0; n < cycle[i]->connection_n; n++) { if (cycle[i]->connections[n].fd != -1) { found = 1; - ngx_log_debug(ngx_cycle->log, "live fd: %d" _ n); + ngx_log_debug(log, "live fd: %d" _ n); break; } } @@ -711,15 +721,15 @@ static void ngx_clean_old_cycles(ngx_event_t *ev) continue; } - ngx_log_debug(ngx_cycle->log, "clean old cycle: %d" _ i); + ngx_log_debug(log, "clean old cycle: %d" _ i); ngx_destroy_pool(cycle[i]->pool); cycle[i] = NULL; } - ngx_log_debug(ngx_cycle->log, "old cycles status: %d" _ live); + ngx_log_debug(log, "old cycles status: %d" _ live); if (live) { - ngx_log_debug(ngx_cycle->log, "TIMER"); + ngx_log_debug(log, "TIMER"); ngx_add_timer(ev, 30000); } else { diff --git a/src/core/nginx.h b/src/core/nginx.h index f58df7c8c..6a9fd493b 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -6,10 +6,10 @@ #define NGINX_CONF "nginx.conf" -extern int ngx_max_module; -extern int ngx_connection_counter; +extern int ngx_max_module; +extern u_int ngx_connection_counter; -extern ngx_module_t ngx_core_module; +extern ngx_module_t ngx_core_module; diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h index 23f436e91..8a473bf5a 100644 --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -264,9 +264,9 @@ char *ngx_conf_set_core_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -extern ngx_module_t *ngx_modules[]; -extern ngx_cycle_t *ngx_cycle; -extern ngx_array_t ngx_old_cycles; +extern ngx_module_t *ngx_modules[]; +extern volatile ngx_cycle_t *ngx_cycle; +extern ngx_array_t ngx_old_cycles; #endif /* _NGX_HTTP_CONF_FILE_H_INCLUDED_ */ diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index ec8182b0a..0dc45bba3 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -5,6 +5,7 @@ typedef struct ngx_module_s ngx_module_t; typedef struct ngx_conf_s ngx_conf_t; typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_log_s ngx_log_t; typedef struct ngx_open_file_s ngx_open_file_t; typedef struct ngx_command_s ngx_command_t; diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c index 61d49c7c2..a9ca9c363 100644 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -91,12 +91,21 @@ void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, PID_FMT "#%d: ", ngx_getpid(), 0); + if (log->data) { + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + "*%u ", * (u_int *) log->data); + } + #if (HAVE_VARIADIC_MACROS) + va_start(args, fmt); len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args); va_end(args); + #else + len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args); + #endif if (err) { diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h index 3eedfff6f..290b11c46 100644 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -66,7 +66,7 @@ typedef enum { typedef size_t (*ngx_log_handler_pt) (void *ctx, char *buf, size_t len); -typedef struct { +struct ngx_log_s { int log_level; ngx_open_file_t *file; void *data; @@ -78,7 +78,7 @@ typedef struct { char *context; /* */ #endif -} ngx_log_t; +}; #define MAX_ERROR_STR 2048 diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index a4f7436e9..17f8899a5 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -5,62 +5,74 @@ #include +static size_t ngx_accept_log_error(void *data, char *buf, size_t len); + + void ngx_event_accept(ngx_event_t *ev) { - int instance; - socklen_t len; - struct sockaddr *sa; - ngx_err_t err; - ngx_pool_t *pool; - ngx_socket_t s; - ngx_event_t *rev, *wev; - ngx_connection_t *c, *ls; - ngx_event_conf_t *ecf; + int instance, accepted; + socklen_t len; + struct sockaddr *sa; + ngx_err_t err; + ngx_log_t *log; + ngx_pool_t *pool; + ngx_socket_t s; + ngx_event_t *rev, *wev; + ngx_connection_t *c, *ls; + ngx_event_conf_t *ecf; ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); ls = ev->data; - ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _ + ngx_log_debug(ev->log, "accept on %s ready: %d" _ + ls->listening->addr_text.data _ ev->available); ev->ready = 0; + accepted = 0; do { /* * Create the pool before accept() to avoid copy the sockaddr. * Although accept() can fail it's an uncommon case - * and the pool can be got from the free pool list + * and besides the pool can be got from the free pool list */ - pool = ngx_create_pool(ls->listening->pool_size, ev->log); - if (pool == NULL) { + if (!(pool = ngx_create_pool(ls->listening->pool_size, ev->log))) { return; } - sa = ngx_palloc(pool, ls->listening->socklen); - if (sa == NULL) { + if (!(sa = ngx_palloc(pool, ls->listening->socklen))) { return; } + if (!(log = ngx_palloc(pool, sizeof(ngx_log_t)))) { + return; + } + ngx_memcpy(log, ls->log, sizeof(ngx_log_t)); + pool->log = log; + + log->data = ls->listening->addr_text.data; + log->handler = ngx_accept_log_error; + len = ls->listening->socklen; -ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); - s = accept(ls->fd, sa, &len); if (s == -1) { err = ngx_socket_errno; if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_NOTICE, ev->log, err, - "EAGAIN while accept() %s", - ls->listening->addr_text.data); + ngx_log_error(NGX_LOG_NOTICE, log, err, + "EAGAIN after %d accepted connection(s)", + accepted); return; } ngx_log_error(NGX_LOG_ALERT, ev->log, err, - "accept() %s failed", ls->listening->addr_text.data); + "accept() on %s failed", + ls->listening->addr_text.data); ngx_destroy_pool(pool); return; @@ -71,15 +83,14 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); if ((unsigned) s >= (unsigned) ecf->connections) { ngx_log_error(NGX_LOG_ALERT, ev->log, 0, - "accept() %s returned socket #%d while " + "accept() on %s returned socket #%d while " "only %d connections was configured, " "sleeping for 1 second", ls->listening->addr_text.data, s, ecf->connections); if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_close_socket_n " %s failed", - ls->listening->addr_text.data); + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_close_socket_n "failed"); } ngx_msleep(1000); @@ -93,14 +104,12 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); if (ngx_inherited_nonblocking) { if ((ngx_event_flags & NGX_USE_AIO_EVENT)) { if (ngx_blocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_blocking_n " %s failed", - ls->listening->addr_text.data); + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_blocking_n " failed"); if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_close_socket_n " %s failed", - ls->listening->addr_text.data); + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_close_socket_n " failed"); } ngx_destroy_pool(pool); @@ -111,14 +120,12 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); } else { if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) { if (ngx_nonblocking(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_nonblocking_n " %s failed", - ls->listening->addr_text.data); + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_nonblocking_n " failed"); if (ngx_close_socket(s) == -1) { - ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_close_socket_n " %s failed", - ls->listening->addr_text.data); + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_close_socket_n " failed"); } ngx_destroy_pool(pool); @@ -134,9 +141,10 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); */ if (s % 4) { - ngx_log_error(NGX_LOG_EMERG, ls->log, 0, - ngx_socket_n - " created socket %d, not divisible by 4", s); + ngx_log_error(NGX_LOG_EMERG, ev->log, 0, + "accept() on %s returned socket #%d, " + "not divisible by 4", + ls->listening->addr_text.data, s); exit(1); } @@ -161,16 +169,21 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); c->sockaddr = sa; c->socklen = len; - rev->instance = wev->instance = !instance; + rev->instance = !instance; + wev->instance = !instance; - rev->index = wev->index = NGX_INVALID_INDEX; + rev->index = NGX_INVALID_INDEX; + wev->index = NGX_INVALID_INDEX; + + rev->data = c; + wev->data = c; - rev->data = wev->data = c; c->read = rev; c->write = wev; c->fd = s; c->unexpected_eof = 1; + wev->write = 1; wev->ready = 1; @@ -182,12 +195,9 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); c->ctx = ls->ctx; c->servers = ls->servers; - c->log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (c->log == NULL) { - return; - } - ngx_memcpy(c->log, ls->log, sizeof(ngx_log_t)); - rev->log = wev->log = c->log; + c->log = log; + rev->log = log; + wev->log = log; /* TODO: x86: MT: lock xadd, MP: lock xadd, shared */ c->number = ngx_connection_counter++; @@ -202,8 +212,7 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); if (ngx_add_conn(c) == NGX_ERROR) { if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, - ngx_close_socket_n " %s failed", - ls->listening->addr_text.data); + ngx_close_socket_n " failed"); } ngx_destroy_pool(pool); @@ -211,13 +220,28 @@ ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); } } + log->data = NULL; + log->handler = NULL; + ls->listening->handler(c); +#if 0 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { ev->available--; } +#endif + + accepted++; } while (ev->available); return; } + + +static size_t ngx_accept_log_error(void *data, char *buf, size_t len) +{ + char *sock = data; + + return ngx_snprintf(buf, len, " while accept() on %s", sock); +} diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index 717a4a4b7..1a61ef7fc 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -158,15 +158,23 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc) ngx_memzero(rev, sizeof(ngx_event_t)); ngx_memzero(wev, sizeof(ngx_event_t)); - rev->index = wev->index = NGX_INVALID_INDEX; - rev->data = wev->data = c; + rev->index = NGX_INVALID_INDEX; + wev->index = NGX_INVALID_INDEX; + + rev->data = c; + wev->data = c; + c->read = rev; c->write = wev; wev->write = 1; - rev->instance = wev->instance = !instance; + rev->instance = !instance; + wev->instance = !instance; + + c->log = pc->log; + rev->log = pc->log; + wev->log = pc->log; - rev->log = wev->log = c->log = pc->log; c->fd = s; pc->connection = c; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 7a012c88d..b7487f833 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -524,22 +524,22 @@ void ngx_http_proxy_close_connection(ngx_http_proxy_ctx_t *p) size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len) { - ngx_http_proxy_ctx_t *p = data; + ngx_http_proxy_log_ctx_t *ctx = data; ngx_http_request_t *r; ngx_peer_connection_t *peer; - r = p->request; - peer = &p->upstream->peer; + r = ctx->proxy->request; + peer = &ctx->proxy->upstream->peer; return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s, upstream: %s%s%s%s%s", - p->action, + ctx->proxy->action, r->connection->addr_text.data, r->unparsed_uri.data, peer->peers->peers[peer->cur_peer].addr_port_text.data, - p->lcf->upstream->uri.data, - r->uri.data + p->lcf->upstream->location->len, + ctx->proxy->lcf->upstream->uri.data, + r->uri.data + ctx->proxy->lcf->upstream->location->len, r->args.len ? "?" : "", r->args.len ? r->args.data : ""); } @@ -934,7 +934,9 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; lcf->upstream->location = &clcf->name; clcf->handler = ngx_http_proxy_handler; - clcf->auto_redirect = 1; + if (clcf->name.data[clcf->name.len - 1] == '/') { + clcf->auto_redirect = 1; + } return NULL; } diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 0258de5d8..43eb5ef2d 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -185,6 +185,12 @@ struct ngx_http_proxy_ctx_s { }; +typedef struct { + u_int connection; + ngx_http_proxy_ctx_t *proxy; +} ngx_http_proxy_log_ctx_t; + + #define NGX_HTTP_PROXY_PARSE_NO_HEADER 20 diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index 12a4c6232..9d442cd4a 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -210,10 +210,11 @@ static void ngx_http_proxy_init_upstream(void *data) { ngx_http_proxy_ctx_t *p = data; - ngx_chain_t *cl; - ngx_http_request_t *r; - ngx_output_chain_ctx_t *octx; - ngx_chain_writer_ctx_t *wctx; + ngx_chain_t *cl; + ngx_http_request_t *r; + ngx_output_chain_ctx_t *octx; + ngx_chain_writer_ctx_t *wctx; + ngx_http_proxy_log_ctx_t *lctx; r = p->request; @@ -252,10 +253,17 @@ ngx_log_debug(r->connection->log, "timer_set: %d" _ r->request_hunks = cl; + if (!(lctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_log_ctx_t)))) { + ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + lctx->connection = r->connection->number; + lctx->proxy = p; + p->upstream->peer.log = r->connection->log; p->saved_ctx = r->connection->log->data; p->saved_handler = r->connection->log->handler; - r->connection->log->data = p; + r->connection->log->data = lctx; r->connection->log->handler = ngx_http_proxy_log_error; p->action = "connecting to upstream"; diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index f4f68ff15..4271da3e7 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -16,9 +16,10 @@ typedef struct { - char *action; - char *client; - char *url; + u_int connection; + char *action; + char *client; + char *url; } ngx_http_log_ctx_t; @@ -52,6 +53,7 @@ void ngx_http_handler(ngx_http_request_t *r); void ngx_http_finalize_request(ngx_http_request_t *r, int error); void ngx_http_writer(ngx_event_t *wev); +void ngx_http_empty_handler(ngx_event_t *wev); int ngx_http_send_last(ngx_http_request_t *r); void ngx_http_close_request(ngx_http_request_t *r, int error); diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c index 8eb62ebd0..fd1a9d01e 100644 --- a/src/http/ngx_http_cache.c +++ b/src/http/ngx_http_cache.c @@ -107,7 +107,7 @@ int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) ctx->date = h->date; ctx->length = h->length; - if (h->key_len > (size_t) (ctx->buf->last - ctx->buf->pos)) { + if (h->key_len > (size_t) (ctx->buf->end - ctx->buf->pos)) { ngx_log_error(NGX_LOG_ALERT, ctx->log, 0, "cache file \"%s\" is probably invalid", ctx->file.name.data); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index f4f5d4f3c..e06198ea0 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -355,7 +355,7 @@ static void ngx_http_run_phases(ngx_http_request_t *r) } if (r->content_handler) { - r->connection->write->event_handler = ngx_http_writer; + r->connection->write->event_handler = ngx_http_empty_handler; rc = r->content_handler(r); ngx_http_finalize_request(r, rc); return; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index a59b12aa1..62c9a666a 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -21,7 +21,6 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r); static void ngx_http_keepalive_handler(ngx_event_t *ev); static void ngx_http_set_lingering_close(ngx_http_request_t *r); static void ngx_http_lingering_close_handler(ngx_event_t *ev); -static void ngx_http_empty_handler(ngx_event_t *wev); static void ngx_http_client_error(ngx_http_request_t *r, int client_error, int error); @@ -52,7 +51,7 @@ static void ngx_http_dummy(ngx_event_t *wev) void ngx_http_init_connection(ngx_connection_t *c) { ngx_event_t *rev; - ngx_http_log_ctx_t *lctx; + ngx_http_log_ctx_t *ctx; c->addr_text.data = ngx_palloc(c->pool, c->listening->addr_text_max_len); if (c->addr_text.data == NULL) { @@ -68,14 +67,15 @@ void ngx_http_init_connection(ngx_connection_t *c) return; } - if (!(lctx = ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)))) { + if (!(ctx = ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)))) { ngx_http_close_connection(c); return; } - lctx->client = c->addr_text.data; - lctx->action = "reading client request line"; - c->log->data = lctx; + ctx->connection = c->number; + ctx->client = c->addr_text.data; + ctx->action = "reading client request line"; + c->log->data = ctx; c->log->handler = ngx_http_log_error; rev = c->read; @@ -263,7 +263,7 @@ static void ngx_http_process_request_line(ngx_event_t *rev) ssize_t n; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_log_ctx_t *lctx; + ngx_http_log_ctx_t *ctx; ngx_http_core_srv_conf_t *cscf; c = rev->data; @@ -414,9 +414,9 @@ static void ngx_http_process_request_line(ngx_event_t *rev) return; } - lctx = c->log->data; - lctx->action = "reading client request headers"; - lctx->url = r->unparsed_uri.data; + ctx = c->log->data; + ctx->action = "reading client request headers"; + ctx->url = r->unparsed_uri.data; /* TODO: ngx_init_table */ r->headers_in.headers = ngx_create_table(r->pool, 20); @@ -874,6 +874,8 @@ void ngx_http_writer(ngx_event_t *wev) ngx_http_request_t *r; ngx_http_core_loc_conf_t *clcf; + ngx_log_debug(wev->log, "http writer handler"); + c = wev->data; r = c->data; @@ -1138,7 +1140,7 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) { ssize_t n; ngx_connection_t *c; - ngx_http_log_ctx_t *lctx; + ngx_http_log_ctx_t *ctx; c = (ngx_connection_t *) rev->data; @@ -1168,19 +1170,19 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) return; } - lctx = (ngx_http_log_ctx_t *) rev->log->data; + ctx = (ngx_http_log_ctx_t *) rev->log->data; rev->log->handler = NULL; if (n == 0) { ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno, - "client %s closed keepalive connection", lctx->client); + "client %s closed keepalive connection", ctx->client); ngx_http_close_connection(c); return; } c->buffer->last += n; rev->log->handler = ngx_http_log_error; - lctx->action = "reading client request line"; + ctx->action = "reading client request line"; ngx_http_init_request(rev); } @@ -1306,7 +1308,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) } -static void ngx_http_empty_handler(ngx_event_t *wev) +void ngx_http_empty_handler(ngx_event_t *wev) { ngx_log_debug(wev->log, "http EMPTY handler"); @@ -1442,7 +1444,7 @@ static void ngx_http_client_error(ngx_http_request_t *r, static size_t ngx_http_log_error(void *data, char *buf, size_t len) { - ngx_http_log_ctx_t *ctx = (ngx_http_log_ctx_t *) data; + ngx_http_log_ctx_t *ctx = data; if (ctx->action && ctx->url) { return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s", diff --git a/src/os/unix/ngx_daemon.c b/src/os/unix/ngx_daemon.c index 7d05fef9b..b2a37c100 100644 --- a/src/os/unix/ngx_daemon.c +++ b/src/os/unix/ngx_daemon.c @@ -9,7 +9,7 @@ int ngx_daemon(ngx_log_t *log) switch (fork()) { case -1: - ngx_log_error(NGX_LOG_EMERG, log, errno, "fork() failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); return NGX_ERROR; case 0: @@ -20,7 +20,7 @@ int ngx_daemon(ngx_log_t *log) } if (setsid() == -1) { - ngx_log_error(NGX_LOG_EMERG, log, errno, "setsid() failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed"); return NGX_ERROR; } @@ -28,30 +28,31 @@ int ngx_daemon(ngx_log_t *log) fd = open("/dev/null", O_RDWR); if (fd == -1) { - ngx_log_error(NGX_LOG_EMERG, log, errno, "open(\"/dev/null\") failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "open(\"/dev/null\") failed"); return NGX_ERROR; } if (dup2(fd, STDIN_FILENO) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDIN) failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed"); return NGX_ERROR; } if (dup2(fd, STDOUT_FILENO) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDOUT) failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed"); return NGX_ERROR; } #if 0 if (dup2(fd, STDERR_FILENO) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed"); return NGX_ERROR; } #endif if (fd > STDERR_FILENO) { if (close(fd) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed"); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed"); return NGX_ERROR; } } diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h index d0f255a4e..a7326b613 100644 --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -19,6 +19,7 @@ typedef int ngx_err_t; #define NGX_ECONNRESET ECONNRESET #define NGX_ETIMEDOUT ETIMEDOUT #define NGX_ECANCELED ECANCELED +#define NGX_ECHILD ECHILD #define NGX_ENOMOREFILES 0 diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c index 7b9d4e440..651113d91 100644 --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -30,9 +30,9 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset) ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed"); return NGX_ERROR; } - } - file->sys_offset = offset; + file->sys_offset = offset; + } n = read(file->fd, buf, size); @@ -77,9 +77,9 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset) ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed"); return NGX_ERROR; } - } - file->sys_offset = offset; + file->sys_offset = offset; + } n = write(file->fd, buf, size); @@ -151,14 +151,14 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, return ngx_write_file(file, iov[0].iov_base, iov[0].iov_len, offset); } - if (file->offset != offset) { + if (file->sys_offset != offset) { if (lseek(file->fd, offset, SEEK_SET) == -1) { ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed"); return NGX_ERROR; } - } - file->sys_offset = offset; + file->sys_offset = offset; + } n = writev(file->fd, io.elts, io.nelts); diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h index 0493b3b88..a045a1d07 100644 --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c index c97083333..7462dcfc4 100644 --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -13,8 +13,8 @@ void ngx_rotate_signal_handler(int signo); int ngx_posix_init(ngx_log_t *log) { - struct sigaction sa; - struct rlimit rlmt; + struct rlimit rlmt; + struct sigaction sa; ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = SIG_IGN; @@ -25,6 +25,15 @@ int ngx_posix_init(ngx_log_t *log) return NGX_ERROR; } + ngx_memzero(&sa, sizeof(struct sigaction)); + sa.sa_handler = ngx_sigchld_handler; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGCHLD, &sa, NULL) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "sigaction(SIGCHLD) failed"); + return NGX_ERROR; + } + sa.sa_handler = ngx_restart_signal_handler; if (sigaction(ngx_signal_value(NGX_RESTART_SIGNAL), &sa, NULL) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c new file mode 100644 index 000000000..e487151ef --- /dev/null +++ b/src/os/unix/ngx_process.c @@ -0,0 +1,112 @@ + +#include +#include + + +void testone(ngx_log_t *log) +{ + ngx_log_debug(log, "child process"); + ngx_msleep(5000); + exit(0); +} + + +int ngx_spawn_process(ngx_log_t *log) +{ + pid_t pid; + sigset_t set, oset; + + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + if (sigprocmask(SIG_BLOCK, &set, &oset) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sigprocmask() failed"); + } + + pid = fork(); + + if (pid == -1 || pid == 0) { + if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "sigprocmask() failed"); + } + } + + switch (pid) { + case -1: + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "fork() failed"); + return NGX_ERROR; + + case 0: + testone(log); + break; + + default: + } + +ngx_log_debug(log, "parent process, child: " PID_FMT _ pid); + + /* book keeping */ + + if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sigprocmask() failed"); + } + + return NGX_OK; +} + + +void ngx_sigchld_handler(int signo) +{ + int status, one; + pid_t pid; + ngx_err_t err; + struct timeval tv; + + ngx_gettimeofday(&tv); + + if (ngx_cached_time != tv.tv_sec) { + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + } + + one = 0; + + for ( ;; ) { + pid = waitpid(-1, &status, WNOHANG); + + if (pid == 0) { + return; + } + + if (pid == -1) { + err = ngx_errno; + + if (err == NGX_EINTR) { + continue; + } + + if (err == NGX_ECHILD && one) { + return; + } + + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno, + "waitpid() failed"); + return; + } + + one = 1; + + ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, + "process " PID_FMT " exited with code %d", pid, status); + + /* TODO: restart handler */ + +#if 0 + ngx_msleep(2000); +#endif + +#if 0 + ngx_spawn_process(ngx_cycle->log); +#endif + } +} diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h index 60689ba9b..15d9c0d1d 100644 --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -2,7 +2,13 @@ #define _NGX_PROCESS_H_INCLUDED_ +typedef pid_t ngx_pid_t; + #define ngx_getpid getpid +int ngx_spawn_process(ngx_log_t *log); +void ngx_sigchld_handler(int signo); + + #endif /* _NGX_PROCESS_H_INCLUDED_ */