changeset 44:0e81ac0bb3e2

nginx-0.0.1-2003-01-09-08:36:00 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 09 Jan 2003 05:36:00 +0000
parents 53cd05892261
children f1ee46c036a4
files src/core/nginx.c src/core/ngx_alloc.h src/core/ngx_array.c src/core/ngx_array.h src/core/ngx_conf_file.c src/core/ngx_conf_file.h src/core/ngx_connection.h src/core/ngx_listen.h src/core/ngx_string.h src/event/ngx_event.c src/event/ngx_event.h src/event/ngx_event_accept.c src/event/ngx_event_write.c src/http/modules/ngx_http_event_proxy_handler.c src/http/modules/ngx_http_index_handler.c src/http/modules/ngx_http_static_handler.c src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_config.c src/http/ngx_http_config.h src/http/ngx_http_core.c src/http/ngx_http_core.h src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_event.c src/http/ngx_http_header_filter.c src/http/ngx_http_output_filter.c src/http/ngx_http_parse.c src/http/ngx_http_parse_time.c src/http/ngx_http_write_filter.c src/os/unix/ngx_pthread.c src/os/unix/ngx_pthread.h src/os/win32/ngx_os_thread.c src/os/win32/ngx_os_thread.h
diffstat 32 files changed, 1415 insertions(+), 716 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -36,7 +36,7 @@ ngx_pool_t   *ngx_pool;
 
 int ngx_connection_counter;
 
-ngx_array_t  *ngx_listening_sockets;
+ngx_array_t  ngx_listening_sockets;
 
 
 int main(int argc, char *const *argv)
@@ -56,9 +56,9 @@ int main(int argc, char *const *argv)
 
     ngx_init_sockets(&ngx_log);
 
-    /* TODO: read config */
+    ngx_init_array(ngx_listening_sockets, ngx_pool, 10, sizeof(ngx_listen_t),
+                   1);
 
-#if 1
     ngx_memzero(&conf, sizeof(ngx_conf_t));
     ngx_test_null(conf.args,
                   ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)), 1);
@@ -69,16 +69,16 @@ int main(int argc, char *const *argv)
     conf_file.len = sizeof("nginx.conf") - 1;
     conf_file.data = "nginx.conf";
 
-    ngx_conf_parse(&conf, &conf_file);
-#endif
+    if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
+        exit(1);
+    }
 
-    ngx_test_null(ngx_listening_sockets,
-                  ngx_create_array(ngx_pool, 10, sizeof(ngx_listen_t)), 1);
-
+#if 0
     /* STUB */
     /* TODO: init chain of global modules (like ngx_http.c),
        they would init its modules and ngx_listening_sockets */
     ngx_http_init(ngx_pool, &ngx_log);
+#endif
 
     ngx_open_listening_sockets(&ngx_log);
 
@@ -86,7 +86,7 @@ int main(int argc, char *const *argv)
 
     /* TODO: fork */
 
-    ngx_pre_thread(ngx_listening_sockets, ngx_pool, &ngx_log);
+    ngx_pre_thread(&ngx_listening_sockets, ngx_pool, &ngx_log);
 
     /* TODO: threads */
 
@@ -125,10 +125,10 @@ static void ngx_open_listening_sockets(n
          failed = 0;
 
         /* for each listening socket */
-        ls = (ngx_listen_t *) ngx_listening_sockets->elts;
-        for (i = 0; i < ngx_listening_sockets->nelts; i++) {
+        ls = (ngx_listen_t *) ngx_listening_sockets.elts;
+        for (i = 0; i < ngx_listening_sockets.nelts; i++) {
 
-            if (ls[i].done)
+            if (ls[i].bound)
                 continue;
 
             if (ls[i].inherited) {
@@ -137,7 +137,7 @@ static void ngx_open_listening_sockets(n
                 /* TODO: nonblocking */
                 /* TODO: deferred accept */
 
-                ls[i].done = 1;
+                ls[i].bound = 1;
                 continue;
             }
 
@@ -194,7 +194,7 @@ static void ngx_open_listening_sockets(n
             /* TODO: deferred accept */
 
             ls[i].fd = s;
-            ls[i].done = 1;
+            ls[i].bound = 1;
         }
 
         if (!failed)
--- a/src/core/ngx_alloc.h
+++ b/src/core/ngx_alloc.h
@@ -10,7 +10,7 @@
 #define NGX_MAX_ALLOC_FROM_POOL (8192 - sizeof(ngx_pool_t))
 #define NGX_DEFAULT_POOL_SIZE   (16 * 1024)
 
-#define ngx_test_null(p, alloc, rc)  if ((p = alloc) == NULL) return rc
+#define ngx_test_null(p, alloc, rc)  if ((p = alloc) == NULL) { return rc; }
 
 
 typedef struct ngx_pool_large_s  ngx_pool_large_t;
--- a/src/core/ngx_array.c
+++ b/src/core/ngx_array.c
@@ -2,19 +2,17 @@
 #include <ngx_config.h>
 
 #include <ngx_alloc.h>
+#include <ngx_string.h>
 #include <ngx_array.h>
 
+
 ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size)
 {
     ngx_array_t *a;
 
-    a = ngx_palloc(p, sizeof(ngx_array_t));
-    if (a == NULL)
-        return NULL;
+    ngx_test_null(a, ngx_palloc(p, sizeof(ngx_array_t)), NULL);
 
-    a->elts = ngx_palloc(p, n * size);
-    if (a->elts == NULL)
-        return NULL;
+    ngx_test_null(a->elts, ngx_palloc(p, n * size), NULL);
 
     a->pool = p;
     a->nelts = 0;
@@ -24,24 +22,31 @@ ngx_array_t *ngx_create_array(ngx_pool_t
     return a;
 }
 
+
 void ngx_destroy_array(ngx_array_t *a)
 {
-    ngx_pool_t *p = a->pool;
+    ngx_pool_t  *p;
 
-    if (a->elts + a->size * a->nalloc == p->last)
+    p = a->pool;
+
+    if (a->elts + a->size * a->nalloc == p->last) {
         p->last -= a->size * a->nalloc;
+    }
 
-    if ((char *) a + sizeof(ngx_array_t) == p->last)
+    if ((char *) a + sizeof(ngx_array_t) == p->last) {
         p->last = (char *) a;
+    }
 }
 
+
 void *ngx_push_array(ngx_array_t *a)
 {
-    void *elt;
+    void        *elt, *new;
+    ngx_pool_t  *p;
 
     /* array is full */
     if (a->nelts == a->nalloc) {
-        ngx_pool_t *p = a->pool;
+        p = a->pool;
 
         /* array allocation is the last in the pool */
         if (a->elts + a->size * a->nelts == p->last
@@ -52,11 +57,9 @@ void *ngx_push_array(ngx_array_t *a)
 
         /* allocate new array */
         } else {
-            void *new = ngx_palloc(p, 2 * a->nalloc * a->size);
-            if (new == NULL)
-                return NULL;
+            ngx_test_null(new, ngx_palloc(p, 2 * a->nalloc * a->size), NULL);
 
-            memcpy(new, a->elts, a->nalloc * a->size);
+            ngx_memcpy(new, a->elts, a->nalloc * a->size);
             a->elts = new;
             a->nalloc *= 2;
         }
--- a/src/core/ngx_array.h
+++ b/src/core/ngx_array.h
@@ -20,4 +20,9 @@ void ngx_destroy_array(ngx_array_t *a);
 void *ngx_push_array(ngx_array_t *a);
 
 
+#define ngx_init_array(a, p, n, s, rc)                                       \
+    ngx_test_null(a.elts, ngx_palloc(p, n * s), rc);                         \
+    a.nelts = 0; a.size = s; a.nalloc = n; a.pool = p;
+
+
 #endif /* _NGX_ARRAY_H_INCLUDED_ */
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -13,10 +13,11 @@ static int argument_number[] = {
 static int ngx_conf_read_token(ngx_conf_t *cf);
 
 
-int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
+char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
 {
-    int               rc, i;
-    char             *error;
+    int               i, rc, found;
+    char             *rv;
+    void             *conf, **pconf;
     ngx_str_t        *name;
     ngx_fd_t          fd;
     ngx_conf_file_t  *prev;
@@ -29,13 +30,13 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s
             ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
                           "ngx_conf_file: "
                           ngx_open_file_n " %s failed", filename->data);
-            return NGX_ERROR;
+            return NGX_CONF_ERROR;
         }
 
         prev = cf->conf_file;
         ngx_test_null(cf->conf_file,
                       ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)),
-                      NGX_ERROR);
+                      NGX_CONF_ERROR);
 
         if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) {
             ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
@@ -45,7 +46,7 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s
 
         ngx_test_null(cf->conf_file->hunk,
                       ngx_create_temp_hunk(cf->pool, 1024, 0, 0),
-                      NGX_ERROR);
+                      NGX_CONF_ERROR);
 
         cf->conf_file->file.fd = fd;
         cf->conf_file->file.name.len = filename->len;
@@ -59,22 +60,29 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s
 
         /* NGX_OK, NGX_ERROR, NGX_CONF_FILE_DONE, NGX_CONF_BLOCK_DONE */
 
-        if (rc == NGX_ERROR || rc == NGX_CONF_FILE_DONE) {
-            return rc;
+ngx_log_debug(cf->log, "token %d" _ rc);
+
+        if (rc == NGX_ERROR) {
+            return NGX_CONF_ERROR;
+        }
+
+        if (rc != NGX_OK) {
+            return NGX_CONF_OK;
         }
 
         if (cf->handler) {
 
-            if ((*cf->handler)(cf) == NGX_ERROR) {
-                return NGX_ERROR;
+            if ((*cf->handler)(cf) == NGX_CONF_ERROR) {
+                return NGX_CONF_ERROR;
             }
 
             continue;
         }
 
         name = (ngx_str_t *) cf->args->elts;
+        found = 0;
 
-        for (i = 0; ngx_modules[i]; i++) {
+        for (i = 0; !found && ngx_modules[i]; i++) {
             if (ngx_modules[i]->type != NULL
                 && ngx_modules[i]->type != cf->type)
             {
@@ -93,86 +101,56 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s
 
 ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
 
-                    cmd->set(cf, cmd, NULL);
+                    if (!(cmd->type & argument_number[cf->args->nelts - 1])) {
+                        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                                      "invalid number arguments in "
+                                      "directive \"%s\" in %s:%d",
+                                      name->data,
+                                      cf->conf_file->file.name.data,
+                                      cf->conf_file->line);
+                        return NGX_CONF_ERROR;
+                    }
+
+                    conf = NULL;
+                    if (cf->ctx) {
+                        pconf = *(void **) ((char *) cf->ctx + cmd->conf);
+
+                        if (pconf) {
+                            conf = pconf[ngx_modules[i]->index];
+                        }
+                    }
+
+                    rv = cmd->set(cf, cmd, conf);
+
+ngx_log_debug(cf->log, "rv: %d" _ rv);
+
+                    if (rv == NGX_CONF_OK) {
+                        found = 1;
+                        break;
+
+                    } else if (rv == NGX_CONF_ERROR) {
+                        return NGX_CONF_ERROR;
+
+                    } else {
+                        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                                     "%s", rv);
+                        return NGX_CONF_ERROR;
+                    }
                 }
 
                 cmd++;
             }
-       }
-
-#if 0
-        cmd = ngx_conf_find_token(cf);
-        if (cmd == NULL) {
-            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                          "unknown directive \"%s\" in %s:%d",
-                          cf->name, cf->file->name, cf->file->line);
-            return NGX_ERROR;
         }
 
-        if (cmd->type & argument_number[cf->args->nelts - 1]) {
-            error = cmd->set(cf, cmd->offset, cf->args);
-
-            if (error) {
-                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                               "%s in directive \"%s\" in %s:%d",
-                               error, cf->name, cf->file->name, cf->file->line);
-                return NGX_ERROR;
-            }
-        }
-#endif
-
-#if 0
-        if (cmd->type == NGX_CONF_CONTAINER) {
-            ngx_conf_parse(cf, cmd->container, NULL);
-
-        } else if (cmd->type == NGX_CONF_FLAG) {
-
-            if (cf->args->nelts != 1) {
-                ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                              "invalid number of arguments "
-                              "in directive \"%s\" in %s:%d",
-                              cf->name, cf->file->name, cf->file->line);
-                return NGX_ERROR;
-            }
-
-            if (ngx_strcasecmp(cf->args->elts[0], "on") == 0) {
-                flag = 1;
-
-            } else if (ngx_strcasecmp(cf->args->elts[0], "off") == 0) {
-                flag = 0;
+        if (!found) {
+            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                          "unknown directive \"%s\" in %s:%d",
+                          name->data,
+                          cf->conf_file->file.name.data,
+                          cf->conf_file->line);
 
-            } else {
-                ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                              "invalid flag in directive \"%s\" in %s:%d",
-                              cf->name, cf->file->name, cf->file->line);
-                return NGX_ERROR;
-            }
-
-            rv = cmd->set(cf, cmd->offset, flag);
-            if (rv) {
-                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                               "%s in directive \"%s\" in %s:%d",
-                               rv, cf->name, cf->file->name, cf->file->line);
-                return NGX_ERROR;
-            }
-
-        } else if (cmd->type & argument_number[args->nelts]) {
-            rv = cmd->set(cf, cmd->offset, cf->args);
-            if (rv) {
-                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                               "%s in directive \"%s\" in %s:%d",
-                               rv, cf->name, cf->file->name, cf->file->line);
-                return NGX_ERROR;
-            }
-
-        } else {
-            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
-                          "invalid number of arguments "
-                          "in directive \"%s\" in %s:%d",
-                          cf->name, cf->file->name, cf->file->line);
-            return NGX_ERROR;
+            return NGX_CONF_ERROR;
         }
