changeset 11:f323b4f74e4a

nginx-0.0.1-2002-09-12-18:42:29 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 12 Sep 2002 14:42:29 +0000
parents 4f3879d9b6f6
children 055ed05235ae
files src/core/ngx_core.h src/event/modules/ngx_kqueue_module.c src/event/ngx_event.c src/http/modules/ngx_http_index_handler.c src/http/ngx_http.h src/http/ngx_http_event.c src/os/unix/ngx_socket.h src/os/unix/ngx_time.h
diffstat 8 files changed, 134 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -4,6 +4,7 @@
 
 #define  NGX_OK          0
 #define  NGX_ERROR      -1
+#define  NGX_DONE        NGX_ERROR
 #define  NGX_AGAIN      -2
 #define  NGX_DECLINED   -3
 
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -57,6 +57,8 @@ void ngx_kqueue_init(int max_connections
 
 int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
 {
+    ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
+
     return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
 }
 
@@ -186,6 +188,9 @@ int ngx_kqueue_process_events(ngx_log_t 
                 ev->error = event_list[i].fflags;
             }
 
+            if (ev->oneshot)
+                ngx_del_timer(ev);
+
             if (ev->event_handler(ev) == NGX_ERROR)
                 ev->close_handler(ev);
 
@@ -207,6 +212,9 @@ void ngx_kqueue_add_timer(ngx_event_t *e
 
     ngx_log_debug(ev->log, "set timer: %d" _ timer);
 
+    ngx_assert((!ev->timer_next && !ev->timer_prev), return, ev->log,
+               "timer already set");
+
     for (e = timer_queue.timer_next;
          e != &timer_queue && timer > e->timer_delta;
          e = e->timer_next)
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -20,7 +20,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/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -109,7 +109,7 @@ static void *ngx_http_index_merge_conf(n
 
         ngx_test_null(index, ngx_push_array(conf->indices), NULL);
         index->name = NGX_HTTP_INDEX;
-        conf->max_index_len = index->len = sizeof(NGX_HTTP_INDEX);
+        conf->max_index_len = index->len = sizeof(NGX_HTTP_INDEX) + 1;
     }
 
     return conf;
@@ -122,7 +122,7 @@ static char *ngx_http_index_set_index(ng
 
     ngx_test_null(index, ngx_push_array(cf->indices), NULL);
     index->name = value;
-    index->len = strlen(value);
+    index->len = strlen(value) + 1;
 
     if (cf->max_index_len < index->len)
         cf->max_index_len = index->len;
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -96,6 +96,8 @@ struct ngx_http_request_s {
 
     int    method;
 
+    time_t  lingering_time;
+
     int    http_version;
     int    http_major;
     int    http_minor;
@@ -111,6 +113,9 @@ struct ngx_http_request_s {
     ssize_t   client_content_length;
     char     *discarded_buffer;
 
+    unsigned  keepalive:1;
+    unsigned  lingering_close:1;
+
     unsigned  header_timeout:1;
     unsigned  process_header:1;
 
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -16,6 +16,9 @@ int ngx_http_static_handler(ngx_http_req
 int ngx_http_index_handler(ngx_http_request_t *r);
 /* */
 
+/* STUB */
+#define LINGERING_TIMEOUT    2 
+#define SOME_LINGERING_TIME  30
 
 int ngx_http_init_connection(ngx_connection_t *c);
 
@@ -34,6 +37,8 @@ static int ngx_http_set_default_handler(
 
 static int ngx_http_writer(ngx_event_t *ev);
 
+static int ngx_http_lingering_close(ngx_event_t *ev);
+
 static int ngx_http_special_response(ngx_http_request_t *r, int error);
 static int ngx_http_redirect(ngx_http_request_t *r, int redirect);
 static int ngx_http_error(ngx_http_request_t *r, int error);
@@ -334,10 +339,15 @@ static int ngx_http_read_discarded_body(
         size = r->server->discarded_buffer_size;
 
     n = ngx_event_recv(c, r->discarded_buffer, size);
-    if (n > 0)
-        r->client_content_length -= n;
+    if (n == NGX_ERROR)
+        return NGX_ERROR;
 
-    return n;
+    if (n == NGX_AGAIN)
+        return NGX_OK;
+
+    r->client_content_length -= n;
+    /* XXX: what if r->client_content_length == 0 ? */
+    return NGX_OK;
 }
 
 static int ngx_http_discarded_read(ngx_event_t *ev)
@@ -376,6 +386,7 @@ static int ngx_http_handler(ngx_http_req
     r->process_header = 0;
     r->state_handler = NULL;
     r->connection->unexpected_eof = 0;
+    r->lingering_close = 1;
 
     r->connection->read->event_handler = ngx_http_block_read;
 
@@ -426,17 +437,70 @@ static int ngx_http_handler(ngx_http_req
 
     /* rc == NGX_OK */
 
-    /* STUB */
-    return ngx_http_close_request(r);
+    if (!r->keepalive) {
+        if (r->lingering_close) {
+            r->lingering_time = ngx_time() + SOME_LINGERING_TIME;
+            r->connection->read->event_handler = ngx_http_lingering_close;
+            ngx_del_timer(r->connection->read);
+            ngx_add_timer(r->connection->read, LINGERING_TIMEOUT * 1000);
+            if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
+                              NGX_ONESHOT_EVENT) == NGX_ERROR) {
+               return ngx_http_close_request(r);
+            }
+            if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN)
+                == NGX_ERROR)
+            {
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno,
+                              ngx_shutdown_socket_n " failed");
+                return ngx_http_close_request(r);
+            }
+        } else {
+            return ngx_http_close_request(r);
+        }
+    }
+}
+
+static int ngx_http_lingering_close(ngx_event_t *ev)
+{
+    ssize_t  n;
+    ngx_msec_t   timer;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
 
-/*
-    if (!keepalive)
-        if (linger)
-            set linger timeout on read
-            shutdown socket
-        else
-            close socket
-*/
+    c = (ngx_connection_t *) ev->data;
+    r = (ngx_http_request_t *) c->data;
+
+    ngx_log_debug(ev->log, "http lingering close");
+
+    if (ev->timedout)
+        return NGX_DONE;
+
+    /* STUB */
+    timer = r->lingering_time - ngx_time();
+    if (timer <= 0)
+        return NGX_DONE;
+
+    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);
+
+    if (n == NGX_ERROR)
+        return NGX_ERROR;
+
+    if (n == 0)
+        return NGX_DONE;
+
+    if (timer > LINGERING_TIMEOUT)
+        timer = LINGERING_TIMEOUT;
+
+    ngx_del_timer(ev);
+    ngx_add_timer(ev, timer * 1000);
+
+    return NGX_OK;
 }
 
 int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri)
@@ -543,23 +607,34 @@ static int ngx_http_writer(ngx_event_t *
 
     /* rc == NGX_OK */
 
-    return ngx_http_close_request(r);
-
-/*
-    if (!keepalive)
-        if (linger)
-            shutdown socket
-        else
-            close socket
+    ngx_log_debug(ev->log, "ngx_http_writer done");
 
-    log http request
-    close http request
-    if (keepalive)
-        return NGX_OK;
-    else
-        close connection
-        return NGX_OK;
-*/
+    if (!r->keepalive) {
+        if (r->lingering_close) {
+            r->lingering_time = ngx_time() + SOME_LINGERING_TIME;
+            r->connection->read->event_handler = ngx_http_lingering_close;
+            ngx_del_timer(r->connection->read);
+            ngx_add_timer(r->connection->read, LINGERING_TIMEOUT * 1000);
+            if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
+                              NGX_ONESHOT_EVENT) == NGX_ERROR) {
+               return ngx_http_close_request(r);
+            }
+            if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN)
+                == NGX_ERROR)
+            {
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno,
+                              ngx_shutdown_socket_n " failed");
+                return ngx_http_close_request(r);
+            }
+        } else {
+            return ngx_http_close_request(r);
+        }
+    }
+
+    /* keepalive */
+    ev = r->connection->read;
+    ngx_http_close_request(r);
+    ev->event_handler = ngx_http_init_request;
 }
 
 #if 0
