diff src/http/ngx_http_event.c @ 13:2aba961a1d34

nginx-0.0.1-2002-09-16-19:01:44 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 16 Sep 2002 15:01:44 +0000
parents 055ed05235ae
children 8dd06e2844f5
line wrap: on
line diff
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -1,6 +1,6 @@
 /*
-   TODO Win32 inet_ntoa
-        ngx_inet_ntop
+   TODO: Win32 inet_ntoa
+         ngx_inet_ntop
 */
 
 #include <ngx_config.h>
@@ -13,6 +13,7 @@
 #include <ngx_connection.h>
 #include <ngx_http.h>
 #include <ngx_http_config.h>
+#include <ngx_http_core.h>
 
 /* STUB */
 #include <ngx_http_output_filter.h>
@@ -20,10 +21,6 @@ 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);
 
 static int ngx_http_init_request(ngx_event_t *ev);
@@ -36,10 +33,12 @@ static int ngx_http_process_request_head
 static int ngx_http_block_read(ngx_event_t *ev);
 static int ngx_http_read_discarded_body(ngx_event_t *ev);
 
+static int ngx_http_event_handler(ngx_http_request_t *r);
 static int ngx_http_handler(ngx_http_request_t *r);
 static int ngx_http_set_default_handler(ngx_http_request_t *r);
 
 static int ngx_http_writer(ngx_event_t *ev);
+static int ngx_http_set_lingering_close(ngx_http_request_t *r);
 static int ngx_http_keepalive_handler(ngx_event_t *ev);
 static int ngx_http_lingering_close(ngx_event_t *ev);
 
@@ -65,10 +64,12 @@ 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),
@@ -81,7 +82,8 @@ int ngx_http_init_connection(ngx_connect
     ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen),
                   NGX_ERROR);
 #if (WIN32)
-    c->addr_text = inet_ntoa((struct in_addr) ((char *)c->sockaddr + c->addr));
+    c->addr_text = inet_ntoa((struct in_addr *)
+                                              ((char *)c->sockaddr + c->addr));
 #else
     inet_ntop(c->family, (char *)c->sockaddr + c->addr,
               c->addr_text, c->addr_textlen);
@@ -130,26 +132,27 @@ static int ngx_http_init_request(ngx_eve
     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->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,
                                            0, 0),
                       NGX_ERROR);
     } else {
-        c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start;
+        r->header_read = 1;
     }
 
-    ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)),
-                  NGX_ERROR);
-
-    c->data = r;
-    r->connection = c;
-    r->server = srv;
     r->header_in = c->buffer;
 
-    r->srv_conf = ngx_srv_conf;
-    r->loc_conf = ngx_loc_conf;
-
     ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log),
                   ngx_http_close_request(r));
 
@@ -177,32 +180,39 @@ static int ngx_http_process_request(ngx_
 
     ngx_log_debug(ev->log, "http process request");
 
-    n = ngx_event_recv(c, r->header_in->last.mem,
-                       r->header_in->end - r->header_in->last.mem);
+    if (r->header_read) {
+        r->header_read = 0;
+        ngx_log_debug(ev->log, "http preread %d" _
+                      r->header_in->last.mem - r->header_in->pos.mem);
 
-    if (n == NGX_AGAIN) {
-        if (r->header_timeout) {
-            r->header_timeout = 0;
-            ngx_del_timer(ev);
-            ngx_add_timer(ev, r->server->header_timeout);
-        }
-        return NGX_AGAIN;
-    }
+    } else {
+        n = ngx_event_recv(c, r->header_in->last.mem,
+                           r->header_in->end - r->header_in->last.mem);
 
-    if (n == NGX_ERROR)
-        return ngx_http_close_request(r);
+        if (n == NGX_AGAIN) {
+            if (r->header_timeout) {
+                r->header_timeout = 0;
+                ngx_del_timer(ev);
+                ngx_add_timer(ev, r->server->header_timeout);
+            }
+            return NGX_AGAIN;
+        }
 
-    ngx_log_debug(ev->log, "http read %d" _ n);
+        if (n == NGX_ERROR)
+            return ngx_http_close_request(r);
 
-    if (n == 0) {
-        if (c->unexpected_eof)
-            ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                          "client prematurely closed connection");
-        return ngx_http_close_request(r);
+        ngx_log_debug(ev->log, "http read %d" _ n);
+
+        if (n == 0) {
+            if (c->unexpected_eof)
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client prematurely closed connection");
+            return ngx_http_close_request(r);
+        }
+
+        r->header_in->last.mem += 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) */
@@ -241,11 +251,18 @@ static int ngx_http_process_request_line
                       ngx_http_close_request(r));
         ngx_cpystrn(r->uri, r->uri_start, r->uri_end - r->uri_start + 1);
 
