changeset 6:669801705ab1

nginx-0.0.1-2002-08-26-19:18:19 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 26 Aug 2002 15:18:19 +0000
parents 62b1a364857c
children b5481d6fbbd4
files src/core/nginx.c src/core/ngx_alloc.c src/core/ngx_config.h src/core/ngx_connection.h src/core/ngx_hunk.c src/core/ngx_hunk.h src/core/ngx_listen.h src/core/ngx_log.c src/core/ngx_log.h src/event/modules/ngx_aio_module.c src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_select_module.c src/event/ngx_event.c src/event/ngx_event.h src/event/ngx_event_accept.c src/event/ngx_event_close.c src/event/ngx_event_close.h src/event/ngx_event_recv.c src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_event.c src/os/unix/freebsd/ngx_sendfile.c src/os/unix/ngx_errno.h src/os/unix/ngx_file.c src/os/unix/ngx_file.h src/os/unix/ngx_sendfile.h src/os/unix/ngx_socket.h src/os/win32/ngx_file.h src/os/win32/ngx_socket.h src/os/win32/ngx_types.h
diffstat 30 files changed, 431 insertions(+), 175 deletions(-) [+]
line wrap: on
line diff
--- 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);
+    }
 }
--- 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;
 }
 
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -48,6 +48,7 @@
 #else /* POSIX */
 
 #include <unistd.h>
+#include <stddef.h>    /* offsetof */
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.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;
 };
 
 
--- 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;
--- 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;
--- 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;
--- 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)
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -3,6 +3,7 @@
 
 
 #include <ngx_errno.h>
+#include <ngx_file.h>
 
 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
--- 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
--- 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;
 
--- 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;
 
--- 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);
     }
--- 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;
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -1,5 +1,6 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_types.h>
 #include <ngx_log.h>
 #include <ngx_connection.h>
@@ -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;
--- a/src/event/ngx_event_close.c
+++ b/src/event/ngx_event_close.c
@@ -5,7 +5,7 @@
 #include <ngx_event_close.h>
 
 
-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;
--- a/src/event/ngx_event_close.h
+++ b/src/event/ngx_event_close.h
@@ -4,7 +4,7 @@
 
 #include <ngx_event.h>
 
-int ngx_event_close(ngx_event_t *ev);
+int ngx_event_close_connection(ngx_event_t *ev);
 
 
 #endif /* _NGX_EVENT_CLOSE_H_INCLUDED_ */
--- 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;
     }
 
--- 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;
--- 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"
 
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -1,5 +1,7 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_string.h>
 #include <ngx_file.h>
 #include <ngx_log.h>
 #include <ngx_alloc.h>
@@ -8,15 +10,8 @@
 
 #include <ngx_http.h>
 
-/*
-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);
+}
--- 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)
--- 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
--- 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
--- a/src/os/unix/ngx_file.h
+++ b/src/os/unix/ngx_file.h
@@ -5,7 +5,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-typedef int                      ngx_file_t;
+typedef int                      ngx_fd_t;
 typedef struct stat              ngx_file_info_t;
 
 
--- 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);
--- 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_ */
--- 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;
 
 
--- 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_ */
--- a/src/os/win32/ngx_types.h
+++ b/src/os/win32/ngx_types.h
@@ -5,9 +5,7 @@
 #include <ngx_config.h>
 
 
-typedef HANDLE            ngx_file_t;
 typedef long              time_t;
-typedef unsigned __int64  off_t;
 
 
 #define QD_FMT            "%I64d"