@@ -672,6 +747,11 @@ static int ngx_process_http_request(ngx_
 
 static int ngx_http_close_request(ngx_http_request_t *r)
 {
+/*
+    if (r->logging)
+        ngx_http_log_request(r);
+*/
+
     ngx_destroy_pool(r->pool);
 
     ngx_log_debug(r->connection->log, "http close");
@@ -679,7 +759,7 @@ static int ngx_http_close_request(ngx_ht
     ngx_del_timer(r->connection->read);
     ngx_del_timer(r->connection->write);
 
-    return NGX_ERROR;
+    return NGX_DONE;
 }
 
 
--- a/src/os/unix/ngx_socket.h
+++ b/src/os/unix/ngx_socket.h
@@ -4,6 +4,7 @@
 
 #include <ngx_config.h>
 
+#define NGX_WRITE_SHUTDOWN SHUT_WR
 
 typedef int  ngx_socket_t;
 
@@ -15,6 +16,9 @@ typedef int  ngx_socket_t;
 #define ngx_nonblocking(s)  fcntl(s, F_SETFL, O_NONBLOCK)
 #define ngx_nonblocking_n   "fcntl(O_NONBLOCK)"
 
+#define ngx_shutdown_socket    shutdown
+#define ngx_shutdown_socket_n  "shutdown()"
+
 #define ngx_close_socket    close
 #define ngx_close_socket_n  "close()"
 
--- a/src/os/unix/ngx_time.h
+++ b/src/os/unix/ngx_time.h
@@ -22,5 +22,8 @@ void ngx_localtime(ngx_tm_t *tm);
 
 ngx_msec_t ngx_msec(void);
 
+/* STUB */
+#define ngx_time()  time(NULL)
+
 
 #endif /* _NGX_TIME_H_INCLUDED_ */