-        ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _
-                      r->method _ r->http_version _ r->uri);
+        if (r->uri_ext) {
+            ngx_test_null(r->exten,
+                          ngx_palloc(r->pool, r->uri_end - r->uri_ext + 1), 
+                          ngx_http_close_request(r));
+            ngx_cpystrn(r->exten, r->uri_ext, r->uri_end - r->uri_ext + 1);
+        }
+
+        ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _
+                      r->method _ r->http_version _ r->uri _ r->exten);
 
         if (r->http_version == 9)
-            return ngx_http_handler(r);
+            return ngx_http_event_handler(r);
 
         /* TODO: check too long URI - no space for header, compact buffer */
 
@@ -292,7 +309,7 @@ static int ngx_http_process_request_head
 
         } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
             ngx_log_debug(r->connection->log, "HTTP header done");
-            return ngx_http_handler(r);
+            return ngx_http_event_handler(r);
 
         } else if (rc == NGX_AGAIN) {
             return NGX_AGAIN;
@@ -397,29 +414,13 @@ static int ngx_http_discarded_read(ngx_e
 
 /* ******************** */
 
-static int ngx_http_handler(ngx_http_request_t *r)
+
+static int ngx_http_event_handler(ngx_http_request_t *r)
 {
-    int  rc;
+    int rc;
     ngx_msec_t  timeout;
 
-    ngx_del_timer(r->connection->read);
-    r->header_timeout = 0;
-
-    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;
-
-    /* STUB: should find handler */
-    r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
-    rc = ngx_http_set_default_handler(r);
-
-    if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
-        return ngx_http_special_response(r, rc);
-
-    rc = r->handler(r);
+    rc = ngx_http_handler(r);
 
     /* transfer not completed */
     if (rc == NGX_AGAIN) {
@@ -460,25 +461,47 @@ static int ngx_http_handler(ngx_http_req
 
     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);
-            }
+            return ngx_http_set_lingering_close(r);
+
         } else {
             return ngx_http_close_request(r);
         }
     }
+
+    /* keepalive */
+
+    ngx_http_close_request(r);
+    r->connection->buffer->pos.mem = r->connection->buffer->last.mem
+                                               = r->connection->buffer->start;
+    r->connection->read->event_handler = ngx_http_keepalive_handler;
+}
+
+static int ngx_http_handler(ngx_http_request_t *r)
+{
+    int  rc;
+
+    ngx_del_timer(r->connection->read);
+    r->header_timeout = 0;
+
+    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;
+
+    /* STUB: should find handler */
+#if 0
+    r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
+#endif
+    rc = ngx_http_set_default_handler(r);
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
+        return ngx_http_special_response(r, rc);
+
+    rc = r->handler(r);
+
+    return rc;
 }
 
 int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri)
