diff options
41 files changed, 1510 insertions, 941 deletions
diff --git a/src/core/nginx.c b/src/core/nginx.c index ad0cd57c4..6fbc33bfd 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -4,6 +4,7 @@ #include <ngx_config.h> #include <ngx_core.h> +#include <ngx_connection.h> #include <ngx_os_init.h> #include <ngx_string.h> #include <ngx_errno.h> @@ -13,7 +14,6 @@ #include <ngx_array.h> #include <ngx_socket.h> #include <ngx_server.h> -#include <ngx_connection.h> #include <ngx_listen.h> #include <ngx_conf_file.h> @@ -33,8 +33,12 @@ u_int ngx_sendfile_flags; ngx_server_t ngx_server; /* */ -ngx_log_t ngx_log; -ngx_pool_t *ngx_pool; +ngx_log_t ngx_log; +ngx_pool_t *ngx_pool; +void ****ngx_conf_ctx; + + +ngx_os_io_t ngx_io; int ngx_max_module; @@ -55,94 +59,76 @@ int main(int argc, char *const *argv) ngx_log.log_level = NGX_LOG_DEBUG; if (ngx_os_init(&ngx_log) == NGX_ERROR) { - exit(1); + return 1; } ngx_pool = ngx_create_pool(16 * 1024, &ngx_log); /* */ -#if (WIN32) - - if (ngx_init_sockets(&ngx_log) == NGX_ERROR) { - exit(1); - } - -#else - - ngx_set_signals(&ngx_log); - -#endif - - ngx_init_array(ngx_listening_sockets, ngx_pool, 10, sizeof(ngx_listen_t), - 1); - ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; } - ngx_memzero(&conf, sizeof(ngx_conf_t)); + /* life cycle */ - ngx_test_null(conf.args, ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)), - 1); + { + ngx_init_array(ngx_listening_sockets, + ngx_pool, 10, sizeof(ngx_listen_t), + 1); - ngx_test_null(conf.ctx, - ngx_pcalloc(ngx_pool, ngx_max_module * sizeof(void *)), - 1); + ngx_memzero(&conf, sizeof(ngx_conf_t)); - conf.pool = ngx_pool; - conf.log = &ngx_log; - conf.module_type = NGX_CORE_MODULE_TYPE; - conf.cmd_type = NGX_MAIN_CONF; + ngx_test_null(conf.args, + ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)), + 1); - conf_file.len = sizeof("nginx.conf") - 1; - conf_file.data = "nginx.conf"; + ngx_test_null(ngx_conf_ctx, + ngx_pcalloc(ngx_pool, ngx_max_module * sizeof(void *)), + 1); - if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) { - return 1; - } + conf.ctx = ngx_conf_ctx; + conf.pool = ngx_pool; + conf.log = &ngx_log; + conf.module_type = NGX_CORE_MODULE_TYPE; + conf.cmd_type = NGX_MAIN_CONF; - ngx_init_temp_number(); + conf_file.len = sizeof("nginx.conf") - 1; + conf_file.data = "nginx.conf"; - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->init_module) { - if (ngx_modules[i]->init_module(ngx_pool) == NGX_ERROR) { - return 1; + if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) { + return 1; + } + + ngx_init_temp_number(); + + ngx_io = ngx_os_io; + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->init_module) { + if (ngx_modules[i]->init_module(ngx_pool) == NGX_ERROR) { + return 1; + } } } - } - ngx_open_listening_sockets(&ngx_log); + ngx_open_listening_sockets(&ngx_log); - /* TODO: daemon */ + /* TODO: daemon, once only */ - /* TODO: fork */ + /* TODO: fork */ - ngx_pre_thread(&ngx_listening_sockets, ngx_pool, &ngx_log); + ngx_pre_thread(&ngx_listening_sockets, ngx_pool, &ngx_log); - /* TODO: threads */ + /* TODO: threads */ - /* STUB */ - ngx_worker(&ngx_log); + /* STUB */ + ngx_worker(&ngx_log); + } return 0; } -#if !(WIN32) -static void ngx_set_signals(ngx_log_t *log) -{ - struct sigaction sa; - - ngx_memzero(&sa, sizeof(struct sigaction)); - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGPIPE, &sa, NULL) == -1) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, - "sigaction(SIGPIPE, SIG_IGN) failed"); - exit(1); - } -} -#endif static void ngx_open_listening_sockets(ngx_log_t *log) { diff --git a/src/core/ngx_alloc.h b/src/core/ngx_alloc.h index 722d79cd1..1d2f2f7ea 100644 --- a/src/core/ngx_alloc.h +++ b/src/core/ngx_alloc.h @@ -42,5 +42,7 @@ void ngx_destroy_pool(ngx_pool_t *pool); void *ngx_palloc(ngx_pool_t *pool, size_t size); void *ngx_pcalloc(ngx_pool_t *pool, size_t size); +#define ngx_free free + #endif /* _NGX_ALLOC_H_INCLUDED_ */ diff --git a/src/core/ngx_array.h b/src/core/ngx_array.h index 22c7c4b0f..22cb3fc35 100644 --- a/src/core/ngx_array.h +++ b/src/core/ngx_array.h @@ -7,7 +7,7 @@ #include <ngx_alloc.h> typedef struct { - char *elts; + void *elts; int nelts; size_t size; int nalloc; diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c index 3d93f02e0..99af0afbd 100644 --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -19,7 +19,7 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { int i, rc, found; char *rv; - void *conf, **pconf; + void *conf, **confp; ngx_str_t *name; ngx_fd_t fd; ngx_conf_file_t *prev; @@ -164,10 +164,10 @@ ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data); conf = &(((void **) cf->ctx)[ngx_modules[i]->index]); } else if (cf->ctx) { - pconf = *(void **) ((char *) cf->ctx + cmd->conf); + confp = *(void **) ((char *) cf->ctx + cmd->conf); - if (pconf) { - conf = pconf[*(int *)(ngx_modules[i]->ctx)]; + if (confp) { + conf = confp[*(int *)(ngx_modules[i]->ctx)]; } } diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h index a63262519..40b976316 100644 --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -96,17 +96,35 @@ struct ngx_conf_s { }; -#define ngx_conf_merge(conf, prev, default) \ +#define ngx_get_conf(module) ngx_conf_ctx[module.index] + + +#define ngx_conf_init_value(conf, default) \ + if (conf == NGX_CONF_UNSET) { \ + conf = default; \ + } + +#define ngx_conf_init_size_value(conf, default) \ + if (conf == NGX_CONF_UNSET) { \ + conf = default; \ + } + +#define ngx_conf_init_msec_value(conf, default) \ + if (conf == NGX_CONF_UNSET) { \ + conf = default; \ + } + +#define ngx_conf_merge_value(conf, prev, default) \ if (conf == NGX_CONF_UNSET) { \ conf = (prev == NGX_CONF_UNSET) ? default : prev; \ } -#define ngx_conf_msec_merge(conf, prev, default) \ +#define ngx_conf_merge_msec_value(conf, prev, default) \ if (conf == (ngx_msec_t) NGX_CONF_UNSET) { \ conf = (prev == (ngx_msec_t) NGX_CONF_UNSET) ? default : prev; \ } -#define ngx_conf_size_merge(conf, prev, default) \ +#define ngx_conf_merge_size_value(conf, prev, default) \ if (conf == (size_t) NGX_CONF_UNSET) { \ conf = (prev == (size_t) NGX_CONF_UNSET) ? default : prev; \ } @@ -126,7 +144,8 @@ char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); -extern ngx_module_t *ngx_modules[]; +extern ngx_module_t *ngx_modules[]; +extern void ****ngx_conf_ctx; #endif /* _NGX_HTTP_CONF_FILE_H_INCLUDED_ */ diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h index 8287d5680..e039cd6a5 100644 --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -92,6 +92,7 @@ #include <sys/time.h> #include <sys/socket.h> #include <sys/uio.h> +#include <sys/resource.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 544101b44..8ad48c8d1 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -81,12 +81,26 @@ EV_VNODE should notify by some signal if diretory tree is changed #endif +typedef struct { + ssize_t (*recv)(ngx_connection_t *c, char *buf, size_t size); + void *dummy_recv_chain; + void *dummy_send; + ngx_chain_t *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in); +} ngx_os_io_t; + + +extern ngx_os_io_t ngx_io; + + + extern ngx_chain_t *(*ngx_write_chain_proc) (ngx_connection_t *c, ngx_chain_t *in); ssize_t ngx_recv_chain(ngx_connection_t *c, ngx_chain_t *ce); +#if 0 ngx_chain_t *ngx_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t flush); +#endif /* TODO: move it to OS specific file */ diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index fd5bb9273..acb7fa430 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -2,6 +2,23 @@ #define _NGX_CORE_H_INCLUDED_ +#include <ngx_types.h> +#include <ngx_time.h> +#include <ngx_socket.h> +#include <ngx_files.h> + +#include <ngx_log.h> +#include <ngx_alloc.h> +#include <ngx_hunk.h> +#include <ngx_array.h> +#include <ngx_string.h> +#include <ngx_file.h> +#include <ngx_conf_file.h> +#include <ngx_connection.h> +#include <ngx_os_init.h> + + + #define NGX_OK 0 #define NGX_ERROR -1 #define NGX_AGAIN -2 diff --git a/src/core/ngx_modules.c b/src/core/ngx_modules.c index 273c5550e..db6cf7351 100644 --- a/src/core/ngx_modules.c +++ b/src/core/ngx_modules.c @@ -7,6 +7,11 @@ extern ngx_module_t ngx_events_module; extern ngx_module_t ngx_event_module; +extern ngx_module_t ngx_select_module; +#if (HAVE_KQUEUE) +extern ngx_module_t ngx_kqueue_module; +#endif + extern ngx_module_t ngx_http_module; extern ngx_module_t ngx_http_core_module; @@ -26,6 +31,11 @@ ngx_module_t *ngx_modules[] = { &ngx_events_module, &ngx_event_module, + &ngx_select_module, +#if (HAVE_KQUEUE) + &ngx_kqueue_module, +#endif + /* http */ &ngx_http_module, diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index e678f7333..7c97c1344 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -53,4 +53,8 @@ int ngx_rstrncmp(char *s1, char *s2, size_t n); int ngx_atoi(char *line, size_t n); +#define ngx_value_helper(n) #n +#define ngx_value(n) ngx_value_helper(n) + + #endif /* _NGX_STRING_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c index f2d0e83c7..20cb1a63c 100644 --- a/src/event/modules/ngx_aio_module.c +++ b/src/event/modules/ngx_aio_module.c @@ -21,7 +21,7 @@ int ngx_aio_init(int max_connections, ngx_log_t *log) rc = ngx_kqueue_init(max_connections, log); - ngx_event_flags = NGX_HAVE_AIO_EVENT; + ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_USE_AIO_EVENT; ngx_write_chain_proc = ngx_aio_write_chain; return rc; diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index 8cc7190a1..bf03f5c87 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -1,3 +1,4 @@ + /* * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru */ @@ -5,39 +6,30 @@ #include <ngx_config.h> #include <ngx_core.h> -#include <ngx_types.h> -#include <ngx_log.h> #include <ngx_connection.h> #include <ngx_event.h> -#include <ngx_event_timer.h> -#include <ngx_conf_file.h> #include <ngx_kqueue_module.h> -/* STUB */ -#define KQUEUE_NCHANGES 512 -#define KQUEUE_NEVENTS 512 - +static int ngx_kqueue_init(ngx_log_t *log); +static void ngx_kqueue_done(ngx_log_t *log); +static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); +static int ngx_kqueue_process_events(ngx_log_t *log); -static int ngx_kqueue_changes; -static int ngx_kqueue_events; +static void *ngx_kqueue_create_conf(ngx_pool_t *pool); +static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf); -/* should be per-thread if threads are used without thread pool */ -#if 1 -int kq; -#else -static int kq; -#endif -static struct kevent *change_list, *event_list; -static unsigned int nchanges; -static int nevents; +int ngx_kqueue; -static ngx_event_t *timer_queue; -/* */ +static struct kevent *change_list, *event_list; +static u_int max_changes, nchanges; +static int nevents; -static ngx_str_t kqueue_name = ngx_string("kqueue"); +static ngx_str_t kqueue_name = ngx_string("kqueue"); static ngx_command_t ngx_kqueue_commands[] = { @@ -45,21 +37,42 @@ static ngx_command_t ngx_kqueue_commands[] = { NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, - addressof(ngx_kqueue_changes), + offsetof(ngx_kqueue_conf_t, changes), NULL}, {ngx_string("kqueue_events"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, - addressof(ngx_kqueue_events), + offsetof(ngx_kqueue_conf_t, events), NULL}, {ngx_string(""), 0, NULL, 0, 0, NULL} }; + +ngx_event_module_t ngx_kqueue_module_ctx = { + NGX_EVENT_MODULE, + &kqueue_name, + ngx_kqueue_create_conf, /* create configuration */ + ngx_kqueue_init_conf, /* init configuration */ + + { + ngx_kqueue_add_event, /* add an event */ + ngx_kqueue_del_event, /* delete an event */ + ngx_kqueue_add_event, /* enable an event */ + ngx_kqueue_del_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + ngx_kqueue_process_events, /* process the events */ + ngx_kqueue_init, /* init the events */ + ngx_kqueue_done, /* done the events */ + } + +}; + ngx_module_t ngx_kqueue_module = { - &kqueue_name, /* module context */ + &ngx_kqueue_module_ctx, /* module context */ 0, /* module index */ ngx_kqueue_commands, /* module directives */ NGX_EVENT_MODULE_TYPE, /* module type */ @@ -67,109 +80,91 @@ ngx_module_t ngx_kqueue_module = { }; - -int ngx_kqueue_init(int max_connections, ngx_log_t *log) +static int ngx_kqueue_init(ngx_log_t *log) { - int change_size, event_size; + ngx_kqueue_conf_t *kcf; - nevents = KQUEUE_NEVENTS; + kcf = ngx_event_get_conf(ngx_kqueue_module_ctx); + +ngx_log_debug(log, "CH: %d" _ kcf->changes); +ngx_log_debug(log, "EV: %d" _ kcf->events); + + max_changes = kcf->changes; + nevents = kcf->events; nchanges = 0; - change_size = sizeof(struct kevent) * KQUEUE_NCHANGES; - event_size = sizeof(struct kevent) * KQUEUE_NEVENTS; - kq = kqueue(); + ngx_kqueue = kqueue(); - if (kq == -1) { + if (ngx_kqueue == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "kqueue() failed"); return NGX_ERROR; } - ngx_test_null(change_list, ngx_alloc(change_size, log), NGX_ERROR); - ngx_test_null(event_list, ngx_alloc(event_size, log), NGX_ERROR); + ngx_test_null(change_list, + ngx_alloc(kcf->changes * sizeof(struct kevent), log), + NGX_ERROR); + ngx_test_null(event_list, + ngx_alloc(kcf->events * sizeof(struct kevent), log), + NGX_ERROR); - timer_queue = ngx_event_init_timer(log); - if (timer_queue == NULL) { + if (ngx_event_timer_init(log) == NGX_ERROR) { return NGX_ERROR; } - ngx_event_actions.add = ngx_kqueue_add_event; - ngx_event_actions.del = ngx_kqueue_del_event; - ngx_event_actions.timer = ngx_event_add_timer; - ngx_event_actions.process = ngx_kqueue_process_events; - -#if (HAVE_AIO_EVENT) - - ngx_event_flags = NGX_HAVE_AIO_EVENT; - -#else + ngx_event_actions = ngx_kqueue_module_ctx.actions; ngx_event_flags = NGX_HAVE_LEVEL_EVENT |NGX_HAVE_ONESHOT_EVENT - #if (HAVE_CLEAR_EVENT) |NGX_HAVE_CLEAR_EVENT #else |NGX_USE_LEVEL_EVENT #endif - #if (HAVE_LOWAT_EVENT) |NGX_HAVE_LOWAT_EVENT #endif - |NGX_HAVE_KQUEUE_EVENT; - ngx_write_chain_proc = ngx_freebsd_write_chain; - -#endif - return NGX_OK; } -void ngx_kqueue_done(ngx_log_t *log) +static void ngx_kqueue_done(ngx_log_t *log) { - if (close(kq) == -1) { + if (close(ngx_kqueue) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kqueue close() failed"); } + + ngx_event_timer_done(log); + + ngx_free(change_list); + ngx_free(event_list); } -int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) +static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) { + ngx_connection_t *c; + ev->active = 1; ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; - /* The event addition or change should be always passed to a kernel - because there can be case when event was passed to a kernel then - added again to the change_list and then deleted from the change_list - by ngx_kqueue_del_event() so the first event still remains in a kernel */ - -#if 0 - if (nchanges > 0 && ev->index < nchanges - && change_list[ev->index].udata == ev) + && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev) { -#if (NGX_DEBUG_EVENT) - ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_log_debug(ev->log, "kqueue add event: %d: ft:%d" _ c->fd _ event); -#endif - - /* if the event is still not passed to a kernel we change it */ + c = ev->data; + ngx_log_error(NGX_LOG_ALERT, ev->log, 0, + "previous event were not passed in kernel", c->fd); - change_list[ev->index].filter = event; - change_list[ev->index].flags = flags; - - return NGX_OK; + return NGX_ERROR; } -#endif - return ngx_kqueue_set_event(ev, event, EV_ADD | flags); } -int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) +static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) { ngx_event_t *e; @@ -181,7 +176,8 @@ int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) { #if (NGX_DEBUG_EVENT) ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ c->fd _ event); + ngx_log_debug(ev->log, "kqueue event deleted: %d: ft:%d" _ + c->fd _ event); #endif /* if the event is still not passed to a kernel we will not pass it */ @@ -207,26 +203,26 @@ int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) } -int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) +static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) { - struct timespec ts; - ngx_connection_t *c; + struct timespec ts; + ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + c = ev->data; #if (NGX_DEBUG_EVENT) ngx_log_debug(ev->log, "kqueue set event: %d: ft:%d f:%08x" _ c->fd _ filter _ flags); #endif - if (nchanges >= KQUEUE_NCHANGES) { + if (nchanges >= max_changes) { ngx_log_error(NGX_LOG_WARN, ev->log, 0, "kqueue change list is filled up"); ts.tv_sec = 0; ts.tv_nsec = 0; - if (kevent(kq, change_list, nchanges, NULL, 0, &ts) == -1) { + if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent failed"); return NGX_ERROR; } @@ -265,7 +261,7 @@ int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) } -int ngx_kqueue_process_events(ngx_log_t *log) +static int ngx_kqueue_process_events(ngx_log_t *log) { int events, instance, i; ngx_msec_t timer, delta; @@ -292,7 +288,7 @@ int ngx_kqueue_process_events(ngx_log_t *log) ngx_log_debug(log, "kevent timer: %d" _ timer); #endif - events = kevent(kq, change_list, nchanges, event_list, nevents, tp); + events = kevent(ngx_kqueue, change_list, nchanges, event_list, nevents, tp); if (events == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kevent failed"); @@ -305,8 +301,8 @@ int ngx_kqueue_process_events(ngx_log_t *log) gettimeofday(&tv, NULL); delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; - /* Expired timers must be deleted before the events processing - because the new timers can be added during the processing */ + /* The expired timers must be handled before a processing of the events + because the new timers can be added during a processing */ ngx_event_expire_timers(delta); @@ -370,8 +366,9 @@ int ngx_kqueue_process_events(ngx_log_t *log) ev->error = event_list[i].fflags; } - if (ev->oneshot) { + if (ev->oneshot && ev->timer_set) { ngx_del_timer(ev); + ev->timer_set = 0; } /* fall through */ @@ -392,3 +389,28 @@ int ngx_kqueue_process_events(ngx_log_t *log) return NGX_OK; } + + +static void *ngx_kqueue_create_conf(ngx_pool_t *pool) +{ + ngx_kqueue_conf_t *kcf; + + ngx_test_null(kcf, ngx_palloc(pool, sizeof(ngx_kqueue_conf_t)), + NGX_CONF_ERROR); + + kcf->changes = NGX_CONF_UNSET; + kcf->events = NGX_CONF_UNSET; + + return kcf; +} + + +static char *ngx_kqueue_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_kqueue_conf_t *kcf = conf; + + ngx_conf_init_value(kcf->changes, 512); + ngx_conf_init_value(kcf->events, 512); + + return NGX_CONF_OK; +} diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h index 568476ed0..4f41ae790 100644 --- a/src/event/modules/ngx_kqueue_module.h +++ b/src/event/modules/ngx_kqueue_module.h @@ -2,22 +2,13 @@ #define _NGX_KQUEUE_MODULE_H_INCLUDED_ -#include <ngx_types.h> -#include <ngx_log.h> -#include <ngx_event.h> +typedef struct { + int changes; + int events; +} ngx_kqueue_conf_t; -int ngx_kqueue_init(int max_connections, ngx_log_t *log); -int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags); -int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags); -int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags); -void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer); -int ngx_kqueue_process_events(ngx_log_t *log); - - -#if 1 -extern int kq; -#endif +extern int ngx_kqueue; #endif /* _NGX_KQUEUE_MODULE_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c index f0f39ddbc..c58c898e4 100644 --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -242,7 +242,10 @@ int ngx_poll_process_events(ngx_log_t *log) ev->ready = 1; if (ev->oneshot) { - ngx_del_timer(ev); + if (ev->timer_set) { + ngx_del_timer(ev); + ev->timer_set = 0; + } if (ev->write) { ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0); diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c index 74c790e52..bb3c89d29 100644 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -1,16 +1,24 @@ +/* + * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru + */ + + #include <ngx_config.h> #include <ngx_core.h> -#include <ngx_types.h> -#include <ngx_log.h> -#include <ngx_time.h> #include <ngx_connection.h> #include <ngx_event.h> -#include <ngx_event_timer.h> -#include <ngx_select_module.h> -/* should be per-thread */ +static int ngx_select_init(ngx_log_t *log); +static void ngx_select_done(ngx_log_t *log); +static int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_select_process_events(ngx_log_t *log); + +static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf); + + static fd_set master_read_fd_set; static fd_set master_write_fd_set; static fd_set work_read_fd_set; @@ -27,45 +35,67 @@ static u_int nevents; static ngx_event_t **event_index; static ngx_event_t **ready_index; -static ngx_event_t *timer_queue; -/* */ -int ngx_select_init(int max_connections, ngx_log_t *log) -{ - if (max_connections > FD_SETSIZE) { - ngx_log_error(NGX_LOG_EMERG, log, 0, -#if (WIN32) - "maximum number of descriptors " - "supported by select() is %d", FD_SETSIZE); -#else - "maximum descriptor number" - "supported by select() is %d", FD_SETSIZE - 1); -#endif - exit(1); + +static ngx_str_t select_name = ngx_string("select"); + +ngx_event_module_t ngx_select_module_ctx = { + NGX_EVENT_MODULE, + &select_name, + NULL, /* create configuration */ + ngx_select_init_conf, /* init configuration */ + + { + ngx_select_add_event, /* add an event */ + ngx_select_del_event, /* delete an event */ + ngx_select_add_event, /* enable an event */ + ngx_select_del_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + ngx_select_process_events, /* process the events */ + ngx_select_init, /* init the events */ + ngx_select_done /* done the events */ } +}; + +ngx_module_t ngx_select_module = { + &ngx_select_module_ctx, /* module context */ + 0, /* module index */ + NULL, /* module directives */ + NGX_EVENT_MODULE_TYPE, /* module type */ + NULL /* init module */ +}; + + +static int ngx_select_init(ngx_log_t *log) +{ + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(ngx_event_module_ctx); + FD_ZERO(&master_read_fd_set); FD_ZERO(&master_write_fd_set); ngx_test_null(event_index, - ngx_alloc(sizeof(ngx_event_t *) * 2 * max_connections, log), + ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log), NGX_ERROR); ngx_test_null(ready_index, - ngx_alloc(sizeof(ngx_event_t *) * 2 * max_connections, log), + ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log), NGX_ERROR); nevents = 0; - timer_queue = ngx_event_init_timer(log); - if (timer_queue == NULL) { + if (ngx_event_timer_init(log) == NGX_ERROR) { return NGX_ERROR; } - ngx_event_actions.add = ngx_select_add_event; - ngx_event_actions.del = ngx_select_del_event; - ngx_event_actions.timer = ngx_event_add_timer; - ngx_event_actions.process = ngx_select_process_events; + ngx_event_actions = ngx_select_module_ctx.actions; + + ngx_event_flags = NGX_HAVE_LEVEL_EVENT + |NGX_HAVE_ONESHOT_EVENT + |NGX_USE_LEVEL_EVENT; #if (WIN32) max_read = max_write = 0; @@ -76,11 +106,19 @@ int ngx_select_init(int max_connections, ngx_log_t *log) return NGX_OK; } -int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) + +static void ngx_select_done(ngx_log_t *log) +{ + ngx_free(event_index); + ngx_free(ready_index); +} + + +static int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) { ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + c = ev->data; #if (NGX_DEBUG_EVENT) ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event); @@ -132,10 +170,12 @@ int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) return NGX_OK; } -int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags) + +static int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags) { - ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + ngx_connection_t *c; + + c = ev->data; if (ev->index == NGX_INVALID_INDEX) return NGX_OK; @@ -175,7 +215,8 @@ int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags) return NGX_OK; } -int ngx_select_process_events(ngx_log_t *log) + +static int ngx_select_process_events(ngx_log_t *log) { int ready, found; u_int i, nready; @@ -298,7 +339,10 @@ int ngx_select_process_events(ngx_log_t *log) ev->ready = 1; if (ev->oneshot) { - ngx_del_timer(ev); + if (ev->timer_set) { + ngx_del_timer(ev); + ev->timer_set = 0; + } if (ev->write) ngx_select_del_event(ev, NGX_WRITE_EVENT, 0); @@ -315,3 +359,18 @@ int ngx_select_process_events(ngx_log_t *log) return NGX_OK; } + + +static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(ngx_event_module_ctx); + + if (ecf->connections > FD_SETSIZE) { + return "maximum number of connections " + "supported by select() is " ngx_value(FD_SETSIZE); + } + + return NGX_CONF_OK; +} diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index a3b12d0f6..ed22db5c6 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -11,7 +11,7 @@ #include <ngx_event.h> #include <ngx_conf_file.h> -#include <ngx_select_module.h> +extern ngx_event_module_t ngx_select_module_ctx; #if (HAVE_POLL) #include <ngx_poll_module.h> @@ -22,6 +22,7 @@ #endif #if (HAVE_KQUEUE) +extern ngx_event_module_t ngx_kqueue_module_ctx; #include <ngx_kqueue_module.h> #endif @@ -36,46 +37,26 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); +static void *ngx_event_create_conf(ngx_pool_t *pool); +static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf); -ngx_connection_t *ngx_connections; -ngx_event_t *ngx_read_events, *ngx_write_events; - -#if !(USE_KQUEUE) - -ngx_event_type_e ngx_event_type; - int ngx_event_flags; - ngx_event_actions_t ngx_event_actions; -/* ngx_event_type_e order */ -static int (*ngx_event_init[]) (int max_connections, ngx_log_t *log) = { - ngx_select_init, -#if (HAVE_POLL) - ngx_poll_init, -#endif -#if (HAVE_DEVPOLL) - ngx_devpoll_init, -#endif -#if (HAVE_KQUEUE) - ngx_kqueue_init, -#endif -#if (HAVE_AIO) - ngx_aio_init, -#endif -#if (HAVE_IOCP) - ngx_iocp_init -#endif -}; +ngx_connection_t *ngx_connections; +ngx_event_t *ngx_read_events, *ngx_write_events; + -#endif /* USE_KQUEUE */ +static int ngx_event_max_module; static int ngx_event_connections; static ngx_str_t events_name = ngx_string("events"); +static ngx_str_t event_name = ngx_string("event"); static ngx_command_t ngx_events_commands[] = { @@ -106,67 +87,87 @@ static ngx_command_t ngx_event_commands[] = { NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, 0, - addressof(ngx_event_connections), + offsetof(ngx_event_conf_t, connections), NULL}, -#if 0 {ngx_string("type"), NGX_EVENT_CONF|NGX_CONF_TAKE1, ngx_event_set_type, 0, 0, NULL}, -#endif + + {ngx_string("timer_queues"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_event_conf_t, timer_queues), + NULL}, {ngx_string(""), 0, NULL, 0, 0, NULL} }; +ngx_event_module_t ngx_event_module_ctx = { + NGX_EVENT_MODULE, + &event_name, + ngx_event_create_conf, /* create configuration */ + ngx_event_init_conf, /* init configuration */ + + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + + ngx_module_t ngx_event_module = { - NULL, /* module context */ + &ngx_event_module_ctx, /* module context */ 0, /* module index */ - ngx_events_commands, /* module directives */ + ngx_event_commands, /* module directives */ NGX_EVENT_MODULE_TYPE, /* module type */ NULL /* init module */ }; -void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) +int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) { - int i, fd; + int m, i, fd; ngx_listen_t *s; ngx_event_t *ev; ngx_connection_t *c; + ngx_event_conf_t *ecf; + ngx_event_module_t *module; - /* STUB */ - int max_connections = 512; + ecf = ngx_event_get_conf(ngx_event_module_ctx); -#if 0 - ngx_event_type = NGX_POLL_EVENT_N; -#endif -#if 1 - ngx_event_type = NGX_KQUEUE_EVENT_N; -#endif -#if 0 - ngx_event_type = NGX_DEVPOLL_EVENT_N; -#endif -#if 0 - ngx_event_type = NGX_AIO_EVENT_N; -#endif -#if 0 - ngx_event_type = NGX_IOCP_EVENT_N; -#endif +ngx_log_debug(log, "CONN: %d" _ ecf->connections); +ngx_log_debug(log, "TYPE: %d" _ ecf->type); - if (ngx_init_events(max_connections, log) == NGX_ERROR) { - exit(1); + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } + + module = ngx_modules[m]->ctx; + if (module->index == ecf->type) { + if (module->actions.init(log) == NGX_ERROR) { + return NGX_ERROR; + } + break; + } } - ngx_connections = ngx_alloc(sizeof(ngx_connection_t) - * max_connections, log); - ngx_read_events = ngx_alloc(sizeof(ngx_event_t) * max_connections, log); - ngx_write_events = ngx_alloc(sizeof(ngx_event_t) * max_connections, log); + ngx_test_null(ngx_connections, + ngx_alloc(sizeof(ngx_connection_t) * ecf->connections, log), + NGX_ERROR); + + ngx_test_null(ngx_read_events, + ngx_alloc(sizeof(ngx_event_t) * ecf->connections, log), + NGX_ERROR); + + ngx_test_null(ngx_write_events, + ngx_alloc(sizeof(ngx_event_t) * ecf->connections, log), + NGX_ERROR); /* for each listening socket */ s = (ngx_listen_t *) ls->elts; @@ -196,7 +197,9 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) c->pool_size = s[i].pool_size; ngx_test_null(ev->log, - ngx_palloc(pool, sizeof(ngx_log_t)), /* void */ ; ); + ngx_palloc(pool, sizeof(ngx_log_t)), + NGX_ERROR); + ngx_memcpy(ev->log, c->log, sizeof(ngx_log_t)); c->read = ev; ev->data = c; @@ -235,6 +238,8 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) #endif } + + return NGX_OK; } @@ -248,35 +253,50 @@ void ngx_worker(ngx_log_t *log) } -static char *ngx_events_init(ngx_pool_t *pool) +static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { - ngx_event_connections = -1; - ngx_event_type = -1; + int m; + char *rv; + void ***ctx; + ngx_conf_t pcf; + ngx_event_conf_t *ecf; + ngx_event_module_t *module; + + /* count the number of the event modules and set up their indices */ + + ngx_event_max_module = 0; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } - return NGX_CONF_OK; -} + module = ngx_modules[m]->ctx; + module->index = ngx_event_max_module++; + } + ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(void *)), NGX_CONF_ERROR); -static char *ngx_events_postconf(ngx_pool_t *pool) -{ - if (ngx_event_connections == -1) { - ngx_event_connections = 512; - } + ngx_test_null(*ctx, + ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)), + NGX_CONF_ERROR); - return NGX_CONF_OK; -} + *(void **) conf = ctx; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } -static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) -{ - char *rv; - ngx_conf_t pcf; + module = ngx_modules[m]->ctx; -#if 0 - *(ngx_events_conf_ctx_t **) conf = ctx; -#endif + if (module->create_conf) { + ngx_test_null((*ctx)[module->index], module->create_conf(cf->pool), + NGX_CONF_ERROR); + } + } pcf = *cf; + cf->ctx = ctx; cf->module_type = NGX_EVENT_MODULE_TYPE; cf->cmd_type = NGX_EVENT_CONF; rv = ngx_conf_parse(cf, NULL); @@ -285,5 +305,90 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) if (rv != NGX_CONF_OK) return rv; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } + + module = ngx_modules[m]->ctx; + + if (module->init_conf) { + rv = module->init_conf(cf->pool, (*ctx)[module->index]); + if (rv != NGX_CONF_OK) { + return rv; + } + } + } + + return NGX_CONF_OK; +} + + +static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +{ + ngx_event_conf_t *ecf = (ngx_event_conf_t *) conf; + + int m; + ngx_str_t *args; + ngx_event_module_t *module; + + if (ecf->type != NGX_CONF_UNSET) { + return "duplicate event type" ; + } + + args = cf->args->elts; + + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + continue; + } + + module = ngx_modules[m]->ctx; + if (module->name->len == args[1].len) { + if (ngx_strcmp(module->name->data, args[1].data) == 0) { + ecf->type = module->index; + return NGX_CONF_OK; + } + } + } + + return "invalid event type"; +} + + +static void *ngx_event_create_conf(ngx_pool_t *pool) +{ + ngx_event_conf_t *ecf; + + ngx_test_null(ecf, ngx_palloc(pool, sizeof(ngx_event_conf_t)), + NGX_CONF_ERROR); + + ecf->connections = NGX_CONF_UNSET; + ecf->type = NGX_CONF_UNSET; + + return ecf; +} + + +static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_event_conf_t *ecf = conf; + +#if (HAVE_KQUEUE) + + ngx_conf_init_value(ecf->connections, 1024); + ngx_conf_init_value(ecf->type, ngx_kqueue_module_ctx.index); + +#else /* HAVE_SELECT */ + + ngx_conf_init_value(ecf->connections, + FD_SETSIZE < 1024 ? FD_SETSIZE : 1024); + + ngx_conf_init_value(ecf->type, ngx_select_module_ctx.index); + +#endif + + ngx_conf_init_value(ecf->timer_queues, 10); + return NGX_CONF_OK; } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index c976e17a5..3b189d631 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -9,12 +9,16 @@ #include <ngx_log.h> #include <ngx_alloc.h> #include <ngx_array.h> +#include <ngx_conf_file.h> + + /* STUB */ #define NGX_LOWAT 10000 #define NGX_INVALID_INDEX 0x80000000 + typedef struct ngx_event_s ngx_event_t; #if (HAVE_IOCP) @@ -141,15 +145,21 @@ typedef enum { NGX_DUMMY_EVENT_N /* avoid comma at end of enumerator list */ } ngx_event_type_e ; + + typedef struct { - int (*add)(ngx_event_t *ev, int event, u_int flags); - int (*del)(ngx_event_t *ev, int event, u_int flags); - void (*timer)(ngx_event_t *ev, ngx_msec_t timer); - int (*process)(ngx_log_t *log); - int (*read)(ngx_event_t *ev, char *buf, size_t size); -/* - int (*write)(ngx_event_t *ev, char *buf, size_t size); -*/ + int (*add)(ngx_event_t *ev, int event, u_int flags); + int (*del)(ngx_event_t *ev, int event, u_int flags); + + int (*enable)(ngx_event_t *ev, int event, u_int flags); + int (*disable)(ngx_event_t *ev, int event, u_int flags); + + int (*add_conn)(ngx_connection_t *c); + int (*del_conn)(ngx_connection_t *c); + + int (*process)(ngx_log_t *log); + int (*init)(ngx_log_t *log); + void (*done)(ngx_log_t *log); } ngx_event_actions_t; @@ -273,7 +283,8 @@ typedef struct { #elif (HAVE_AIO_EVENT) #define ngx_event_recv ngx_event_aio_read #else -#define ngx_event_recv ngx_event_recv_core +#define ngx_event_recv ngx_io.recv +#define ngx_write_chain ngx_io.send_chain #endif #endif @@ -301,6 +312,33 @@ extern int ngx_event_flags; #define NGX_EVENT_MODULE_TYPE 0x544E5645 /* "EVNT" */ #define NGX_EVENT_CONF 0x00200000 +#define NGX_EVENT_MODULE 0 + + +typedef struct { + int connections; + int type; + int timer_queues; +} ngx_event_conf_t; + + +typedef struct { + int index; + ngx_str_t *name; + + void *(*create_conf)(ngx_pool_t *p); + char *(*init_conf)(ngx_pool_t *p, void *conf); + + ngx_event_actions_t actions; +} ngx_event_module_t; + + +extern ngx_module_t ngx_events_module; +extern ngx_event_module_t ngx_event_module_ctx; + + +#define ngx_event_get_conf(module) \ + (*(ngx_get_conf(ngx_events_module))) [module.index]; @@ -311,8 +349,11 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size); int ngx_event_close_connection(ngx_event_t *ev); -void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log); +int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log); void ngx_worker(ngx_log_t *log); +#include <ngx_event_timer.h> + + #endif /* _NGX_EVENT_H_INCLUDED_ */ diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 26bc2e3cf..720b3a53b 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -175,10 +175,7 @@ void ngx_event_accept(ngx_event_t *ev) #elif (HAVE_KQUEUE) -/* - if (ngx_event_type == NGX_HAVE_AIO_EVENT or NGX_HAVE_KQUEUE_EVENT) { -*/ - if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) { + if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { ev->available--; } diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c index b5dfdf9ef..03e29d9c4 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -9,33 +9,38 @@ #include <ngx_event_timer.h> -/* STUB */ -#define NGX_TIMER_QUEUE_NUM 5 -/* should be per-thread */ static ngx_event_t *ngx_timer_queue; static int ngx_timer_cur_queue; -/* */ static int ngx_timer_queue_num; -ngx_event_t *ngx_event_init_timer(ngx_log_t *log) +int ngx_event_timer_init(ngx_log_t *log) { - int i; + int i; + ngx_event_conf_t *ecf; - ngx_timer_queue_num = NGX_TIMER_QUEUE_NUM; + ecf = ngx_event_get_conf(ngx_event_module_ctx); + + ngx_timer_queue_num = ecf->timer_queues; ngx_timer_cur_queue = 0; ngx_test_null(ngx_timer_queue, ngx_alloc(ngx_timer_queue_num * sizeof(ngx_event_t), log), - NULL); + NGX_ERROR); for (i = 0; i < ngx_timer_queue_num; i++) { ngx_timer_queue[i].timer_prev = &ngx_timer_queue[i]; ngx_timer_queue[i].timer_next = &ngx_timer_queue[i]; } - return ngx_timer_queue; + return NGX_OK;; +} + + +void ngx_event_timer_done(ngx_log_t *log) +{ + ngx_free(ngx_timer_queue); } @@ -126,6 +131,8 @@ void ngx_event_expire_timers(ngx_msec_t timer) delta -= ev->timer_delta; ngx_del_timer(ev); + ev->timer_set = 0; + if (ev->delayed) { ev->delayed = 0; if (ev->ready == 0) { diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h index f5f78ae95..cb024a38f 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -9,9 +9,10 @@ #include <ngx_event.h> -ngx_event_t *ngx_event_init_timer(ngx_log_t *log); +int ngx_event_timer_init(ngx_log_t *log); +void ngx_event_timer_done(ngx_log_t *log); void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer); -int ngx_event_find_timer(void); +int ngx_event_find_timer(void); void ngx_event_expire_timers(ngx_msec_t timer); diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c index 2a236ee6d..49a4e0ab3 100644 --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -38,11 +38,14 @@ static ngx_command_t ngx_http_index_commands[] = { ngx_http_module_t ngx_http_index_module_ctx = { NGX_HTTP_MODULE, - NULL, /* create server config */ - NULL, /* init server config */ + NULL, /* create main configuration */ + NULL, /* init main configuration */ - ngx_http_index_create_conf, /* create location config */ - ngx_http_index_merge_conf /* merge location config */ + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_index_create_conf, /* create location configration */ + ngx_http_index_merge_conf /* merge location configration */ }; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 17c3da57f..ffa94cff3 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -16,17 +16,6 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); int ngx_http_max_module; -ngx_array_t ngx_http_servers; /* array of ngx_http_core_srv_conf_t */ - -int ngx_http_post_accept_timeout = 30000; -int ngx_http_connection_pool_size = 16384; -int ngx_http_request_pool_size = 16384; -int ngx_http_client_header_timeout = 60000; -int ngx_http_client_header_buffer_size = 1024; -int ngx_http_large_client_header = 1; - -int ngx_http_url_in_error_log = 1; - ngx_array_t ngx_http_translate_handlers; ngx_array_t ngx_http_index_handlers; @@ -63,65 +52,79 @@ ngx_module_t ngx_http_module = { static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { - int i, s, l, p, a, n, start; - int port_found, addr_found, virtual_names; - char *rv; - struct sockaddr_in *addr_in; - ngx_array_t in_ports; - ngx_listen_t *ls; - ngx_http_module_t *module; - ngx_conf_t pcf; - ngx_http_conf_ctx_t *ctx; - ngx_http_in_port_t *in_port, *inport; - ngx_http_in_addr_t *in_addr, *inaddr; - ngx_http_core_srv_conf_t **cscf; - ngx_http_listen_t *lscf; - ngx_http_server_name_t *s_name, *name; - - ngx_init_array(ngx_http_servers, cf->pool, 10, - sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR); - + int mi, m, s, l, p, a, n; + int port_found, addr_found, virtual_names; + char *rv; + struct sockaddr_in *addr_in; + ngx_array_t in_ports; + ngx_listen_t *ls; + ngx_http_module_t *module; + ngx_conf_t pcf; + ngx_http_conf_ctx_t *ctx; + ngx_http_in_port_t *in_port, *inport; + ngx_http_in_addr_t *in_addr, *inaddr; + ngx_http_core_main_conf_t *cmcf; + ngx_http_core_srv_conf_t **cscfp; + ngx_http_core_loc_conf_t **clcfp; + ngx_http_listen_t *lscf; + ngx_http_server_name_t *s_name, *name; + + /* the main http context */ ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); *(ngx_http_conf_ctx_t **) conf = ctx; + + /* count the number of the http modules and set up their indices */ + ngx_http_max_module = 0; - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { continue; } - module = (ngx_http_module_t *) ngx_modules[i]->ctx; - + module = (ngx_http_module_t *) ngx_modules[m]->ctx; module->index = ngx_http_max_module++; } - /* TODO: http main_conf */ - + /* the main http main_conf, it's the same in the all http contexts */ ngx_test_null(ctx->main_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); - /* TODO: http srv_conf */ - + /* the http null srv_conf, it's used to merge the server{}s' srv_conf's */ ngx_test_null(ctx->srv_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); - /* http null loc_conf */ - + /* the http null loc_conf, it's used to merge the server{}s' loc_conf's */ ngx_test_null(ctx->loc_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + + /* create the main_conf, srv_conf and loc_conf in all http modules */ + + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { continue; } - module = (ngx_http_module_t *) ngx_modules[i]->ctx; + module = (ngx_http_module_t *) ngx_modules[m]->ctx; + + if (module->create_main_conf) { + ngx_test_null(ctx->main_conf[module->index], + module->create_main_conf(cf->pool), + NGX_CONF_ERROR); + } + + if (module->create_srv_conf) { + ngx_test_null(ctx->srv_conf[module->index], + module->create_srv_conf(cf->pool), + NGX_CONF_ERROR); + } if (module->create_loc_conf) { ngx_test_null(ctx->loc_conf[module->index], @@ -130,6 +133,9 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) } } + + /* parse inside the http{} block */ + pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_HTTP_MODULE_TYPE; @@ -141,22 +147,71 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) return rv; -#if 0 - /* DEBUG STUFF */ - cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; - for (s = 0; s < ngx_http_servers.nelts; s++) { - ngx_http_core_loc_conf_t **loc; - - ngx_log_debug(cf->log, "srv: %08x" _ cscf[s]); - loc = (ngx_http_core_loc_conf_t **) cscf[s]->locations.elts; - for (l = 0; l < cscf[s]->locations.nelts; l++) { - ngx_log_debug(cf->log, "loc: %08x:%s, %08x:%s" _ - loc[l] _ loc[l]->name.data _ - &loc[l]->doc_root _ loc[l]->doc_root.data); + /* init http{} main_conf's, merge the server{}s' srv_conf's + and its location{}s' loc_conf's */ + + cmcf = ctx->main_conf[ngx_http_core_module_ctx.index]; + cscfp = (ngx_http_core_srv_conf_t **)cmcf->servers.elts; + + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) ngx_modules[m]->ctx; + mi = module->index; + + /* init http{} main_conf's */ + + if (module->init_main_conf) { + rv = module->init_main_conf(cf->pool, ctx->main_conf[mi]); + if (rv != NGX_CONF_OK) { + return rv; + } + } + + for (s = 0; s < cmcf->servers.nelts; s++) { + + /* merge the server{}s' srv_conf's */ + + if (module->merge_srv_conf) { + rv = module->merge_srv_conf(cf->pool, + ctx->srv_conf[mi], + cscfp[s]->ctx->srv_conf[mi]); + if (rv != NGX_CONF_OK) { + return rv; + } + } + + if (module->merge_loc_conf) { + + /* merge the server{}'s loc_conf */ + + rv = module->merge_loc_conf(cf->pool, + ctx->loc_conf[mi], + cscfp[s]->ctx->loc_conf[mi]); + if (rv != NGX_CONF_OK) { + return rv; + } + + /* merge the locations{}' loc_conf's */ + + clcfp = (ngx_http_core_loc_conf_t **)cscfp[s]->locations.elts; + + for (l = 0; l < cscfp[s]->locations.nelts; l++) { + rv = module->merge_loc_conf(cf->pool, + cscfp[s]->ctx->loc_conf[mi], + clcfp[l]->loc_conf[mi]); + if (rv != NGX_CONF_OK) { + return rv; + } + } + } } } - /**/ -#endif + + + /* init list of the handlers */ ngx_init_array(ngx_http_translate_handlers, cf->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); @@ -172,12 +227,12 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) NGX_CONF_ERROR); /* "server" directives */ - cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; - for (s = 0; s < ngx_http_servers.nelts; s++) { + cscfp = (ngx_http_core_srv_conf_t **) cmcf->servers.elts; + for (s = 0; s < cmcf->servers.nelts; s++) { /* "listen" directives */ - lscf = (ngx_http_listen_t *) cscf[s]->listen.elts; - for (l = 0; l < cscf[s]->listen.nelts; l++) { + lscf = (ngx_http_listen_t *) cscfp[s]->listen.elts; + for (l = 0; l < cscfp[s]->listen.nelts; l++) { port_found = 0; @@ -202,8 +257,8 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) /* "server_name" directives */ s_name = (ngx_http_server_name_t *) - cscf[s]->server_names.elts; - for (n = 0; n < cscf[s]->server_names.nelts; n++) { + cscfp[s]->server_names.elts; + for (n = 0; n < cscfp[s]->server_names.nelts; n++) { /* add the server name and server core module configuration to the address:port */ @@ -234,7 +289,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) } in_addr[a].flags |= NGX_HTTP_DEFAULT_SERVER; - in_addr[a].core_srv_conf = cscf[s]; + in_addr[a].core_srv_conf = cscfp[s]; } addr_found = 1; @@ -256,7 +311,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) in_addr[a].addr = lscf[l].addr; in_addr[a].flags = lscf[l].flags; - in_addr[a].core_srv_conf = cscf[s]; + in_addr[a].core_srv_conf = cscfp[s]; /* create the empty list of the server names that can be served on this address:port */ @@ -282,7 +337,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) inaddr->addr = lscf[l].addr; inaddr->flags = lscf[l].flags; - inaddr->core_srv_conf = cscf[s]; + inaddr->core_srv_conf = cscfp[s]; /* create the empty list of the server names that can be served on this address:port */ @@ -317,7 +372,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) inaddr->addr = lscf[l].addr; inaddr->flags = lscf[l].flags; - inaddr->core_srv_conf = cscf[s]; + inaddr->core_srv_conf = cscfp[s]; /* create the empty list of the server names that can be served on this address:port */ @@ -407,12 +462,12 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) ls->addr = offsetof(struct sockaddr_in, sin_addr); ls->addr_text_max_len = INET_ADDRSTRLEN; ls->backlog = -1; - ls->post_accept_timeout = ngx_http_post_accept_timeout; + ls->post_accept_timeout = cmcf->post_accept_timeout; ls->nonblocking = 1; ls->handler = ngx_http_init_connection; ls->log = cf->log; - ls->pool_size = ngx_http_connection_pool_size; + ls->pool_size = cmcf->connection_pool_size; ls->ctx = ctx; if (in_port[p].addrs.nelts > 1) { @@ -475,87 +530,3 @@ ngx_log_debug(cf->log, "%s %08x" _ ip _ in_addr[a].core_srv_conf); return NGX_CONF_OK; } - - -#if 0 -/* STUB */ - -static struct sockaddr_in addr; -static char addr_text[22]; - - -int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log) -{ - ngx_listen_t *ls; - - ngx_http_server.connection_pool_size = 16384; - ngx_http_server.request_pool_size = 16384; - ngx_http_server.header_timeout = 20000; - ngx_http_server.header_buffer_size = 1024; - ngx_http_server.discarded_buffer_size = 1500; - - ngx_http_server.lingering_timeout = 5000; - ngx_http_server.lingering_time = 30; - -#if (WIN32) - ngx_http_server.doc_root = "html"; -#else - ngx_http_server.doc_root = "/home/is/dox/"; - ngx_http_server.doc_root = "/home/is/work/xml/site-1.0.0/html"; - ngx_http_server.doc_root = "/spool/test/lperltk"; - ngx_http_server.doc_root = "/home/is/dox/ora/lperltk"; -#endif - ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 1; - - - ngx_http_config_modules(pool, ngx_modules); - -#if 0 - /* STUB */ - ngx_http_output_filter_set_stub(pool, ngx_http_modules); - ngx_http_write_filter_set_stub(pool, ngx_http_modules); - ngx_http_index_set_stub(pool, ngx_http_modules); - - ngx_http_init_modules(pool, ngx_http_modules); -#endif - - ngx_http_init_filters(pool, ngx_modules); - - ls = ngx_push_array(&ngx_listening_sockets); - ngx_memzero(ls, sizeof(ngx_listen_t)); - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("0.0.0.0"); - addr.sin_port = htons(8000); - - ngx_snprintf(ngx_cpystrn(addr_text, inet_ntoa(addr.sin_addr), 16), - 7, ":%d", ntohs(addr.sin_port)); - - ls->family = AF_INET; - ls->type = SOCK_STREAM; - ls->protocol = IPPROTO_IP; - -#if (NGX_OVERLAPPED) - ls->flags = WSA_FLAG_OVERLAPPED; -#else - ls->nonblocking = 1; -#endif - - ls->sockaddr = (struct sockaddr *) &addr; - ls->socklen = sizeof(struct sockaddr_in); - ls->addr = offsetof(struct sockaddr_in, sin_addr); - ls->addr_text.len = INET_ADDRSTRLEN; - ls->addr_text.data = addr_text; - ls->backlog = -1; - ls->post_accept_timeout = 10000; - - ls->handler = ngx_http_init_connection; - ls->server = &ngx_http_server; - ls->log = log; - - - return 1; -} - -/**/ -#endif diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index 556a00b99..2a695c776 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -12,190 +12,7 @@ #include <ngx_connection.h> #include <ngx_conf_file.h> -/* STUB */ -#include <ngx_event_timer.h> - -#define NGX_HTTP_VERSION_9 9 -#define NGX_HTTP_VERSION_10 1000 -#define NGX_HTTP_VERSION_11 1001 - -#define NGX_HTTP_GET 1 -#define NGX_HTTP_HEAD 2 -#define NGX_HTTP_POST 3 - -#define NGX_HTTP_CONN_CLOSE 0 -#define NGX_HTTP_CONN_KEEP_ALIVE 1 - - -#define NGX_HTTP_PARSE_HEADER_DONE 1 -#define NGX_HTTP_PARSE_INVALID_METHOD 10 -#define NGX_HTTP_PARSE_INVALID_REQUEST 11 -#define NGX_HTTP_PARSE_TOO_LONG_URI 12 -#define NGX_HTTP_PARSE_INVALID_09_METHOD 13 -#define NGX_HTTP_PARSE_INVALID_HEADER 14 -#define NGX_HTTP_PARSE_TOO_LONG_HEADER 15 -#define NGX_HTTP_PARSE_NO_HOST_HEADER 16 -#define NGX_HTTP_PARSE_INVALID_CL_HEADER 17 - - -#define NGX_HTTP_OK 200 - -#define NGX_HTTP_SPECIAL_RESPONSE 300 -#define NGX_HTTP_MOVED_PERMANENTLY 301 -#define NGX_HTTP_MOVED_TEMPORARILY 302 -#define NGX_HTTP_NOT_MODIFIED 304 - -#define NGX_HTTP_BAD_REQUEST 400 -#define NGX_HTTP_FORBIDDEN 403 -#define NGX_HTTP_NOT_FOUND 404 -#define NGX_HTTP_REQUEST_TIME_OUT 408 -#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 - -#define NGX_HTTP_INTERNAL_SERVER_ERROR 500 -#define NGX_HTTP_NOT_IMPLEMENTED 501 -#define NGX_HTTP_BAD_GATEWAY 502 -#define NGX_HTTP_SERVICE_UNAVAILABLE 503 -#define NGX_HTTP_GATEWAY_TIME_OUT 504 - - - -#define NGX_HTTP_STATIC_HANDLER 0 -#define NGX_HTTP_DIRECTORY_HANDLER 1 - - -typedef struct { - ngx_str_t name; - int offset; -} ngx_http_header_t; - - -typedef struct { - size_t host_name_len; - ssize_t content_length_n; - - ngx_table_elt_t *host; - ngx_table_elt_t *connection; - ngx_table_elt_t *if_modified_since; - ngx_table_elt_t *content_length; - ngx_table_elt_t *accept_encoding; - - ngx_table_elt_t *user_agent; - - ngx_table_t *headers; -} ngx_http_headers_in_t; - - -typedef struct { - ngx_chain_t chain[4]; - ngx_hunk_t *header_out; - ngx_hunk_t *hunk; - ngx_hunk_t *file_hunk; - ngx_file_t temp_file; - ngx_path_t *temp_path; - off_t offset; - char *header_in_pos; -} ngx_http_request_body_t; - - -typedef struct { - int status; - ngx_str_t status_line; - - ngx_table_elt_t *server; - ngx_table_elt_t *date; - ngx_table_elt_t *content_type; - ngx_table_elt_t *location; - ngx_table_elt_t *last_modified; - - ngx_table_t *headers; - - off_t content_length; - char *charset; - char *etag; - time_t date_time; - time_t last_modified_time; -} ngx_http_headers_out_t; - - -typedef struct ngx_http_request_s ngx_http_request_t; - -struct ngx_http_request_s { - ngx_connection_t *connection; - - void **ctx; - void **srv_conf; - void **loc_conf; - - ngx_file_t file; - - ngx_pool_t *pool; - ngx_hunk_t *header_in; - ngx_http_request_body_t *request_body; - - 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; - int http_version; - int http_major; - int http_minor; - - ngx_str_t request_line; - ngx_str_t uri; - ngx_str_t args; - ngx_str_t exten; - ngx_http_request_t *main; - - u_int in_addr; - - int port; - ngx_str_t port_name; - - int filter; - - char *discarded_buffer; - - ngx_str_t path; - int path_err; - - unsigned proxy:1; - unsigned cachable:1; - unsigned pipeline:1; - unsigned keepalive:1; - unsigned lingering_close:1; - - unsigned header_read:1; - unsigned header_timeout_set:1; - - unsigned logging:1; - - unsigned header_only:1; - unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */ - unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */ - unsigned path_not_found:1; -#ifdef NGX_EVENT - unsigned write_level_event:1; -#endif - - int state; - char *uri_start; - char *uri_end; - char *uri_ext; - char *args_start; - char *request_start; - char *request_end; - char *header_name_start; - char *header_name_end; - char *header_start; - char *header_end; -#ifdef NGX_EVENT - int (*state_handler)(ngx_http_request_t *r); -#endif -}; +#include <ngx_http_request.h> typedef struct { @@ -263,20 +80,11 @@ int ngx_http_discard_body(ngx_http_request_t *r); - -extern int ngx_max_module; -extern ngx_array_t ngx_http_servers; +extern ngx_module_t ngx_http_module; -extern int ngx_http_post_accept_timeout; -extern int ngx_http_connection_pool_size; -extern int ngx_http_request_pool_size; -extern int ngx_http_client_header_timeout; -extern int ngx_http_client_header_buffer_size; -extern int ngx_http_large_client_header; -extern int ngx_http_discarded_buffer_size; +extern int ngx_max_module; -extern int ngx_http_url_in_error_log; extern ngx_array_t ngx_http_translate_handlers; extern ngx_array_t ngx_http_index_handlers; diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h index 370b7db3a..abd3bdb26 100644 --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -7,9 +7,9 @@ typedef struct { - void **main_conf; - void **srv_conf; - void **loc_conf; + void **main_conf; + void **srv_conf; + void **loc_conf; } ngx_http_conf_ctx_t; @@ -22,8 +22,11 @@ typedef struct { typedef struct { int index; + void *(*create_main_conf)(ngx_pool_t *p); + char *(*init_main_conf)(ngx_pool_t *p, void *conf); + void *(*create_srv_conf)(ngx_pool_t *p); - char *(*init_srv_conf)(ngx_pool_t *p, void *conf); + char *(*merge_srv_conf)(ngx_pool_t *p, void *prev, void *conf); void *(*create_loc_conf)(ngx_pool_t *p); char *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 19bafda28..2b82c2992 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -6,10 +6,13 @@ #include <ngx_string.h> #include <ngx_conf_file.h> +#include <nginx.h> + #include <ngx_http.h> #include <ngx_http_config.h> #include <ngx_http_core_module.h> + /* STUB for r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; */ #include <ngx_http_output_filter.h> @@ -21,8 +24,11 @@ static int ngx_http_core_index_handler(ngx_http_request_t *r); static int ngx_http_core_init(ngx_pool_t *pool); +static void *ngx_http_core_create_main_conf(ngx_pool_t *pool); +static char *ngx_http_core_init_main_conf(ngx_pool_t *pool, void *conf); static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool); -static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf); +static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool, + void *parent, void *child); static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool); static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, void *parent, void *child); @@ -46,29 +52,29 @@ static ngx_command_t ngx_http_core_commands[] = { {ngx_string("post_accept_timeout"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, - 0, - addressof(ngx_http_post_accept_timeout), + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, post_accept_timeout), NULL}, {ngx_string("connection_pool_size"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, - 0, - addressof(ngx_http_connection_pool_size), + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, connection_pool_size), NULL}, {ngx_string("request_pool_size"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, - 0, - addressof(ngx_http_request_pool_size), + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, request_pool_size), NULL}, {ngx_string("client_header_timeout"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, - 0, - addressof(ngx_http_client_header_timeout), + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, client_header_timeout), NULL}, {ngx_string("client_header_buffer_size"), @@ -81,8 +87,8 @@ static ngx_command_t ngx_http_core_commands[] = { {ngx_string("large_client_header"), NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, - 0, - addressof(ngx_http_large_client_header), + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, large_client_header), NULL}, {ngx_string("location"), @@ -93,49 +99,50 @@ static ngx_command_t ngx_http_core_commands[] = { NULL}, {ngx_string("listen"), - NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_set_listen, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL}, {ngx_string("types"), - NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF + |NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_types_block, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL}, {ngx_string("root"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, doc_root), NULL}, {ngx_string("sendfile"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, sendfile), NULL}, {ngx_string("send_timeout"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, send_timeout), NULL}, {ngx_string("lingering_time"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, lingering_time), NULL}, {ngx_string("lingering_timeout"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, lingering_timeout), @@ -148,11 +155,14 @@ static ngx_command_t ngx_http_core_commands[] = { ngx_http_module_t ngx_http_core_module_ctx = { NGX_HTTP_MODULE, - ngx_http_core_create_srv_conf, /* create server config */ - ngx_http_core_init_srv_conf, /* init server config */ + ngx_http_core_create_main_conf, /* create main configuration */ + ngx_http_core_init_main_conf, /* init main configuration */ + + ngx_http_core_create_srv_conf, /* create server configuration */ + ngx_http_core_merge_srv_conf, /* merge server configuration */ - ngx_http_core_create_loc_conf, /* create location config */ - ngx_http_core_merge_loc_conf /* merge location config */ + ngx_http_core_create_loc_conf, /* create location configuration */ + ngx_http_core_merge_loc_conf /* merge location configuration */ }; @@ -207,6 +217,7 @@ ngx_log_debug(r->connection->log, "FOUND"); } } +/* DEBUG */ if (a == in_port->addrs.nelts) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "addr not found"); @@ -257,12 +268,12 @@ void ngx_http_handler(ngx_http_request_t *r) int rc, i; ngx_http_handler_pt *h; ngx_http_module_t *module; - ngx_http_core_loc_conf_t *lcf, **plcf; + ngx_http_core_loc_conf_t *lcf, **lcfp; ngx_http_core_srv_conf_t *scf; r->connection->unexpected_eof = 0; - r->keepalive = 0; + r->keepalive = 1; if (r->headers_in.content_length_n > 0) { r->lingering_close = 1; @@ -279,23 +290,23 @@ void ngx_http_handler(ngx_http_request_t *r) scf = (ngx_http_core_srv_conf_t *) ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); - plcf = (ngx_http_core_loc_conf_t **) scf->locations.elts; + lcfp = (ngx_http_core_loc_conf_t **) scf->locations.elts; for (i = 0; i < scf->locations.nelts; i++) { #if 0 -ngx_log_debug(r->connection->log, "trans: %s" _ plcf[i]->name.data); +ngx_log_debug(r->connection->log, "trans: %s" _ lcfp[i]->name.data); #endif - if (r->uri.len < plcf[i]->name.len) { + if (r->uri.len < lcfp[i]->name.len) { continue; } - rc = ngx_rstrncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len); + rc = ngx_rstrncmp(r->uri.data, lcfp[i]->name.data, lcfp[i]->name.len); if (rc < 0) { break; } if (rc == 0) { - r->loc_conf = plcf[i]->loc_conf; + r->loc_conf = lcfp[i]->loc_conf; } } @@ -587,7 +598,8 @@ int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri) r->uri.len = uri.len; r->uri.data = uri.data; - /* NEEDED ? */ + /* BROKEN, NEEDED ? */ + /* r->exten */ r->uri_start = uri.data; r->uri_end = uri.data + uri.len; /**/ @@ -611,28 +623,28 @@ static int ngx_http_core_init(ngx_pool_t *pool) static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) { - int i, j; - char *rv; - ngx_http_module_t *module; - ngx_conf_t pcf; - ngx_http_conf_ctx_t *ctx, *tctx, *pctx; - ngx_http_core_srv_conf_t *scf; - ngx_http_core_loc_conf_t **plcf; + int i, j; + char *rv; + ngx_http_module_t *module; + ngx_conf_t pcf; + ngx_http_conf_ctx_t *ctx, *hctx, *pctx; + ngx_http_core_main_conf_t *cmcf; + ngx_http_core_srv_conf_t *cscf, **cscfp; ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); - tctx = (ngx_http_conf_ctx_t *) cf->ctx; - ctx->main_conf = tctx->main_conf; + hctx = (ngx_http_conf_ctx_t *) cf->ctx; + ctx->main_conf = hctx->main_conf; - /* server configuration */ + /* the server{}'s srv_conf */ ngx_test_null(ctx->srv_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); - /* server location configuration */ + /* the server{}'s loc_conf */ ngx_test_null(ctx->loc_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), @@ -658,6 +670,17 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) } } + /* create links of the srv_conf's */ + + cscf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + cscf->ctx = ctx; + + cmcf = ctx->main_conf[ngx_http_core_module_ctx.index]; + ngx_test_null(cscfp, ngx_push_array(&cmcf->servers), NGX_CONF_ERROR); + *cscfp = cscf; + + /* parse inside server{} */ + pcf = *cf; pctx = cf->ctx; cf->ctx = ctx; @@ -665,50 +688,7 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) rv = ngx_conf_parse(cf, NULL); *cf = pcf; - if (rv != NGX_CONF_OK) - return rv; - - - scf = ctx->srv_conf[ngx_http_core_module_ctx.index]; - scf->ctx = ctx; - - plcf = (ngx_http_core_loc_conf_t **)scf->locations.elts; - - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) ngx_modules[i]->ctx; - - if (module->init_srv_conf) { - if (module->init_srv_conf(cf->pool, - ctx->srv_conf[module->index]) - == NGX_CONF_ERROR) { - return NGX_CONF_ERROR; - } - } - - if (module->merge_loc_conf) { - rv = module->merge_loc_conf(cf->pool, - pctx->loc_conf[module->index], - ctx->loc_conf[module->index]); - if (rv != NGX_CONF_OK) { - return rv; - } - - for (j = 0; j < scf->locations.nelts; j++) { - rv = module->merge_loc_conf(cf->pool, - ctx->loc_conf[module->index], - plcf[j]->loc_conf[module->index]); - if (rv != NGX_CONF_OK) { - return rv; - } - } - } - } - - return NGX_CONF_OK; + return rv; } @@ -720,14 +700,15 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) ngx_http_module_t *module; ngx_conf_t pcf; ngx_http_conf_ctx_t *ctx, *pctx; - ngx_http_core_srv_conf_t *scf; - ngx_http_core_loc_conf_t *lcf, **plcf; + ngx_http_core_srv_conf_t *cscf; + ngx_http_core_loc_conf_t *clcf, **clcfp; ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); pctx = (ngx_http_conf_ctx_t *) cf->ctx; + ctx->main_conf = pctx->main_conf; ctx->srv_conf = pctx->srv_conf; ngx_test_null(ctx->loc_conf, @@ -748,17 +729,15 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) } } - lcf = (ngx_http_core_loc_conf_t *) - ctx->loc_conf[ngx_http_core_module_ctx.index]; + clcf = ctx->loc_conf[ngx_http_core_module_ctx.index]; location = (ngx_str_t *) cf->args->elts; - lcf->name.len = location[1].len; - lcf->name.data = location[1].data; - lcf->loc_conf = ctx->loc_conf; + clcf->name.len = location[1].len; + clcf->name.data = location[1].data; + clcf->loc_conf = ctx->loc_conf; - scf = (ngx_http_core_srv_conf_t *) - ctx->srv_conf[ngx_http_core_module_ctx.index]; - ngx_test_null(plcf, ngx_push_array(&scf->locations), NGX_CONF_ERROR); - *plcf = lcf; + cscf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR); + *clcfp = clcf; pcf = *cf; cf->ctx = ctx; @@ -821,43 +800,81 @@ static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) } +static void *ngx_http_core_create_main_conf(ngx_pool_t *pool) +{ + ngx_http_core_main_conf_t *cmcf; + + ngx_test_null(cmcf, + ngx_palloc(pool, sizeof(ngx_http_core_main_conf_t)), + NGX_CONF_ERROR); + + cmcf->post_accept_timeout = NGX_CONF_UNSET; + cmcf->connection_pool_size = NGX_CONF_UNSET; + cmcf->request_pool_size = NGX_CONF_UNSET; + cmcf->client_header_timeout = NGX_CONF_UNSET; + cmcf->client_header_buffer_size = NGX_CONF_UNSET; + cmcf->large_client_header = NGX_CONF_UNSET; + + ngx_init_array(cmcf->servers, pool, 5, sizeof(ngx_http_core_srv_conf_t *), + NGX_CONF_ERROR); + + return cmcf; +} + + +static char *ngx_http_core_init_main_conf(ngx_pool_t *pool, void *conf) +{ + ngx_http_core_main_conf_t *cmcf = (ngx_http_core_main_conf_t *) conf; + + ngx_conf_init_msec_value(cmcf->post_accept_timeout, 30000); + ngx_conf_init_size_value(cmcf->connection_pool_size, 16384); + ngx_conf_init_size_value(cmcf->request_pool_size, 16384); + ngx_conf_init_msec_value(cmcf->client_header_timeout, 60000); + ngx_conf_init_size_value(cmcf->client_header_buffer_size, 1024); + ngx_conf_init_value(cmcf->large_client_header, 1); + + return NGX_CONF_OK; +} + + static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool) { - ngx_http_core_srv_conf_t *scf, **cf; + ngx_http_core_srv_conf_t *cscf; - ngx_test_null(scf, + ngx_test_null(cscf, ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), NGX_CONF_ERROR); - ngx_init_array(scf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR); - ngx_init_array(scf->listen, pool, 5, sizeof(ngx_http_listen_t), + ngx_init_array(cscf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR); + ngx_init_array(cscf->listen, pool, 5, sizeof(ngx_http_listen_t), NGX_CONF_ERROR); - ngx_init_array(scf->server_names, pool, 5, sizeof(ngx_http_server_name_t), + ngx_init_array(cscf->server_names, pool, 5, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); - ngx_test_null(cf, ngx_push_array(&ngx_http_servers), NGX_CONF_ERROR); - *cf = scf; - - return scf; + return cscf; } -static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf) +static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool, + void *parent, void *child) { - ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; + ngx_http_core_srv_conf_t *prev = (ngx_http_core_srv_conf_t *) parent; + ngx_http_core_srv_conf_t *conf = (ngx_http_core_srv_conf_t *) child; ngx_http_listen_t *l; ngx_http_server_name_t *n; - if (scf->listen.nelts == 0) { - ngx_test_null(l, ngx_push_array(&scf->listen), NGX_CONF_ERROR); + /* TODO: it does not merge, it init only */ + + if (conf->listen.nelts == 0) { + ngx_test_null(l, ngx_push_array(&conf->listen), NGX_CONF_ERROR); l->addr = INADDR_ANY; l->port = 8000; l->family = AF_INET; } - if (scf->server_names.nelts == 0) { - ngx_test_null(n, ngx_push_array(&scf->server_names), NGX_CONF_ERROR); + if (conf->server_names.nelts == 0) { + ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR); ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN), NGX_CONF_ERROR); if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) { @@ -959,15 +976,16 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, } } - ngx_conf_merge(conf->sendfile, prev->sendfile, 0); + ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); - ngx_conf_msec_merge(conf->send_timeout, prev->send_timeout, 10000); + ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000); - ngx_conf_size_merge(conf->discarded_buffer_size, - prev->discarded_buffer_size, 1500); - - ngx_conf_msec_merge(conf->lingering_time, prev->lingering_time, 30000); - ngx_conf_msec_merge(conf->lingering_timeout, prev->lingering_timeout, 5000); + ngx_conf_merge_size_value(conf->discarded_buffer_size, + prev->discarded_buffer_size, 1500); + ngx_conf_merge_msec_value(conf->lingering_time, prev->lingering_time, + 30000); + ngx_conf_merge_msec_value(conf->lingering_timeout, prev->lingering_timeout, + 5000); return NGX_CONF_OK; } @@ -975,11 +993,12 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { + ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; + uint p; char *addr; ngx_str_t *args; ngx_http_listen_t *ls; - ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; /* TODO: check duplicate 'listen' directives */ @@ -1001,7 +1020,8 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) ls->addr = inet_addr(addr); if (ls->addr == INADDR_NONE) { - return "bad addr"; + /* TODO: gethostbyname() */ + return "can not resolve host name"; } break; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index d44a86c11..c6c86f23a 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -18,17 +18,27 @@ typedef struct { typedef struct { + int post_accept_timeout; + int connection_pool_size; int request_pool_size; + int client_header_timeout; int client_header_buffer_size; + int large_client_header; + int url_in_error_log; + + ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */ } ngx_http_core_main_conf_t; typedef struct { - ngx_array_t locations; /* array of ngx_http_core_loc_conf_t */ + ngx_array_t locations; /* array of ngx_http_core_loc_conf_t, + used in the translation handler + and in the merge phase */ ngx_array_t listen; /* 'listen', array of ngx_http_listen_t */ ngx_array_t server_names; /* 'server_name', array of ngx_http_server_name_t */ + ngx_http_conf_ctx_t *ctx; /* server ctx */ } ngx_http_core_srv_conf_t; @@ -78,8 +88,7 @@ typedef struct { typedef struct { ngx_str_t name; /* location name */ - void **loc_conf; /* pointer to modules loc_conf, - used in translation handler */ + void **loc_conf ; /* pointer to the modules' loc_conf */ int (*handler) (ngx_http_request_t *r); diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index 94aa62225..1b9110fe1 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -137,15 +137,19 @@ void ngx_http_init_connection(ngx_connection_t *c) static void ngx_http_init_request(ngx_event_t *rev) { - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_conf_ctx_t *ctx; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_conf_ctx_t *ctx; + ngx_http_core_main_conf_t *cmcf; - c = (ngx_connection_t *) rev->data; + c = rev->data; + ctx = c->ctx; + + cmcf = ngx_http_get_module_main_conf(ctx, ngx_http_core_module_ctx); if (c->buffer == NULL) { c->buffer = ngx_create_temp_hunk(c->pool, - ngx_http_client_header_buffer_size, + cmcf->client_header_buffer_size, 0, 0); if (c->buffer == NULL) { ngx_http_close_connection(c); @@ -159,7 +163,7 @@ static void ngx_http_init_request(ngx_event_t *rev) return; } - r->pool = ngx_create_pool(ngx_http_request_pool_size, c->log); + r->pool = ngx_create_pool(cmcf->request_pool_size, c->log); if (r->pool == NULL) { ngx_http_close_connection(c); return; @@ -179,7 +183,7 @@ static void ngx_http_init_request(ngx_event_t *rev) return; } - ctx = (ngx_http_conf_ctx_t *) c->ctx; + r->main_conf = ctx->main_conf; r->srv_conf = ctx->srv_conf; r->loc_conf = ctx->loc_conf; @@ -202,14 +206,15 @@ static void ngx_http_init_request(ngx_event_t *rev) static void ngx_http_process_request_line(ngx_event_t *rev) { - int rc, offset; - ssize_t n; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_log_ctx_t *lcx; + int rc, offset; + ssize_t n; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_log_ctx_t *lcx; + ngx_http_core_main_conf_t *cmcf; - c = (ngx_connection_t *) rev->data; - r = (ngx_http_request_t *) c->data; + c = rev->data; + r = c->data; ngx_log_debug(rev->log, "http process request line"); @@ -231,8 +236,10 @@ static void ngx_http_process_request_line(ngx_event_t *rev) /* the request line has been parsed successfully */ + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); + if (r->http_version >= NGX_HTTP_VERSION_10 - && ngx_http_large_client_header == 0 + && cmcf->large_client_header == 0 && r->header_in->pos == r->header_in->end) { /* no space for "\r\n" at the end of the header */ @@ -259,12 +266,29 @@ static void ngx_http_process_request_line(ngx_event_t *rev) ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); +#if 1 /* needed to log url on errors in proxy only ? */ + + /* copy unparsed URI */ + + r->unparsed_uri.len = r->uri_end - r->uri_start; + r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1); + if (r->unparsed_uri.data == NULL) { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_http_close_connection(c); + return; + } + + ngx_cpystrn(r->unparsed_uri.data, r->uri_start, + r->unparsed_uri.len + 1); + +#endif + r->request_line.len = r->request_end - r->request_start; /* if the large client headers are enabled then we need to copy a request line */ - if (ngx_http_large_client_header) { + if (cmcf->large_client_header) { r->request_line.data = ngx_palloc(r->pool, r->request_line.len + 1); if (r->request_line.data == NULL) { @@ -325,19 +349,6 @@ static void ngx_http_process_request_line(ngx_event_t *rev) if (r->args.data[0] == '\0') { r->args.data = NULL; } #endif - lcx = c->log->data; - - if (ngx_http_url_in_error_log) { - lcx->url = ngx_palloc(r->pool, r->uri_end - r->uri_start + 1); - if (lcx->url == NULL) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_http_close_connection(c); - return; - } - - ngx_cpystrn(lcx->url, r->uri_start, r->uri_end - r->uri_start + 1); - } - if (r->http_version == NGX_HTTP_VERSION_9) { if (ngx_http_find_server_conf(r) == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -350,10 +361,12 @@ static void ngx_http_process_request_line(ngx_event_t *rev) return; } + lcx = c->log->data; lcx->action = "reading client request headers"; + lcx->url = r->unparsed_uri.data; r->headers_in.headers = ngx_create_table(r->pool, 10); - if (ngx_http_large_client_header + if (cmcf->large_client_header && r->header_in->pos == r->header_in->last) { r->header_in->pos = r->header_in->last = r->header_in->start; @@ -384,7 +397,9 @@ static void ngx_http_process_request_line(ngx_event_t *rev) are enabled otherwise a request line had been already copied to the start of the r->header_in hunk in ngx_http_set_keepalive() */ - if (ngx_http_large_client_header) { + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); + + if (cmcf->large_client_header) { offset = r->request_start - r->header_in->start; if (offset == 0) { @@ -422,16 +437,17 @@ static void ngx_http_process_request_line(ngx_event_t *rev) static void ngx_http_process_request_headers(ngx_event_t *rev) { - int rc, i, offset; - size_t len; - ssize_t n; - ngx_table_elt_t *h; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_log_ctx_t *ctx; - - c = (ngx_connection_t *) rev->data; - r = (ngx_http_request_t *) c->data; + int rc, i, offset; + size_t len; + ssize_t n; + ngx_table_elt_t *h; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_log_ctx_t *ctx; + ngx_http_core_main_conf_t *cmcf; + + c = rev->data; + r = c->data; ngx_log_debug(rev->log, "http process request header line"); @@ -471,7 +487,9 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) /* if the large client headers are enabled then we need to copy the header name and value */ - if (ngx_http_large_client_header) { + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); + + if (cmcf->large_client_header) { h->key.data = ngx_palloc(r->pool, h->key.len + 1 + h->value.len + 1); if (h->key.data == NULL) { @@ -505,7 +523,7 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _ h->key.data _ h->value.data); - if (ngx_http_large_client_header + if (cmcf->large_client_header && r->header_in->pos == r->header_in->last) { r->header_in->pos = r->header_in->last = r->header_in->start; @@ -574,7 +592,9 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) /* if the large client headers are enabled then we need to compact r->header_in hunk */ - if (ngx_http_large_client_header) { + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); + + if (cmcf->large_client_header) { offset = r->header_name_start - r->header_in->start; if (offset == 0) { @@ -606,9 +626,10 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) static ssize_t ngx_http_read_request_header(ngx_http_request_t *r) { - int event; - ssize_t n; - ngx_event_t *rev; + int event; + ssize_t n; + ngx_event_t *rev; + ngx_http_core_main_conf_t *cmcf; n = r->header_in->last - r->header_in->pos; @@ -629,7 +650,9 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r) rev->timer_set = 1; } - ngx_add_timer(rev, ngx_http_client_header_timeout); + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); + + ngx_add_timer(rev, cmcf->client_header_timeout); r->header_timeout_set = 1; } @@ -724,7 +747,7 @@ void ngx_http_set_write_handler(ngx_http_request_t *r) { int event; ngx_event_t *wev; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; wev = r->connection->write; wev->event_handler = ngx_http_writer; @@ -733,10 +756,10 @@ void ngx_http_set_write_handler(ngx_http_request_t *r) return; } - lcf = (ngx_http_core_loc_conf_t *) + clcf = (ngx_http_core_loc_conf_t *) ngx_http_get_module_loc_conf(r->main ? r->main : r, ngx_http_core_module_ctx); - ngx_add_timer(wev, lcf->send_timeout); + ngx_add_timer(wev, clcf->send_timeout); wev->timer_set = 1; if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) { @@ -747,7 +770,7 @@ void ngx_http_set_write_handler(ngx_http_request_t *r) #if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */ if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) { - wev->lowat = lcf->send_lowat; + wev->lowat = clcf->send_lowat; } #endif @@ -823,9 +846,8 @@ static void ngx_http_writer(ngx_event_t *wev) if (r->keepalive != 0) { ngx_http_set_keepalive(r); - } - if (r->lingering_close) { + } else if (r->lingering_close) { ngx_http_set_lingering_close(r); } else { @@ -970,11 +992,12 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r) static void ngx_http_set_keepalive(ngx_http_request_t *r) { - int len, blocked; - ngx_hunk_t *h; - ngx_event_t *rev, *wev; - ngx_connection_t *c; - ngx_http_log_ctx_t *ctx; + int len, blocked; + ngx_hunk_t *h; + ngx_event_t *rev, *wev; + ngx_connection_t *c; + ngx_http_log_ctx_t *ctx; + ngx_http_core_main_conf_t *cmcf; c = (ngx_connection_t *) r->connection; rev = c->read; @@ -1007,7 +1030,9 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) This copy should be rare because clients that support pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */ - if (!ngx_http_large_client_header) { + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); + + if (!cmcf->large_client_header) { len = h->last - h->pos; ngx_memcpy(h->start, h->pos, len); h->pos = h->start; diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 926a286e0..3ad260eab 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -18,14 +18,17 @@ static int ngx_http_header_filter_init(ngx_pool_t *pool); static int ngx_http_header_filter(ngx_http_request_t *r); -ngx_http_module_t ngx_http_header_filter_module_ctx = { - NULL, /* create server config */ - NULL, /* init server config */ +static ngx_http_module_t ngx_http_header_filter_module_ctx = { + NGX_HTTP_MODULE, - NULL, /* create location config */ - NULL, /* merge location config */ + NULL, /* create main configuration */ + NULL, /* init main configuration */ - NULL /* init filters */ + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL, /* merge location configuration */ }; diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c index 738c3836a..53c32e1ad 100644 --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -23,7 +23,7 @@ static void ngx_http_output_filter_init(ngx_pool_t *pool, static ngx_command_t ngx_http_output_filter_commands[] = { {ngx_string("output_buffer"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_output_filter_conf_t, hunk_size), @@ -36,11 +36,14 @@ static ngx_command_t ngx_http_output_filter_commands[] = { static ngx_http_module_t ngx_http_output_filter_module_ctx = { NGX_HTTP_MODULE, - NULL, /* create server config */ - NULL, /* init server config */ + NULL, /* create main configuration */ + NULL, /* init main configuration */ - ngx_http_output_filter_create_conf, /* create location config */ - ngx_http_output_filter_merge_conf /* merge location config */ + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_output_filter_create_conf, /* create location configuration */ + ngx_http_output_filter_merge_conf /* merge location configuration */ }; @@ -336,7 +339,7 @@ static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, ngx_http_output_filter_conf_t *conf = (ngx_http_output_filter_conf_t *) child; - ngx_conf_size_merge(conf->hunk_size, prev->hunk_size, 32768); + ngx_conf_merge_size_value(conf->hunk_size, prev->hunk_size, 32768); return NULL; } diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c index 765da83c8..a7784a36d 100644 --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -9,13 +9,24 @@ int ngx_parse_http_request_line(ngx_http_request_t *r) char *p; enum { sw_start = 0, + sw_G, + sw_GE, + sw_H, + sw_HE, + sw_HEA, + sw_P, + sw_PO, + sw_POS, 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_http_H, + sw_http_HT, + sw_http_HTT, + sw_http_HTTP, sw_first_major_digit, sw_major_digit, sw_first_minor_digit, @@ -30,7 +41,7 @@ int ngx_parse_http_request_line(ngx_http_request_t *r) while (p < r->header_in->last && state < sw_done) { ch = *p++; - /* GCC 2.95.2 and VC 6.0 compile this switch as jump table */ + /* gcc 2.95.2 and vc 6.0 compile this switch as an jump table */ switch (state) { @@ -40,49 +51,100 @@ int ngx_parse_http_request_line(ngx_http_request_t *r) switch (ch) { case 'G': - if (p + 1 >= r->header_in->last) { - return NGX_AGAIN; - } + state = sw_G; + break; + case 'H': + state = sw_H; + break; + case 'P': + state = sw_P; + break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; - if (*p != 'E' || *(p + 1) != 'T') { - return NGX_HTTP_PARSE_INVALID_METHOD; - } + case sw_G: + switch (ch) { + case 'E': + state = sw_GE; + break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; + case sw_GE: + switch (ch) { + case 'T': r->method = NGX_HTTP_GET; - p += 2; + state = sw_space_after_method; break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; - case 'H': - if (p + 2 >= r->header_in->last) { - return NGX_AGAIN; - } + case sw_H: + switch (ch) { + case 'E': + state = sw_HE; + break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; - if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D') { - return NGX_HTTP_PARSE_INVALID_METHOD; - } + case sw_HE: + switch (ch) { + case 'A': + state = sw_HEA; + break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; + case sw_HEA: + switch (ch) { + case 'D': r->method = NGX_HTTP_HEAD; - p += 3; + state = sw_space_after_method; break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; - case 'P': - if (p + 2 >= r->header_in->last) { - return NGX_AGAIN; - } + case sw_P: + switch (ch) { + case 'O': + state = sw_PO; + break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; - if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T') { - return NGX_HTTP_PARSE_INVALID_METHOD; - } + case sw_PO: + switch (ch) { + case 'S': + state = sw_POS; + break; + default: + return NGX_HTTP_PARSE_INVALID_METHOD; + } + break; + case sw_POS: + switch (ch) { + case 'T': r->method = NGX_HTTP_POST; - p += 3; + state = sw_space_after_method; break; - default: return NGX_HTTP_PARSE_INVALID_METHOD; } - - state = sw_space_after_method; break; /* single space after method */ @@ -214,27 +276,51 @@ int ngx_parse_http_request_line(ngx_http_request_t *r) state = sw_done; break; case 'H': - state = sw_http_version; + state = sw_http_H; break; default: return NGX_HTTP_PARSE_INVALID_REQUEST; } break; - /* "TTP/" */ - case sw_http_version: - if (p + 2 >= r->header_in->last) { - r->state = sw_http_version; - r->header_in->pos = p - 1; - return NGX_AGAIN; + case sw_http_H: + switch (ch) { + case 'T': + state = sw_http_HT; + break; + default: + return NGX_HTTP_PARSE_INVALID_REQUEST; + } + break; + + case sw_http_HT: + switch (ch) { + case 'T': + state = sw_http_HTT; + break; + default: + return NGX_HTTP_PARSE_INVALID_REQUEST; } + break; - if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/') { + case sw_http_HTT: + switch (ch) { + case 'P': + state = sw_http_HTTP; + break; + default: return NGX_HTTP_PARSE_INVALID_REQUEST; } + break; - p += 3; - state = sw_first_major_digit; + case sw_http_HTTP: + switch (ch) { + case '/': + state = sw_first_major_digit; + break; + default: + return NGX_HTTP_PARSE_INVALID_REQUEST; + } break; /* first digit of major HTTP version */ diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h new file mode 100644 index 000000000..c77fa288e --- /dev/null +++ b/src/http/ngx_http_request.h @@ -0,0 +1,205 @@ +#ifndef _NGX_HTTP_REQUEST_H_INCLUDED_ +#define _NGX_HTTP_REQUEST_H_INCLUDED_ + + +#if 0 +#include <ngx_config.h> + +#include <ngx_types.h> +#include <ngx_string.h> +#include <ngx_table.h> +#include <ngx_hunk.h> +#include <ngx_files.h> +#include <ngx_connection.h> +#include <ngx_conf_file.h> + +#endif + + +#define NGX_HTTP_VERSION_9 9 +#define NGX_HTTP_VERSION_10 1000 +#define NGX_HTTP_VERSION_11 1001 + +#define NGX_HTTP_GET 1 +#define NGX_HTTP_HEAD 2 +#define NGX_HTTP_POST 3 + +#define NGX_HTTP_CONN_CLOSE 0 +#define NGX_HTTP_CONN_KEEP_ALIVE 1 + + +#define NGX_HTTP_PARSE_HEADER_DONE 1 +#define NGX_HTTP_PARSE_INVALID_METHOD 10 +#define NGX_HTTP_PARSE_INVALID_REQUEST 11 +#define NGX_HTTP_PARSE_TOO_LONG_URI 12 +#define NGX_HTTP_PARSE_INVALID_09_METHOD 13 +#define NGX_HTTP_PARSE_INVALID_HEADER 14 +#define NGX_HTTP_PARSE_TOO_LONG_HEADER 15 +#define NGX_HTTP_PARSE_NO_HOST_HEADER 16 +#define NGX_HTTP_PARSE_INVALID_CL_HEADER 17 + + +#define NGX_HTTP_OK 200 + +#define NGX_HTTP_SPECIAL_RESPONSE 300 +#define NGX_HTTP_MOVED_PERMANENTLY 301 +#define NGX_HTTP_MOVED_TEMPORARILY 302 +#define NGX_HTTP_NOT_MODIFIED 304 + +#define NGX_HTTP_BAD_REQUEST 400 +#define NGX_HTTP_FORBIDDEN 403 +#define NGX_HTTP_NOT_FOUND 404 +#define NGX_HTTP_REQUEST_TIME_OUT 408 +#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 + +#define NGX_HTTP_INTERNAL_SERVER_ERROR 500 +#define NGX_HTTP_NOT_IMPLEMENTED 501 +#define NGX_HTTP_BAD_GATEWAY 502 +#define NGX_HTTP_SERVICE_UNAVAILABLE 503 +#define NGX_HTTP_GATEWAY_TIME_OUT 504 + + + +#define NGX_HTTP_STATIC_HANDLER 0 +#define NGX_HTTP_DIRECTORY_HANDLER 1 + + +typedef struct { + ngx_str_t name; + int offset; +} ngx_http_header_t; + + +typedef struct { + size_t host_name_len; + ssize_t content_length_n; + + ngx_table_elt_t *host; + ngx_table_elt_t *connection; + ngx_table_elt_t *if_modified_since; + ngx_table_elt_t *content_length; + ngx_table_elt_t *accept_encoding; + + ngx_table_elt_t *user_agent; + + ngx_table_t *headers; +} ngx_http_headers_in_t; + + +typedef struct { + ngx_chain_t chain[4]; + ngx_hunk_t *header_out; + ngx_hunk_t *hunk; + ngx_hunk_t *file_hunk; + ngx_file_t temp_file; + ngx_path_t *temp_path; + off_t offset; + char *header_in_pos; +} ngx_http_request_body_t; + + +typedef struct { + int status; + ngx_str_t status_line; + + ngx_table_elt_t *server; + ngx_table_elt_t *date; + ngx_table_elt_t *content_type; + ngx_table_elt_t *location; + ngx_table_elt_t *last_modified; + + ngx_table_t *headers; + + off_t content_length; + char *charset; + char *etag; + time_t date_time; + time_t last_modified_time; +} ngx_http_headers_out_t; + + +typedef struct ngx_http_request_s ngx_http_request_t; + +struct ngx_http_request_s { + ngx_connection_t *connection; + + void **ctx; + void **main_conf; + void **srv_conf; + void **loc_conf; + + ngx_file_t file; + + ngx_pool_t *pool; + ngx_hunk_t *header_in; + ngx_http_request_body_t *request_body; + + 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; + int http_version; + int http_major; + int http_minor; + + ngx_str_t request_line; + ngx_str_t uri; + ngx_str_t args; + ngx_str_t exten; + ngx_str_t unparsed_uri; + + ngx_http_request_t *main; + + u_int in_addr; + + int port; + ngx_str_t port_name; + + int filter; + + char *discarded_buffer; + + ngx_str_t path; + int path_err; + + unsigned proxy:1; + unsigned cachable:1; + unsigned pipeline:1; + unsigned keepalive:1; + unsigned lingering_close:1; + + unsigned header_read:1; + unsigned header_timeout_set:1; + + unsigned logging:1; + + unsigned header_only:1; + unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */ + unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */ + unsigned path_not_found:1; +#ifdef NGX_EVENT + unsigned write_level_event:1; +#endif + + int state; + char *uri_start; + char *uri_end; + char *uri_ext; + char *args_start; + char *request_start; + char *request_end; + char *header_name_start; + char *header_name_end; + char *header_start; + char *header_end; +#ifdef NGX_EVENT + int (*state_handler)(ngx_http_request_t *r); +#endif +}; + + +#endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */ diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index 31303d4ad..81cf19cf8 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -35,11 +35,14 @@ static ngx_command_t ngx_http_write_filter_commands[] = { ngx_http_module_t ngx_http_write_filter_module_ctx = { NGX_HTTP_MODULE, - NULL, /* create server config */ - NULL, /* init server config */ + NULL, /* create main configuration */ + NULL, /* init main configuration */ - ngx_http_write_filter_create_conf, /* create location config */ - ngx_http_write_filter_merge_conf /* merge location config */ + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_write_filter_create_conf, /* create location configuration */ + ngx_http_write_filter_merge_conf /* merge location configuration */ }; @@ -61,9 +64,9 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_http_write_filter_conf_t *conf; - ctx = (ngx_http_write_filter_ctx_t *) - ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_write_filter_module_ctx); + ctx = ngx_http_get_module_ctx(r->main ? r->main : r, + ngx_http_write_filter_module_ctx); + if (ctx == NULL) { ngx_http_create_ctx(r, ctx, ngx_http_write_filter_module_ctx, sizeof(ngx_http_write_filter_ctx_t), NGX_ERROR); @@ -118,9 +121,8 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) } } - conf = (ngx_http_write_filter_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_write_filter_module_ctx); + conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_write_filter_module_ctx); #if (NGX_DEBUG_WRITE_FILTER) ngx_log_debug(r->connection->log, @@ -139,7 +141,11 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_AGAIN; } +#if 1 + chain = ngx_write_chain(r->connection, ctx->out); +#else chain = ngx_write_chain(r->connection, ctx->out, flush); +#endif #if (NGX_DEBUG_WRITE_FILTER) ngx_log_debug(r->connection->log, "write filter %x" _ chain); @@ -177,12 +183,10 @@ static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool) static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool, void *parent, void *child) { - ngx_http_write_filter_conf_t *prev = - (ngx_http_write_filter_conf_t *) parent; - ngx_http_write_filter_conf_t *conf = - (ngx_http_write_filter_conf_t *) child; + ngx_http_write_filter_conf_t *prev = parent; + ngx_http_write_filter_conf_t *conf = child; - ngx_conf_size_merge(conf->buffer_output, prev->buffer_output, 1460); + ngx_conf_merge_size_value(conf->buffer_output, prev->buffer_output, 1460); return NULL; } diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c index f8896e871..f9cba480c 100644 --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -10,6 +10,14 @@ int ngx_freebsd_net_inet_tcp_sendspace; int ngx_freebsd_sendfile_nbytes_bug; +ngx_os_io_t ngx_os_io = { + ngx_unix_recv, + NULL, + NULL, + ngx_freebsd_write_chain +}; + + int ngx_os_init(ngx_log_t *log) { size_t size; @@ -99,5 +107,5 @@ int ngx_os_init(ngx_log_t *log) ngx_log_error(NGX_LOG_INFO, log, 0, "net.inet.tcp.sendspace: %d", ngx_freebsd_net_inet_tcp_sendspace); - return NGX_OK; + return ngx_unix_init(log); } diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h index 400295ae7..d0d2c5b87 100644 --- a/src/os/unix/ngx_freebsd_init.h +++ b/src/os/unix/ngx_freebsd_init.h @@ -5,10 +5,12 @@ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_log.h> +#include <ngx_os_init.h> #include <sys/sysctl.h> -int ngx_os_init(ngx_log_t *log); +int ngx_unix_init(ngx_log_t *log); +ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size); extern int ngx_freebsd_kern_osreldate; diff --git a/src/os/unix/ngx_init.c b/src/os/unix/ngx_init.c deleted file mode 100644 index 28af1288d..000000000 --- a/src/os/unix/ngx_init.c +++ /dev/null @@ -1,20 +0,0 @@ - - -int ngx_unix_init(ngx_log_t *log) -{ - struct rlimit rlmt; - - if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, - "getrlimit(RLIMIT_NOFILE) failed)"); - return NGX_ERROR; - } - - ngx_log_error(NGX_LOG_INFO, log, 0, - "getrlimit(RLIMIT_NOFILE): %d", rlmt.rlim_cur); - - RLIM_INFINITY - max_connections =< rlmt.rlim_cur; - - return NGX_OK; -} diff --git a/src/os/unix/ngx_os_init.h b/src/os/unix/ngx_os_init.h index 5c445ace6..25e0b6a7a 100644 --- a/src/os/unix/ngx_os_init.h +++ b/src/os/unix/ngx_os_init.h @@ -4,9 +4,13 @@ #include <ngx_config.h> #include <ngx_log.h> +#include <ngx_hunk.h> +#include <ngx_connection.h> int ngx_os_init(ngx_log_t *log); +extern ngx_os_io_t ngx_os_io; + #endif /* _NGX_OS_INIT_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c new file mode 100644 index 000000000..c6e8b0390 --- /dev/null +++ b/src/os/unix/ngx_recv.c @@ -0,0 +1,92 @@ + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_errno.h> +#include <ngx_log.h> +#include <ngx_recv.h> +#include <ngx_connection.h> + + +ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size) +{ + ssize_t n; + ngx_err_t err; + ngx_event_t *ev; + + ev = c->read; + +#if (HAVE_KQUEUE) /* DEBUG */ + if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + ngx_log_debug(c->log, "ngx_recv: eof:%d, avail:%d, err:%d" _ + ev->eof _ ev->available _ ev->error); + } +#endif + +#if (HAVE_KQUEUE) + + if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) + && ev->eof && ev->available == 0) { + + if (ev->error == 0) { + return 0; + } + + ngx_set_socket_errno(ev->error); + err = ev->error; + n = -1; + + } else { + n = recv(c->fd, buf, size, 0); + +ngx_log_debug(c->log, "ngx_recv: read:%d:%d" _ n _ size); + + if (n == -1) { + err = ngx_socket_errno; + } + } + +#else /* not kqueue */ + + n = recv(c->fd, buf, size, 0); + + if (n == -1) { + err = ngx_socket_errno; + } + +#endif + + if (n == -1) { + ev->ready = 0; + + if (err == NGX_ECONNRESET && ev->ignore_econnreset) { + return 0; + } + + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returned EAGAIN"); + return NGX_AGAIN; + } + + ngx_log_error(NGX_LOG_ERR, c->log, err, "recv() failed"); + return NGX_ERROR; + } + +#if (HAVE_KQUEUE) + + if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + ev->available -= n; + if (ev->available == 0) { + ev->ready = 0; + } + + return n; + } + +#endif + + if ((size_t) n < size) { + ev->ready = 0; + } + + return n; +} diff --git a/src/os/unix/ngx_recv.h b/src/os/unix/ngx_recv.h index e92832cc7..01d662fec 100644 --- a/src/os/unix/ngx_recv.h +++ b/src/os/unix/ngx_recv.h @@ -2,9 +2,11 @@ #define _NGX_RECV_H_INCLUDED_ +#if 0 #include <errno.h> #define ngx_recv(fd, buf, size, flags) recv(fd, buf, size, flags) +#endif #endif /* _NGX_RECV_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_unix_init.c b/src/os/unix/ngx_unix_init.c new file mode 100644 index 000000000..2916c9e44 --- /dev/null +++ b/src/os/unix/ngx_unix_init.c @@ -0,0 +1,39 @@ + +#include <ngx_config.h> +#include <ngx_core.h> + + +int ngx_unix_init(ngx_log_t *log) +{ + struct sigaction sa; + struct rlimit rlmt; + + ngx_memzero(&sa, sizeof(struct sigaction)); + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + + if (sigaction(SIGPIPE, &sa, NULL) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "sigaction(SIGPIPE, SIG_IGN) failed"); + return NGX_ERROR; + } + + + if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "getrlimit(RLIMIT_NOFILE) failed)"); + return NGX_ERROR; + } + + ngx_log_error(NGX_LOG_INFO, log, 0, + "getrlimit(RLIMIT_NOFILE): %qd:%qd", + rlmt.rlim_cur, rlmt.rlim_max); + + +#if 0 + RLIM_INFINITY + max_connections =< rlmt.rlim_cur; +#endif + + return NGX_OK; +} diff --git a/src/os/win32/ngx_init.c b/src/os/win32/ngx_init.c new file mode 100644 index 000000000..cc4f25e62 --- /dev/null +++ b/src/os/win32/ngx_init.c @@ -0,0 +1,11 @@ + +#include <ngx_os_init.h> + +int ngx_os_init(ngx_log_t *log) +{ + if (ngx_init_sockets(&ngx_log) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_OK; +} diff --git a/src/os/win32/ngx_os_init.h b/src/os/win32/ngx_os_init.h new file mode 100644 index 000000000..5c445ace6 --- /dev/null +++ b/src/os/win32/ngx_os_init.h @@ -0,0 +1,12 @@ +#ifndef _NGX_OS_INIT_H_INCLUDED_ +#define _NGX_OS_INIT_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_log.h> + + +int ngx_os_init(ngx_log_t *log); + + +#endif /* _NGX_OS_INIT_H_INCLUDED_ */ |