-#endif
     }
 
     if (filename) {
@@ -182,11 +160,11 @@ ngx_log_debug(cf->log, "command '%s'" _ 
             ngx_log_error(NGX_LOG_ERR, cf->log, ngx_errno,
                           ngx_close_file_n " %s failed",
                           cf->conf_file->file.name.data);
-            return NGX_ERROR;
+            return NGX_CONF_ERROR;
         }
     }
 
-    return NGX_OK;
+    return NGX_CONF_OK;
 }
 
 
@@ -391,6 +369,20 @@ ngx_log_debug(cf->log, "FOUND %d:'%s'" _
 }
 
 
+char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
+{
+    ngx_str_t  *field, *value;
+
+    field = (ngx_str_t *) conf + cmd->offset;
+    value = (ngx_str_t *) cf->args->elts;
+
+    field->len = value->len;
+    field->data = value->data;
+
+    return NGX_CONF_OK;
+}
+
+
 char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
 {
     int         size;
@@ -405,7 +397,7 @@ char *ngx_conf_set_size_slot(ngx_conf_t 
 
     *(int *) (conf + cmd->offset) = size;
 
-    return NULL;
+    return NGX_CONF_OK;
 }
 
 
@@ -423,5 +415,5 @@ char *ngx_conf_set_time_slot(ngx_conf_t 
 
     *(int *) (conf + cmd->offset) = size;
 
-    return NULL;
+    return NGX_CONF_OK;
 }
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -15,15 +15,16 @@
 #define NGX_CONF_NOARGS      1
 #define NGX_CONF_TAKE1       2
 #define NGX_CONF_TAKE2       4
-#define NGX_CONF_ARGS_NUMBER 0x0ffff
-#define NGX_CONF_ANY         0x10000
-#define NGX_CONF_BLOCK       0x20000
+#define NGX_CONF_ARGS_NUMBER 0x00ffff
+#define NGX_CONF_ANY         0x010000
+#define NGX_CONF_BLOCK       0x020000
 
 
 #define NGX_CONF_UNSET       -1
 
 
-#define NGX_CONF_ERROR       (char *) -1
+#define NGX_CONF_OK          NULL
+#define NGX_CONF_ERROR       (void *) -1
 
 #define NGX_CONF_BLOCK_DONE  1
 #define NGX_CONF_FILE_DONE   2
@@ -46,6 +47,7 @@ struct ngx_command_s {
 
 
 typedef struct {
+    int             index;
     void           *ctx;
     ngx_command_t  *commands;
     int             type;
@@ -70,13 +72,21 @@ struct ngx_conf_s {
 
     void             *ctx;
     int               type;
-    int             (*handler)(ngx_conf_t *cf);
+    char           *(*handler)(ngx_conf_t *cf);
 };
 
 
-int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
+#define ngx_conf_merge(conf, prev, default)                                  \
+    if (conf == NGX_CONF_UNSET) {                                            \
+        conf = (prev == NGX_CONF_UNSET) ? default : prev;                    \
+    }
 
 
+
+char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
+
+
+char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
 char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
 char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
 
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -30,16 +30,18 @@ struct ngx_connection_s {
 
     off_t             sent;
 
+    int             (*handler)(ngx_connection_t *c);
+    void             *ctx;
+    ngx_server_t     *servers;
+
+    ngx_pool_t       *pool;
     ngx_log_t        *log;
-    int             (*handler)(ngx_connection_t *c);
-    ngx_server_t     *server;
-    ngx_server_t     *servers;
-    ngx_pool_t       *pool;
 
     int               family;
     struct sockaddr  *sockaddr;
     socklen_t         socklen;
-    size_t            addr;
+    int               addr;
+    int               addr_text_max_len;
     ngx_str_t         addr_text;
 
     ngx_hunk_t       *buffer;
--- a/src/core/ngx_listen.h
+++ b/src/core/ngx_listen.h
@@ -9,36 +9,44 @@
 #include <ngx_connection.h>
 
 typedef struct {
-    ngx_socket_t  fd;
+    ngx_socket_t      fd;
 
     struct sockaddr  *sockaddr;
-    socklen_t         socklen;
-    size_t            addr;
+    socklen_t         socklen;    /* size of sockaddr */
+    int               addr;       /* offset to address in sockaddr */
+    int               addr_text_max_len;
     ngx_str_t         addr_text;
 
-    int           family;
-    int           type;
-    int           protocol;
-    int           flags;
+    int               family;
+    int               type;
+    int               protocol;
+    int               flags;      /* Winsock2 flags */
 
-    ngx_log_t    *log;
-    void         *server;
-    int         (*handler)(ngx_connection_t *c);
+    int             (*handler)(ngx_connection_t *c); /* handler of accepted
+                                                        connection */
+    void             *ctx;        /* ngx_http_conf_ctx_t, for example */
+    void             *servers;    /* array of ngx_http_in_addr_t, for example */
+
+    ngx_log_t        *log;
 
-    int           backlog;
-    time_t        post_accept_timeout;
+    int               backlog;
+    time_t            post_accept_timeout;  /* should be here because
+                                               of the deferred accept */
 
-    unsigned      done:1;
-    unsigned      inherited:1;
-    unsigned      nonblocking:1;
+    unsigned          bound:1;       /* already bound */
+    unsigned          inherited:1;   /* inherited from previous process */
+    unsigned          nonblocking:1;
 #if 0
-    unsigned      overlapped:1;
+    unsigned          overlapped:1;  /* Winsock2 overlapped */
 #endif
-    unsigned      shared:1;          /* shared between threads or processes */
+    unsigned          shared:1;    /* shared between threads or processes */
 #if (HAVE_DEFERRED_ACCEPT)
-    unsigned      deferred_accept:1;
+    unsigned          deferred_accept:1;
 #endif
 } ngx_listen_t;
 
 
+extern ngx_array_t ngx_listening_sockets;
+
+
 #endif /* _NGX_LISTEN_H_INCLUDED_ */
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -18,7 +18,8 @@ typedef struct {
 
 #define ngx_memzero               ZeroMemory
 
-#define strcasecmp                stricmp
+#define ngx_strcasecmp            stricmp
+#define ngx_strncmp               strncmp
 #define ngx_strcmp                strcmp
 
 #define ngx_snprintf              _snprintf
@@ -28,6 +29,7 @@ typedef struct {
 
 #define ngx_memzero               bzero
 
+#define ngx_strncmp               strncmp
 #define ngx_strcmp                strcmp
 
 #define ngx_snprintf              snprintf
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -84,8 +84,9 @@ void ngx_pre_thread(ngx_array_t *ls, ngx
     /* STUB */
     int max_connections = 512;
 
-    if (ngx_init_events(max_connections, log) == NGX_ERROR)
+    if (ngx_init_events(max_connections, log) == NGX_ERROR) {
         exit(1);
+    }
 
     ngx_connections = ngx_alloc(sizeof(ngx_connection_t)
                                                        * max_connections, log);
@@ -101,43 +102,44 @@ void ngx_pre_thread(ngx_array_t *ls, ngx
         c = &ngx_connections[fd];
         ev = &ngx_read_events[fd];
 
-        ngx_memzero(&ngx_connections[fd], sizeof(ngx_connection_t));
-        ngx_memzero(&ngx_read_events[fd], sizeof(ngx_event_t));
+        ngx_memzero(c, sizeof(ngx_connection_t));
+        ngx_memzero(ev, sizeof(ngx_event_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].post_accept_timeout = s[i].post_accept_timeout;
+        c->fd = fd;
+        c->family = s[i].family;
+        c->socklen = s[i].socklen;
+        c->sockaddr = ngx_palloc(pool, s[i].socklen);
+        c->addr = s[i].addr;
+        c->addr_text = s[i].addr_text;
+        c->addr_text_max_len = s[i].addr_text_max_len;
+        c->post_accept_timeout = s[i].post_accept_timeout;
 
-        ngx_connections[fd].server = s[i].server;
-        ngx_connections[fd].handler = s[i].handler;
-        ngx_connections[fd].log = s[i].log;
+        c->handler = s[i].handler;
+        c->ctx = s[i].ctx;
+        c->servers = s[i].servers;
+        c->log = s[i].log;
 
-        ngx_test_null(ngx_read_events[fd].log,
+        ngx_test_null(ev->log,
                       ngx_palloc(pool, sizeof(ngx_log_t)), /* void */ ; );
-        ngx_memcpy(ngx_read_events[fd].log, ngx_connections[fd].log,
-                   sizeof(ngx_log_t));
+        ngx_memcpy(ev->log, c->log, sizeof(ngx_log_t));
         c->read = ev;
-        ngx_read_events[fd].data = &ngx_connections[fd];
-        ngx_read_events[fd].event_handler = &ngx_event_accept;
-        ngx_read_events[fd].listening = 1;
+        ev->data = c;
+        ev->event_handler = &ngx_event_accept;
+        ev->listening = 1;
         ev->index = NGX_INVALID_INDEX;
 
-        ngx_read_events[fd].available = 0;
+        ev->available = 0;
 
 #if (HAVE_DEFERRED_ACCEPT)
-        ngx_read_events[fd].deferred_accept = s[i].deferred_accept;
+        ev->deferred_accept = s[i].deferred_accept;
 #endif
-        ngx_add_event(&ngx_read_events[fd], NGX_READ_EVENT, 0);
+        ngx_add_event(ev, NGX_READ_EVENT, 0);
     }
 }
 
 void ngx_worker(ngx_log_t *log)
 {
-    while (1) {
+    for ( ;; ) {
         ngx_log_debug(log, "ngx_worker cycle");
 
         ngx_process_events(log);
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -98,12 +98,14 @@ typedef struct {
 /*
 NGX_LEVEL_EVENT (default)  select, poll, /dev/poll, kqueue
                                 requires to read whole data
-NGX_ONESHOT_EVENT          select, poll, kqueue
-NGX_CLEAR_EVENT            kqueue
+NGX_ONESHOT_EVENT          select, poll, /dev/poll(*), kqueue, epoll(*)
+                           (*) - additional syscall
+NGX_CLEAR_EVENT            kqueue, epoll
 NGX_AIO_EVENT              overlapped, aio_read, aioread
                                 no need to add or delete events
 
 NGX_CLOSE_EVENT            kqueue: kqueue deletes events for file that closed
+                           /dev/poll: need to flush events before closing
 */
 
 #define NGX_CLOSE_EVENT    1
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -59,7 +59,7 @@ int ngx_event_accept(ngx_event_t *ev)
         c->family = ac->family;
         c->socklen = ac->socklen;
         c->addr = ac->addr;
-        c->addr_text.len = ac->addr_text.len;
+        c->addr_text_max_len = ac->addr_text_max_len;
         c->post_accept_timeout = ac->post_accept_timeout;
 
         rev->index = wev->index = NGX_INVALID_INDEX;
@@ -77,7 +77,7 @@ int ngx_event_accept(ngx_event_t *ev)
         wev->timer_handler = rev->timer_handler = ngx_event_close_connection;
         wev->close_handler = rev->close_handler = ngx_event_close_connection;
 
-        c->server = ac->server;
+        c->ctx = ac->ctx;
         c->servers = ac->servers;
         c->log = rev->log = wev->log = ev->log;
 
--- a/src/event/ngx_event_write.c
+++ b/src/event/ngx_event_write.c
@@ -102,7 +102,9 @@ ngx_chain_t *ngx_event_write(ngx_connect
 
                 sent = rc > 0 ? rc: 0;
 
+#if (NGX_DEBUG_EVENT_WRITE)
                 ngx_log_debug(c->log, "sendv: " QD_FMT _ sent);
+#endif
             }
 #if (HAVE_MAX_SENDFILE_IOVEC)
         }
@@ -115,17 +117,21 @@ ngx_chain_t *ngx_event_write(ngx_connect
 
         for (ch = in; ch; ch = ch->next) {
 
-            ngx_log_debug(c->log, "ch event write: %x %qx %qd" _
+#if (NGX_DEBUG_EVENT_WRITE)
+            ngx_log_debug(c->log, "event write: %x " QX_FMT " " QD_FMT _
                           ch->hunk->type _
                           ch->hunk->pos.file _
                           ch->hunk->last.file - ch->hunk->pos.file);
+#endif
 
             if (sent >= ch->hunk->last.file - ch->hunk->pos.file) {
                 sent -= ch->hunk->last.file - ch->hunk->pos.file;
                 ch->hunk->pos.file = ch->hunk->last.file;
 
+#if (NGX_DEBUG_EVENT_WRITE)
                 ngx_log_debug(c->log, "event write: " QX_FMT " 0 " QD_FMT _
                               ch->hunk->pos.file _ sent);
+#endif
 
 /*
                 if (ch->hunk->type & NGX_HUNK_LAST)
@@ -137,9 +143,11 @@ ngx_chain_t *ngx_event_write(ngx_connect
 
             ch->hunk->pos.file += sent;
 
-            ngx_log_debug(c->log, "event write: %qx %qd" _
+#if (NGX_DEBUG_EVENT_WRITE)
+            ngx_log_debug(c->log, "event write: " QX_FMT " " QD_FMT _
                           ch->hunk->pos.file _
                           ch->hunk->last.file - ch->hunk->pos.file);
+#endif
 
             break;
         }
--- a/src/http/modules/ngx_http_event_proxy_handler.c
+++ b/src/http/modules/ngx_http_event_proxy_handler.c
@@ -39,13 +39,15 @@ int ngx_http_proxy_handler(ngx_http_requ
     p = (ngx_http_proxy_ctx_t *)
                          ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
 
-    if (p == NULL)
+    if (p == NULL) {
         ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx,
                             sizeof(ngx_http_proxy_ctx_t));
+    }
 
     chain = ngx_http_proxy_create_request(r);
-    if (chain == NULL)
+    if (chain == NULL) {
         return NGX_ERROR;
+    }
 
     p->out = chain;
 
@@ -75,11 +77,13 @@ static ngx_chain_t *ngx_http_proxy_creat
 
     header = (ngx_table_elt_t *) r->headers_in.headers->elts;
     for (i = 0; i < r->headers_in.headers->nelts; i++) {
-        if (&header[i] == r->headers_in.host)
+        if (&header[i] == r->headers_in.host) {
             continue;
+        }
 
-        if (&header[i] == r->headers_in.connection)
+        if (&header[i] == r->headers_in.connection) {
             continue;
+        }
 
         /* 2 is for ": " and 2 is for "\r\n" */
         len += header[i].key.len + 2 + header[i].value.len + 2;
@@ -98,11 +102,13 @@ static ngx_chain_t *ngx_http_proxy_creat
     hunk->last.mem += sizeof(conn_close) - 1;
 
     for (i = 0; i < r->headers_in.headers->nelts; i++) {
-        if (&header[i] == r->headers_in.host)
+        if (&header[i] == r->headers_in.host) {
             continue;
+        }
 
-        if (&header[i] == r->headers_in.connection)
+        if (&header[i] == r->headers_in.connection) {
             continue;
+        }
 
         ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len);
         hunk->last.mem += header[i].key.len;
@@ -115,7 +121,7 @@ static ngx_chain_t *ngx_http_proxy_creat
         *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF;
 
         ngx_log_debug(r->connection->log, "proxy: '%s: %s'" _
-                  header[i].key.data _ header[i].value.data);
+                      header[i].key.data _ header[i].value.data);
     }
 
     /* add "\r\n" at the header end */
@@ -157,9 +163,10 @@ static int ngx_http_proxy_connect(ngx_ht
             ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
                           "setsockopt(SO_RCVBUF) failed");
 
-            if (ngx_close_socket(s) == -1)
+            if (ngx_close_socket(s) == -1) {
                 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
                               ngx_close_socket_n " failed");
+            }
 
             return NGX_ERROR;
         }
@@ -170,9 +177,10 @@ static int ngx_http_proxy_connect(ngx_ht
         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
                       ngx_nonblocking_n " failed");
 
-        if (ngx_close_socket(s) == -1)
+        if (ngx_close_socket(s) == -1) {
             ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
                           ngx_close_socket_n " failed");
+        }
 
         return NGX_ERROR;
     }
@@ -184,9 +192,10 @@ static int ngx_http_proxy_connect(ngx_ht
         if (err != NGX_EINPROGRESS) {
             ngx_log_error(NGX_LOG_ERR, c->log, err, "connect() failed");
 
-            if (ngx_close_socket(s) == -1)
+            if (ngx_close_socket(s) == -1) {
                 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
                               ngx_close_socket_n " failed");
+            }
 
             return NGX_ERROR;
         }
@@ -207,7 +216,6 @@ static int ngx_http_proxy_connect(ngx_ht
     pc->data = r;
 
     pc->fd = s;
-    pc->server = c->server;
     pc->servers = c->servers;
 
     pc->log = rev->log = wev->log = c->log;
@@ -220,14 +228,16 @@ static int ngx_http_proxy_connect(ngx_ht
     rev->event_handler = ngx_http_proxy_read_response_header;
 
 #if (HAVE_CLEAR_EVENT)
-    if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK)
+    if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) {
 #else
-    if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK)
+    if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) {
 #endif
         return NGX_ERROR;
+    }
 
-    if (rc == -1)
+    if (rc == -1) {
         return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT);
+    }
 
     wev->write = 1;
     wev->ready = 1;
@@ -249,8 +259,9 @@ static int ngx_http_proxy_send_request(n
                          ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
 
     chain = ngx_event_write(c, p->out, 0);
-    if (chain == (ngx_chain_t *) -1)
+    if (chain == (ngx_chain_t *) -1) {
         return NGX_ERROR;
+    }
 
     p->out = chain;
 
@@ -266,8 +277,9 @@ static int ngx_http_proxy_read_response_
     ngx_http_request_t    *r;
     ngx_http_proxy_ctx_t  *p;
 
-    if (ev->timedout)
+    if (ev->timedout) {
         return NGX_ERROR;
+    }
 
     c = (ngx_connection_t *) ev->data;
     r = (ngx_http_request_t *) c->data;
@@ -330,8 +342,9 @@ static int ngx_http_proxy_read_response_
     do {
         rc = (p->state_handler)(r, p);
 
-        if (rc == NGX_ERROR)
+        if (rc == NGX_ERROR) {
             return rc;
+        }
 
         /* rc == NGX_OK || rc == NGX_AGAIN */
 
@@ -339,8 +352,9 @@ static int ngx_http_proxy_read_response_
 #endif
 
     ev->event_handler = ngx_http_proxy_read_response_body;
-    if (p->header_in->end - p->header_in->last.mem == 0)
+    if (p->header_in->end - p->header_in->last.mem == 0) {
         return ngx_http_proxy_read_response_body(ev);
+    }
 
     return NGX_WAITING;
 }
@@ -406,11 +420,15 @@ static int ngx_http_proxy_read_response_
 
 #if (HAVE_KQUEUE)
 #if !(USE_KQUEUE)
-        if (ngx_event_type == NGX_KQUEUE_EVENT)
+        if (ngx_event_type == NGX_KQUEUE_EVENT) {
 #endif
             /* do not allocate new block if there is EOF */
-            if (ev->eof && ev->available == 0)
+            if (ev->eof && ev->available == 0) {
                 left = 1;
+            }
+#if !(USE_KQUEUE)
+        }
+#endif
 #endif
         if (left == 0) {
             ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR);
@@ -427,11 +445,13 @@ static int ngx_http_proxy_read_response_
 
         ngx_log_debug(c->log, "READ:%d" _ n);
 
-        if (n == NGX_AGAIN)
+        if (n == NGX_AGAIN) {
             return NGX_WAITING;
+        }
 
-        if (n == NGX_ERROR)
+        if (n == NGX_ERROR) {
             return NGX_ERROR;
+        }
 
         h->last.mem += n;
         left = h->end - h->last.mem;
@@ -475,11 +495,13 @@ static int ngx_http_proxy_write_to_clien
         h = ((ngx_hunk_t **) p->hunks->elts)[p->hunk_n];
 
         rc = ngx_http_output_filter(r, h);
-        if (rc != NGX_OK)
+        if (rc != NGX_OK) {
             return rc;
+        }
 
-        if (p->hunk_n >= p->hunks->nelts)
+        if (p->hunk_n >= p->hunks->nelts) {
             break;
+        }
 
         p->hunk_n++;
 
@@ -519,12 +541,15 @@ fprintf(stderr, "state: %d, pos: %x, end
 
         /* "HTTP/" */
         case sw_start:
-            if (p + 3 >= ctx->header_in->last.mem)
+            if (p + 3 >= ctx->header_in->last.mem) {
                 return NGX_AGAIN;
+            }
 
             if (ch != 'H' || *p != 'T' || *(p + 1) != 'T' || *(p + 2) != 'P'
                           || *(p + 3) != '/')
+            {
                 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+            }
 
             p += 4;
             state = sw_first_major_digit;
@@ -532,8 +557,9 @@ fprintf(stderr, "state: %d, pos: %x, end
 
         /* first digit of major HTTP version */
         case sw_first_major_digit:
-            if (ch < '1' || ch > '9')
+            if (ch < '1' || ch > '9') {
                 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+            }
 
             state = sw_major_digit;
             break;
@@ -545,15 +571,17 @@ fprintf(stderr, "state: %d, pos: %x, end
                 break;
             }
 
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+            }
 
             break;
 
         /* first digit of minor HTTP version */
         case sw_first_minor_digit:
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+            }
 
             state = sw_minor_digit;
             break;
@@ -565,15 +593,17 @@ fprintf(stderr, "state: %d, pos: %x, end
                 break;
             }
 
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+            }
 
             break;
 
         /* HTTP status code */
         case sw_status:
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
+            }
 
             ctx->status = ctx->status * 10 + ch - '0';
 
@@ -630,10 +660,13 @@ fprintf(stderr, "state: %d, pos: %x, end
     ctx->header_in->pos.mem = p;
 
     if (state == sw_done) {
-        if (ctx->request_end == NULL)
+        if (ctx->request_end == NULL) {
             ctx->request_end = p - 1;
+        }
+
         ctx->state = sw_start;
         return NGX_OK;
+
     } else {
         ctx->state = state;
         return NGX_AGAIN;
--- a/src/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -9,11 +9,12 @@
 
 #include <ngx_http.h>
 #include <ngx_http_config.h>
+#include <ngx_http_core_module.h>
 #include <ngx_http_index_handler.h>
 
 
 static void *ngx_http_index_create_conf(ngx_pool_t *pool);
-static void *ngx_http_index_merge_conf(ngx_pool_t *p,
+static char *ngx_http_index_merge_conf(ngx_pool_t *p,
                                        void *parent, void *child);
 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
                                       char *conf);
@@ -50,6 +51,7 @@ ngx_http_module_t  ngx_http_index_module
 
 
 ngx_module_t  ngx_http_index_module = {
+    0,                                     /* module index */
     &ngx_http_index_module_ctx,            /* module context */
     ngx_http_index_commands,               /* module directives */
     NGX_HTTP_MODULE_TYPE,                  /* module type */
@@ -65,18 +67,23 @@ int ngx_http_index_handler(ngx_http_requ
     ngx_err_t    err;
     ngx_fd_t     fd;
 
-    ngx_http_index_conf_t  *cf;
+    ngx_http_index_conf_t     *cf;
+    ngx_http_core_loc_conf_t  *core_cf;
 
     cf = (ngx_http_index_conf_t *)
                    ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx);
 
+    core_cf = (ngx_http_core_loc_conf_t *)
+                    ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
+
     ngx_test_null(name,
                   ngx_palloc(r->pool,
-                             r->server->doc_root_len + r->uri.len
+                             core_cf->doc_root.len + r->uri.len
                              + cf->max_index_len),
                   NGX_HTTP_INTERNAL_SERVER_ERROR);
 
-    loc.data = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len);
+    loc.data = ngx_cpystrn(name, core_cf->doc_root.data,
+                           core_cf->doc_root.len + 1);
     file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1);
 
     index = (ngx_str_t *) cf->indices->elts;
@@ -101,7 +108,7 @@ int ngx_http_index_handler(ngx_http_requ
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
-        r->file.name.len = r->server->doc_root_len + r->uri.len + index[i].len;
+        r->file.name.len = core_cf->doc_root.len + r->uri.len + index[i].len;
         r->file.name.data = name; 
         r->file.fd = fd; 
 
@@ -117,17 +124,34 @@ static void *ngx_http_index_create_conf(
 {
     ngx_http_index_conf_t  *conf;
 
-    ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), NULL);
+    ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)),
+                  NGX_CONF_ERROR);
 
     ngx_test_null(conf->indices,
                   ngx_create_array(pool, sizeof(ngx_str_t), 3),
-                  NULL);
+                  NGX_CONF_ERROR);
 
     return conf;
 }
 
 
-static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
+static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
+{
+    ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent;
+    ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child;
+    ngx_str_t  *index;
+
+    ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR);
+    index->len = sizeof(NGX_HTTP_INDEX) - 1;
+    index->data = NGX_HTTP_INDEX;
+    conf->max_index_len = sizeof(NGX_HTTP_INDEX);
+
+    return NULL;
+}
+
+
+#if 0
+static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
 {
     ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent;
     ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child;
@@ -146,7 +170,7 @@ static void *ngx_http_index_merge_conf(n
 
     return conf;
 }
-
+#endif
 
 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
                                       char *conf)
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -117,6 +117,9 @@ int ngx_http_static_handler(ngx_http_req
         } else if (strcasecmp(r->exten.data, "jpg") == 0) {
             r->headers_out.content_type->value.len = 10;
             r->headers_out.content_type->value.data = "image/jpeg";
+        } else if (strcasecmp(r->exten.data, "pdf") == 0) {
+            r->headers_out.content_type->value.len = 15;
+            r->headers_out.content_type->value.data = "application/pdf";
         }
 
     } else {
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -5,15 +5,343 @@
 #include <ngx_listen.h>
 #include <ngx_http.h>
 #include <ngx_http_config.h>
+#include <ngx_http_core_module.h>
 
-extern ngx_array_t *ngx_listening_sockets;
+
+static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
+
+
+int  ngx_http_max_module;
+
+ngx_array_t  ngx_http_servers;   /* array of ngx_http_core_srv_conf_t */ 
+
+int  ngx_http_post_accept_timeout = 10000;
+int  ngx_http_connection_pool_size = 16384;
+int  ngx_http_request_pool_size = 16384;
+int  ngx_http_client_header_timeout = 20000;
+int  ngx_http_client_header_buffer_size = 1024;
+
+/* STUB: per location */
+int  ngx_http_lingering_timeout = 5000;
+int  ngx_http_lingering_time = 30;
+/**/
+
+int  (*ngx_http_top_header_filter) (ngx_http_request_t *r);
+
+
+static ngx_str_t  http_name = ngx_string("http");
+
+
+static ngx_command_t  ngx_http_commands[] = {
+
+    {ngx_string("http"),
+     NGX_CONF_BLOCK|NGX_CONF_NOARGS,
+     ngx_http_block,
+     0,
+     0},
+
+    {ngx_string(""), 0, NULL, 0, 0}
+};
+
+
+ngx_module_t  ngx_http_module = {
+    0,                                     /* module index */
+    &http_name,                            /* module context */
+    ngx_http_commands,                     /* module directives */
+    NGX_CORE_MODULE_TYPE,                  /* module type */
+    NULL                                   /* init module */
+};
+
+
+static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
+{
+    int                         i, s, l, p, a, n, start;
+    int                         port_found, addr_found, virtual_names;
+    char                       *rv;
+    struct sockaddr_in         *addr_in;
+    ngx_array_t                 in_ports;
+    ngx_listen_t               *ls;
+    ngx_http_module_t          *module;
+    ngx_http_conf_ctx_t        *ctx, *prev;
+    ngx_http_in_port_t         *in_port;
+    ngx_http_in_addr_t         *in_addr, *inaddr;
+    ngx_http_core_srv_conf_t  **cscf;
+    ngx_http_listen_t          *lscf;
+    ngx_http_server_name_t     *s_name, *name;;
+
+    ngx_init_array(ngx_http_servers, cf->pool, 10,
+                   sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR);
+
+    ngx_test_null(ctx,
+                  ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
+                  NGX_CONF_ERROR);
+
+    for (i = 0; ngx_modules[i]; i++) {
+        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        /* STUB */
+        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
+        module->index = ngx_http_max_module;
+
+        ngx_modules[i]->index = ngx_http_max_module++;
+    }
+
+    /* null loc_conf */
+    ngx_test_null(ctx->loc_conf,
+                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
+                  NGX_CONF_ERROR);
+
+    for (i = 0; ngx_modules[i]; i++) {
+        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
+
+        if (module->create_loc_conf) {
+            ngx_test_null(ctx->loc_conf[module->index],
+                          module->create_loc_conf(cf->pool),
+                          NGX_CONF_ERROR);
+        }
+    }
+
+    prev = cf->ctx;
+    cf->ctx = ctx;
+    cf->type = NGX_HTTP_MODULE_TYPE;
+
+    rv = ngx_conf_parse(cf, NULL);
+    cf->ctx = prev;
+
+    if (rv != NGX_CONF_OK)
+        return rv;
+
+    ngx_http_init_filters(cf->pool, ngx_modules);
+
+#if 1
+    ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t),
+                   NGX_CONF_ERROR);
+
+    cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts;
+    for (s = 0; s < ngx_http_servers.nelts; s++) {
+
+        lscf = (ngx_http_listen_t *) cscf[s]->listen.elts;
+        for (l = 0; l < cscf[s]->listen.nelts; l++) {
+
+            port_found = 0;
+
+            /* AF_INET only */
+
+            in_port = (ngx_http_in_port_t *) in_ports.elts;
+            for (p = 0; p < in_ports.nelts; p++) {
+
+                if (lscf[l].port == in_port[p].port) {
+
+                    port_found = 1;
+                    addr_found = 0;
+
+                    in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
+                    for (a = 0; a < in_port[p].addr.nelts; a++) {
+
+                        if (lscf[l].addr == in_addr[a].addr) {
+                            s_name = (ngx_http_server_name_t *)
+                                                    cscf[s]->server_names.elts;
+                            for (n = 0; n < cscf[s]->server_names.nelts; n++) {
+                                ngx_test_null(name,
+                                              ngx_push_array(&in_addr[a].names),
+                                              NGX_CONF_ERROR);
+
+                                name->name = s_name[n].name;
+                                name->core_srv_conf = s_name[n].core_srv_conf;
+                            }
+
+                            if (lscf[l].flags & NGX_HTTP_DEFAULT_SERVER) {
+                                if (in_addr[a].flags
+                                                   & NGX_HTTP_DEFAULT_SERVER) {
+
+                                    ngx_log_error(NGX_LOG_ERR, cf->log, 0,
+                                        "duplicate default server in %s:%d",
+                                        lscf[l].conf_file->file.name.data,
+                                        lscf[l].line);
+
+                                    return NGX_CONF_ERROR;
+                                }
+
+                                in_addr[a].flags |= NGX_HTTP_DEFAULT_SERVER;
+                                in_addr[a].core_srv_conf = cscf[s];
+                            }
 
+                            addr_found = 1;
+
+                            break;
+
+                        /* "*:XX" is the last resort */
+                        } else if (in_addr[p].addr == INADDR_ANY) {
+                            ngx_test_null(inaddr,
+                                          ngx_push_array(&in_port[p].addr),
+                                          NGX_CONF_ERROR);
+
+                            ngx_memcpy(inaddr, &in_addr[a],
+                                       sizeof(ngx_http_in_addr_t));
+
+                            inaddr->addr = lscf[l].addr;
+                            inaddr->flags = lscf[l].flags;
+                            inaddr->core_srv_conf = cscf[s];
+
+                            ngx_init_array(inaddr->names, cf->pool, 10,
+                                           sizeof(ngx_http_server_name_t),
+                                           NGX_CONF_ERROR);
+
+                            addr_found = 1;
+
+                            break;
+                        }
+                    }
+
+                    if (!addr_found) {
+                        ngx_test_null(inaddr,
+                                      ngx_push_array(&in_port[p].addr),
+                                      NGX_CONF_ERROR);
+
+                        inaddr->addr = lscf[l].addr;
+                        inaddr->flags = lscf[l].flags;
+                        inaddr->core_srv_conf = cscf[s];
+
+                        ngx_init_array(inaddr->names, cf->pool, 10,
+                                       sizeof(ngx_http_server_name_t),
+                                       NGX_CONF_ERROR);
+                    }
+                }
+            }
+
+            if (!port_found) {
+                ngx_test_null(in_port,
+                              ngx_push_array(&in_ports),
+                              NGX_CONF_ERROR);
+
+                in_port->port = lscf[l].port;
+
+                ngx_init_array(in_port->addr, cf->pool, 10,
+                               sizeof(ngx_http_in_addr_t),
+                               NGX_CONF_ERROR);
+
+                ngx_test_null(inaddr, ngx_push_array(&in_port[p].addr),
+                              NGX_CONF_ERROR);
+
+                inaddr->addr = lscf[l].addr;
+                inaddr->flags = lscf[l].flags;
+                inaddr->core_srv_conf = cscf[s];
+
+                ngx_init_array(inaddr->names, cf->pool, 10,
+                               sizeof(ngx_http_server_name_t),
+                               NGX_CONF_ERROR);
+            }
+        }
+    }
+
+    /* AF_INET only */
+
+    in_port = (ngx_http_in_port_t *) in_ports.elts;
+    for (p = 0; p < in_ports.nelts; p++) {
+
+        in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
+        for (a = 0; a < in_port[p].addr.nelts; a++) {
+
+            virtual_names = 0;
+
+            name = (ngx_http_server_name_t *) in_addr[a].names.elts;
+            for (n = 0; n < in_addr[a].names.nelts; n++) {
+                if (in_addr[a].core_srv_conf != name[n].core_srv_conf) {
+                    virtual_names = 1;
+                    break;
+                }
+            }
+
+            /* if all server names point to the same server
+               then we do not need to check them at run time */
+            if (!virtual_names) {
+                in_addr[a].names.nelts = 0;
+            }
+        }
+
+        /* if there is binding to "*:XX" then we need to bind to "*:XX" only
+           and ignore other binding */
+        if (in_addr[a - 1].addr == INADDR_ANY) {
+            start = a - 1;
+
+        } else {
+            start = 0;
+        }
+
+        in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
+        for (a = start; a < in_port[p].addr.nelts; a++) {
+
+            ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets),
+                          NGX_CONF_ERROR);
+            ngx_memzero(ls, sizeof(ngx_listen_t));
+
+            ngx_test_null(addr_in,
+                          ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)),
+                          NGX_CONF_ERROR);
+
+            addr_in->sin_family = AF_INET;
+            addr_in->sin_addr.s_addr = in_addr[a].addr;
+            addr_in->sin_port = htons(in_port[p].port);
+
+            ngx_test_null(ls->addr_text.data,
+                          ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6),
+                          NGX_CONF_ERROR);
+
+            ls->addr_text.len =
+                ngx_snprintf(ls->addr_text.data
+                             + ngx_inet_ntop(AF_INET,
+                                             &in_addr[a].addr,
+                                             ls->addr_text.data,
+                                             INET_ADDRSTRLEN),
+                             6, ":%d", in_port[p].port);
+
+            ls->family = AF_INET;
+            ls->type = SOCK_STREAM;
+            ls->protocol = IPPROTO_IP;
+#if (NGX_OVERLAPPED)
+            ls->flags = WSA_FLAG_OVERLAPPED;
+#endif
+            ls->sockaddr = (struct sockaddr *) addr_in;
+            ls->socklen = sizeof(struct sockaddr_in);
+            ls->addr = offsetof(struct sockaddr_in, sin_addr);
+            ls->addr_text_max_len = INET_ADDRSTRLEN;
+            ls->backlog = -1;
+            ls->post_accept_timeout = ngx_http_post_accept_timeout;
+            ls->nonblocking = 1;
+
+            ls->handler = ngx_http_init_connection;
+            ls->log = cf->log;
+            ls->ctx = ctx;
+            ls->servers = &in_port[p].addr;
+
+            if (in_port[p].addr.nelts == 1) {
+                in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
+
+                if (in_addr[a].names.nelts == 0) {
+                    ls->ctx = in_addr->core_srv_conf->ctx;
+                    ls->servers = NULL;
+                }
+            }
+        }
+    }
+#endif
+
+    return NGX_CONF_OK;
+}
+
+
+#if 0
 /* STUB */
 
 static struct sockaddr_in  addr;
 static char addr_text[22];
 
