# HG changeset patch # User Igor Sysoev # Date 1031841749 0 # Node ID f323b4f74e4a3b48e448df73eb1c71d1ebe4b4ed # Parent 4f3879d9b6f67b467c65c7a59475b87dfbfd9cf1 nginx-0.0.1-2002-09-12-18:42:29 import diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- 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 diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- 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) diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- 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; diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- 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; diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- 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; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- 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; } diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -4,6 +4,7 @@ #include +#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()" diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h --- 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_ */