# HG changeset patch # User Igor Sysoev # Date 1030375099 0 # Node ID 669801705ab12826bd58ce04d273ba80aae50c04 # Parent 62b1a364857cc3a4b5abbba11991c477a7eb7a95 nginx-0.0.1-2002-08-26-19:18:19 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -85,43 +85,57 @@ static void ngx_open_listening_sockets(n /* for each listening socket */ ls = (ngx_listen_t *) ngx_listening_sockets->elts; for (i = 0; i < ngx_listening_sockets->nelts; i++) { + if (ls[i].done) continue; -#if (WIN32) - s = WSASocket(ls[i].family, ls[i].type, ls[i].protocol, NULL, 0, 0); -#else - s = socket(ls[i].family, ls[i].type, ls[i].protocol); -#endif - if (s == -1) + if (ls[i].inherited) { + + /* TODO: close on exit */ + /* TODO: nonblocking */ + /* TODO: deferred accept */ + + ls[i].done = 1; + continue; + } + + s = ngx_socket(ls[i].family, ls[i].type, ls[i].protocol, + ls[i].flags); + if (s == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - "nginx: socket %s falied", ls[i].addr_text); + ngx_socket_n " %s falied", ls[i].addr_text); + exit(1); + } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &reuseaddr, sizeof(int)) == -1) + (const void *) &reuseaddr, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - "nginx: setsockopt (SO_REUSEADDR) %s failed", + "setsockopt(SO_REUSEADDR) %s failed", ls[i].addr_text); + exit(1); + } /* TODO: close on exit */ if (ls[i].nonblocking) { - if (ngx_nonblocking(s) == -1) + if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_nonblocking_n " %s failed", ls[i].addr_text); + exit(1); + } } - if (bind(s, (struct sockaddr *) ls[i].addr, ls[i].addr_len) == -1) { + if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { err = ngx_socket_errno; - ngx_log_error(NGX_LOG_ALERT, log, err, - "bind to %s failed", ls[i].addr_text); + ngx_log_error(NGX_LOG_EMERG, log, err, + "bind() to %s failed", ls[i].addr_text); if (err != NGX_EADDRINUSE) exit(1); if (ngx_close_socket(s) == -1) - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_close_socket_n " %s failed", ls[i].addr_text); @@ -129,9 +143,11 @@ static void ngx_open_listening_sockets(n continue; } - if (listen(s, ls[i].backlog) == -1) + if (listen(s, ls[i].backlog) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - "listen to %s failed", ls[i].addr_text); + "listen() to %s failed", ls[i].addr_text); + exit(1); + } /* TODO: deferred accept */ @@ -142,10 +158,13 @@ static void ngx_open_listening_sockets(n if (!failed) break; - ngx_log_error(NGX_LOG_NOTICE, log, 0, "try to bind again after 500ms"); + ngx_log_error(NGX_LOG_NOTICE, log, 0, + "try again to bind() after 500ms"); ngx_msleep(500); } - if (failed) - ngx_log_error(NGX_LOG_EMERG, log, 0, "can't bind"); + if (failed) { + ngx_log_error(NGX_LOG_EMERG, log, 0, "can not bind(), exiting"); + exit(1); + } } diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c --- a/src/core/ngx_alloc.c +++ b/src/core/ngx_alloc.c @@ -12,8 +12,8 @@ void *ngx_alloc(size_t size, ngx_log_t * p = malloc(size); if (p == NULL) - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "ngx_alloc: malloc() %d bytes failed", size); + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "malloc() %d bytes failed", size); return p; } diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -48,6 +48,7 @@ #else /* POSIX */ #include +#include /* offsetof */ #include #include #include diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -26,6 +26,15 @@ struct ngx_connection_s { ngx_server_t *server; ngx_server_t *servers; ngx_pool_t *pool; + + int family; + struct sockaddr *sockaddr; + socklen_t socklen; + size_t addr; + char *addr_text; + size_t addr_textlen; + + time_t post_accept_timeout; }; diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c --- a/src/core/ngx_hunk.c +++ b/src/core/ngx_hunk.c @@ -18,7 +18,7 @@ ngx_hunk_t *ngx_get_hunk(ngx_pool_t *poo h->type = NGX_HUNK_TEMP; h->tag = 0; - h->fd = (ngx_file_t) -1; + h->fd = (ngx_fd_t) -1; return h; } @@ -39,7 +39,7 @@ ngx_hunk_t *ngx_get_hunk_before(ngx_pool h->type = NGX_HUNK_TEMP; h->tag = 0; - h->fd = (ngx_file_t) -1; + h->fd = (ngx_fd_t) -1; } else { h->pre_start = h->start = h->pos.mem = h->last.mem @@ -48,7 +48,7 @@ ngx_hunk_t *ngx_get_hunk_before(ngx_pool h->type = NGX_HUNK_TEMP; h->tag = 0; - h->fd = (ngx_file_t) -1; + h->fd = (ngx_fd_t) -1; } return h; @@ -71,7 +71,7 @@ ngx_hunk_t *ngx_get_hunk_after(ngx_pool_ hunk->last.mem; h->type = NGX_HUNK_TEMP; h->tag = 0; - h->fd = (ngx_file_t) -1; + h->fd = (ngx_fd_t) -1; } else { h->pre_start = h->start = h->pos.mem = h->last.mem = @@ -80,7 +80,7 @@ ngx_hunk_t *ngx_get_hunk_after(ngx_pool_ h->type = NGX_HUNK_TEMP; h->tag = 0; - h->fd = (ngx_file_t) -1; + h->fd = (ngx_fd_t) -1; } return h; diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h --- a/src/core/ngx_hunk.h +++ b/src/core/ngx_hunk.h @@ -48,7 +48,7 @@ struct ngx_hunk_s { char *pre_start; /* start of pre-allocated hunk */ char *post_end; /* end of post-allocated hunk */ int tag; - ngx_file_t fd; + ngx_fd_t fd; }; typedef struct ngx_chain_s ngx_chain_t; diff --git a/src/core/ngx_listen.h b/src/core/ngx_listen.h --- a/src/core/ngx_listen.h +++ b/src/core/ngx_listen.h @@ -11,22 +11,26 @@ typedef struct { ngx_socket_t fd; - void *addr; - size_t addr_len; - char *addr_text; + struct sockaddr *sockaddr; + socklen_t socklen; + size_t addr; + char *addr_text; + size_t addr_textlen; int family; int type; int protocol; + int flags; ngx_log_t *log; void *server; int (*handler)(ngx_connection_t *c); int backlog; + time_t post_accept_timeout; unsigned done:1; - unsigned close:1; + unsigned inherited:1; unsigned nonblocking:1; #if 0 unsigned overlapped:1; diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -37,31 +37,15 @@ void ngx_log_error_core(int level, ngx_l #endif ngx_localtime(&tm); - len = ngx_snprintf(errstr, sizeof(errstr), "%02d:%02d:%02d", + len = ngx_snprintf(errstr, sizeof(errstr), "%4d/%02d/%02d %02d:%02d:%02d", + tm.ngx_tm_year + 1900, tm.ngx_tm_mon, tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); - if (err) { - if ((unsigned) err < 0x80000000) - len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, - " [%s] (%d)", - err_levels[level], err); - else - len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, - " [%s] (%X)", - err_levels[level], err); + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + " [%s] ", err_levels[level]); - len += ngx_strerror_r(err, errstr + len, sizeof(errstr) - len - 1); - if (len < sizeof(errstr) - 2) { - errstr[len++] = ':'; - errstr[len++] = ' '; - } else { - len = sizeof(errstr) - 2; - } - - } else { - len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, - " [%s] ", err_levels[level]); - } + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + "%d#%d: ", getpid(), 0); #if (HAVE_VARIADIC_MACROS) va_start(args, fmt); @@ -71,15 +55,31 @@ void ngx_log_error_core(int level, ngx_l len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args); #endif + if (err) { + if ((unsigned) err < 0x80000000) + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + " (%d: ", err); + else + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + " (%X: ", err); + + len += ngx_strerror_r(err, errstr + len, sizeof(errstr) - len - 1); + if (len < sizeof(errstr) - 2) { + errstr[len++] = ')'; + } else { + len = sizeof(errstr) - 2; + } + } + + if (level != NGX_LOG_DEBUG && log->handler) + len += log->handler(log->data, errstr + len, sizeof(errstr) - len - 1); + if (len > sizeof(errstr) - 2) len = sizeof(errstr) - 2; errstr[len] = '\n'; errstr[len + 1] = '\0'; fputs(errstr, stderr); - - if (level == NGX_LOG_EMERG) - exit(1); } #if !(HAVE_VARIADIC_MACROS) diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -3,6 +3,7 @@ #include +#include typedef enum { NGX_LOG_EMERG = 0, @@ -59,13 +60,14 @@ typedef enum { */ typedef struct { - int log_level; - char *action; - char *context; -#if 0 - void *data; /* i.e. ngx_http_proxy_error_context_t */ - char *func(ngx_log_t *log); -#endif + int log_level; + ngx_fd_t fd; + void *data; + size_t (*handler)(void *ctx, char *buf, size_t len); +/* STUB */ + char *action; + char *context; +/* */ } ngx_log_t; #define MAX_ERROR_STR 2048 diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c --- a/src/event/modules/ngx_aio_module.c +++ b/src/event/modules/ngx_aio_module.c @@ -1,4 +1,14 @@ +/* 1 */ +int ngx_posix_aio_process_events(ngx_log_t *log) +{ + listen via SIGIO; + aio_* via SIGxxx; + + sigsuspend()/sigwaitinfo()/sigtimedwait(); +} + +/* 2 */ int ngx_posix_aio_process_events(ngx_log_t *log) { unmask signal @@ -18,6 +28,7 @@ int ngx_posix_aio_process_events(ngx_log aio } +/* 3 */ int ngx_posix_aio_process_events(ngx_log_t *log) { unmask signal diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -18,7 +18,7 @@ #error "kqueue is not supported on this platform" #endif -static void ngx_add_timer(ngx_event_t *ev, u_int timer); +static void ngx_add_timer_core(ngx_event_t *ev, u_int timer); static void ngx_inline ngx_del_timer(ngx_event_t *ev); @@ -35,9 +35,11 @@ void ngx_kqueue_init(int max_connections nchanges = 0; nevents = 512; - if ((kq = kqueue()) == -1) + if ((kq = kqueue()) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, - "ngx_kqueue_init: kqueue failed"); + "kqueue() failed"); + exit(1); + } change_list = ngx_alloc(size, log); event_list = ngx_alloc(size, log); @@ -56,7 +58,7 @@ void ngx_kqueue_init(int max_connections int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) { if (event == NGX_TIMER_EVENT) { - ngx_add_timer(ev, flags); + ngx_add_timer_core(ev, flags); return 0; } @@ -154,8 +156,14 @@ int ngx_kqueue_process_events(ngx_log_t delta -= ev->timer_delta; nx = ev->timer_next; ngx_del_timer(ev); +#if 1 + ev->timedout = 1; + if (ev->event_handler(ev) == -1) + ev->close_handler(ev); +#else if (ev->timer_handler(ev) == -1) ev->close_handler(ev); +#endif ev = nx; } @@ -207,7 +215,7 @@ int ngx_kqueue_process_events(ngx_log_t return 0; } -static void ngx_add_timer(ngx_event_t *ev, u_int timer) +static void ngx_add_timer_core(ngx_event_t *ev, u_int timer) { ngx_event_t *e; diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -23,7 +23,7 @@ static ngx_event_t event_queue; static ngx_event_t timer_queue; -static void ngx_add_timer(ngx_event_t *ev, u_int timer); +static void ngx_add_timer_core(ngx_event_t *ev, u_int timer); static void ngx_inline ngx_del_timer(ngx_event_t *ev); static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, @@ -31,19 +31,17 @@ static fd_set *ngx_select_get_fd_set(ngx void ngx_select_init(int max_connections, ngx_log_t *log) { -#if (WIN32) - if (max_connections > FD_SETSIZE) + if (max_connections > FD_SETSIZE) { ngx_log_error(NGX_LOG_EMERG, log, 0, - "ngx_select_init: maximum number of descriptors " - "supported by select() is %d", - FD_SETSIZE); +#if (WIN32) + "maximum number of descriptors " + "supported by select() is %d", FD_SETSIZE); #else - if (max_connections >= FD_SETSIZE) - ngx_log_error(NGX_LOG_EMERG, log, 0, - "ngx_select_init: maximum descriptor number" - "supported by select() is %d", - FD_SETSIZE - 1); + "maximum descriptor number" + "supported by select() is %d", FD_SETSIZE - 1); #endif + exit(1); + } FD_ZERO(&master_read_fds); FD_ZERO(&master_write_fds); @@ -71,7 +69,7 @@ int ngx_select_add_event(ngx_event_t *ev ngx_connection_t *cn = (ngx_connection_t *) ev->data; if (event == NGX_TIMER_EVENT) { - ngx_add_timer(ev, flags); + ngx_add_timer_core(ev, flags); return 0; } @@ -271,8 +269,14 @@ int ngx_select_process_events(ngx_log_t delta -= ev->timer_delta; nx = ev->timer_next; ngx_del_timer(ev); +#if 1 + ev->timedout = 1; + if (ev->event_handler(ev) == -1) + ev->close_handler(ev); +#else if (ev->timer_handler(ev) == -1) ev->close_handler(ev); +#endif ev = nx; } @@ -316,7 +320,7 @@ int ngx_select_process_events(ngx_log_t return 0; } -static void ngx_add_timer(ngx_event_t *ev, u_int timer) +static void ngx_add_timer_core(ngx_event_t *ev, u_int timer) { ngx_event_t *e; diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -46,15 +46,15 @@ void ngx_pre_thread(ngx_array_t *ls, ngx int i, fd; ngx_listen_t *s; - /* per group */ + /* STUB */ int max_connections = 512; ngx_init_events(max_connections, log); + ngx_connections = ngx_alloc(sizeof(ngx_connection_t) + * max_connections, log); ngx_read_events = ngx_alloc(sizeof(ngx_event_t) * max_connections, log); ngx_write_events = ngx_alloc(sizeof(ngx_event_t) * max_connections, log); - ngx_connections = ngx_alloc(sizeof(ngx_connection_t) - * max_connections, log); /* for each listening socket */ s = (ngx_listen_t *) ls->elts; @@ -62,16 +62,23 @@ void ngx_pre_thread(ngx_array_t *ls, ngx fd = s[i].fd; + ngx_memzero(&ngx_connections[fd], sizeof(ngx_connection_t)); ngx_memzero(&ngx_read_events[fd], sizeof(ngx_event_t)); - ngx_memzero(&ngx_write_events[fd], sizeof(ngx_event_t)); - ngx_memzero(&ngx_connections[fd], sizeof(ngx_connection_t)); ngx_connections[fd].fd = fd; + ngx_connections[fd].family = s[i].family; + ngx_connections[fd].socklen = s[i].socklen; + ngx_connections[fd].sockaddr = ngx_palloc(pool, s[i].socklen); + ngx_connections[fd].addr = s[i].addr; + ngx_connections[fd].addr_text = s[i].addr_text; + ngx_connections[fd].addr_textlen = s[i].addr_textlen; + ngx_connections[fd].post_accept_timeout = s[i].post_accept_timeout; + ngx_connections[fd].server = s[i].server; - ngx_connections[fd].read = (void *) &ngx_read_events[fd].data; ngx_connections[fd].handler = s[i].handler; - ngx_read_events[fd].data = &ngx_connections[fd]; - ngx_read_events[fd].log = ngx_connections[fd].log = s[i].log; + ngx_connections[fd].log = s[i].log; + + ngx_read_events[fd].log = ngx_connections[fd].log; ngx_read_events[fd].data = &ngx_connections[fd]; ngx_read_events[fd].event_handler = &ngx_event_accept; ngx_read_events[fd].listening = 1; @@ -79,7 +86,7 @@ void ngx_pre_thread(ngx_array_t *ls, ngx ngx_read_events[fd].available = 0; #if (HAVE_DEFERRED_ACCEPT) - ngx_read_events[fd].accept_filter = s[i].accept_filter; + ngx_read_events[fd].deferred_accept = s[i].deferred_accept; #endif ngx_add_event(&ngx_read_events[fd], NGX_READ_EVENT, 0); } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -51,7 +51,7 @@ struct ngx_event_s { unsigned unexpected_eof:1; #if (HAVE_DEFERRED_ACCEPT) - unsigned accept_filter:1; + unsigned deferred_accept:1; #endif #if (HAVE_KQUEUE) unsigned eof:1; @@ -81,10 +81,12 @@ typedef struct { /* -NGX_LEVEL_EVENT (default) select, poll, kqueue +NGX_LEVEL_EVENT (default) select, poll, /dev/poll, kqueue requires to read whole data -NGX_ONESHOT_EVENT kqueue +NGX_ONESHOT_EVENT select, poll, kqueue NGX_CLEAR_EVENT kqueue +NGX_AIO_EVENT overlapped, aio_read, aioread + no need to add or delete events */ #if (HAVE_KQUEUE) @@ -93,6 +95,7 @@ NGX_CLEAR_EVENT kqueue #define NGX_WRITE_EVENT EVFILT_WRITE #define NGX_TIMER_EVENT (-EVFILT_SYSCOUNT - 1) +#define NGX_LEVEL_EVENT 0 #define NGX_ONESHOT_EVENT EV_ONESHOT #define NGX_CLEAR_EVENT EV_CLEAR @@ -102,6 +105,7 @@ NGX_CLEAR_EVENT kqueue #define NGX_WRITE_EVENT 1 #define NGX_TIMER_EVENT 2 +#define NGX_LEVEL_EVENT 0 #define NGX_ONESHOT_EVENT 1 #define NGX_CLEAR_EVENT 2 @@ -127,6 +131,8 @@ NGX_CLEAR_EVENT kqueue #endif +#define ngx_add_timer(ev, time) ngx_add_event(ev, NGX_TIMER_EVENT, time) + extern ngx_event_t *ngx_read_events; extern ngx_event_t *ngx_write_events; extern ngx_connection_t *ngx_connections; diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -22,21 +23,22 @@ int ngx_event_accept(ngx_event_t *ev) ev->ready = 0; do { - if ((s = accept(cn->fd, (struct sockaddr *) &addr, &addrlen)) == -1) { + if ((s = accept(cn->fd, cn->sockaddr, &cn->socklen)) == -1) { err = ngx_socket_errno; if (err == NGX_EAGAIN) { ngx_log_error(NGX_LOG_INFO, ev->log, err, - "ngx_event_accept: EAGAIN while accept"); - return 0; + "ngx_event_accept: EAGAIN while accept %s", + cn->addr_text); + return NGX_OK; } - + ngx_log_error(NGX_LOG_ERR, ev->log, err, - "ngx_event_accept: accept failed"); - /* if we return -1 listen socket would be closed */ - return 0; + "ngx_event_accept: accept %s failed", cn->addr_text); + /* if we return NGX_ERROR listen socket would be closed */ + return NGX_OK; } - - ngx_log_debug(ev->log, "ngx_event_accept: accepted socket: %d" _ s); + + ngx_log_debug(ev->log, "ngx_event_accept: accept: %d" _ s); #if !(HAVE_INHERITED_NONBLOCK) if (ngx_nonblocking(s) == -1) @@ -48,6 +50,13 @@ int ngx_event_accept(ngx_event_t *ev) ngx_memzero(&ngx_write_events[s], sizeof(ngx_event_t)); ngx_memzero(&ngx_connections[s], sizeof(ngx_connection_t)); + ngx_connections[s].sockaddr = cn->sockaddr; + ngx_connections[s].family = cn->family; + ngx_connections[s].socklen = cn->socklen; + ngx_connections[s].addr = cn->addr; + ngx_connections[s].addr_textlen = cn->addr_textlen; + ngx_connections[s].post_accept_timeout = cn->post_accept_timeout; + ngx_read_events[s].data = ngx_write_events[s].data = &ngx_connections[s]; ngx_connections[s].read = &ngx_read_events[s]; @@ -60,16 +69,16 @@ int ngx_event_accept(ngx_event_t *ev) ngx_write_events[s].timer = ngx_read_events[s].timer = 10000; ngx_write_events[s].timer_handler = - ngx_read_events[s].timer_handler = ngx_event_close; + ngx_read_events[s].timer_handler = ngx_event_close_connection; ngx_write_events[s].close_handler = - ngx_read_events[s].close_handler = ngx_event_close; + ngx_read_events[s].close_handler = ngx_event_close_connection; ngx_connections[s].server = cn->server; ngx_connections[s].servers = cn->servers; ngx_connections[s].log = ngx_read_events[s].log = ngx_write_events[s].log = ev->log; - + #if (HAVE_DEFERRED_ACCEPT) if (ev->accept_filter) ngx_read_events[s].ready = 1; diff --git a/src/event/ngx_event_close.c b/src/event/ngx_event_close.c --- a/src/event/ngx_event_close.c +++ b/src/event/ngx_event_close.c @@ -5,7 +5,7 @@ #include -int ngx_event_close(ngx_event_t *ev) +int ngx_event_close_connection(ngx_event_t *ev) { int rc; ngx_connection_t *cn = (ngx_connection_t *) ev->data; diff --git a/src/event/ngx_event_close.h b/src/event/ngx_event_close.h --- a/src/event/ngx_event_close.h +++ b/src/event/ngx_event_close.h @@ -4,7 +4,7 @@ #include -int ngx_event_close(ngx_event_t *ev); +int ngx_event_close_connection(ngx_event_t *ev); #endif /* _NGX_EVENT_CLOSE_H_INCLUDED_ */ diff --git a/src/event/ngx_event_recv.c b/src/event/ngx_event_recv.c --- a/src/event/ngx_event_recv.c +++ b/src/event/ngx_event_recv.c @@ -14,6 +14,12 @@ int ngx_event_recv_core(ngx_event_t *ev, c = (ngx_connection_t *) ev->data; + if (ev->timedout) { + ngx_set_socket_errno(NGX_ETIMEDOUT); + ngx_log_error(NGX_LOG_ERR, ev->log, NGX_ETIMEDOUT, "recv() failed"); + return NGX_ERROR; + } + #if (HAVE_KQUEUE) ngx_log_debug(ev->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _ ev->eof _ ev->available _ ev->error); @@ -22,10 +28,7 @@ int ngx_event_recv_core(ngx_event_t *ev, #endif if (ev->eof && ev->available == 0) { if (ev->error) { - ngx_log_error(NGX_LOG_ERR, ev->log, ev->error, - "ngx_event_recv: recv() failed while %s", - ev->log->action); - + ngx_log_error(NGX_LOG_ERR, ev->log, ev->error, "recv() failed"); return NGX_ERROR; } @@ -39,16 +42,11 @@ int ngx_event_recv_core(ngx_event_t *ev, err = ngx_socket_errno; if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, ev->log, err, - "ngx_event_recv: recv() returns EAGAIN while %s", - ev->log->action); + ngx_log_error(NGX_LOG_INFO, ev->log, err, "recv() returns EAGAIN"); return NGX_AGAIN; } - ngx_log_error(NGX_LOG_INFO, ev->log, err, - "ngx_event_recv: recv() failed while %s", - ev->log->action); - + ngx_log_error(NGX_LOG_ERR, ev->log, err, "recv() failed"); return NGX_ERROR; } diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -40,10 +40,16 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ ls->family = AF_INET; ls->type = SOCK_STREAM; ls->protocol = IPPROTO_IP; - ls->addr = &addr; - ls->addr_len = sizeof(struct sockaddr_in); +#if (NGX_OVERLAPPED) + ls->flags = WSA_FLAG_OVERLAPPED; +#endif + ls->sockaddr = (struct sockaddr *) &addr; + ls->socklen = sizeof(struct sockaddr_in); + ls->addr = offsetof(struct sockaddr_in, sin_addr); ls->addr_text = addr_text; + ls->addr_textlen = INET_ADDRSTRLEN; ls->backlog = -1; + ls->post_accept_timeout = 10000; ls->nonblocking = 1; ls->handler = ngx_http_init_connection; diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -70,7 +70,7 @@ typedef struct ngx_http_request_s ngx_ht struct ngx_http_request_s { char *filename; char *location; - ngx_file_t fd; + ngx_fd_t fd; ngx_http_headers_out_t *headers_out; @@ -113,6 +113,12 @@ struct ngx_http_request_s { #endif }; +typedef struct { + char *action; + char *client; + char *url; +} ngx_http_log_ctx_t; + #define NGX_INDEX "index.html" diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -1,5 +1,7 @@ #include +#include +#include #include #include #include @@ -8,15 +10,8 @@ #include -/* -ngx_read should check errors (if we ask) and return - -2 EAGAIN - -1 error - 0 EOF - >0 number of bytes -*/ +int ngx_http_init_connection(ngx_connection_t *c); - int ngx_http_init_connection(ngx_connection_t *c); static int ngx_http_init_request(ngx_event_t *ev); static int ngx_http_process_request(ngx_event_t *ev); @@ -26,61 +21,90 @@ static int ngx_process_http_request_head static int ngx_process_http_request(ngx_http_request_t *r); static int ngx_http_close_request(ngx_event_t *ev); +static size_t ngx_http_log_error(void *data, char *buf, size_t len); + /* STUB */ static int ngx_http_writer(ngx_event_t *ev); -/* - returns - -1 if error - 0 need more data or EOF (filter is deleted) - 1 there is unread data -*/ + int ngx_http_init_connection(ngx_connection_t *c) { - ngx_event_t *ev; + ngx_event_t *ev; + struct sockaddr *addr; + ngx_http_log_ctx_t *ctx; ev = c->read; ev->event_handler = ngx_http_init_request; - ev->log->action = "reading client request line"; + + /* TODO: connection's pool size */ + ngx_test_null(c->pool, ngx_create_pool(1024, ev->log), NGX_ERROR); - ngx_log_debug(ev->log, "ngx_http_init_connection: entered"); + ngx_test_null(addr, ngx_palloc(c->pool, c->socklen), NGX_ERROR); + ngx_memcpy(addr, c->sockaddr, c->socklen); + c->sockaddr = addr; - /* XXX: ev->timer ? */ - if (ngx_add_event(ev, NGX_TIMER_EVENT, ev->timer) == -1) - return -1; + ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), + NGX_ERROR); + inet_ntop(c->family, (char *)c->sockaddr + c->addr, + c->addr_text, c->addr_textlen); + + ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), + NGX_ERROR); + ctx->client = c->addr_text; + ctx->action = "reading client request line"; + c->log->data = ctx; + c->log->handler = ngx_http_log_error; + + ngx_add_timer(ev, c->post_accept_timeout); #if (HAVE_DEFERRED_ACCEPT) if (ev->ready) return ngx_http_init_request(ev); else #endif -#if (NGX_CLEAR_EVENT) +#if (USE_KQUEUE) return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); #else - return ngx_add_event(ev, NGX_READ_EVENT, NGX_ONESHOT_EVENT); +#if (HAVE_AIO_EVENT) + if (ngx_event_type == NGX_AIO_EVENT) + return ngx_http_init_request(ev); + else +#endif +#if (HAVE_CLEAR_EVENT) + if (ngx_event_type == NGX_KQUEUE_EVENT) + return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); + else +#else + return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT); +#endif #endif } + int ngx_http_init_request(ngx_event_t *ev) { - ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_http_server_t *srv = (ngx_http_server_t *) c->server; - ngx_http_request_t *r; + ngx_connection_t *c; + ngx_http_server_t *srv; + ngx_http_request_t *r; - ngx_log_debug(ev->log, "ngx_http_init_request: entered"); + c = (ngx_connection_t *) ev->data; + srv = (ngx_http_server_t *) c->server; - ngx_test_null(c->pool, ngx_create_pool(16384, ev->log), -1); - ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), -1); + ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), + NGX_ERROR); c->data = r; r->connection = c; r->server = srv; - ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), -1); - ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), -1); - ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size), -1); + ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), NGX_ERROR); + + /* TODO: buff -> hunk */ + ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), NGX_ERROR); + ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size), + NGX_ERROR); r->buff->pos = r->buff->last = r->buff->buff; r->buff->end = r->buff->buff + srv->buff_size; @@ -90,33 +114,39 @@ int ngx_http_init_request(ngx_event_t *e ev->event_handler = ngx_http_process_request; ev->close_handler = ngx_http_close_request; c->write->close_handler = ngx_http_close_request; + return ngx_http_process_request(ev); } + int ngx_http_process_request(ngx_event_t *ev) { int n; - ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_http_request_t *r = (ngx_http_request_t *) c->data; + ngx_connection_t *c ; + ngx_http_request_t *r; + + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; ngx_log_debug(ev->log, "http process request"); n = ngx_event_recv(ev, r->buff->last, r->buff->end - r->buff->last); - if (n == -2) - return 0; + if (n == NGX_AGAIN) + return NGX_AGAIN; - if (n == -1) - return -1; + if (n == NGX_ERROR) { + /* close request */ + return NGX_ERROR; + } ngx_log_debug(ev->log, "http read %d" _ n); if (n == 0) { if (ev->unexpected_eof) { - ngx_log_error(NGX_LOG_INFO, ev->log, 0, - "ngx_http_process_request: " - "connection is closed while %s", ev->action); - return -1; + ngx_log_error(NGX_LOG_INFO, ev->log, 0, "connection is closed"); + /* close request */ + return NGX_ERROR; } return ngx_http_close_request(ev); @@ -183,6 +213,14 @@ static int ngx_process_http_request_head return ngx_process_http_request(r); } +#if 0 +static int ngx_http_lock_read(ngx_event_t *ev) +{ + ngx_del_event(ev, NGX_READ_EVENT); + ev->read_blocked = 1; +} +#endif + static int ngx_process_http_request(ngx_http_request_t *r) { int err, rc; @@ -245,6 +283,114 @@ static int ngx_process_http_request(ngx_ return NGX_OK; } +#if 0 + +static int ngx_http_handler(ngx_http_request_t *r) +{ + find_http_handler(); + + if (r->discard_body && r->connection->read->ready) + ngx_http_discarad_body(); + + rc = http_handler(); + + /* transfer not completed */ + if (rc == NGX_AGAIN) + return rc; + + if (rc == NGX_ERROR) { + log http request + close http request + return rc; + } + + if (rc > 300) { + send special response + } + + /* rc == NGX_OK */ + + if (!keepalive) + if (linger) + set linger timeout on read + shutdown socket + else + close socket + + log http request + close http request + if (keepalive) + return NGX_OK; + else + close connection + return NGX_OK; +} + +static int ngx_http_writer(ngx_event_t *ev) +{ + int rc; + + ngx_connection_t *c = (ngx_connection_t *) ev->data; + ngx_http_request_t *r = (ngx_http_request_t *) c->data; + + rc = ngx_http_filter(r, NULL); + + if (rc == NGX_AGAIN) + return rc; + + if (rc == NGX_ERROR) + return rc; + + /* rc == NGX_OK */ + + + if (!keepalive) + if (linger) + shutdown socket + else + close socket + + log http request + close http request + if (keepalive) + return NGX_OK; + else + close connection + return NGX_OK; +} + +static int ngx_http_discarded_read(ngx_event_t *ev) +{ + if (ev->timedout) + return NGX_ERROR; + + while (full) { + recv(); + } + + return NGX_OK; +} + +static int ngx_http_keepalive_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + ngx_http_log_ctx_t *ctx; + + if (closed) + /* NGX_LOG_INFO or even silent */ + return NGX_ERROR; + + c = (ngx_connection_t *) ev->data; + + ctx = (ngx_http_log_ctx_t *) c->log->data; + ctx->action = "reading client request line"; + c->log->handler = ngx_http_log_error; + + return ngx_http_init_request(ev); +} + +#endif + static int ngx_http_writer(ngx_event_t *ev) { @@ -352,5 +498,17 @@ static int ngx_http_close_request(ngx_ev ngx_del_event(c->read, NGX_TIMER_EVENT); ngx_del_event(c->write, NGX_TIMER_EVENT); - return ngx_event_close(ev); + return ngx_event_close_connection(ev); } + + +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; + if (ctx->url) + return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s", + ctx->action, ctx->client, ctx->url); + else + return ngx_snprintf(buf, len, " while %s, client: %s", + ctx->action, ctx->client); +} diff --git a/src/os/unix/freebsd/ngx_sendfile.c b/src/os/unix/freebsd/ngx_sendfile.c --- a/src/os/unix/freebsd/ngx_sendfile.c +++ b/src/os/unix/freebsd/ngx_sendfile.c @@ -24,7 +24,7 @@ int ngx_sendfile(ngx_socket_t s, ngx_iovec_t *headers, int hdr_cnt, - ngx_file_t fd, off_t offset, size_t nbytes, + ngx_fd_t fd, off_t offset, size_t nbytes, ngx_iovec_t *trailers, int trl_cnt, off_t *sent, ngx_log_t *log) diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -11,6 +11,7 @@ typedef int ngx_err_t; #define NGX_EINTR EINTR #define NGX_EAGAIN EWOULDBLOCK #define NGX_EADDRINUSE EADDRINUSE +#define NGX_ETIMEDOUT ETIMEDOUT #define ngx_errno errno #define ngx_socket_errno errno diff --git a/src/os/unix/ngx_file.c b/src/os/unix/ngx_file.c --- a/src/os/unix/ngx_file.c +++ b/src/os/unix/ngx_file.c @@ -1,8 +1,8 @@ -ssize_t ngx_read_file(ngx_file_t file, char *buf, size_t size) +ssize_t ngx_read_file(ngx_file_t file, char *buf, size_t size, off_t offset) { - read(); + return pread(file->fd, buf, size, offset); } #if 0 diff --git a/src/os/unix/ngx_file.h b/src/os/unix/ngx_file.h --- a/src/os/unix/ngx_file.h +++ b/src/os/unix/ngx_file.h @@ -5,7 +5,7 @@ #include #include -typedef int ngx_file_t; +typedef int ngx_fd_t; typedef struct stat ngx_file_info_t; diff --git a/src/os/unix/ngx_sendfile.h b/src/os/unix/ngx_sendfile.h --- a/src/os/unix/ngx_sendfile.h +++ b/src/os/unix/ngx_sendfile.h @@ -10,7 +10,7 @@ int ngx_sendfile(ngx_socket_t s, ngx_iovec_t *headers, int hdr_cnt, - ngx_file_t fd, off_t offset, size_t nbytes, + ngx_fd_t fd, off_t offset, size_t nbytes, ngx_iovec_t *trailers, int trl_cnt, off_t *sent, ngx_log_t *log); diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -9,11 +9,14 @@ typedef int ngx_socket_t; #define ngx_init_sockets +#define ngx_socket(af, type, proto, flags) socket(af, type, proto) +#define ngx_socket_n "socket()" + #define ngx_nonblocking(s) fcntl(s, F_SETFL, O_NONBLOCK) -#define ngx_nonblocking_n "fcntl (O_NONBLOCK)" +#define ngx_nonblocking_n "fcntl(O_NONBLOCK)" #define ngx_close_socket close -#define ngx_close_socket_n "close" +#define ngx_close_socket_n "close()" #endif /* _NGX_SOCKET_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_file.h b/src/os/win32/ngx_file.h --- a/src/os/win32/ngx_file.h +++ b/src/os/win32/ngx_file.h @@ -10,7 +10,9 @@ #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF #endif -typedef HANDLE ngx_file_t; +typedef HANDLE ngx_fd_t; +typedef unsigned __int64 off_t; + typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t; diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h --- a/src/os/win32/ngx_socket.h +++ b/src/os/win32/ngx_socket.h @@ -9,11 +9,15 @@ typedef SOCKET ngx_socket_t; void ngx_init_sockets(ngx_log_t *log); +#define ngx_socket(af, type, proto, flags) \ + WSASocket(af, type, proto, NULL, 0, flags) +#define ngx_socket_n "WSASocket()" + int ngx_nonblocking_n(s); -#define ngx_nonblocking_n "ioctlsocket (FIONBIO)" +#define ngx_nonblocking_n "ioctlsocket(FIONBIO)" #define ngx_close_socket closesocket -#define ngx_close_socket_n "closesocket" +#define ngx_close_socket_n "closesocket()" #endif /* _NGX_SOCKET_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h --- a/src/os/win32/ngx_types.h +++ b/src/os/win32/ngx_types.h @@ -5,9 +5,7 @@ #include -typedef HANDLE ngx_file_t; typedef long time_t; -typedef unsigned __int64 off_t; #define QD_FMT "%I64d"