-static ngx_http_server_t ngx_http_server;
 
 int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
 {
@@ -40,8 +368,8 @@ int ngx_http_init(ngx_pool_t *pool, ngx_
 
 
     ngx_http_config_modules(pool, ngx_modules);
+
 #if 0
-
     /* STUB */
     ngx_http_output_filter_set_stub(pool, ngx_http_modules);
     ngx_http_write_filter_set_stub(pool, ngx_http_modules);
@@ -49,9 +377,10 @@ int ngx_http_init(ngx_pool_t *pool, ngx_
 
     ngx_http_init_modules(pool, ngx_http_modules);
 #endif
+
     ngx_http_init_filters(pool, ngx_modules);
 
-    ls = ngx_push_array(ngx_listening_sockets);
+    ls = ngx_push_array(&ngx_listening_sockets);
     ngx_memzero(ls, sizeof(ngx_listen_t));
 
     addr.sin_family = AF_INET;
@@ -84,4 +413,5 @@ int ngx_http_init(ngx_pool_t *pool, ngx_
     return 1;
 }
 
-/* */
+/**/
+#endif
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -114,8 +114,8 @@ struct ngx_http_request_s {
 #endif
 
     void  **ctx;
+    void  **srv_conf;
     void  **loc_conf;
-    void  **srv_conf;
 
     ngx_pool_t  *pool;
     ngx_hunk_t  *header_in;
@@ -139,7 +139,6 @@ struct ngx_http_request_s {
     ngx_http_request_t *main;
 
     ngx_connection_t  *connection;
-    ngx_http_server_t *server;
 
     int       filter;
 
@@ -192,9 +191,9 @@ typedef struct {
     int      index;
 
     void  *(*create_srv_conf)(ngx_pool_t *p);
-    void  *(*init_srv_conf)(ngx_pool_t *p, void *conf);
+    char  *(*init_srv_conf)(ngx_pool_t *p, void *conf);
     void  *(*create_loc_conf)(ngx_pool_t *p);
-    void  *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf);
+    char  *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf);
 
     int    (*translate_handler)(ngx_http_request_t *r);
 
@@ -217,8 +216,8 @@ typedef struct {
 
 #define ngx_http_create_ctx(r, cx, module, size)                              \
             do {                                                              \
-               ngx_test_null(cx, ngx_pcalloc(r->pool, size), NGX_ERROR);      \
-               r->ctx[module.index] = cx;                                     \
+                ngx_test_null(cx, ngx_pcalloc(r->pool, size), NGX_ERROR);     \
+                r->ctx[module.index] = cx;                                    \
             } while (0)
 
 
@@ -237,9 +236,22 @@ int ngx_http_init_connection(ngx_connect
 int ngx_http_discard_body(ngx_http_request_t *r);
 
 
-extern int ngx_max_module;
+extern int  ngx_max_module;
+extern ngx_array_t  ngx_http_servers;
+
 
-extern ngx_http_module_t *ngx_http_modules[];
+extern int  ngx_http_post_accept_timeout;
+extern int  ngx_http_connection_pool_size;
+extern int  ngx_http_request_pool_size;
+extern int  ngx_http_client_header_timeout;
+extern int  ngx_http_client_header_buffer_size;
+extern int  ngx_http_discarded_buffer_size;
+
+extern int  ngx_http_lingering_timeout;
+extern int  ngx_http_lingering_time;
+
+
+extern ngx_http_module_t  *ngx_http_modules[];
 
 
 
deleted file mode 100644
--- a/src/http/ngx_http_config.c
+++ /dev/null
@@ -1,316 +0,0 @@
-
-/* TODO:
-    ngx_http_conf_ctx_t   ctx; on stack or in pool ? */
-
-
-#include <ngx_config.h>
-
-#include <ngx_core.h>
-#include <ngx_conf_file.h>
-
-#include <ngx_http.h>
-#include <ngx_http_core.h>
-#include <ngx_http_config.h>
-#include <ngx_http_write_filter.h>
-#include <ngx_http_output_filter.h>
-#include <ngx_http_index_handler.h>
-
-
-/* STUB */
-void **ngx_srv_conf;
-void **ngx_loc_conf;
-/**/
-
-
-static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
-static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
-
-
-void **null_loc_conf;
-
-
-static ngx_command_t  ngx_http_commands[] = {
-
-    {ngx_string("http"),
-     NGX_CONF_BLOCK|NGX_CONF_NOARGS,
-     ngx_http_block,
-     0,
-     0},
-
-    {ngx_string(""), 0, NULL, 0, 0}
-};
-
-
-ngx_module_t  ngx_http_module = {
-    NULL,                                  /* module context */
-    ngx_http_commands,                     /* module directives */
-    NGX_CORE_MODULE_TYPE,                  /* module type */
-    NULL                                   /* init module */
-};
-
-
-static ngx_command_t  ngx_http_core_commands[] = {
-
-    {ngx_string("server"),
-     NGX_CONF_BLOCK|NGX_CONF_NOARGS,
-     ngx_server_block,
-     NGX_HTTP_MODULE_TYPE,
-     0},
-
-    {ngx_string(""), 0, NULL, 0, 0}
-};
-
-
-static ngx_http_module_t  ngx_http_core_module_ctx = {
-    NGX_HTTP_MODULE,
-
-    NULL,                                  /* create server config */
-    NULL,                                  /* init server config */
-    NULL,                                  /* create location config */
-    NULL,                                  /* merge location config */
-
-    NULL,                                  /* translate handler */
-
-    NULL,                                  /* output header filter */
-    NULL,                                  /* next output header filter */
-    NULL,                                  /* output body filter */
-    NULL                                   /* next output body filter */
-};
-
-
-ngx_module_t  ngx_http_core_module = {
-    &ngx_http_core_module_ctx,             /* module context */
-    ngx_http_core_commands,                /* module directives */
-    NGX_HTTP_MODULE_TYPE,                  /* module type */
-    NULL                                   /* init module */
-};
-
-
-static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
-{
-    int  i;
-    ngx_http_module_t    *module;
-    ngx_http_conf_ctx_t   ctx;
-
-    for (i = 0; ngx_modules[i]; i++) {
-        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
-            continue;
-        }
-
-        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
-        module->index = ngx_http_max_module++;
-    }
-
-    ngx_test_null(null_loc_conf,
-                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
-                  NGX_CONF_ERROR);
-
-    ctx.srv_conf = NULL;
-    ctx.loc_conf = null_loc_conf;
-    ctx.locations = NULL;
-
-    for (i = 0; ngx_modules[i]; i++) {
-        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
-            continue;
-        }
-
-        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
-
-        if (module->create_loc_conf) {
-            ngx_test_null(null_loc_conf[module->index],
-                          module->create_loc_conf(cf->pool),
-                          NGX_CONF_ERROR);
-        }
-    }
-
-    cf->ctx = &ctx;
-    cf->type = NGX_HTTP_MODULE_TYPE;
-    return ngx_conf_parse(cf, NULL);
-}
-
-
-static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
-{
-    int    i, j;
-    char  *rv;
-    void                ***loc_conf;     /* YES! 3 stars */
-    ngx_http_module_t     *module;
-    ngx_http_conf_ctx_t   *ctx, *prev;
-
-    ngx_test_null(ctx,
-                  ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
-                  NGX_CONF_ERROR);
-
-    /* server config */
-    ngx_test_null(ctx->srv_conf,
-                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
-                  NGX_CONF_ERROR);
-
-    /* server location config */
-    ngx_test_null(ctx->loc_conf,
-                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
-                  NGX_CONF_ERROR);
-
-    for (i = 0; ngx_modules[i]; i++) {
-        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
-            continue;
-        }
-
-        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
-
-        if (module->create_srv_conf) {
-            ngx_test_null(ctx->srv_conf[module->index],
-                          module->create_srv_conf(cf->pool),
-                          NGX_CONF_ERROR);
-        }
-
-        if (module->create_loc_conf) {
-            ngx_test_null(ctx->loc_conf[module->index],
-                          module->create_loc_conf(cf->pool),
-                          NGX_CONF_ERROR);
-        }
-    }
-
-    prev = cf->ctx;
-    cf->ctx = ctx;
-    rv = ngx_conf_parse(cf, NULL);
-    cf->ctx = prev;
-
-    if (rv != NULL)
-        return rv;
-
-    for (i = 0; ngx_modules[i]; i++) {
-        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
-            continue;
-        }
-
-        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
-
-        if (module->init_srv_conf) {
-            if (module->init_srv_conf(cf->pool,
-                                      ctx->srv_conf[module->index])
-                                                           == NGX_CONF_ERROR) {
-                return NGX_CONF_ERROR;
-            }
-        }
-
-        if (module->merge_loc_conf) {
-            if (module->merge_loc_conf(cf->pool,
-                                       prev->loc_conf[module->index],
-                                       ctx->loc_conf[module->index])
-                                                           == NGX_CONF_ERROR) {
-                return NGX_CONF_ERROR;
-            }
-
-            loc_conf = (void ***)ctx->locations->elts;
-            for (j = 0; j < ctx->locations->nelts; j++) {
-                if (module->merge_loc_conf(cf->pool,
-                                           ctx->loc_conf[module->index],
-                                           loc_conf[j][module->index])
-                                                           == NGX_CONF_ERROR) {
-                    return NGX_CONF_ERROR;
-                }
-            }
-        }
-    }
-
-    return NULL;
-}
-
-
-#if 0
-int ngx_location_block(ngx_conf_t *cf)
-{
-    ngx_http_conf_ctx_t  *ctx, *prev;
-
-    ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
-                  NGX_ERROR);
-
-    ctx->srv_conf = cf->ctx->srv_conf;
-
-    ngx_test_null(ctx->loc_conf,
-                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_max_module),
-                  NGX_ERROR);
-
-    for (i = 0; modules[i]; i++) {
-        if (modules[i]->create_loc_conf)
-            ngx_test_null(ctx->loc_conf[i],
-                          modules[i]->create_loc_conf(cf->pool),
-                          NGX_ERROR);
-
-        if (ngx_http_core_module.index == i)
-            ctx->loc_conf[i].location = cf->args[0];
-    }
-
-    push
-
-    return ngx_conf_parse(cf);
-}
-
-#endif
-
-
-int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules)
-{
-    int i;
-    ngx_http_module_t  *module;
-
-    for (i = 0; modules[i]; i++) {
-        if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
-            continue;
-        }
-
-        module = (ngx_http_module_t *) modules[i]->ctx;
-        module->index = i;
-    }
-
-    ngx_http_max_module = i;
-
-#if 0
-    ngx_test_null(ngx_srv_conf,
-                  ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
-                  NGX_ERROR);
-    ngx_test_null(ngx_loc_conf,
-                  ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
-                  NGX_ERROR);
-
-    for (i = 0; modules[i]; i++) {
-        if (modules[i]->create_srv_conf)
-            ngx_srv_conf[i] = modules[i]->create_srv_conf(pool);
-
-        if (modules[i]->create_loc_conf)
-            ngx_loc_conf[i] = modules[i]->create_loc_conf(pool);
-    }
-#endif
-}
-
-
-void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules)
-{
-    int  i;
-    ngx_http_module_t  *module;
-    int (*ohf)(ngx_http_request_t *r);
-    int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch);
-
-    ohf = NULL;
-    obf = NULL;
-
-    for (i = 0; modules[i]; i++) {
-        if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
-            continue;
-        }
-
-        module = (ngx_http_module_t *) modules[i]->ctx;
-        if (module->output_header_filter) {
-            module->next_output_header_filter = ohf;
-            ohf = module->output_header_filter;
-        }
-
-        if (module->output_body_filter) {
-            module->next_output_body_filter = obf;
-            obf = module->output_body_filter;
-        }
-    }
-
-    ngx_http_top_header_filter = ohf;
-}
--- a/src/http/ngx_http_config.h
+++ b/src/http/ngx_http_config.h
@@ -9,12 +9,15 @@
 typedef struct {
     void        **srv_conf;
     void        **loc_conf;
-    ngx_array_t  *locations;
 } ngx_http_conf_ctx_t;
 
 