@@ -548,17 +571,18 @@ static int ngx_http_block_read(ngx_event
 {
     ngx_log_debug(ev->log, "http read blocked");
 
-    ngx_del_event(ev, NGX_READ_EVENT);
     ev->blocked = 1;
+    return ngx_del_event(ev, NGX_READ_EVENT);
 }
 
 
 static int ngx_http_writer(ngx_event_t *ev)
 {
     int rc;
-    unsigned int timeout;
-    ngx_connection_t    *c;
-    ngx_http_request_t  *r;
+    ngx_msec_t             timeout;
+    ngx_connection_t      *c;
+    ngx_http_request_t    *r;
+    ngx_http_core_conf_t  *conf;
 
     c = (ngx_connection_t *) ev->data;
     r = (ngx_http_request_t *) c->data;
@@ -567,14 +591,20 @@ static int ngx_http_writer(ngx_event_t *
 
     rc = ngx_http_output_filter(r, NULL);
 
-    ngx_log_debug(ev->log, "output_filter: %d" _ rc);
+    ngx_log_debug(ev->log, "output filter in writer: %d" _ rc);
 
     if (rc == NGX_AGAIN) {
 
         if (c->sent > 0) {
+            conf = (ngx_http_core_conf_t *)
+                        ngx_get_module_loc_conf(r->main ? r->main : r,
+                                                ngx_http_core_module);
+
+            timeout = (ngx_msec_t) (c->sent * conf->send_timeout);
+
             ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent);
-            timeout = (ngx_msec_t) (c->sent * 10);
             ngx_log_debug(ev->log, "timeout: %d" _ timeout);
+
             ngx_del_timer(ev);
             ngx_add_timer(ev, timeout);
         }
@@ -582,7 +612,6 @@ static int ngx_http_writer(ngx_event_t *
         if (ev->oneshot)
             if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
                               NGX_ONESHOT_EVENT) == NGX_ERROR) {
-            /* log http request */
             return ngx_http_close_request(r);
         }
 
@@ -594,62 +623,88 @@ static int ngx_http_writer(ngx_event_t *
 
     /* rc == NGX_OK */
 
-    ngx_log_debug(ev->log, "ngx_http_writer done");
+    ngx_log_debug(ev->log, "http writer done");
 
     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);
-            }
+            ngx_http_set_lingering_close(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;
+    c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start;
+    c->read->event_handler = ngx_http_keepalive_handler;
 }
 
-#if 0
+static int ngx_http_set_lingering_close(ngx_http_request_t *r)
+{
+    r->lingering_time = ngx_time() + r->server->lingering_time;
+    r->connection->read->event_handler = ngx_http_lingering_close;
+
+    ngx_del_timer(r->connection->read);
+    ngx_add_timer(r->connection->read, r->server->lingering_timeout);
+
+#if (HAVE_CLEAR_EVENT)
+    if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
+                      NGX_CLEAR_EVENT) == NGX_ERROR) {
+#else
+    if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
+                      NGX_ONESHOT_EVENT) == NGX_ERROR) {
+#endif
+       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);
+    }
+
+    return NGX_OK;
+}
+
 
 static int ngx_http_keepalive_handler(ngx_event_t *ev)
 {
+    ssize_t n;
     ngx_connection_t    *c;
     ngx_http_log_ctx_t  *ctx;
 
+    c = (ngx_connection_t *) ev->data;
+
     ngx_log_debug(ev->log, "http keepalive");
 
     if (ev->timedout)
         return NGX_DONE;
 
-    if (closed)
-        /* NGX_LOG_INFO or even silent */
-        return NGX_ERROR;
+    n = ngx_event_recv(c, c->buffer->last.mem,
+                       c->buffer->end - c->buffer->last.mem);
+
+    if (n == NGX_AGAIN || n == NGX_ERROR)
+        return n;
+
+    ctx = (ngx_http_log_ctx_t *) ev->log->data;
+    ev->log->handler = NULL;
 
-    c = (ngx_connection_t *) ev->data;
+    if (n == 0) {
+        ngx_log_error(NGX_LOG_INFO, ev->log, 0,
+                      "client %s closed keepalive connection", ctx->client);
+        return NGX_DONE;
+    }
 
-    ctx = (ngx_http_log_ctx_t *) c->log->data;
+    c->buffer->last.mem += n;
+    ev->log->handler = ngx_http_log_error;
     ctx->action = "reading client request line";
-    c->log->handler = ngx_http_log_error;
 
     return ngx_http_init_request(ev);
 }
 
-#endif
 
 static int ngx_http_lingering_close(ngx_event_t *ev)
 {
@@ -666,15 +721,21 @@ static int ngx_http_lingering_close(ngx_
     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);
+    if (r->discarded_buffer == NULL) {
+        if (r->header_in->end - r->header_in->last.mem
+                                         >= r->server->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_ERROR);
+        }
+    }
 
     n = ngx_event_recv(c, r->discarded_buffer,
                        r->server->discarded_buffer_size);
@@ -685,11 +746,12 @@ static int ngx_http_lingering_close(ngx_
     if (n == 0)
         return NGX_DONE;
 
-    if (timer > LINGERING_TIMEOUT)
-        timer = LINGERING_TIMEOUT;
+    timer *= 1000;
+    if (timer > r->server->lingering_timeout)
+        timer = r->server->lingering_timeout;
 
     ngx_del_timer(ev);
-    ngx_add_timer(ev, timer * 1000);
+    ngx_add_timer(ev, timer);
 
     return NGX_OK;
 }
@@ -700,6 +762,7 @@ static int ngx_http_special_response(ngx
     return ngx_http_error(r, error);
 }
 
+
 static int ngx_http_redirect(ngx_http_request_t *r, int redirect)
 {
     /* STUB */
@@ -709,6 +772,7 @@ static int ngx_http_redirect(ngx_http_re
     return ngx_http_close_request(r);
 }
 
+
 static int ngx_http_error(ngx_http_request_t *r, int error)
 {
     /* STUB */