changeset 7:b5481d6fbbd4

nginx-0.0.1-2002-08-29-20:59:54 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 29 Aug 2002 16:59:54 +0000
parents 669801705ab1
children 708f8bb772ec
files src/core/ngx_alloc.c src/core/ngx_connection.h src/core/ngx_hunk.h src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_select_module.c src/event/ngx_event.c src/event/ngx_event.h src/event/ngx_event_close.c src/event/ngx_event_recv.c src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_event.c src/http/ngx_http_filter.c src/http/ngx_http_parse.c
diffstat 14 files changed, 339 insertions(+), 243 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_alloc.c
+++ b/src/core/ngx_alloc.c
@@ -14,6 +14,9 @@ void *ngx_alloc(size_t size, ngx_log_t *
     if (p == NULL)
         ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                       "malloc() %d bytes failed", size);
+
+    ngx_log_debug(log, "malloc: %x" _ p);
+
     return p;
 }
 
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -34,7 +34,7 @@ struct ngx_connection_s {
     char             *addr_text;
     size_t            addr_textlen;
 
-    time_t            post_accept_timeout;
+    unsigned int      post_accept_timeout;
 };
 
 
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -57,6 +57,9 @@ struct ngx_chain_s {
     ngx_chain_t *next;
 };
 
+#define ngx_create_temp_hunk(pool, size, before, after)                      \
+            ngx_get_hunk(pool, size, before, after)
+
 #define ngx_add_hunk_to_chain(chain, h, pool, error)                         \
             do {                                                             \
                 ngx_test_null(chain, ngx_create_chain_entry(pool), error);   \
@@ -66,6 +69,7 @@ struct ngx_chain_s {
 
 
 
+
 ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after);
 
 
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -8,6 +8,7 @@
 */
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_types.h>
 #include <ngx_log.h>
 #include <ngx_connection.h>
@@ -19,7 +20,6 @@
 #endif
 
 static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
-static void ngx_inline ngx_del_timer(ngx_event_t *ev);
 
 
 static int              kq;
@@ -145,7 +145,7 @@ int ngx_kqueue_process_events(ngx_log_t 
     }
 
     ngx_log_debug(log, "ngx_kqueue_process_events: "
-                       "timer: %d, delta: %d" _ timer _ delta);
+                  "timer: %d, delta: %d" _ timer _ delta);
 
     if (timer) {
         if (delta >= timer) {
@@ -158,7 +158,7 @@ int ngx_kqueue_process_events(ngx_log_t 
                 ngx_del_timer(ev);
 #if 1
                 ev->timedout = 1;
-                if (ev->event_handler(ev) == -1)
+                if (ev->event_handler(ev) == NGX_ERROR)
                     ev->close_handler(ev);
 #else
                 if (ev->timer_handler(ev) == -1)
@@ -200,7 +200,7 @@ int ngx_kqueue_process_events(ngx_log_t 
                 ev->error = event_list[i].fflags;
             }
 
-            if (ev->event_handler(ev) == -1)
+            if (ev->event_handler(ev) == NGX_ERROR)
                 ev->close_handler(ev);
 
             break;
@@ -233,6 +233,7 @@ static void ngx_add_timer_core(ngx_event
     e->timer_prev = ev;
 }
 
+#if 0
 static void ngx_inline ngx_del_timer(ngx_event_t *ev)
 {
     if (ev->timer_prev)
@@ -240,9 +241,10 @@ static void ngx_inline ngx_del_timer(ngx
 
     if (ev->timer_next) {
         ev->timer_next->timer_prev = ev->timer_prev;
-        ev->timer_prev = NULL;
+        ev->timer_next = NULL;
     }
 
     if (ev->timer_prev)
-        ev->timer_next = NULL;
+        ev->timer_prev = NULL;
 }
+#endif
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -24,7 +24,6 @@ static ngx_event_t  timer_queue;
 
 
 static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
-static void ngx_inline ngx_del_timer(ngx_event_t *ev);
 
 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
                                      ngx_log_t *log);
@@ -338,6 +337,7 @@ static void ngx_add_timer_core(ngx_event
     e->timer_prev = ev;
 }
 
+#if 0
 static void ngx_inline ngx_del_timer(ngx_event_t *ev)
 {
     if (ev->timer_prev)
@@ -345,9 +345,10 @@ static void ngx_inline ngx_del_timer(ngx
 
     if (ev->timer_next) {
         ev->timer_next->timer_prev = ev->timer_prev;
-        ev->timer_prev = NULL;
+        ev->timer_next = NULL;
     }
 
     if (ev->timer_prev)
-        ev->timer_next = NULL;
+        ev->timer_prev = NULL;
 }
+#endif
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -19,7 +19,7 @@ ngx_event_t         *ngx_read_events, *n
 
 #if !(USE_KQUEUE)
 
-#if 1
+#if 0
 ngx_event_type_e     ngx_event_type = NGX_SELECT_EVENT;
 #else
 ngx_event_type_e     ngx_event_type = NGX_KQUEUE_EVENT;
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -133,6 +133,23 @@ NGX_AIO_EVENT              overlapped, a
 
 #define ngx_add_timer(ev, time)  ngx_add_event(ev, NGX_TIMER_EVENT, time)
 
+static void ngx_inline ngx_del_timer(ngx_event_t *ev)
+{
+    if (ev->timer_prev)
+        ev->timer_prev->timer_next = ev->timer_next;
+
+    if (ev->timer_next) {
+        ev->timer_next->timer_prev = ev->timer_prev;
+        ev->timer_next = NULL;
+    }
+
+    if (ev->timer_prev)
+        ev->timer_prev = NULL;
+}
+
+
+
+
 extern ngx_event_t          *ngx_read_events;
 extern ngx_event_t          *ngx_write_events;
 extern ngx_connection_t     *ngx_connections;
--- a/src/event/ngx_event_close.c
+++ b/src/event/ngx_event_close.c
@@ -1,5 +1,6 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_types.h>
 #include <ngx_connection.h>
 #include <ngx_event_close.h>
@@ -8,22 +9,24 @@
 int ngx_event_close_connection(ngx_event_t *ev)
 {
     int rc;
-    ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+    ngx_connection_t *c = (ngx_connection_t *) ev->data;
 
-    ngx_assert((cn->fd != -1), return -1, ev->log,
+    ngx_assert((c->fd != -1), return NGX_ERROR, c->log,
                "ngx_event_close: already closed");
 
-    if ((rc = ngx_close_socket(cn->fd)) == -1)
-        ngx_log_error(NGX_LOG_ERR, ev->log, ngx_socket_errno,
+    ngx_destroy_pool(c->pool);
+
+    if ((rc = ngx_close_socket(c->fd)) == -1)
+        ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
                       "ngx_event_close: close failed");
 
-    if (cn->read->next)
-        ngx_del_event(cn->read, NGX_READ_EVENT);
+    if (c->read->next)
+        ngx_del_event(c->read, NGX_READ_EVENT);
 
-    if (cn->write->next)
-        ngx_del_event(cn->write, NGX_WRITE_EVENT);
+    if (c->write->next)
+        ngx_del_event(c->write, NGX_WRITE_EVENT);
 
-    cn->fd = -1;
+    c->fd = -1;
 
     return rc;
 }
--- a/src/event/ngx_event_recv.c
+++ b/src/event/ngx_event_recv.c
@@ -6,29 +6,27 @@
 #include <ngx_recv.h>
 #include <ngx_connection.h>
 
-int ngx_event_recv_core(ngx_event_t *ev, char *buf, size_t size)
+int ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
 {
     int                n;
     ngx_err_t          err;
-    ngx_connection_t  *c;
 
-    c = (ngx_connection_t *) ev->data;
-
-    if (ev->timedout) {
+    if (c->read->timedout) {
         ngx_set_socket_errno(NGX_ETIMEDOUT);
-        ngx_log_error(NGX_LOG_ERR, ev->log, NGX_ETIMEDOUT, "recv() failed");
+        ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "recv() failed");
         return NGX_ERROR;
     }
 
 #if (HAVE_KQUEUE)
-    ngx_log_debug(ev->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
-                  ev->eof _ ev->available _ ev->error);
+    ngx_log_debug(c->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
+                  c->read->eof _ c->read->available _ c->read->error);
 #if !(USE_KQUEUE)
     if (ngx_event_type == NGX_KQUEUE_EVENT)
 #endif
-        if (ev->eof && ev->available == 0) {
-            if (ev->error) {
-                ngx_log_error(NGX_LOG_ERR, ev->log, ev->error, "recv() failed");
+        if (c->read->eof && c->read->available == 0) {
+            if (c->read->error) {
+                ngx_log_error(NGX_LOG_ERR, c->log, c->read->error,
+                              "recv() failed");
                 return NGX_ERROR;
             }
 
@@ -42,11 +40,11 @@ int ngx_event_recv_core(ngx_event_t *ev,
         err = ngx_socket_errno;
 
         if (err == NGX_EAGAIN) {
-            ngx_log_error(NGX_LOG_INFO, ev->log, err, "recv() returns EAGAIN");
+            ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returns EAGAIN");
             return NGX_AGAIN;
         }
 
-        ngx_log_error(NGX_LOG_ERR, ev->log, err, "recv() failed");
+        ngx_log_error(NGX_LOG_ERR, c->log, err, "recv() failed");
         return NGX_ERROR;
     }
 
@@ -54,7 +52,7 @@ int ngx_event_recv_core(ngx_event_t *ev,
 #if !(USE_KQUEUE)
     if (ngx_event_type == NGX_KQUEUE_EVENT)
 #endif
-        ev->available -= n;
+        c->read->available -= n;
 #endif
 
     return n;
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -17,6 +17,7 @@ int ngx_http_init(ngx_pool_t *pool, ngx_
 {
     ngx_listen_t  *ls;
 
+    ngx_http_server.header_timeout = 20000;
     ngx_http_server.buff_size = 1024;
 #if (WIN32)
     ngx_http_server.doc_root = "html";
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -4,15 +4,11 @@
 
 #include <ngx_config.h>
 #include <ngx_types.h>
+#include <ngx_hunk.h>
 #include <ngx_file.h>
 #include <ngx_connection.h>
 
 
-#define NGX_SYS_ERROR             -1
-#define NGX_HTTP_INVALID_METHOD   -2
-#define NGX_HTTP_INVALID_REQUEST  -3
-#define NGX_HTTP_INVALID_HEADER   -4
-
 #define NGX_HTTP_GET   1
 #define NGX_HTTP_HEAD  2
 #define NGX_HTTP_POST  3
@@ -20,10 +16,17 @@
 #define NGX_HTTP_CONN_CLOSE       0
 #define NGX_HTTP_CONN_KEEP_ALIVE  1
 
-#define NGX_OK                          0
+
+#define NGX_HTTP_HEADER_DONE            1
+#define NGX_HTTP_INVALID_METHOD         10
+#define NGX_HTTP_INVALID_REQUEST        11
+#define NGX_HTTP_INVALID_HEAD           12
+#define NGX_HTTP_INVALID_HEADER         13
+
 
 #define NGX_HTTP_OK                     200
 #define NGX_HTTP_MOVED_PERMANENTLY      302
+#define NGX_HTTP_BAD_REQUEST            400
 #define NGX_HTTP_NOT_FOUND              404
 #define NGX_HTTP_INTERNAL_SERVER_ERROR  503
 
@@ -40,9 +43,11 @@ typedef struct {
 #define ngx_get_module_ctx(r, module)  (module)->ctx
 
 typedef struct {
-    char   *doc_root;
-    size_t  doc_root_len;
-    size_t  buff_size;
+    char          *doc_root;
+    size_t         doc_root_len;
+    size_t         buff_size;
+
+    unsigned int   header_timeout;
 } ngx_http_server_t;
 
 typedef struct {
@@ -72,6 +77,12 @@ struct ngx_http_request_s {
     char  *location;
     ngx_fd_t  fd;
 
+    ngx_pool_t  *pool;
+    ngx_hunk_t  *header_in;
+
+/*
+    ngx_http_headers_in_t *headers_in;
+*/
     ngx_http_headers_out_t *headers_out;
 
     int    filename_len;
@@ -90,11 +101,11 @@ struct ngx_http_request_s {
 
     ngx_connection_t  *connection;
     ngx_http_server_t *server;
-    ngx_buff_t  *buff;
-    ngx_pool_t  *pool;
 
     int       filter;
 
+    unsigned  header_timeout:1;
+
     unsigned  header_only:1;
     unsigned  unusual_uri:1;
     unsigned  complex_uri:1;
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -15,12 +15,12 @@ int ngx_http_init_connection(ngx_connect
 static int ngx_http_init_request(ngx_event_t *ev);
 static int ngx_http_process_request(ngx_event_t *ev);
 
-static int ngx_process_http_request_line(ngx_http_request_t *r);
-static int ngx_process_http_request_header(ngx_http_request_t *r);
+static int ngx_http_process_request_line(ngx_http_request_t *r);
+static int ngx_http_process_request_header(ngx_http_request_t *r);
 
-static int ngx_process_http_request(ngx_http_request_t *r);
+static int ngx_http_process_http_request(ngx_http_request_t *r);
 
-static int ngx_http_close_request(ngx_event_t *ev);
+static int ngx_http_close_request(ngx_http_request_t *r);
 static size_t ngx_http_log_error(void *data, char *buf, size_t len);
 
 
@@ -28,6 +28,13 @@ static size_t ngx_http_log_error(void *d
 static int ngx_http_writer(ngx_event_t *ev);
 
 
+static char *header_errors[] = {
+    "client %s sent invalid method",
+    "client %s sent invalid request",
+    "client %s sent HEAD method in HTTP/0.9 request"
+};
+
+
 
 int ngx_http_init_connection(ngx_connection_t *c)
 {
@@ -57,13 +64,12 @@ int ngx_http_init_connection(ngx_connect
     c->log->data = ctx;
     c->log->handler = ngx_http_log_error;
 
-    ngx_add_timer(ev, c->post_accept_timeout);
-
 #if (HAVE_DEFERRED_ACCEPT)
-    if (ev->ready)
+    if (ev->ready) {
         return ngx_http_init_request(ev);
-    else
+    } else {
 #endif
+        ngx_add_timer(ev, c->post_accept_timeout);
 #if (USE_KQUEUE)
         return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
 #else
@@ -76,9 +82,11 @@ int ngx_http_init_connection(ngx_connect
             if (ngx_event_type == NGX_KQUEUE_EVENT)
                 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
             else
-#else
+#endif
                 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
-#endif
+#endif /* USE_KQUEUE */
+#if (HAVE_DEFERRED_ACCEPT)
+    }
 #endif
 }
 
@@ -99,21 +107,16 @@ int ngx_http_init_request(ngx_event_t *e
     r->connection = c;
     r->server = srv;
 
-    ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), NGX_ERROR);
+    /* TODO: request's pool size */
+    ngx_test_null(r->pool, ngx_create_pool(16384, ev->log),
+                  ngx_http_close_request(r));
 
-    /* TODO: buff -> hunk */
-    ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), NGX_ERROR);
-    ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size),
-                  NGX_ERROR);
-
-    r->buff->pos = r->buff->last = r->buff->buff;
-    r->buff->end = r->buff->buff + srv->buff_size;
-
-    r->state_handler = ngx_process_http_request_line;
+    ngx_test_null(r->header_in,
+                  ngx_create_temp_hunk(r->pool, srv->buff_size, 0, 0),
+                  ngx_http_close_request(r));
 
     ev->event_handler = ngx_http_process_request;
-    ev->close_handler = ngx_http_close_request;
-    c->write->close_handler = ngx_http_close_request;
+    r->state_handler = ngx_http_process_request_line;
 
     return ngx_http_process_request(ev);
 }
@@ -121,7 +124,7 @@ int ngx_http_init_request(ngx_event_t *e
 
 int ngx_http_process_request(ngx_event_t *ev)
 {
-    int n;
+    int n, rc;
     ngx_connection_t *c ;
     ngx_http_request_t *r;
 
@@ -130,79 +133,128 @@ int ngx_http_process_request(ngx_event_t
 
     ngx_log_debug(ev->log, "http process request");
 
-    n = ngx_event_recv(ev, r->buff->last, r->buff->end - r->buff->last);
-
-    if (n == NGX_AGAIN)
-        return NGX_AGAIN;
+    n = ngx_event_recv(c, r->header_in->last.mem,
+                       r->header_in->end - r->header_in->last.mem);
 
-    if (n == NGX_ERROR) {
-        /* close request */
-        return NGX_ERROR;
+    if (n == NGX_AGAIN) {
+        if (!r->header_timeout) {
+            r->header_timeout = 1;
+            ngx_del_timer(ev);
+            ngx_add_timer(ev, r->server->header_timeout);
+        }
+        return NGX_AGAIN;
     }
 
+    if (n == NGX_ERROR)
+        return ngx_http_close_request(r);
+
     ngx_log_debug(ev->log, "http read %d" _ n);
 
     if (n == 0) {
-        if (ev->unexpected_eof) {
-            ngx_log_error(NGX_LOG_INFO, ev->log, 0, "connection is closed");
-            /* close request */
-            return NGX_ERROR;
-        }
+        /* STUB: c-> */
+        if (ev->unexpected_eof)
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          "client prematurely closed connection");
 
-        return ngx_http_close_request(ev);
+        return ngx_http_close_request(r);
     }
 
-    if (!ev->read_discarded) {
-        r->buff->last += n;
+    r->header_in->last.mem += n;
+
+    /* state_handlers are called in following order:
+        ngx_http_process_request_line(r)
+        ngx_http_process_request_header(r) */
+
+    do {
+        rc = (r->state_handler)(r);
 
-        /* state_handlers are called in following order:
-            ngx_process_http_request_line()
-            ngx_process_http_request_header() */
+        if (rc == NGX_ERROR)
+            return rc;
+
+        /* rc == NGX_OK || rc == NGX_AGAIN */
 
-        do {
-            if ((r->state_handler)(r) < 0)
-                return -1;
-        } while (r->buff->pos < r->buff->last);
+    } while (r->header_in->pos.mem < r->header_in->last.mem);
+             
+    if (!r->header_timeout) {
+        r->header_timeout = 1;
+        ngx_del_timer(ev);
+        ngx_add_timer(ev, r->server->header_timeout);
     }
 
-    if (ngx_del_event(ev, NGX_TIMER_EVENT) == -1)
-        return -1;
-
-    if (ngx_add_event(ev, NGX_TIMER_EVENT, ev->timer) == -1)
-        return -1;
-
-    return 0;
+    return rc;
 }
 
-static int ngx_process_http_request_line(ngx_http_request_t *r)
+static int ngx_http_process_request_line(ngx_http_request_t *r)
 {
-    int n;
+    int rc;
+    ngx_http_log_ctx_t  *ctx;
+
+    rc = ngx_read_http_request_line(r);
+
+    if (rc == NGX_OK) {
+        ngx_test_null(r->uri,
+                      ngx_palloc(r->pool, r->uri_end - r->uri_start + 1), 
+                      ngx_http_close_request(r));
+        ngx_cpystrn(r->uri, r->uri_start, r->uri_end - r->uri_start + 1);
 
-    if ((n = ngx_read_http_request_line(r)) == 1) {
-        *r->uri_end = '\0';
         ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _
-                     r->method _ r->http_version _ r->uri_start);
-        r->state_handler = ngx_process_http_request_header;
+                      r->method _ r->http_version _ r->uri);
+
+        if (r->http_version == 9) {
+            /* set lock event */
+            return ngx_http_process_http_request(r);
+        }
+
+        r->state_handler = ngx_http_process_request_header;
         r->connection->read->action = "reading client request headers";
+
+        return NGX_OK;
     }
 
-    return n;
+    r->connection->log->handler = NULL;
+    ctx = r->connection->log->data;
+
+    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                  header_errors[rc - NGX_HTTP_INVALID_METHOD], ctx->client);
+
+    r->connection->log->handler = ngx_http_log_error;
+
+    /* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST)  */
+    return ngx_http_close_request(r);
 }
 
-static int ngx_process_http_request_header(ngx_http_request_t *r)
+static int ngx_http_process_request_header(ngx_http_request_t *r)
 {
-    int n;
+    int rc;
+    ngx_http_log_ctx_t  *ctx;
+
+    for ( ;; ) {
+        rc = ngx_read_http_header_line(r);
+
+        if (rc == NGX_OK) {
+            *r->header_name_end = '\0';
+            *r->header_end = '\0';
+            ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
+                          r->header_name_start _ r->header_start);
 
-    while ((n = ngx_read_http_header_line(r)) == 1) {
-        *r->header_name_end = '\0';
-        *r->header_end = '\0';
-        ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
-                     r->header_name_start _ r->header_start);
+        } else if (rc == NGX_AGAIN) {
+            return NGX_AGAIN;
+
+        } else if (rc == NGX_HTTP_HEADER_DONE) {
+            break;
+
+        } else if (rc == NGX_HTTP_INVALID_HEADER) {
+            r->connection->log->handler = NULL;
+            ctx = r->connection->log->data;
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client %s sent invalid header", ctx->client);
+            r->connection->log->handler = ngx_http_log_error;
+
+            /* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST)  */
+            return ngx_http_close_request(r);
+        }
     }
 
-    if (n != 2)
-        return n;
-
     r->state_handler = NULL;
     r->connection->read->action = "reading client request body";
 
@@ -210,7 +262,9 @@ static int ngx_process_http_request_head
     r->connection->read->unexpected_eof = 0;
     ngx_log_debug(r->connection->log, "HTTP header done");
 
-    return ngx_process_http_request(r);
+    ngx_del_timer(r->connection->read);
+
+    return ngx_http_process_http_request(r);
 }
 
 #if 0
@@ -221,7 +275,7 @@ static int ngx_http_lock_read(ngx_event_
 }
 #endif
 
-static int ngx_process_http_request(ngx_http_request_t *r)
+static int ngx_http_process_http_request(ngx_http_request_t *r)
 {
     int   err, rc;
     char *name, *loc, *file;
@@ -489,16 +543,16 @@ static int ngx_process_http_request(ngx_
 
 #endif
 
-static int ngx_http_close_request(ngx_event_t *ev)
+static int ngx_http_close_request(ngx_http_request_t *r)
 {
-    ngx_connection_t *c = (ngx_connection_t *) ev->data;
+    ngx_destroy_pool(r->pool);
 
-    ngx_log_debug(ev->log, "http close");
+    ngx_log_debug(r->connection->log, "http close");
 
-    ngx_del_event(c->read, NGX_TIMER_EVENT);
-    ngx_del_event(c->write, NGX_TIMER_EVENT);
+    ngx_del_event(r->connection->read, NGX_TIMER_EVENT);
+    ngx_del_event(r->connection->write, NGX_TIMER_EVENT);
 
-    return ngx_event_close_connection(ev);
+    return NGX_ERROR;
 }
 
 
--- a/src/http/ngx_http_filter.c
+++ b/src/http/ngx_http_filter.c
@@ -141,7 +141,7 @@ int ngx_http_filter(ngx_http_request_t *
 
                         ngx_test_null(ctx->hunk,
                                       ngx_create_temp_hunk(r->pool, size,
-                                          50, 50),
+                                                           50, 50),
                                       NGX_ERROR);
 
                         rc = ngx_http_filter_copy_hunk(ctx->hunk,
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -1,47 +1,47 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_http.h>
 
 int ngx_read_http_request_line(ngx_http_request_t *r)
 {
     char  ch;
-    char *buff = r->buff->buff;
-    char *p = r->buff->pos;
+    char *p = r->header_in->pos.mem;
     enum {
-        rl_start = 0,
-        rl_space_after_method,
-        rl_spaces_before_uri,
-        rl_after_slash_in_uri,
-        rl_check_uri,
-        rl_uri,
-        rl_http_09,
-        rl_http_version,
-        rl_first_major_digit,
-        rl_major_digit,
-        rl_first_minor_digit,
-        rl_minor_digit,
-        rl_almost_done,
-        rl_done
+        sw_start = 0,
+        sw_space_after_method,
+        sw_spaces_before_uri,
+        sw_after_slash_in_uri,
+        sw_check_uri,
+        sw_uri,
+        sw_http_09,
+        sw_http_version,
+        sw_first_major_digit,
+        sw_major_digit,
+        sw_first_minor_digit,
+        sw_minor_digit,
+        sw_almost_done,
+        sw_done
     } state = r->state;
 
-    while (p < r->buff->last && state < rl_done) {
+    while (p < r->header_in->last.mem && state < sw_done) {
         ch = *p++;
 
 /*
 printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
-       state, p, r->buff->last, ch, p);
+       state, p, r->header_in->last, ch, p);
 */
 
-        /* GCC complie it as jump table */
+        /* GCC compiles switch as jump table */
 
         switch (state) {
 
         /* HTTP methods: GET, HEAD, POST */
-        case rl_start:
+        case sw_start:
             switch (ch) {
             case 'G':
-                if (p + 1 >= r->buff->last)
-                    return 0;
+                if (p + 1 >= r->header_in->last.mem)
+                    return NGX_AGAIN;
 
                 if (*p != 'E' || *(p + 1) != 'T')
                     return NGX_HTTP_INVALID_METHOD;
@@ -51,8 +51,8 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 break;
 
             case 'H':
-                if (p + 2 >= r->buff->last)
-                    return 0;
+                if (p + 2 >= r->header_in->last.mem)
+                    return NGX_AGAIN;
 
                 if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D')
                     return NGX_HTTP_INVALID_METHOD;
@@ -62,8 +62,8 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 break;
 
             case 'P':
-                if (p + 2 >= r->buff->last)
-                    return 0;
+                if (p + 2 >= r->header_in->last.mem)
+                    return NGX_AGAIN;
 
                 if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T')
                     return NGX_HTTP_INVALID_METHOD;
@@ -76,14 +76,14 @@ printf("\nstate: %d, pos: %x, end: %x, c
                 return NGX_HTTP_INVALID_METHOD;
             }
 
-            state = rl_space_after_method;
+            state = sw_space_after_method;
             break;
 
         /* single space after method */
-        case rl_space_after_method:
+        case sw_space_after_method:
             switch (ch) {
             case ' ':
-                state = rl_spaces_before_uri;
+                state = sw_spaces_before_uri;
                 break;
             default:
                 return NGX_HTTP_INVALID_METHOD;
@@ -91,123 +91,123 @@ printf("\nstate: %d, pos: %x, end: %x, c
             break;
 
         /* space* before URI */
-        case rl_spaces_before_uri:
+        case sw_spaces_before_uri:
             switch (ch) {
             case '/':
                 r->uri_start = p - 1;
-                state = rl_after_slash_in_uri;
+                state = sw_after_slash_in_uri;
                 break;
             case ' ':
                 break;
             default:
                 r->unusual_uri = 1;
                 r->uri_start = p - 1;
-                state = rl_uri;
+                state = sw_uri;
                 break;
             }
             break;
 
         /* check dot after slash */
-        case rl_after_slash_in_uri:
+        case sw_after_slash_in_uri:
             switch (ch) {
             case CR:
                 r->uri_end = p - 1;
                 r->http_minor = 9;
-                state = rl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
                 r->uri_end = p - 1;
                 r->http_minor = 9;
-                state = rl_done;
+                state = sw_done;
                 break;
             case ' ':
                 r->uri_end = p - 1;
-                state = rl_http_09;
+                state = sw_http_09;
                 break;
             case '.':
                 r->complex_uri = 1;
-                state = rl_uri;
+                state = sw_uri;
                 break;
             case '/':
                 r->complex_uri = 1;
-                state = rl_uri;
+                state = sw_uri;
                 break;
             case '?':
                 r->args_start = p;
-                state = rl_uri;
+                state = sw_uri;
                 break;
             default:
-                state = rl_check_uri;
+                state = sw_check_uri;
                 break;
             }
             break;
 
         /* check slash in URI */
-        case rl_check_uri:
+        case sw_check_uri:
             switch (ch) {
             case CR:
                 r->uri_end = p - 1;
                 r->http_minor = 9;
-                state = rl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
                 r->uri_end = p - 1;
                 r->http_minor = 9;
-                state = rl_done;
+                state = sw_done;
                 break;
             case ' ':
                 r->uri_end = p - 1;
-                state = rl_http_09;
+                state = sw_http_09;
                 break;
             case '.':
                 r->uri_ext = p;
                 break;
             case '/':
                 r->uri_ext = NULL;
-                state = rl_after_slash_in_uri;
+                state = sw_after_slash_in_uri;
                 break;
             case '?':
                 r->args_start = p;
-                state = rl_uri;
+                state = sw_uri;
                 break;
             }
             break;
 
         /* URI */
-        case rl_uri:
+        case sw_uri:
             switch (ch) {
             case CR:
                 r->uri_end = p - 1;
                 r->http_minor = 9;
-                state = rl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
                 r->uri_end = p - 1;
                 r->http_minor = 9;
-                state = rl_done;
+                state = sw_done;
                 break;
             case ' ':
                 r->uri_end = p - 1;
-                state = rl_http_09;
+                state = sw_http_09;
                 break;
             }
             break;
 
         /* space+ after URI */
-        case rl_http_09:
+        case sw_http_09:
             switch (ch) {
             case ' ':
                 break;
             case CR:
                 r->http_minor = 9;
-                state = rl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
                 r->http_minor = 9;
-                state = rl_done;
+                state = sw_done;
                 break;
             case 'H':
-                state = rl_http_version;
+                state = sw_http_version;
                 break;
             default:
                 return NGX_HTTP_INVALID_REQUEST;
@@ -215,33 +215,33 @@ printf("\nstate: %d, pos: %x, end: %x, c
             break;
 
         /* TTP/ */
-        case rl_http_version:
-            if (p + 2 >= r->buff->last) {
-                r->state = rl_http_version;
-                r->buff->pos = p - 1;
-                return 0;
+        case sw_http_version:
+            if (p + 2 >= r->header_in->last.mem) {
+                r->state = sw_http_version;
+                r->header_in->pos.mem = p - 1;
+                return NGX_AGAIN;
             }
 
             if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/')
                 return NGX_HTTP_INVALID_REQUEST;
 
             p += 3;
-            state = rl_first_major_digit;
+            state = sw_first_major_digit;
             break;
 
         /* first digit of major HTTP version */
-        case rl_first_major_digit:
+        case sw_first_major_digit:
             if (ch < '1' || ch > '9')
                 return NGX_HTTP_INVALID_REQUEST;
 
             r->http_major = ch - '0';
-            state = rl_major_digit;
+            state = sw_major_digit;
             break;
 
         /* major HTTP version or dot */
-        case rl_major_digit:
+        case sw_major_digit:
             if (ch == '.') {
-                state = rl_first_minor_digit;
+                state = sw_first_minor_digit;
                 break;
             }
 
@@ -252,24 +252,24 @@ printf("\nstate: %d, pos: %x, end: %x, c
             break;
 
         /* first digit of minor HTTP version */
-        case rl_first_minor_digit:
+        case sw_first_minor_digit:
             if (ch < '0' || ch > '9')
                 return NGX_HTTP_INVALID_REQUEST;
 
             r->http_minor = ch - '0';
 
-            state = rl_minor_digit;
+            state = sw_minor_digit;
             break;
 
         /* minor HTTP version or end of request line */
-        case rl_minor_digit:
+        case sw_minor_digit:
             if (ch == CR) {
-                state = rl_almost_done;
+                state = sw_almost_done;
                 break;
             }
 
             if (ch == LF) {
-                state = rl_done;
+                state = sw_done;
                 break;
             }
 
@@ -280,70 +280,72 @@ printf("\nstate: %d, pos: %x, end: %x, c
             break;
 
         /* end of request line */
-        case rl_almost_done:
+        case sw_almost_done:
             switch (ch) {
             case LF:
-                state = rl_done;
+                state = sw_done;
                 break;
             default:
-                return NGX_HTTP_INVALID_METHOD;
+                return NGX_HTTP_INVALID_REQUEST;
             }
             break;
         }
     }
 
-    r->buff->pos = p;
+    r->header_in->pos.mem = p;
 
-    if (state == rl_done) {
+    if (state == sw_done) {
         r->http_version = r->http_major * 1000 + r->http_minor;
-        r->state = rl_start;
-        return 1;
+        r->state = sw_start;
+        if (r->http_version == 9 && r->method == NGX_HTTP_HEAD)
+            return NGX_HTTP_INVALID_HEAD;
+        else
+            return NGX_OK;
     } else {
         r->state = state;
-        return 0;
+        return NGX_AGAIN;
     }
 }
 
 int ngx_read_http_header_line(ngx_http_request_t *r)
 {
     char  c, ch;
-    char *buff = r->buff->buff;
-    char *p = r->buff->pos;
+    char *p = r->header_in->pos.mem;
     enum  {
-        hl_start = 0,
-        hl_name,
-        hl_space_before_value,
-        hl_value,
-        hl_space_after_value,
-        hl_almost_done,
-        header_almost_done,
-        hl_done,
-        header_done
+        sw_start = 0,
+        sw_name,
+        sw_space_before_value,
+        sw_value,
+        sw_space_after_value,
+        sw_almost_done,
+        sw_header_almost_done,
+        sw_done,
+        sw_header_done
     } state = r->state;
 
-    while (p < r->buff->last && state < hl_done) {
+    while (p < r->header_in->last.mem && state < sw_done) {
         ch = *p++;
 
 /*
 printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
-       state, p, r->buff->last, ch, p);
+       state, p, r->header_in->last.mem, ch, p);
 */
 
         switch (state) {
 
         /* first char */
-        case hl_start:
+        case sw_start:
             switch (ch) {
             case CR:
                 r->header_end = p - 1;
-                state = header_almost_done;
+                state = sw_header_almost_done;
                 break;
             case LF:
                 r->header_end = p - 1;
-                state = header_done;
+                state = sw_header_done;
                 break;
             default:
-                state = hl_name;
+                state = sw_name;
                 r->header_name_start = p - 1;
 
                 c = ch | 0x20;
@@ -362,14 +364,14 @@ printf("\nstate: %d, pos: %x, end: %x, c
             break;
 
         /* header name */
-        case hl_name:
+        case sw_name:
             c = ch | 0x20;
             if (c >= 'a' && c <= 'z')
                 break;
 
             if (ch == ':') {
                 r->header_name_end = p - 1;
-                state = hl_space_before_value;
+                state = sw_space_before_value;
                 break;
             }
 
@@ -382,65 +384,65 @@ printf("\nstate: %d, pos: %x, end: %x, c
             return NGX_HTTP_INVALID_HEADER;
 
         /* space* before header value */
-        case hl_space_before_value:
+        case sw_space_before_value:
             switch (ch) {
             case ' ':
                 break;
             case CR:
                 r->header_start = r->header_end = p - 1;
-                state = hl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
                 r->header_start = r->header_end = p - 1;
-                state = hl_done;
+                state = sw_done;
                 break;
             default:
                 r->header_start = p - 1;
-                state = hl_value;
+                state = sw_value;
                 break;
             }
             break;
 
         /* header value */
-        case hl_value:
+        case sw_value:
             switch (ch) {
             case ' ':
                 r->header_end = p - 1;
-                state = hl_space_after_value;
+                state = sw_space_after_value;
                 break;
             case CR:
                 r->header_end = p - 1;
-                state = hl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
                 r->header_end = p - 1;
-                state = hl_done;
+                state = sw_done;
                 break;
             }
             break;
 
         /* space* before end of header line */
-        case hl_space_after_value:
+        case sw_space_after_value:
             switch (ch) {
             case ' ':
                 break;
             case CR:
-                state = hl_almost_done;
+                state = sw_almost_done;
                 break;
             case LF:
-                state = hl_done;
+                state = sw_done;
                 break;
             default:
-                state = hl_value;
+                state = sw_value;
                 break;
             }
             break;
 
         /* end of header line */
-        case hl_almost_done:
+        case sw_almost_done:
             switch (ch) {
             case LF:
-                state = hl_done;
+                state = sw_done;
                 break;
             default:
                 return NGX_HTTP_INVALID_HEADER;
@@ -448,10 +450,10 @@ printf("\nstate: %d, pos: %x, end: %x, c
             break;
 
         /* end of header */
-        case header_almost_done:
+        case sw_header_almost_done:
             switch (ch) {
             case LF:
-                state = header_done;
+                state = sw_header_done;
                 break;
             default:
                 return NGX_HTTP_INVALID_HEADER;
@@ -460,16 +462,16 @@ printf("\nstate: %d, pos: %x, end: %x, c
         }
     }
 
-    r->buff->pos = p;
+    r->header_in->pos.mem = p;
 
-    if (state == hl_done) {
-        r->state = hl_start;
-        return 1;
-    } else if (state == header_done) {
-        r->state = hl_start;
-        return 2;
+    if (state == sw_done) {
+        r->state = sw_start;
+        return NGX_OK;
+    } else if (state == sw_header_done) {
+        r->state = sw_start;
+        return NGX_HTTP_HEADER_DONE;
     } else {
         r->state = state;
-        return 0;
+        return NGX_AGAIN;
     }
 }