-#define NGX_HTTP_SRV_CONF  offsetof(ngx_http_conf_ctx_t, srv_conf)
-#define NGX_HTTP_LOC_CONF  offsetof(ngx_http_conf_ctx_t, loc_conf)
+#define NGX_HTTP_MAIN_CONF        0x1000000
+#define NGX_HTTP_SRV_CONF         0x2000000
+#define NGX_HTTP_LOC_CONF         0x6000000
+
+#define NGX_HTTP_SRV_CONF_OFFSET  offsetof(ngx_http_conf_ctx_t, srv_conf)
+#define NGX_HTTP_LOC_CONF_OFFSET  offsetof(ngx_http_conf_ctx_t, loc_conf)
 
 
 int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules);
rename from src/http/ngx_http_core.c
rename to src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core.c
+++ b/src/http/ngx_http_core_module.c
@@ -5,42 +5,66 @@
 #include <ngx_conf_file.h>
 
 #include <ngx_http.h>
-#include <ngx_http_core.h>
 #include <ngx_http_config.h>
+#include <ngx_http_core_module.h>
+
+#if 0
+#include <ngx_http_write_filter.h>
+#include <ngx_http_output_filter.h>
+#include <ngx_http_index_handler.h>
+#endif
 
 /* STUB */
+#include <ngx_http_output_filter.h>
 int ngx_http_static_handler(ngx_http_request_t *r);
 int ngx_http_index_handler(ngx_http_request_t *r);
 int ngx_http_proxy_handler(ngx_http_request_t *r);
 /**/
 
