# HG changeset patch # User Igor Sysoev # Date 1065798650 0 # Node ID 5526213be452ad298605c1d8805d985e3b82155e # Parent cb77c084acdb254c8afec2f1acfcbd112353371c nginx-0.0.1-2003-10-10-19:10:50 import diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -102,7 +102,6 @@ struct ngx_connection_s { unsigned pipeline:1; unsigned unexpected_eof:1; unsigned tcp_nopush:1; - unsigned tcp_nopush_enabled:1; #if (HAVE_IOCP) unsigned accept_context_updated:1; #endif 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 @@ -36,12 +36,12 @@ typedef struct ngx_connection_s ngx_con #define NGX_OK 0 #define NGX_ERROR -1 #define NGX_AGAIN -2 +#define NGX_DECLINED -4 +#define NGX_ABORT -5 + +/* #define NGX_DONE -3 -/* #define NGX_BUSY -3 -*/ -#define NGX_DECLINED -4 -/* #define NGX_ALERT -5 */ diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -379,6 +379,106 @@ void ngx_worker(ngx_cycle_t *cycle); #include #endif + + +ngx_inline static int ngx_handle_read_event(ngx_event_t *rev) +{ + if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) { + + /* aio, iocp, epoll */ + + return NGX_OK; + } + + if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { + + /* kqueue */ + + if (!rev->active && !rev->ready) { + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) + == NGX_ERROR) { + return NGX_ERROR; + } + } + + return NGX_OK; + } + + /* select, poll, /dev/poll */ + + if (!rev->active && !rev->ready) { + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_OK; + } + + if (rev->active && rev->ready) { + if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_OK; + } + + return NGX_OK; +} + + +ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, int lowat) +{ + if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) { + + /* aio, iocp, epoll */ + + return NGX_OK; + } + + if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { + + /* kqueue */ + +#if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */ + + if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) { + wev->lowat = lowat; + } + +#endif + if (!wev->active && !wev->ready) { + if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) + == NGX_ERROR) { + return NGX_ERROR; + } + } + + return NGX_OK; + } + + /* select, poll, /dev/poll */ + + if (!wev->active && !wev->ready) { + if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_OK; + } + + if (wev->active && wev->ready) { + if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_OK; + } + + return NGX_OK; +} + + + /* ***************************** */ diff --git a/src/event/ngx_event_proxy.c b/src/event/ngx_event_proxy.c --- a/src/event/ngx_event_proxy.c +++ b/src/event/ngx_event_proxy.c @@ -82,16 +82,14 @@ ngx_log_debug(p->log, "free hunk: %08X:% } else if (p->allocated < p->max_block_size) { h = ngx_create_temp_hunk(p->pool, p->block_size, 20, 20); if (h == NULL) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } p->allocated += p->block_size; temp = ngx_alloc_chain_entry(p->pool); if (temp == NULL) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } temp->hunk = h; @@ -163,8 +161,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ if (p->upstream->read->blocked) { if (ngx_add_event(p->upstream->read, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } p->block_upstream = 0; p->upstream->read->blocked = 0; @@ -237,8 +234,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ h = ngx_alloc_hunk(p->pool); if (h == NULL) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t)); @@ -248,8 +244,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ temp = ngx_alloc_chain_entry(p->pool); if (temp == NULL) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } temp->hunk = h; @@ -282,8 +277,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ if (p->input_filter) { if (p->input_filter(p, chain) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } } @@ -326,14 +320,12 @@ ngx_log_debug(p->log, "eof: %d block: %d #if (NGX_EVENT_COPY_FILTER) if (p->input_filter(p, NULL) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } #else if (p->input_filter) { if (p->input_filter(p, NULL) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } } else { @@ -380,18 +372,14 @@ ngx_log_debug(p->log, "eof: %d block: %d } if (p->out_hunks && p->downstream->write->ready) { - if (ngx_event_proxy_write_to_downstream(p) == NGX_ERROR - && p->fatal_error) - { - return NGX_ERROR; + if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) { + return NGX_ABORT; } } } else if ((p->out_hunks || p->in_hunks) && p->downstream->write->ready) { - if (ngx_event_proxy_write_to_downstream(p) == NGX_ERROR - && p->fatal_error) - { - return NGX_ERROR; + if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) { + return NGX_ABORT; } } @@ -404,8 +392,7 @@ ngx_log_debug(p->log, "upstream level: % && ngx_event_flags & NGX_USE_LEVEL_EVENT) { if (ngx_del_event(p->upstream->read, NGX_READ_EVENT, 0) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } p->upstream->read->blocked = 1; @@ -437,8 +424,7 @@ int ngx_event_proxy_write_to_downstream( { if (ngx_del_event(p->downstream->write, NGX_WRITE_EVENT, 0) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } p->downstream->write->blocked = 1; @@ -516,8 +502,7 @@ ngx_log_debug(p->log, "event proxy: %d" if (p->downstream->write->blocked) { if (ngx_add_event(p->downstream->write, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } p->downstream->write->blocked = 0; } @@ -584,8 +569,8 @@ ngx_log_debug(p->log, "event proxy: %d" } if (p->upstream->read->ready) { - if (ngx_event_proxy_read_upstream(p) == NGX_ERROR && p->fatal_error) { - return NGX_ERROR; + if (ngx_event_proxy_read_upstream(p) == NGX_ERROR) { + return NGX_ABORT; } } @@ -610,8 +595,7 @@ ngx_log_debug(p->log, "write to file"); p->cachable); if (rc == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } if (rc == NGX_AGAIN) { @@ -660,8 +644,7 @@ ngx_log_debug(p->log, "write to file"); if (ngx_write_chain_to_file(p->temp_file, p->in_hunks, p->temp_offset, p->pool) == NGX_ERROR) { - p->fatal_error = 1; - return NGX_ERROR; + return NGX_ABORT; } for (entry = p->in_hunks; entry; entry = next) { diff --git a/src/event/ngx_event_proxy.h b/src/event/ngx_event_proxy.h --- a/src/event/ngx_event_proxy.h +++ b/src/event/ngx_event_proxy.h @@ -40,7 +40,6 @@ struct ngx_event_proxy_s { void *output_data; unsigned cachable:1; - unsigned fatal_error:1; unsigned block_upstream:1; unsigned upstream_eof:1; unsigned upstream_error:1; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -127,33 +127,12 @@ int ngx_http_static_handler(ngx_http_req rc = ngx_http_send_header(r); - if (rc == NGX_ERROR || rc > NGX_OK) { - ngx_http_finalize_request(r, rc); - return NGX_OK; + + if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { + return rc; } - if (r->header_only) { - ngx_http_finalize_request(r, rc); - -#if 0 - if (rc == NGX_AGAIN) { - ngx_http_set_write_handler(r); - - } else { - ngx_http_finalize_request(r, 0); - } -#endif - - return NGX_OK; - } - - -#if 0 h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST; -#else - h->type = NGX_HUNK_FILE; -#endif - h->file_pos = 0; h->file_last = ngx_file_size(r->file.info); @@ -161,20 +140,5 @@ int ngx_http_static_handler(ngx_http_req h->file->fd = r->file.fd; h->file->log = r->connection->log; - rc = ngx_http_output_filter(r, h); - - ngx_http_finalize_request(r, rc); - -#if 0 - if (r->main == NULL) { - if (rc == NGX_AGAIN) { - ngx_http_set_write_handler(r); - - } else { - ngx_http_finalize_request(r, 0); - } - } -#endif - - return NGX_OK; + return ngx_http_output_filter(r, h); } diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -1108,7 +1108,9 @@ static int ngx_http_proxy_init(ngx_cycle ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; - ngx_test_null(h, ngx_push_array(&cmcf->translate_handlers), NGX_ERROR); + ngx_test_null(h, ngx_push_array( + &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers), + NGX_ERROR); *h = ngx_http_proxy_translate_handler; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -203,8 +203,21 @@ static char *ngx_http_block(ngx_conf_t * /* init list of the handlers */ - ngx_init_array(cmcf->translate_handlers, cf->cycle->pool, - 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); + ngx_init_array(cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers, + cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), + NGX_CONF_ERROR); + + cmcf->phases[NGX_HTTP_REWRITE_PHASE].type = NGX_OK; + cmcf->phases[NGX_HTTP_REWRITE_PHASE].post_handler = + ngx_http_find_location_config; + + + ngx_init_array(cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers, + cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), + NGX_CONF_ERROR); + + cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].type = NGX_OK; + ngx_init_array(cmcf->index_handlers, cf->cycle->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); 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 @@ -17,8 +17,6 @@ typedef struct { } ngx_http_log_ctx_t; -typedef int (*ngx_http_handler_pt)(ngx_http_request_t *r); - typedef int (*ngx_http_output_header_filter_p)(ngx_http_request_t *r); typedef int (*ngx_http_output_body_filter_p) @@ -51,7 +49,7 @@ int ngx_http_parse_header_line(ngx_http_ int ngx_http_find_server_conf(ngx_http_request_t *r); void ngx_http_handler(ngx_http_request_t *r); void ngx_http_finalize_request(ngx_http_request_t *r, int error); -void ngx_http_set_write_handler(ngx_http_request_t *r); +void ngx_http_writer(ngx_event_t *wev); int ngx_http_send_last(ngx_http_request_t *r); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -8,6 +9,8 @@ /* STUB */ int ngx_http_static_handler(ngx_http_request_t *r); +static void ngx_http_phase_event_handler(ngx_event_t *rev); +static void ngx_http_run_phases(ngx_http_request_t *r); static int ngx_http_core_index_handler(ngx_http_request_t *r); @@ -201,12 +204,7 @@ ngx_module_t ngx_http_core_module = { void ngx_http_handler(ngx_http_request_t *r) { - int rc, i; - ngx_http_log_ctx_t *lcx; - ngx_http_handler_pt *h; - ngx_http_core_loc_conf_t *clcf, **clcfp; - ngx_http_core_srv_conf_t *cscf; - ngx_http_core_main_conf_t *cmcf; + ngx_http_log_ctx_t *lcx; r->connection->unexpected_eof = 0; @@ -221,11 +219,100 @@ void ngx_http_handler(ngx_http_request_t /* TEST STUB */ r->lingering_close = 1; + r->connection->write->event_handler = ngx_http_phase_event_handler; - /* TODO: run rewrite url phase */ + r->phase = 0; + r->phase_handler = 0; + + ngx_http_run_phases(r); + + return; +} + + +static void ngx_http_phase_event_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + ngx_http_request_t *r; + + c = ev->data; + r = c->data; + + ngx_http_run_phases(r); + + return; +} - /* find location config */ +static void ngx_http_run_phases(ngx_http_request_t *r) +{ + int rc; + ngx_http_handler_pt *h; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + rc = NGX_DECLINED; + + for (/* void */; r->phase < NGX_HTTP_LAST_PHASE; r->phase++) { + + h = cmcf->phases[r->phase].handlers.elts; + for (r->phase_handler = cmcf->phases[r->phase].handlers.nelts - 1; + r->phase_handler >= 0; + r->phase_handler--) + { + rc = h[r->phase_handler](r); + + if (rc == NGX_DECLINED) { + continue; + } + + if (rc == NGX_AGAIN) { + return; + } + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + ngx_http_finalize_request(r, rc); + return; + } + + if (rc == NGX_OK && cmcf->phases[r->phase].type == NGX_OK) { + break; + } + } + + if (cmcf->phases[r->phase].post_handler) { + rc = cmcf->phases[r->phase].post_handler(r); + + if (rc == NGX_AGAIN) { + return; + } + + if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { + ngx_http_finalize_request(r, rc); + return; + } + } + } + + if (r->content_handler) { + r->connection->write->event_handler = ngx_http_writer; + rc = r->content_handler(r); + ngx_http_finalize_request(r, rc); + return; + } + + /* TODO: no handlers found ? */ + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return; +} + + +int ngx_http_find_location_config(ngx_http_request_t *r) +{ + int i, rc; + ngx_http_core_loc_conf_t *clcf, **clcfp; + ngx_http_core_srv_conf_t *cscf; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); @@ -261,36 +348,7 @@ ngx_log_debug(r->connection->log, "rc: % r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; } - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - - /* run translation phase */ - - h = cmcf->translate_handlers.elts; - for (i = cmcf->translate_handlers.nelts - 1; i >= 0; i--) { - - rc = h[i](r); - - if (rc == NGX_DECLINED) { - continue; - } - - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { - ngx_http_finalize_request(r, rc); - return; - } - - if (rc == NGX_OK) { - rc = r->handler(r); - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { - ngx_http_finalize_request(r, rc); - } - return; - } - } - - /* TODO: no handlers found ? */ - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; + return NGX_OK; } @@ -305,14 +363,14 @@ int ngx_http_core_translate_handler(ngx_ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (clcf->handler) { - r->handler = clcf->handler; + r->content_handler = clcf->handler; return NGX_OK; } cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (r->uri.data[r->uri.len - 1] == '/') { - r->handler = ngx_http_core_index_handler; + r->content_handler = ngx_http_core_index_handler; return NGX_OK; } @@ -424,7 +482,7 @@ ngx_log_debug(r->connection->log, "HTTP return NGX_HTTP_MOVED_PERMANENTLY; } - r->handler = ngx_http_static_handler; + r->content_handler = ngx_http_static_handler; return NGX_OK; } @@ -548,7 +606,9 @@ static int ngx_http_core_init(ngx_cycle_ ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; - ngx_test_null(h, ngx_push_array(&cmcf->translate_handlers), NGX_ERROR); + ngx_test_null(h, ngx_push_array( + &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers), + NGX_ERROR); *h = ngx_http_core_translate_handler; @@ -756,7 +816,7 @@ static void *ngx_http_core_create_main_c ngx_http_core_main_conf_t *cmcf; ngx_test_null(cmcf, - ngx_palloc(cf->pool, sizeof(ngx_http_core_main_conf_t)), + ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t)), NGX_CONF_ERROR); ngx_init_array(cmcf->servers, cf->pool, diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -18,9 +18,20 @@ typedef struct { typedef struct { - ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */ - ngx_array_t translate_handlers; - ngx_array_t index_handlers; + ngx_array_t handlers; + int type; /* NGX_OK, NGX_DECLINED */ + ngx_http_handler_pt post_handler; +} ngx_http_phase_t; + +#define NGX_HTTP_REWRITE_PHASE 0 +#define NGX_HTTP_TRANSLATE_PHASE 1 +#define NGX_HTTP_LAST_PHASE 2 + +typedef struct { + ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */ + + ngx_http_phase_t phases[NGX_HTTP_LAST_PHASE]; + ngx_array_t index_handlers; } ngx_http_core_main_conf_t; @@ -138,6 +149,7 @@ extern int ngx_http_max_module; +int ngx_http_find_location_config(ngx_http_request_t *r); int ngx_http_core_translate_handler(ngx_http_request_t *r); int ngx_http_internal_redirect(ngx_http_request_t *r, diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -4,12 +4,6 @@ #include #include -/* STUB probably, needed for ngx_freebsd_tcp_nopush_flush */ -#ifdef __FreeBSD__ -#include -#endif - - static int ngx_http_header_filter_init(ngx_cycle_t *cycle); static int ngx_http_header_filter(ngx_http_request_t *r); @@ -100,23 +94,6 @@ static int ngx_http_header_filter(ngx_ht ngx_chain_t *ch; ngx_table_elt_t *header; -#ifdef __FreeBSD__ - - if (r->keepalive) { - if (ngx_freebsd_tcp_nopush_flush) { - r->connection->tcp_nopush_enabled = 1; - } - - } else { - r->connection->tcp_nopush_enabled = 1; - } - -#else - - r->connection->tcp_nopush_enabled = 1; - -#endif - if (r->http_version < NGX_HTTP_VERSION_10) { return NGX_OK; } diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -203,7 +203,9 @@ int ngx_http_output_filter(ngx_http_requ ctx->last_out = &ce->next; ctx->hunk = NULL; - break; + if (ctx->free == NULL) { + break; + } } if (ctx->out == NULL && last != NGX_NONE) { diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -10,7 +10,7 @@ static void ngx_http_process_request_lin static void ngx_http_process_request_headers(ngx_event_t *rev); static ssize_t ngx_http_read_request_header(ngx_http_request_t *r); -static void ngx_http_writer(ngx_event_t *ev); +static void ngx_http_set_write_handler(ngx_http_request_t *r); static void ngx_http_block_read(ngx_event_t *ev); static void ngx_http_read_discarded_body_event(ngx_event_t *rev); @@ -112,6 +112,13 @@ void ngx_http_init_connection(ngx_connec return; } + if (ngx_handle_read_event(rev) == NGX_ERROR) { + ngx_http_close_connection(c); + return; + } + +#if 0 + if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { /* kqueue */ event = NGX_CLEAR_EVENT; @@ -124,6 +131,10 @@ void ngx_http_init_connection(ngx_connec if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) { ngx_http_close_connection(c); } + +#endif + + return; } @@ -660,6 +671,7 @@ static void ngx_http_process_request_hea } rev->event_handler = ngx_http_block_read; + c->write->event_handler = ngx_http_writer; ngx_http_handler(r); return; @@ -743,6 +755,13 @@ static ssize_t ngx_http_read_request_hea r->header_timeout_set = 1; } + if (ngx_handle_read_event(rev) == NGX_ERROR) { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_http_close_connection(r->connection); + return NGX_ERROR; + } + +#if 0 if (!rev->active) { if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { /* kqueue */ @@ -759,6 +778,7 @@ static ssize_t ngx_http_read_request_hea return NGX_ERROR; } } +#endif return NGX_AGAIN; } @@ -780,17 +800,14 @@ static ssize_t ngx_http_read_request_hea } -void ngx_http_finalize_request(ngx_http_request_t *r, int error) +void ngx_http_finalize_request(ngx_http_request_t *r, int rc) { - int rc; ngx_event_t *rev, *wev; - if (r->main) { + if (r->main || r->closed) { return; } - rc = error; - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { rev = r->connection->read; @@ -805,37 +822,18 @@ void ngx_http_finalize_request(ngx_http_ wev->timer_set = 0; } - rc = ngx_http_special_response_handler(r, rc); - - if (rc == NGX_AGAIN) { - return; - } + ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc)); - if (rc == NGX_ERROR) { - ngx_http_close_request(r, 0); - ngx_http_close_connection(r->connection); - return; - } - -#if 1 return; -#endif } else if (rc == NGX_ERROR) { - r->keepalive = 0; - r->lingering_close = 0; + ngx_http_close_request(r, 0); + ngx_http_close_connection(r->connection); + return; - } else { - if (ngx_http_send_last(r) == NGX_ERROR) { - ngx_http_close_request(r, 0); - ngx_http_close_connection(r->connection); - return; - } - - if (rc == NGX_AGAIN) { - ngx_http_set_write_handler(r); - return; - } + } else if (rc == NGX_AGAIN) { + ngx_http_set_write_handler(r); + return; } rev = r->connection->read; @@ -865,7 +863,7 @@ void ngx_http_finalize_request(ngx_http_ } -void ngx_http_set_write_handler(ngx_http_request_t *r) +static void ngx_http_set_write_handler(ngx_http_request_t *r) { int event; ngx_event_t *wev; @@ -883,6 +881,13 @@ void ngx_http_set_write_handler(ngx_http ngx_add_timer(wev, clcf->send_timeout); wev->timer_set = 1; + if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { + ngx_http_close_request(r, 0); + ngx_http_close_connection(r->connection); + } + +#if 0 + if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) { /* aio, iocp, epoll */ return; @@ -910,11 +915,13 @@ void ngx_http_set_write_handler(ngx_http ngx_http_close_connection(r->connection); } +#endif + return; } -static void ngx_http_writer(ngx_event_t *wev) +void ngx_http_writer(ngx_event_t *wev) { int rc; ngx_event_t *rev; @@ -1454,6 +1461,10 @@ void ngx_http_close_request(ngx_http_req ctx->url = NULL; ngx_destroy_pool(r->pool); + + r->closed = 1; + + return; } @@ -1497,6 +1508,8 @@ void ngx_http_close_connection(ngx_conne c->fd = -1; ngx_destroy_pool(c->pool); + + return; } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -126,6 +126,8 @@ typedef struct { typedef struct ngx_http_request_s ngx_http_request_t; +typedef int (*ngx_http_handler_pt)(ngx_http_request_t *r); + struct ngx_http_request_s { ngx_connection_t *connection; @@ -143,8 +145,6 @@ struct ngx_http_request_s { ngx_http_headers_in_t headers_in; ngx_http_headers_out_t headers_out; - int (*handler)(ngx_http_request_t *r); - time_t lingering_time; int method; @@ -166,6 +166,9 @@ struct ngx_http_request_s { ngx_str_t *server_name; ngx_array_t *virtual_names; + int phase; + int phase_handler; + ngx_http_handler_pt content_handler; char *discarded_buffer; @@ -188,6 +191,7 @@ struct ngx_http_request_s { unsigned header_only:1; unsigned keepalive:1; unsigned lingering_close:1; + unsigned closed:1; /* TODO: use filter or bits ???? */ int filter; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -200,20 +200,8 @@ int ngx_http_special_response_handler(ng rc = ngx_http_send_header(r); - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (r->header_only) { - ngx_http_finalize_request(r, rc); -#if 0 - if (rc == NGX_AGAIN) { - ngx_http_set_write_handler(r); - return NGX_AGAIN; - } -#endif - - return NGX_OK; + if (rc == NGX_ERROR || r->header_only) { + return rc; } if (error_pages[err].len == 0) { @@ -236,7 +224,7 @@ int ngx_http_special_response_handler(ng h->pos = error_tail; h->last = error_tail + sizeof(error_tail) - 1; - if (1) { + if (/* STUB: "msie_padding on/off" */ 1) { if (ngx_http_output_filter(r, h) == NGX_ERROR) { return NGX_ERROR; } @@ -250,19 +238,5 @@ int ngx_http_special_response_handler(ng h->type |= NGX_HUNK_LAST; - rc = ngx_http_output_filter(r, h); - - ngx_http_finalize_request(r, rc); - -#if 0 - if (r->main == NULL) { - if (rc == NGX_AGAIN) { - ngx_http_set_write_handler(r); - return NGX_AGAIN; - } - } -#endif - - return NGX_OK; - + return ngx_http_output_filter(r, h); } diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -143,6 +143,10 @@ int ngx_http_write_filter(ngx_http_reque return NGX_AGAIN; } + if (size == 0) { + return NGX_OK; + } + chain = ngx_write_chain(r->connection, ctx->out); #if (NGX_DEBUG_WRITE_FILTER) diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -9,7 +9,7 @@ int ngx_freebsd_kern_osreldate; int ngx_freebsd_hw_ncpu; int ngx_freebsd_net_inet_tcp_sendspace; int ngx_freebsd_sendfile_nbytes_bug; -int ngx_freebsd_tcp_nopush_flush; +int ngx_freebsd_use_tcp_nopush; /* FreeBSD 5.0 */ int ngx_freebsd_kern_ipc_zero_copy_send; @@ -125,7 +125,7 @@ int ngx_os_init(ngx_log_t *log) if ((version < 500000 && version >= 440003) || version >= 500017) { - ngx_freebsd_tcp_nopush_flush = 1; + ngx_freebsd_use_tcp_nopush = 1; } diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h --- a/src/os/unix/ngx_freebsd_init.h +++ b/src/os/unix/ngx_freebsd_init.h @@ -19,9 +19,8 @@ extern int ngx_freebsd_kern_osreldate; extern int ngx_freebsd_hw_ncpu; extern int ngx_freebsd_net_inet_tcp_sendspace; extern int ngx_freebsd_sendfile_nbytes_bug; -extern int ngx_freebsd_tcp_nopush_flush; extern int ngx_freebsd_kern_ipc_zero_copy_send; -extern int ngx_freebsd_tcp_nopush_flush; +extern int ngx_freebsd_use_tcp_nopush; #endif /* _NGX_FREEBSD_INIT_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -14,16 +14,16 @@ * and the first part of the file in one packet but also sends 4K pages * in the full packets. * - * Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush - * the pending data that less than MSS and the data sent with 5 second delay. - * So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection - * is not needed to be keepalive. + * Until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush + * the pending data that less than MSS so the data is sent with 5 second delay. + * We do not use TCP_NOPUSH on FreeBSD prior to 4.5 although it can be used + * for non-keepalive HTTP connections. */ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) { - int rc, eintr, tcp_nopush; + int rc, eintr; char *prev; ssize_t hsize, size; off_t sent; @@ -34,8 +34,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( ngx_hunk_t *file; ngx_chain_t *ce, *tail; - tcp_nopush = 0; - do { ce = in; file = NULL; @@ -47,42 +45,33 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); - /* create the header iovec */ + /* create the iovec and coalesce the neighbouring chain entries */ + + prev = NULL; + iov = NULL; -#if 0 - if (ngx_hunk_in_memory_only(ce->hunk) || ngx_hunk_special(ce->hunk)) { -#endif - prev = NULL; - iov = NULL; + for (ce = in; ce; ce = ce->next) { + if (ngx_hunk_special(ce->hunk)) { + continue; + } - /* create the iovec and coalesce the neighbouring chain entries */ - - for ( /* void */; ce; ce = ce->next) { - if (ngx_hunk_special(ce->hunk)) { - continue; - } + if (!ngx_hunk_in_memory_only(ce->hunk)) { + break; + } - if (!ngx_hunk_in_memory_only(ce->hunk)) { - break; - } - - if (prev == ce->hunk->pos) { - iov->iov_len += ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; + if (prev == ce->hunk->pos) { + iov->iov_len += ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; - } else { - ngx_test_null(iov, ngx_push_array(&header), - NGX_CHAIN_ERROR); - iov->iov_base = ce->hunk->pos; - iov->iov_len = ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; - } + } else { + ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR); + iov->iov_base = ce->hunk->pos; + iov->iov_len = ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; + } - hsize += ce->hunk->last - ce->hunk->pos; - } -#if 0 + hsize += ce->hunk->last - ce->hunk->pos; } -#endif /* TODO: coalesce the neighbouring file hunks */ @@ -91,57 +80,46 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( ce = ce->next; } - /* create the trailer iovec */ + /* create the iovec and coalesce the neighbouring chain entries */ + + prev = NULL; + iov = NULL; -#if 0 - if (ce - && (ngx_hunk_in_memory_only(ce->hunk) - || ngx_hunk_special(ce->hunk))) - { -#endif - prev = NULL; - iov = NULL; - - /* create the iovec and coalesce the neighbouring chain entries */ - - for ( /* void */; ce; ce = ce->next) { - if (ngx_hunk_special(ce->hunk)) { - continue; - } + for ( /* void */; ce; ce = ce->next) { + if (ngx_hunk_special(ce->hunk)) { + continue; + } - if (!ngx_hunk_in_memory_only(ce->hunk)) { - break; - } + if (!ngx_hunk_in_memory_only(ce->hunk)) { + break; + } - if (prev == ce->hunk->pos) { - iov->iov_len += ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; + if (prev == ce->hunk->pos) { + iov->iov_len += ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; - } else { - ngx_test_null(iov, ngx_push_array(&trailer), - NGX_CHAIN_ERROR); - iov->iov_base = ce->hunk->pos; - iov->iov_len = ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; - } + } else { + ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR); + iov->iov_base = ce->hunk->pos; + iov->iov_len = ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; } -#if 0 } -#endif tail = ce; if (file) { - if (!c->tcp_nopush && c->tcp_nopush_enabled) { + if (ngx_freebsd_use_tcp_nopush && !c->tcp_nopush) { c->tcp_nopush = 1; - tcp_nopush = 1; + +ngx_log_debug(c->log, "NOPUSH"); + if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, ngx_tcp_nopush_n " failed"); return NGX_CHAIN_ERROR; } -ngx_log_debug(c->log, "NOPUSH"); } hdtr.headers = (struct iovec *) header.elts; @@ -182,36 +160,28 @@ ngx_log_debug(c->log, "NOPUSH"); #endif } else { - if (hsize) { - rc = writev(c->fd, (struct iovec *) header.elts, header.nelts); + rc = writev(c->fd, (struct iovec *) header.elts, header.nelts); - if (rc == -1) { - err = ngx_errno; - if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, c->log, err, - "writev() EAGAIN"); + if (rc == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); - } else if (err == NGX_EINTR) { - eintr = 1; - ngx_log_error(NGX_LOG_INFO, c->log, err, - "writev() EINTR"); + } else if (err == NGX_EINTR) { + eintr = 1; + ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); - } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, - "writev() failed"); - return NGX_CHAIN_ERROR; - } + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); + return NGX_CHAIN_ERROR; } + } - sent = rc > 0 ? rc : 0; + sent = rc > 0 ? rc : 0; #if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "writev: %qd" _ sent); + ngx_log_debug(c->log, "writev: %qd" _ sent); #endif - - } else { - sent = 0; - } } c->sent += sent;