+
+static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
+static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
+                                                                  char *dummy);
 static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool);
+static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf);
 static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool);
-static int ngx_http_core_translate_handler(ngx_http_request_t *r);
 
 
-int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
+static ngx_command_t  ngx_http_core_commands[] = {
+
+    {ngx_string("server"),
+     NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
+     ngx_server_block,
+     0,
+     0},
 
-int ngx_http_max_module;
+    {ngx_string("location"),
+     NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
+     ngx_location_block,
+     0,
+     0},
 
-#if 0
-static ngx_command_t ngx_http_core_commands[] = {
+    {ngx_string("root"),
+     NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
+     ngx_conf_set_str_slot,
+     NGX_HTTP_LOC_CONF_OFFSET,
+     offsetof(ngx_http_core_loc_conf_t, doc_root)},
 
     {ngx_string("send_timeout"),
-     NGX_CONF_TAKE1, 
+     NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
      ngx_conf_set_time_slot,
-     NGX_HTTP_LOC_CONF,
+     NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_core_loc_conf_t, send_timeout)},
 
     {ngx_string(""), 0, NULL, 0, 0}
 };
-#endif
+
 
 ngx_http_module_t  ngx_http_core_module_ctx = {
     NGX_HTTP_MODULE,
 
     ngx_http_core_create_srv_conf,         /* create server config */
-    NULL,                                  /* init server config */
+    ngx_http_core_init_srv_conf,           /* init server config */
     ngx_http_core_create_loc_conf,         /* create location config */
     NULL,                                  /* merge location config */
 
@@ -49,28 +73,39 @@ ngx_http_module_t  ngx_http_core_module_
     NULL,                                  /* output header filter */
     NULL,                                  /* next output header filter */
     NULL,                                  /* output body filter */
-    NULL,                                  /* next output body filter */
+    NULL                                   /* next output body filter */
 };
 
-#if 0
+
 ngx_module_t  ngx_http_core_module = {
+    0,                                     /* module index */
     &ngx_http_core_module_ctx,             /* module context */
     ngx_http_core_commands,                /* module directives */
     NGX_HTTP_MODULE_TYPE,                  /* module type */
     NULL                                   /* init module */
 };
-#endif
+
 
 int ngx_http_handler(ngx_http_request_t *r)
 {
     int  rc, i;
-    ngx_http_module_t *module;
+    ngx_http_module_t    *module;
+    ngx_http_conf_ctx_t  *ctx;
 
     r->connection->unexpected_eof = 0;
     r->lingering_close = 1;
     r->keepalive = 0;
 
-#if 0
+    ctx = (ngx_http_conf_ctx_t *) r->connection->ctx;
+    r->srv_conf = ctx->srv_conf;
+    r->loc_conf = ctx->loc_conf;
+
+ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf);
+ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf);
+ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers);
+
+
+#if 1
     r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
 #endif
 
@@ -81,6 +116,7 @@ int ngx_http_handler(ngx_http_request_t 
         }
 
         module = (ngx_http_module_t *) ngx_modules[i]->ctx;
+
         if (module->translate_handler == NULL) {
             continue;
         }
@@ -105,13 +141,36 @@ int ngx_http_handler(ngx_http_request_t 
 }
 
 
-static int ngx_http_core_translate_handler(ngx_http_request_t *r)
+int ngx_http_core_translate_handler(ngx_http_request_t *r)
 {
-    char      *loc, *last;
-    ngx_err_t  err;
-    ngx_table_elt_t  *h;
+    int                         i, rc;
+    char                       *location, *last;
+    ngx_err_t                   err;
+    ngx_table_elt_t            *h;
+    ngx_http_core_srv_conf_t   *scf;
+    ngx_http_core_loc_conf_t  **lcf, *loc_conf;
+
+    scf = (ngx_http_core_srv_conf_t *)
+                     ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx);
 
-    /* TODO: find location conf */
+    /* find location config */
+    lcf = (ngx_http_core_loc_conf_t **) scf->locations.elts;
+    for (i = 0; i < scf->locations.nelts; i++) {
+ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data);
+         if (r->uri.len < lcf[i]->name.len) {
+             continue;
+         }
+
+         rc = ngx_strncmp(r->uri.data, lcf[i]->name.data, lcf[i]->name.len);
+
+         if (rc < 0) {
+             break;
+         }
+
+         if (rc == 0) {
+             r->loc_conf = lcf[i]->loc_conf;
+         }
+    }
 
     if (r->uri.data[r->uri.len - 1] == '/') {
         /* TODO: find index handler */
@@ -120,15 +179,18 @@ static int ngx_http_core_translate_handl
         return NGX_OK;
     }
 
-    r->file.name.len = r->server->doc_root_len + r->uri.len + 2;
+    loc_conf = (ngx_http_core_loc_conf_t *)
+                     ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
+
+    r->file.name.len = loc_conf->doc_root.len + r->uri.len;
 
     ngx_test_null(r->file.name.data,
                   ngx_palloc(r->pool, r->file.name.len + 1),
                   NGX_HTTP_INTERNAL_SERVER_ERROR);
 
-    loc = ngx_cpystrn(r->file.name.data, r->server->doc_root,
-                      r->server->doc_root_len);
-    last = ngx_cpystrn(loc, r->uri.data, r->uri.len + 1);
+    location = ngx_cpystrn(r->file.name.data, loc_conf->doc_root.data,
+                           loc_conf->doc_root.len + 1);
+    last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1);
 
     ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _
                   r->file.name.data);
@@ -139,10 +201,6 @@ static int ngx_http_core_translate_handl
        one syscall: Win9X has not FILE_FLAG_BACKUP_SEMANTICS flag.
        so we need to check its type before opening */
 
-#if 0 /* OLD: ngx_file_type() is to be removed */
-    if (ngx_file_type(r->file.name.data, &r->file.info) == -1) {
-#endif
-
     r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
     if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
         err = ngx_errno;
@@ -173,6 +231,10 @@ static int ngx_http_core_translate_handl
 
         if (err == NGX_ENOENT) {
             return NGX_HTTP_NOT_FOUND;
+#if (WIN32)
+        } else if (err == ERROR_PATH_NOT_FOUND) {
+            return NGX_HTTP_NOT_FOUND;
+#endif
         } else {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
@@ -217,8 +279,8 @@ static int ngx_http_core_translate_handl
         *last = '\0';
         h->key.len = 8;
         h->key.data = "Location" ;
-        h->value.len = last - loc;
-        h->value.data = loc;
+        h->value.len = last - location;
+        h->value.data = location;
         r->headers_out.location = h;
 
         return NGX_HTTP_MOVED_PERMANENTLY;
@@ -307,29 +369,342 @@ int ngx_http_internal_redirect(ngx_http_
 }
 
 
+#if 0
+void *ngx_http_find_server_conf(ngx_http_request_t *r)
+{
+    int  i;
+    ngx_http_listen_t       *fs, *ls;
+    ngx_http_server_name_t  *n;
+
+    fs = NULL;
+    ls = (ngx_http_listen_t *) http->ports.elts;
+
+    for (i = 0; i < http->ports.nelts; i++) {
+        if (s->family != ls[i].family || s->port != ls[i].port) {
+            continue;
+        }
+
+        if (s->family == AF_INET) {
+
+            if (ls[i].addr == INADDR_ANY || ls[i].addr == s->addr) {
+                fs = &ls[i];
+                break;
+            }
+
+        } else {
+            /* STUB: AF_INET only */
+        }
+    }
+
+    if (fs == NULL) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "unknown local socket %s:%d",
+                      s->addr_text.data, s->port);
+        return NULL;
+    }
+
+    if (r->headers_in.host && fs->server_names.nelts) {
+
+        n = (ngx_http_server_name_t *) fs->server_names.elts;
+        for (i = 0; i < fs->server_names.nelts; i++) {
+            if (r->headers_in.host->value.len != n[i].name.len) {
+                continue;
+            }
+
+            if (ngx_strcmp(r->headers_in.host->value.data, n[i].name.data) == 0)            {
+                return n[i].srv_conf;
+            }
+        }
+    }
+
+    return fs->srv_conf;
+}
+#endif
+
+
+static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
+{
+    int                        i, j;
+    char                      *rv;
+    ngx_http_module_t         *module;
+    ngx_http_conf_ctx_t       *ctx, *prev;
+    ngx_http_core_srv_conf_t  *scf;
+    ngx_http_core_loc_conf_t **lcf;
+
+    ngx_test_null(ctx,
+                  ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
+                  NGX_CONF_ERROR);
+
+    /* server config */
+    ngx_test_null(ctx->srv_conf,
+                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
+                  NGX_CONF_ERROR);
+
+    /* server location config */
+    ngx_test_null(ctx->loc_conf,
+                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
+                  NGX_CONF_ERROR);
+
+    for (i = 0; ngx_modules[i]; i++) {
+        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
+
+        if (module->create_srv_conf) {
+            ngx_test_null(ctx->srv_conf[module->index],
+                          module->create_srv_conf(cf->pool),
+                          NGX_CONF_ERROR);
+ngx_log_debug(cf->log, "srv_conf: %d:%0x" _
+              module->index _ ctx->loc_conf[module->index]);
+        }
+
+        if (module->create_loc_conf) {
+            ngx_test_null(ctx->loc_conf[module->index],
+                          module->create_loc_conf(cf->pool),
+                          NGX_CONF_ERROR);
+ngx_log_debug(cf->log, "srv loc_conf: %d:%0x" _
+              module->index _ ctx->loc_conf[module->index]);
+        }
+    }
+
+    prev = cf->ctx;
+    cf->ctx = ctx;
+    rv = ngx_conf_parse(cf, NULL);
+    cf->ctx = prev;
+
+    if (rv != NGX_CONF_OK)
+        return rv;
+
+
+    scf = ctx->srv_conf[ngx_http_core_module_ctx.index];
+    scf->ctx = ctx;
+
+    lcf = (ngx_http_core_loc_conf_t **)scf->locations.elts;
+
+    for (i = 0; ngx_modules[i]; i++) {
+        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
+
+        if (module->init_srv_conf) {
+            if (module->init_srv_conf(cf->pool,
+                                      ctx->srv_conf[module->index])
+                                                           == NGX_CONF_ERROR) {
+                return NGX_CONF_ERROR;
+            }
+        }
+
+        if (module->merge_loc_conf) {
+            if (module->merge_loc_conf(cf->pool,
+                                       prev->loc_conf[module->index],
+                                       ctx->loc_conf[module->index])
+                                                           == NGX_CONF_ERROR) {
+                return NGX_CONF_ERROR;
+            }
+
+            for (j = 0; j < scf->locations.nelts; j++) {
+ngx_log_debug(cf->log, "%d:%0x" _ j _ lcf[j]);
+ngx_log_debug(cf->log, "%d:'%s'" _ lcf[j]->name.len _ lcf[j]->name.data);
+                if (module->merge_loc_conf(cf->pool,
+                                           ctx->loc_conf[module->index],
+                                           lcf[j]->loc_conf[module->index])
+                                                           == NGX_CONF_ERROR) {
+                    return NGX_CONF_ERROR;
+                }
+            }
+        }
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
+{
+    int                        i;
+    char                      *rv;
+    void                     **loc;
+    ngx_str_t                 *location;
+    ngx_http_module_t         *module;
+    ngx_http_conf_ctx_t       *ctx, *prev;
+    ngx_http_core_srv_conf_t  *scf;
+    ngx_http_core_loc_conf_t  *lcf;
+
+    ngx_test_null(ctx,
+                  ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
+                  NGX_CONF_ERROR);
+
+    prev = (ngx_http_conf_ctx_t *) cf->ctx;
+    ctx->srv_conf = prev->srv_conf;
+
+    ngx_test_null(ctx->loc_conf,
+                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
+                  NGX_CONF_ERROR);
+
+    for (i = 0; ngx_modules[i]; i++) {
+        if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        module = (ngx_http_module_t *) ngx_modules[i]->ctx;
+
+        if (module->create_loc_conf) {
+            ngx_test_null(ctx->loc_conf[module->index],
+                          module->create_loc_conf(cf->pool),
+                          NGX_CONF_ERROR);
+ngx_log_debug(cf->log, "loc_conf: %d:%0x" _
+              module->index _ ctx->loc_conf[module->index]);
+        }
+    }
+
+    lcf = (ngx_http_core_loc_conf_t *)
+                                 ctx->loc_conf[ngx_http_core_module_ctx.index];
+    location = (ngx_str_t *) cf->args->elts;
+    lcf->name.len = location[1].len;
+    lcf->name.data = location[1].data;
+    lcf->loc_conf = ctx->loc_conf;
+
+    scf = (ngx_http_core_srv_conf_t *)
+                                 ctx->srv_conf[ngx_http_core_module_ctx.index];
+    ngx_test_null(loc, ngx_push_array(&scf->locations), NGX_CONF_ERROR);
+    *loc = lcf;
+
+ngx_log_debug(cf->log, "%0x:%s" _ lcf _ lcf->name.data);
+
+    cf->ctx = ctx;
+    rv = ngx_conf_parse(cf, NULL);
+    cf->ctx = prev;
+
+    return rv;
+}
+
+
+int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules)
+{
+    int i;
+    ngx_http_module_t  *module;
+
+    for (i = 0; modules[i]; i++) {
+        if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        module = (ngx_http_module_t *) modules[i]->ctx;
+        module->index = i;
+    }
+
+    ngx_http_max_module = i;
+
+#if 0
+    ngx_test_null(ngx_srv_conf,
+                  ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
+                  NGX_ERROR);
+    ngx_test_null(ngx_loc_conf,
+                  ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
+                  NGX_ERROR);
+
+    for (i = 0; modules[i]; i++) {
+        if (modules[i]->create_srv_conf)
+            ngx_srv_conf[i] = modules[i]->create_srv_conf(pool);
+
+        if (modules[i]->create_loc_conf)
+            ngx_loc_conf[i] = modules[i]->create_loc_conf(pool);
+    }
+#endif
+}
+
+
+void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules)
+{
+    int  i;
+    ngx_http_module_t  *module;
+    int (*ohf)(ngx_http_request_t *r);
+    int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch);
+
+    ohf = NULL;
+    obf = NULL;
+
+    for (i = 0; modules[i]; i++) {
+        if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
+            continue;
+        }
+
+        module = (ngx_http_module_t *) modules[i]->ctx;
+
+        if (module->output_header_filter) {
+            module->next_output_header_filter = ohf;
+            ohf = module->output_header_filter;
+        }
+
+        if (module->output_body_filter) {
+            module->next_output_body_filter = obf;
+            obf = module->output_body_filter;
+        }
+    }
+
+    ngx_http_top_header_filter = ohf;
+}
+
+
 static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool)
 {
-    ngx_http_core_srv_conf_t *conf;
+    ngx_http_core_srv_conf_t *scf, **cf;
+
+    ngx_test_null(scf,
+                  ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), 
+                  NGX_CONF_ERROR);
+
+    ngx_init_array(scf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR);
+    ngx_init_array(scf->listen, pool, 5, sizeof(ngx_http_listen_t),
+                   NGX_CONF_ERROR);
+
+    ngx_test_null(cf, ngx_push_array(&ngx_http_servers), NGX_CONF_ERROR);
+    *cf = scf;
+
+    return scf;
+}
+
 
-    ngx_test_null(conf,
-                  ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)),
-                  NULL);
+static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf)
+{
+    ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf;
+
+    ngx_http_listen_t        *l;
 
-    return conf;
+    if (scf->listen.nelts == 0) {
+        ngx_test_null(l, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
+        l->addr = INADDR_ANY;
+        l->port = 8000;
+        l->family = AF_INET;
+    }
+
+    return NGX_CONF_OK;
 }
 
+
 static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool)
 {
-    ngx_http_core_loc_conf_t *conf;
+    ngx_http_core_loc_conf_t *lcf;
+
+    ngx_test_null(lcf,
+                  ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), 
+                  NGX_CONF_ERROR);
 
-    ngx_test_null(conf,
-                  ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)),
-                  NULL);
+    lcf->doc_root.len = 4;
+    lcf->doc_root.data = "html";
 
-    conf->send_timeout = 10;
+    lcf->send_timeout = 10;
+    lcf->discarded_buffer_size = 1500;
+    lcf->lingering_time = 30;
+    lcf->lingering_timeout = 5000;
+
 /*
-    conf->send_timeout = NGX_CONF_UNSET;
+    lcf->send_timeout = NGX_CONF_UNSET;
 */
 
-    return conf;
+    return lcf;
 }
rename from src/http/ngx_http_core.h
rename to src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core.h
+++ b/src/http/ngx_http_core_module.h
@@ -2,24 +2,75 @@
 #define _NGX_HTTP_CORE_H_INCLUDED_
 
 
+#include <ngx_string.h>
+#include <ngx_array.h>
 #include <ngx_http.h>
 
 
 typedef struct {
-    int dummy;
-} ngx_http_core_conf_t;
+    int               addr;
+    int               port;
+    int               family;
+    int               flags;             /* 'default' */
+    ngx_conf_file_t  *conf_file;
+    int               line;
+} ngx_http_listen_t;
 
 
 typedef struct {
-    int dummy;
+    ngx_array_t  locations;    /* array of ngx_http_core_loc_conf_t */
+
+    ngx_array_t  listen;       /* 'listen', array of ngx_http_listen_t */
+    ngx_array_t  server_names; /* 'server_name',
+                                  array of ngx_http_server_name_t */
+    ngx_http_conf_ctx_t *ctx;
 } ngx_http_core_srv_conf_t;
 
 
 typedef struct {
-    time_t  send_timeout;
+    ngx_str_t                name;
+    ngx_http_core_srv_conf_t  *core_srv_conf;
+} ngx_http_server_name_t;
+
+
+typedef struct {
+    int           port;
+    ngx_array_t   addr;
+} ngx_http_in_port_t;
+
+typedef struct {
+    u_int32_t                  addr;
+    ngx_array_t                names;
+    int                        flags;
+    ngx_http_core_srv_conf_t  *core_srv_conf;
+} ngx_http_in_addr_t;
+
+#define NGX_HTTP_DEFAULT_SERVER  1
+
+
+
+typedef struct {
+    ngx_str_t   name;          /* location name */
+    void      **loc_conf;      /* used in translation handler */
+
+    ngx_str_t   doc_root;      /* 'root' */
+
+    time_t      send_timeout;  /* 'send_timeout' */
+    size_t      discarded_buffer_size;   /* 'discarded_buffer_size */
+    time_t      lingering_time;          /* 'lingering_time */
+    ngx_msec_t  lingering_timeout;       /* 'lingering_timeout */
 } ngx_http_core_loc_conf_t;
 
 
+
+
+#if 0
+typedef struct {
+    int dummy;
+} ngx_http_core_conf_t;
+#endif
+
+
 extern ngx_http_module_t  ngx_http_core_module_ctx;
 extern ngx_module_t  ngx_http_core_module;
 
@@ -27,4 +78,9 @@ extern int (*ngx_http_top_header_filter)
 extern int ngx_http_max_module;
 
 
+
+int ngx_http_core_translate_handler(ngx_http_request_t *r);
+
+
+
 #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -12,7 +12,7 @@
 #include <ngx_inet.h>
 #include <ngx_http.h>
 #include <ngx_http_config.h>
-#include <ngx_http_core.h>
+#include <ngx_http_core_module.h>
 
 /* STUB */
 #include <ngx_http_output_filter.h>
@@ -75,16 +75,13 @@ int ngx_http_init_connection(ngx_connect
 {
     ngx_event_t         *ev;
     struct sockaddr     *addr;
-    ngx_http_server_t   *srv;
     ngx_http_log_ctx_t  *ctx;
 
     ev = c->read;
     ev->event_handler = ngx_http_init_request;
 
-    srv = (ngx_http_server_t *) c->server;
-
     ngx_test_null(c->pool,
-                  ngx_create_pool(srv->connection_pool_size, ev->log),
+                  ngx_create_pool(ngx_http_connection_pool_size, ev->log),
                   NGX_ERROR);
 
     ngx_test_null(c->requests, ngx_create_array(c->pool, 10, sizeof(char *)),
@@ -97,12 +94,12 @@ int ngx_http_init_connection(ngx_connect
     ngx_memcpy(addr, c->sockaddr, c->socklen);
     c->sockaddr = addr;
 
-    ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len),
+    ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text_max_len),
                   NGX_ERROR);
 
     c->addr_text.len = ngx_inet_ntop(c->family,
                                      (char *)c->sockaddr + c->addr,
-                                     c->addr_text.data, c->addr_text.len);
+                                     c->addr_text.data, c->addr_text_max_len);
     if (c->addr_text.len == 0)
        return NGX_ERROR;
 
@@ -118,7 +115,6 @@ int ngx_http_init_connection(ngx_connect
         return ngx_http_init_request(ev);
     } else {
 #endif
-        /* STUB: post_accept_timeout should be in http_conf */
         ngx_add_timer(ev, c->post_accept_timeout);
 #if (USE_KQUEUE)
         return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
@@ -143,29 +139,22 @@ int ngx_http_init_connection(ngx_connect
 
 static int ngx_http_init_request(ngx_event_t *ev)
 {
-    ngx_connection_t    *c;
-    ngx_http_server_t   *srv;
-    ngx_http_request_t  *r;
+    ngx_connection_t     *c;
+    ngx_http_request_t   *r;
 
     c = (ngx_connection_t *) ev->data;
-    srv = (ngx_http_server_t *) c->server;
 
     ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)),
                   NGX_ERROR);
 
     c->data = r;
     r->connection = c;
-    r->server = srv;
     r->file.fd = NGX_INVALID_FILE;
 
-    /* STUB */
-    r->srv_conf = ngx_srv_conf;
-    r->loc_conf = ngx_loc_conf;
-    /**/
-
     if (c->buffer == NULL) {
         ngx_test_null(c->buffer,
-                      ngx_create_temp_hunk(c->pool, srv->header_buffer_size,
+                      ngx_create_temp_hunk(c->pool,
+                                           ngx_http_client_header_buffer_size,
                                            0, 0),
                       NGX_ERROR);
     } else {
@@ -174,7 +163,7 @@ static int ngx_http_init_request(ngx_eve
 
     r->header_in = c->buffer;
 
-    ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log),
+    ngx_test_null(r->pool, ngx_create_pool(ngx_http_request_pool_size, ev->log),
                   ngx_http_close_request(r));
 
     ngx_test_null(r->ctx,
@@ -218,9 +207,7 @@ static int ngx_http_process_request_head
             if (r->header_timeout) {
                 r->header_timeout = 0;
                 ngx_del_timer(ev);
-                /* STUB: r->server->header_timeout
-                         OR r->srv_conf->header_timeout ? */
-                ngx_add_timer(ev, r->server->header_timeout);
+                ngx_add_timer(ev, ngx_http_client_header_timeout);
             }
             return NGX_AGAIN;
         }
@@ -254,7 +241,7 @@ static int ngx_http_process_request_head
     if (r->header_timeout) {
         r->header_timeout = 0;
         ngx_del_timer(ev);
-        ngx_add_timer(ev, r->server->header_timeout);
+        ngx_add_timer(ev, ngx_http_client_header_timeout);
     }
 
     if (rc == NGX_OK)
@@ -591,25 +578,29 @@ static int ngx_http_read_discarded_body(
 {
     size_t   size;
     ssize_t  n;
-    ngx_connection_t    *c;
-    ngx_http_request_t  *r;
-
-    c = (ngx_connection_t *) ev->data;
-    r = (ngx_http_request_t *) c->data;
+    ngx_connection_t          *c;
+    ngx_http_request_t        *r;
+    ngx_http_core_loc_conf_t  *lcf;
 
     ngx_log_debug(ev->log, "http read discarded body");
 
     if (ev->timedout)
         return NGX_ERROR;
 
+    c = (ngx_connection_t *) ev->data;
+    r = (ngx_http_request_t *) c->data;
+
+    lcf = (ngx_http_core_loc_conf_t *)
+                     ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
+
     if (r->discarded_buffer == NULL)
         ngx_test_null(r->discarded_buffer,
-                      ngx_palloc(r->pool, r->server->discarded_buffer_size),
+                      ngx_palloc(r->pool, lcf->discarded_buffer_size),
                       NGX_ERROR);
 
     size = r->client_content_length;
-    if (size > r->server->discarded_buffer_size)
-        size = r->server->discarded_buffer_size;
+    if (size > lcf->discarded_buffer_size)
+        size = lcf->discarded_buffer_size;
 
     n = ngx_event_recv(c, r->discarded_buffer, size);
     if (n == NGX_ERROR)
@@ -624,34 +615,6 @@ static int ngx_http_read_discarded_body(
 }
 
 
-#if 0
-static int ngx_http_discarded_read(ngx_event_t *ev)
-{
-    ssize_t n;
-    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 discarded read");
-
-    if (ev->timedout)
-        return NGX_ERROR;
-
-    if (r->discarded_buffer == NULL)
-        ngx_test_null(r->discarded_buffer,
-                      ngx_palloc(r->pool, r->server->discarded_buffer_size),
-                      NGX_ERROR);
-
-    n = ngx_event_recv(c, r->discarded_buffer,
-                       r->server->discarded_buffer_size);
-
-    return n;
-}
-#endif
-
-
 static int ngx_http_keepalive_handler(ngx_event_t *ev)
 {
     ssize_t n;
@@ -690,11 +653,16 @@ static int ngx_http_keepalive_handler(ng
 
 static int ngx_http_set_lingering_close(ngx_http_request_t *r)
 {
-    r->lingering_time = ngx_time() + r->server->lingering_time;
+    ngx_http_core_loc_conf_t  *lcf;
+
+    lcf = (ngx_http_core_loc_conf_t *)
+                     ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
+
+    r->lingering_time = ngx_time() + lcf->lingering_time;
     r->connection->read->event_handler = ngx_http_lingering_close_handler;
 
     ngx_del_timer(r->connection->read);
-    ngx_add_timer(r->connection->read, r->server->lingering_timeout);
+    ngx_add_timer(r->connection->read, lcf->lingering_timeout);
 
     if (r->connection->read->blocked) {
         if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
@@ -725,9 +693,7 @@ static int ngx_http_lingering_close_hand
     ngx_msec_t           timer;
     ngx_connection_t    *c;
     ngx_http_request_t  *r;
-
-    c = (ngx_connection_t *) ev->data;
-    r = (ngx_http_request_t *) c->data;
+    ngx_http_core_loc_conf_t  *lcf;
 
     ngx_log_debug(ev->log, "http lingering close handler");
 
@@ -735,25 +701,30 @@ static int ngx_http_lingering_close_hand
         return ngx_http_close_request(r);
     }
 
+    c = (ngx_connection_t *) ev->data;
+    r = (ngx_http_request_t *) c->data;
+
     timer = r->lingering_time - ngx_time();
     if (timer <= 0) {
         return ngx_http_close_request(r);
     }
 
+    lcf = (ngx_http_core_loc_conf_t *)
+                     ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
+
     if (r->discarded_buffer == NULL) {
         if (r->header_in->end - r->header_in->last.mem
-                                         >= r->server->discarded_buffer_size) {
+                                               >= lcf->discarded_buffer_size) {
             r->discarded_buffer = r->header_in->last.mem;
 
         } else {
             ngx_test_null(r->discarded_buffer,
-                          ngx_palloc(c->pool, r->server->discarded_buffer_size),
+                          ngx_palloc(c->pool, lcf->discarded_buffer_size),
                           ngx_http_close_request(r));
         }
     }
 
-    n = ngx_event_recv(c, r->discarded_buffer,
-                       r->server->discarded_buffer_size);
+    n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size);
 
     ngx_log_debug(ev->log, "lingering read: %d" _ n);
 
@@ -762,8 +733,8 @@ static int ngx_http_lingering_close_hand
     }
 
     timer *= 1000;
-    if (timer > r->server->lingering_timeout) {
-        timer = r->server->lingering_timeout;
+    if (timer > lcf->lingering_timeout) {
+        timer = lcf->lingering_timeout;
     }
 
     ngx_del_timer(ev);
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -34,6 +34,7 @@ ngx_http_module_t  ngx_http_header_filte
 
 
 ngx_module_t  ngx_http_header_filter_module = {
+    0,                                     /* module index */
     &ngx_http_header_filter_module_ctx,    /* module context */
     NULL,                                  /* module directives */
     NGX_HTTP_MODULE_TYPE,                  /* module type */
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -14,14 +14,16 @@
 
 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
 static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool);
+static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool,
+                                               void *parent, void *child);
 
 
 static ngx_command_t  ngx_http_output_filter_commands[] = {
 
     {ngx_string("output_buffer"),
-     NGX_CONF_TAKE1,
+     NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
      ngx_conf_set_size_slot,
-     NGX_HTTP_LOC_CONF,
+     NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_output_filter_conf_t, hunk_size)},
 
     {ngx_string(""), 0, NULL, 0, 0}
@@ -34,7 +36,7 @@ static ngx_http_module_t  ngx_http_outpu
     NULL,                                  /* create server config */
     NULL,                                  /* init server config */
     ngx_http_output_filter_create_conf,    /* create location config */
-    NULL,                                  /* merge location config */
+    ngx_http_output_filter_merge_conf,     /* merge location config */
 
     NULL,                                  /* translate handler */
 
@@ -47,6 +49,7 @@ static ngx_http_module_t  ngx_http_outpu
 
 
 ngx_module_t  ngx_http_output_filter_module = {
+    0,                                     /* module index */
     &ngx_http_output_filter_module_ctx,    /* module context */
     ngx_http_output_filter_commands,       /* module directives */
     NGX_HTTP_MODULE_TYPE,                  /* module type */
@@ -249,7 +252,7 @@ int ngx_http_output_filter(ngx_http_requ
         if (ctx->hunk) {
             ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
         }
-#if (!NGX_ONESHOT_EVENT)
+#if (NGX_LEVEL_EVENT)
         ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
 #endif
     }
@@ -315,3 +318,17 @@ static void *ngx_http_output_filter_crea
 
     return conf;
 }
+
+
+static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool,
+                                               void *parent, void *child)
+{
+    ngx_http_output_filter_conf_t *prev =
+                                      (ngx_http_output_filter_conf_t *) parent;
+    ngx_http_output_filter_conf_t *conf =
+                                       (ngx_http_output_filter_conf_t *) child;
+
+    ngx_conf_merge(conf->hunk_size, prev->hunk_size, 32768);
+
+    return NULL;
+}
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -43,33 +43,39 @@ printf("\nstate: %d, pos: %x, end: %x, c
         case sw_start:
             switch (ch) {
             case 'G':
-                if (p + 1 >= r->header_in->last.mem)
+                if (p + 1 >= r->header_in->last.mem) {
                     return NGX_AGAIN;
+                }
 
-                if (*p != 'E' || *(p + 1) != 'T')
+                if (*p != 'E' || *(p + 1) != 'T') {
                     return NGX_HTTP_PARSE_INVALID_METHOD;
+                }
 
                 r->method = NGX_HTTP_GET;
                 p += 2;
                 break;
 
             case 'H':
-                if (p + 2 >= r->header_in->last.mem)
+                if (p + 2 >= r->header_in->last.mem) {
                     return NGX_AGAIN;
+                }
 
-                if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D')
+                if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D') {
                     return NGX_HTTP_PARSE_INVALID_METHOD;
+                }
 
                 r->method = NGX_HTTP_HEAD;
                 p += 3;
                 break;
 
             case 'P':
-                if (p + 2 >= r->header_in->last.mem)
+                if (p + 2 >= r->header_in->last.mem) {
                     return NGX_AGAIN;
+                }
 
-                if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T')
+                if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T') {
                     return NGX_HTTP_PARSE_INVALID_METHOD;
+                }
 
                 r->method = NGX_HTTP_POST;
                 p += 3;
@@ -226,8 +232,9 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 return NGX_AGAIN;
             }
 
-            if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/')
+            if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/') {
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
 
             p += 3;
             state = sw_first_major_digit;
@@ -235,8 +242,9 @@ printf("\nstate: %d, pos: %x, end: %x, c
 
         /* first digit of major HTTP version */
         case sw_first_major_digit:
-            if (ch < '1' || ch > '9')
+            if (ch < '1' || ch > '9') {
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
 
             r->http_major = ch - '0';
             state = sw_major_digit;
@@ -249,16 +257,18 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 break;
             }
 
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
 
             r->http_major = r->http_major * 10 + ch - '0';
             break;
 
         /* first digit of minor HTTP version */
         case sw_first_minor_digit:
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
 
             r->http_minor = ch - '0';
             state = sw_minor_digit;
@@ -276,8 +286,9 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 break;
             }
 
-            if (ch < '0' || ch > '9')
+            if (ch < '0' || ch > '9') {
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
 
             r->http_minor = r->http_minor * 10 + ch - '0';
             break;
@@ -299,14 +310,19 @@ printf("\nstate: %d, pos: %x, end: %x, c
     r->header_in->pos.mem = p;
 
     if (state == sw_done) {
-        if (r->request_end == NULL)
+        if (r->request_end == NULL) {
             r->request_end = p - 1;
+        }
+
         r->http_version = r->http_major * 1000 + r->http_minor;
         r->state = sw_start;
-        if (r->http_version == 9 && r->method == NGX_HTTP_HEAD)
+
+        if (r->http_version == 9 && r->method == NGX_HTTP_HEAD) {
             return NGX_HTTP_PARSE_INVALID_HEAD;
-        else
+        } else {
             return NGX_OK;
+        }
+
     } else {
         r->state = state;
         return NGX_AGAIN;
@@ -358,14 +374,17 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 r->header_name_start = p - 1;
 
                 c = ch | 0x20;
-                if (c >= 'a' && c <= 'z')
+                if (c >= 'a' && c <= 'z') {
                     break;
+                }
 
-                if (ch == '-')
+                if (ch == '-') {
                     break;
+                }
 
-                if (ch >= '0' && ch <= '9')
+                if (ch >= '0' && ch <= '9') {
                     break;
+                }
 
                 return NGX_HTTP_PARSE_INVALID_HEADER;
 
@@ -375,8 +394,9 @@ printf("\nstate: %d, pos: %x, end: %x, c
         /* header name */
         case sw_name:
             c = ch | 0x20;
-            if (c >= 'a' && c <= 'z')
+            if (c >= 'a' && c <= 'z') {
                 break;
+            }
 
             if (ch == ':') {
                 r->header_name_end = p - 1;
@@ -384,11 +404,13 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 break;
             }
 
-            if (ch == '-')
+            if (ch == '-') {
                 break;
+            }
 
-            if (ch >= '0' && ch <= '9')
+            if (ch >= '0' && ch <= '9') {
                 break;
+            }
 
             return NGX_HTTP_PARSE_INVALID_HEADER;
 
@@ -476,9 +498,11 @@ printf("\nstate: %d, pos: %x, end: %x, c
     if (state == sw_done) {
         r->state = sw_start;
         return NGX_OK;
+
     } else if (state == sw_header_done) {
         r->state = sw_start;
         return NGX_HTTP_PARSE_HEADER_DONE;
+
     } else {
         r->state = state;
         return NGX_AGAIN;
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -21,8 +21,9 @@ time_t ngx_http_parse_time(char *value, 
     end = value + len;
 
     for (p = value; p < end; p++) {
-        if (*p == ',')
+        if (*p == ',') {
             break;
+        }
 
         if (*p == ' ') {
             fmt = isoc;
@@ -31,22 +32,26 @@ time_t ngx_http_parse_time(char *value, 
     }
 
     for (p++; p < end; p++)
-        if (*p != ' ')
+        if (*p != ' ') {
             break;
+        }
 
-    if (end - p < 18)
+    if (end - p < 18) {
         return NGX_ERROR;
+        }
 
     if (fmt != isoc) {
-        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
+        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
             return NGX_ERROR;
+        }
 
         day = (*p - '0') * 10 + *(p + 1) - '0';
         p += 2;
 
         if (*p == ' ') {
-            if (end - p < 18)
+            if (end - p < 18) {
                 return NGX_ERROR;
+            }
             fmt = rfc822;
 
         } else if (*p == '-') {
@@ -99,8 +104,9 @@ time_t ngx_http_parse_time(char *value, 
 
     p += 3;
 
-    if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-'))
+    if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
         return NGX_ERROR;
+    }
 
     p++;
 
@@ -108,15 +114,18 @@ time_t ngx_http_parse_time(char *value, 
         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
             || *(p + 2) < '0' || *(p + 2) > '9'
             || *(p + 3) < '0' || *(p + 3) > '9')
+        {
             return NGX_ERROR;
+        }
 
         year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
                + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
         p += 4;
 
     } else if (fmt == rfc850) {
-        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
+        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
             return NGX_ERROR;
+        }
 
         year = (*p - '0') * 10 + *(p + 1) - '0';
         year += (year < 70) ? 2000 : 1900;
@@ -124,61 +133,74 @@ time_t ngx_http_parse_time(char *value, 
     }
 
     if (fmt == isoc) {
-        if (*p == ' ')
+        if (*p == ' ') {
             p++;
+        }
 
-        if (*p < '0' || *p > '9')
+        if (*p < '0' || *p > '9') {
             return NGX_ERROR;
+        }
 
         day = *p++ - '0';
 
         if (*p != ' ') {
-            if (*p < '0' || *p > '9')
+            if (*p < '0' || *p > '9') {
                 return NGX_ERROR;
+            }
 
             day = day * 10 + *p++ - '0';
         }
 
-        if (end - p < 14)
+        if (end - p < 14) {
             return NGX_ERROR;
+        }
     }
 
-    if (*p++ != ' ')
+    if (*p++ != ' ') {
         return NGX_ERROR;
+    }
 
-    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
+    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
         return NGX_ERROR;
+    }
 
     hour = (*p - '0') * 10 + *(p + 1) - '0';
     p += 2;
 
-    if (*p++ != ':')
+    if (*p++ != ':') {
         return NGX_ERROR;
+    }
 
-    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
+    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
         return NGX_ERROR;
+    }
 
     min = (*p - '0') * 10 + *(p + 1) - '0';
     p += 2;
 
-    if (*p++ != ':')
+    if (*p++ != ':') {
         return NGX_ERROR;
+    }
 
-    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
+    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
         return NGX_ERROR;
+    }
 
     sec = (*p - '0') * 10 + *(p + 1) - '0';
 
     if (fmt == isoc) {
         p += 2;
 
-        if (*p++ != ' ')
+        if (*p++ != ' ') {
             return NGX_ERROR;
+        }
 
         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
             || *(p + 2) < '0' || *(p + 2) > '9'
             || *(p + 3) < '0' || *(p + 3) > '9')
+        {
             return NGX_ERROR;
+        }
 
         year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
                + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
@@ -188,19 +210,22 @@ time_t ngx_http_parse_time(char *value, 
     printf("%d.%d.%d %d:%d:%d\n", day, month + 1, year, hour, min, sec);
 #endif
 
-    if (hour > 23 || min > 59 || sec > 59)
+    if (hour > 23 || min > 59 || sec > 59) {
          return NGX_ERROR;
+    }
 
     if (day == 29 && month == 1) {
-        if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0))
+        if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
             return NGX_ERROR;
+        }
 
     } else if (day > mday[month]) {
         return NGX_ERROR;
     }
 
-    if (sizeof(time_t) <= 4 && year >= 2038)
+    if (sizeof(time_t) <= 4 && year >= 2038) {
         return NGX_ERROR;
+    }
 
     /* shift new year to 1st March, needed for Gauss's formula */
     if (--month <= 0) {
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -13,14 +13,16 @@
 
 
 static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool);
+static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool,
+                                              void *parent, void *child);
 
 
 static ngx_command_t ngx_http_write_filter_commands[] = {
 
     {ngx_string("write_buffer"),
-     NGX_CONF_TAKE1, 
+     NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
      ngx_conf_set_size_slot,
-     NGX_HTTP_LOC_CONF,
+     NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_write_filter_conf_t, buffer_output)},
 
     {ngx_string(""), 0, NULL, 0, 0}
@@ -33,7 +35,7 @@ ngx_http_module_t  ngx_http_write_filter
     NULL,                                  /* create server config */
     NULL,                                  /* init server config */
     ngx_http_write_filter_create_conf,     /* create location config */
-    NULL,                                  /* merge location config */
+    ngx_http_write_filter_merge_conf,      /* merge location config */
 
     NULL,                                  /* translate handler */
 
@@ -45,6 +47,7 @@ ngx_http_module_t  ngx_http_write_filter
 
 
 ngx_module_t  ngx_http_write_filter_module = {
+    0,                                     /* module index */
     &ngx_http_write_filter_module_ctx,     /* module context */
     ngx_http_write_filter_commands,        /* module directives */
     NGX_HTTP_MODULE_TYPE,                  /* module type */
@@ -79,9 +82,12 @@ int ngx_http_write_filter(ngx_http_reque
         prev = &ch->next;
         size += ch->hunk->last.file - ch->hunk->pos.file;
 
-        ngx_log_debug(r->connection->log, "old chunk: %x " QX_FMT " " QD_FMT _
+#if (NGX_DEBUG_WRITE_FILTER)
+        ngx_log_debug(r->connection->log, "write filter: old chunk: %x "
+                      QX_FMT " " QD_FMT _
                       ch->hunk->type _ ch->hunk->pos.file _
                       ch->hunk->last.file - ch->hunk->pos.file);
+#endif
 
         if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
             flush = size;
@@ -102,9 +108,12 @@ int ngx_http_write_filter(ngx_http_reque
         prev = &ch->next;
         size += ch->hunk->last.file - ch->hunk->pos.file;
 
-        ngx_log_debug(r->connection->log, "new chunk: %x " QX_FMT " " QD_FMT _
+#if (NGX_DEBUG_WRITE_FILTER)
+        ngx_log_debug(r->connection->log, "write filter: new chunk: %x "
+                      QX_FMT " " QD_FMT _
                       ch->hunk->type _ ch->hunk->pos.file _
                       ch->hunk->last.file - ch->hunk->pos.file);
+#endif
 
         if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
             flush = size;
@@ -119,7 +128,10 @@ int ngx_http_write_filter(ngx_http_reque
                 ngx_http_get_module_loc_conf(r->main ? r->main : r,
                                              ngx_http_write_filter_module_ctx);
 
-    ngx_log_debug(r->connection->log, "l:%d f:%d" _ last _ flush);
+#if (NGX_DEBUG_WRITE_FILTER)
+    ngx_log_debug(r->connection->log, "write filter: last:%d flush:%d" _
+                  last _ flush);
+#endif
 
     if (!last && flush == 0 && size < conf->buffer_output) {
         return NGX_OK;
@@ -150,3 +162,18 @@ static void *ngx_http_write_filter_creat
 
     return conf;
 }
+
+
+static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool,
+                                              void *parent, void *child)
+{
+    ngx_http_write_filter_conf_t *prev =
+                                      (ngx_http_write_filter_conf_t *) parent;
+    ngx_http_write_filter_conf_t *conf =
+                                       (ngx_http_write_filter_conf_t *) child;
+
+    ngx_conf_merge(conf->buffer_output, prev->buffer_output, 1460);
+
+    return NULL;
+}
+
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_pthread.c
@@ -0,0 +1,26 @@
+
+
+#include <ngx_config.h>
+
+#include <ngx_log.h>
+#include <ngx_pthread.h>
+
+
+int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack,
+                         ngx_thread_start_routine_t func, void *arg,
+                         ngx_log_t log)
+{
+    int              err;
+    pthread_attr_t  *attr;
+
+    attr = NULL;
+
+    err = pthread_create(tid, attr, func, arg);
+
+    if (err != 0) {
+        ngx_log_error(NGX_LOG_ERR, log, err, "pthread_create() failed");
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_pthread.h
@@ -0,0 +1,14 @@
+#ifndef _NGX_OS_THREAD_H_INCLUDED_
+#define _NGX_OS_THREAD_H_INCLUDED_
+
+
+#include <pthread.h>
+
+
+typedef pthread_t          ngx_os_tid_t;
+typedef int                ngx_tid_t;
+
+typedef void *(*)(void *)  ngx_thread_start_routine_t
+
+
+#endif /* _NGX_OS_THREAD_H_INCLUDED_ */
new file mode 100644
--- /dev/null
+++ b/src/os/win32/ngx_os_thread.c
@@ -0,0 +1,26 @@
+
+
+#include <ngx_config.h>
+
+#include <ngx_log.h>
+#include <ngx_os_thread.h>
+
+
+int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack,
+                         ngx_thread_start_routine_t func, void *arg,
+                         ngx_log_t log)
+{
+    ngx_os_tid_t  id;
+    int  dummy;       /* needed in Win9X only, in NT can be NULL */
+
+    id = CreateThread(NULL, stack_size, func, arg, 0, &dummy);
+
+    if (id == NULL) {
+        ngx_log_error(NGX_LOG_ERR, log, err, "CreateThread() failed");
+        return NGX_ERROR;
+    }
+
+    *tid = id;
+
+    return NGX_OK;
+}
new file mode 100644
--- /dev/null
+++ b/src/os/win32/ngx_os_thread.h
@@ -0,0 +1,14 @@
+#ifndef _NGX_OS_THREAD_H_INCLUDED_
+#define _NGX_OS_THREAD_H_INCLUDED_
+
+
+#include <ngx_config.h>
+
+
+typedef HANDLE                  ngx_os_tid_t;
+typedef int                     ngx_tid_t;
+
+typedef LPTHREAD_START_ROUTINE  ngx_thread_start_routine_t
+
+
+#endif /* _NGX_OS_THREAD_H_INCLUDED_ */