# HG changeset patch # User Igor Sysoev # Date 1054037934 0 # Node ID a23d010f356df378b3d5c43c9bec759f01b19fee # Parent b48066122884ab0a139869c26f1f72a203ddcd2b nginx-0.0.1-2003-05-27-16:18:54 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -87,7 +87,7 @@ int main(int argc, char *const *argv) conf.ctx = ngx_conf_ctx; conf.pool = ngx_pool; conf.log = &ngx_log; - conf.module_type = NGX_CORE_MODULE_TYPE; + conf.module_type = NGX_CORE_MODULE; conf.cmd_type = NGX_MAIN_CONF; conf_file.len = sizeof("nginx.conf") - 1; @@ -121,7 +121,7 @@ int main(int argc, char *const *argv) /* STUB */ ngx_worker(&ngx_log); - } + } return 0; } diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -6,6 +6,9 @@ #include +char ngx_conf_errstr[MAX_CONF_ERRSTR]; + + static int argument_number[] = { NGX_CONF_NOARGS, NGX_CONF_TAKE1, @@ -17,7 +20,7 @@ static int ngx_conf_read_token(ngx_conf_ char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { - int i, rc, found; + int m, rc, found; char *rv; void *conf, **confp; ngx_str_t *name; @@ -32,7 +35,6 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx fd = ngx_open_file(filename->data, NGX_FILE_RDONLY); if (fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, - "ngx_conf_file: " ngx_open_file_n " %s failed", filename->data); return NGX_CONF_ERROR; } @@ -44,7 +46,6 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) { ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, - "ngx_conf_file: " ngx_stat_fd_n " %s failed", filename->data); } @@ -101,17 +102,17 @@ ngx_log_debug(cf->log, "token %d" _ rc); name = (ngx_str_t *) cf->args->elts; found = 0; - for (i = 0; !found && ngx_modules[i]; i++) { + for (m = 0; !found && ngx_modules[m]; m++) { /* look up the directive in the appropriate modules */ - if (ngx_modules[i]->type != NGX_CONF_MODULE_TYPE - && ngx_modules[i]->type != cf->module_type) + if (ngx_modules[m]->type != NGX_CONF_MODULE + && ngx_modules[m]->type != cf->module_type) { continue; } - cmd = ngx_modules[i]->commands; + cmd = ngx_modules[m]->commands; if (cmd == NULL) { continue; } @@ -160,14 +161,14 @@ ngx_log_debug(cf->log, "command '%s'" _ conf = NULL; - if (cf->module_type == NGX_CORE_MODULE_TYPE) { - conf = &(((void **) cf->ctx)[ngx_modules[i]->index]); + if (cf->module_type == NGX_CORE_MODULE) { + conf = &(((void **) cf->ctx)[ngx_modules[m]->index]); } else if (cf->ctx) { confp = *(void **) ((char *) cf->ctx + cmd->conf); if (confp) { - conf = confp[*(int *)(ngx_modules[i]->ctx)]; + conf = confp[ngx_modules[m]->ctx_index]; } } @@ -185,11 +186,19 @@ ngx_log_debug(cf->log, "rv: %d" _ rv); return NGX_CONF_ERROR; } else { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "%s %s in %s:%d", - name->data, rv, - cf->conf_file->file.name.data, - cf->conf_file->line); + if (rv == ngx_conf_errstr) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "%s in %s:%d", + rv, + cf->conf_file->file.name.data, + cf->conf_file->line); + } else { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "%s %s in %s:%d", + name->data, rv, + cf->conf_file->file.name.data, + cf->conf_file->line); + } return NGX_CONF_ERROR; } @@ -430,7 +439,7 @@ ngx_log_debug(cf->log, "FOUND %d:'%s'" _ } -char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int flag; ngx_str_t *value; @@ -457,13 +466,13 @@ char *ngx_conf_set_flag_slot(ngx_conf_t } -char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *field, *value; field = (ngx_str_t *) (conf + cmd->offset); - if (field->len > 0) { + if (field->data) { return "is duplicate"; } @@ -476,7 +485,7 @@ char *ngx_conf_set_str_slot(ngx_conf_t * } -char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int num, len; ngx_str_t *value; @@ -500,7 +509,7 @@ char *ngx_conf_set_num_slot(ngx_conf_t * } -char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int size, len, scale; char last; @@ -545,7 +554,7 @@ char *ngx_conf_set_size_slot(ngx_conf_t } -char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int size, total, len, scale; u_int max, i; @@ -640,7 +649,7 @@ char *ngx_conf_set_msec_slot(ngx_conf_t } -char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int size, total, len, scale; u_int max, i; @@ -747,7 +756,7 @@ char *ngx_conf_set_sec_slot(ngx_conf_t * } -char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { return "unsupported on this platform"; } diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -40,9 +40,14 @@ #define NGX_CONF_BLOCK_DONE 1 #define NGX_CONF_FILE_DONE 2 +#define NGX_MODULE 0, 0 -#define NGX_CORE_MODULE_TYPE 0x45524F43 /* "CORE" */ -#define NGX_CONF_MODULE_TYPE 0x464E4F43 /* "CONF" */ +#define NGX_CORE_MODULE 0x45524F43 /* "CORE" */ +#define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */ + + +#define MAX_CONF_ERRSTR 256 +extern char ngx_conf_errstr[MAX_CONF_ERRSTR]; typedef struct ngx_conf_s ngx_conf_t; @@ -52,16 +57,18 @@ typedef struct ngx_command_s ngx_comman struct ngx_command_s { ngx_str_t name; int type; - char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); + char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); int conf; int offset; void *bounds; }; +#define ngx_null_command {ngx_null_string, 0, NULL, 0, 0, NULL} typedef struct { + int ctx_index; + int index; void *ctx; - int index; ngx_command_t *commands; int type; int (*init_module)(ngx_pool_t *p); @@ -129,6 +136,17 @@ struct ngx_conf_s { conf = (prev == (size_t) NGX_CONF_UNSET) ? default : prev; \ } +#define ngx_conf_merge_str_value(conf, prev, default) \ + if (conf.len == 0) { \ + if (prev.len) { \ + conf.len = prev.len; \ + conf.data = prev.data; \ + } else { \ + conf.len = sizeof(default) - 1; \ + conf.data = default; \ + } \ + } + #define addressof(addr) ((int) &addr) @@ -136,12 +154,12 @@ struct ngx_conf_s { char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename); -char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); -char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); -char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); -char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); -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); +char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); extern ngx_module_t *ngx_modules[]; diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -10,9 +10,9 @@ #include #include #include -#endif #include +#endif #if 0 typedef struct ngx_connection_s ngx_connection_t; @@ -35,7 +35,7 @@ struct ngx_connection_s { void (*handler)(ngx_connection_t *c); void *ctx; - ngx_server_t *servers; + void *servers; ngx_log_t *log; @@ -114,7 +114,6 @@ ngx_chain_t *ngx_write_chain(ngx_connect /* TODO: move it to OS specific file */ #if (__FreeBSD__) -ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in); ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in); #endif diff --git a/src/core/ngx_modules.c b/src/core/ngx_modules.c --- a/src/core/ngx_modules.c +++ b/src/core/ngx_modules.c @@ -30,6 +30,7 @@ extern ngx_module_t ngx_http_output_fil extern ngx_module_t ngx_http_header_filter_module; extern ngx_module_t ngx_http_index_module; +extern ngx_module_t ngx_http_static_module; extern ngx_module_t ngx_http_proxy_module; @@ -68,9 +69,8 @@ ngx_module_t *ngx_modules[] = { /* &ngx_http_ssi_filter_module, */ &ngx_http_index_module, -/* - &ngx_http_proxy_module, -*/ + /* &ngx_http_static_module, */ + /* &ngx_http_proxy_module, */ NULL }; diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c --- a/src/event/modules/ngx_aio_module.c +++ b/src/event/modules/ngx_aio_module.c @@ -29,7 +29,6 @@ ngx_os_io_t ngx_os_aio = { static ngx_str_t aio_name = ngx_string("aio"); ngx_event_module_t ngx_aio_module_ctx = { - NGX_EVENT_MODULE, &aio_name, NULL, /* create configuration */ NULL, /* init configuration */ @@ -49,10 +48,10 @@ ngx_event_module_t ngx_aio_module_ctx = }; ngx_module_t ngx_aio_module = { + NGX_MODULE, &ngx_aio_module_ctx, /* module context */ - 0, /* module index */ NULL, /* module directives */ - NGX_EVENT_MODULE_TYPE, /* module type */ + NGX_EVENT_MODULE, /* module type */ NULL /* init module */ }; diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -72,12 +72,11 @@ static ngx_command_t ngx_devpoll_comman offsetof(ngx_devpoll_conf_t, events), NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_event_module_t ngx_devpoll_module_ctx = { - NGX_EVENT_MODULE, &devpoll_name, ngx_devpoll_create_conf, /* create configuration */ ngx_devpoll_init_conf, /* init configuration */ @@ -97,10 +96,10 @@ ngx_event_module_t ngx_devpoll_module_c }; ngx_module_t ngx_devpoll_module = { + NGX_MODULE, &ngx_devpoll_module_ctx, /* module context */ - 0, /* module index */ ngx_devpoll_commands, /* module directives */ - NGX_EVENT_MODULE_TYPE, /* module type */ + NGX_EVENT_MODULE, /* module type */ NULL /* init module */ }; @@ -109,7 +108,7 @@ static int ngx_devpoll_init(ngx_log_t *l { ngx_devpoll_conf_t *dpcf; - dpcf = ngx_event_get_conf(ngx_devpoll_module_ctx); + dpcf = ngx_event_get_conf(ngx_devpoll_module); ngx_log_debug(log, "CH: %d" _ dpcf->changes); ngx_log_debug(log, "EV: %d" _ dpcf->events); @@ -194,7 +193,7 @@ static int ngx_devpoll_del_event(ngx_eve ngx_event_t *e; #if (NGX_DEBUG_EVENT) - ngx_connection_t *c = (ngx_connection_t *) ev->data; + ngx_connection_t *c = ev->data; ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); #endif @@ -229,7 +228,7 @@ static int ngx_devpoll_del_event(ngx_eve static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags) { - int n; + int n; ngx_connection_t *c; c = ev->data; diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -47,12 +47,11 @@ static ngx_command_t ngx_kqueue_command offsetof(ngx_kqueue_conf_t, events), NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; 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 */ @@ -72,10 +71,10 @@ ngx_event_module_t ngx_kqueue_module_ct }; ngx_module_t ngx_kqueue_module = { + NGX_MODULE, &ngx_kqueue_module_ctx, /* module context */ - 0, /* module index */ ngx_kqueue_commands, /* module directives */ - NGX_EVENT_MODULE_TYPE, /* module type */ + NGX_EVENT_MODULE, /* module type */ NULL /* init module */ }; @@ -84,7 +83,7 @@ static int ngx_kqueue_init(ngx_log_t *lo { ngx_kqueue_conf_t *kcf; - kcf = ngx_event_get_conf(ngx_kqueue_module_ctx); + kcf = ngx_event_get_conf(ngx_kqueue_module); ngx_log_debug(log, "CH: %d" _ kcf->changes); ngx_log_debug(log, "EV: %d" _ kcf->events); diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h --- a/src/event/modules/ngx_kqueue_module.h +++ b/src/event/modules/ngx_kqueue_module.h @@ -8,8 +8,9 @@ typedef struct { } ngx_kqueue_conf_t; -extern int ngx_kqueue; -/* STUB */ extern ngx_event_module_t ngx_kqueue_module_ctx; +extern int ngx_kqueue; +extern ngx_module_t ngx_kqueue_module; +extern ngx_event_module_t ngx_kqueue_module_ctx; diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -27,7 +27,6 @@ static ngx_event_t **ready_index; static ngx_str_t poll_name = ngx_string("poll"); ngx_event_module_t ngx_poll_module_ctx = { - NGX_EVENT_MODULE, &poll_name, NULL, /* create configuration */ NULL, /* init configuration */ @@ -47,10 +46,10 @@ ngx_event_module_t ngx_poll_module_ctx }; ngx_module_t ngx_poll_module = { + NGX_MODULE, &ngx_poll_module_ctx, /* module context */ - 0, /* module index */ NULL, /* module directives */ - NGX_EVENT_MODULE_TYPE, /* module type */ + NGX_EVENT_MODULE, /* module type */ NULL /* init module */ }; @@ -60,7 +59,7 @@ static int ngx_poll_init(ngx_log_t *log) { ngx_event_conf_t *ecf; - ecf = ngx_event_get_conf(ngx_event_module_ctx); + ecf = ngx_event_get_conf(ngx_event_module); ngx_test_null(event_list, ngx_alloc(sizeof(struct pollfd) * ecf->connections, log), diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -40,7 +40,6 @@ static ngx_event_t **ready_index; 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 */ @@ -60,10 +59,10 @@ ngx_event_module_t ngx_select_module_ct }; ngx_module_t ngx_select_module = { + NGX_MODULE, &ngx_select_module_ctx, /* module context */ - 0, /* module index */ NULL, /* module directives */ - NGX_EVENT_MODULE_TYPE, /* module type */ + NGX_EVENT_MODULE, /* module type */ NULL /* init module */ }; @@ -72,7 +71,7 @@ static int ngx_select_init(ngx_log_t *lo { ngx_event_conf_t *ecf; - ecf = ngx_event_get_conf(ngx_event_module_ctx); + ecf = ngx_event_get_conf(ngx_event_module); FD_ZERO(&master_read_fd_set); FD_ZERO(&master_write_fd_set); @@ -378,7 +377,7 @@ static char *ngx_select_init_conf(ngx_po { ngx_event_conf_t *ecf; - ecf = ngx_event_get_conf(ngx_event_module_ctx); + ecf = ngx_event_get_conf(ngx_event_module); if (ecf->connections > FD_SETSIZE) { return "maximum number of connections " diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -12,12 +12,11 @@ extern ngx_event_module_t ngx_select_module_ctx; #if (HAVE_KQUEUE) -extern ngx_event_module_t ngx_kqueue_module_ctx; #include #endif #if (HAVE_DEVPOLL) -extern ngx_event_module_t ngx_devpoll_module_ctx; +extern ngx_module_t ngx_devpoll_module; #endif #if (HAVE_AIO) @@ -30,8 +29,8 @@ extern ngx_event_module_t ngx_devpoll_mo #endif -static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); -static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); +static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void *ngx_event_create_conf(ngx_pool_t *pool); static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf); @@ -61,15 +60,15 @@ static ngx_command_t ngx_events_command 0, NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_module_t ngx_events_module = { + NGX_MODULE, &events_name, /* module context */ - 0, /* module index */ ngx_events_commands, /* module directives */ - NGX_CORE_MODULE_TYPE, /* module type */ + NGX_CORE_MODULE, /* module type */ NULL /* init module */ }; @@ -98,12 +97,11 @@ static ngx_command_t ngx_event_commands offsetof(ngx_event_conf_t, timer_queues), NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; 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 */ @@ -113,10 +111,10 @@ ngx_event_module_t ngx_event_module_ctx ngx_module_t ngx_event_module = { + NGX_MODULE, &ngx_event_module_ctx, /* module context */ - 0, /* module index */ ngx_event_commands, /* module directives */ - NGX_EVENT_MODULE_TYPE, /* module type */ + NGX_EVENT_MODULE, /* module type */ NULL /* init module */ }; @@ -132,18 +130,18 @@ int ngx_pre_thread(ngx_array_t *ls, ngx_ ngx_event_conf_t *ecf; ngx_event_module_t *module; - ecf = ngx_event_get_conf(ngx_event_module_ctx); + ecf = ngx_event_get_conf(ngx_event_module); ngx_log_debug(log, "CONN: %d" _ ecf->connections); ngx_log_debug(log, "TYPE: %d" _ ecf->use); for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } - module = ngx_modules[m]->ctx; - if (module->index == ecf->use) { + if (ngx_modules[m]->ctx_index == ecf->use) { + module = ngx_modules[m]->ctx; if (module->actions.init(log) == NGX_ERROR) { return NGX_ERROR; } @@ -247,7 +245,7 @@ void ngx_worker(ngx_log_t *log) } -static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int m; char *rv; @@ -259,12 +257,11 @@ static char *ngx_events_block(ngx_conf_t ngx_event_max_module = 0; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } - module = ngx_modules[m]->ctx; - module->index = ngx_event_max_module++; + ngx_modules[m]->ctx_index = ngx_event_max_module++; } ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(void *)), NGX_CONF_ERROR); @@ -276,21 +273,22 @@ static char *ngx_events_block(ngx_conf_t *(void **) conf = ctx; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } module = ngx_modules[m]->ctx; if (module->create_conf) { - ngx_test_null((*ctx)[module->index], module->create_conf(cf->pool), + ngx_test_null((*ctx)[ngx_modules[m]->ctx_index], + module->create_conf(cf->pool), NGX_CONF_ERROR); } } pcf = *cf; cf->ctx = ctx; - cf->module_type = NGX_EVENT_MODULE_TYPE; + cf->module_type = NGX_EVENT_MODULE; cf->cmd_type = NGX_EVENT_CONF; rv = ngx_conf_parse(cf, NULL); *cf = pcf; @@ -299,14 +297,14 @@ static char *ngx_events_block(ngx_conf_t return rv; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } module = ngx_modules[m]->ctx; if (module->init_conf) { - rv = module->init_conf(cf->pool, (*ctx)[module->index]); + rv = module->init_conf(cf->pool, (*ctx)[ngx_modules[m]->ctx_index]); if (rv != NGX_CONF_OK) { return rv; } @@ -317,9 +315,9 @@ static char *ngx_events_block(ngx_conf_t } -static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_event_conf_t *ecf = (ngx_event_conf_t *) conf; + ngx_event_conf_t *ecf = conf; int m; ngx_str_t *args; @@ -332,14 +330,14 @@ static char *ngx_event_use(ngx_conf_t *c args = cf->args->elts; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } module = ngx_modules[m]->ctx; if (module->name->len == args[1].len) { if (ngx_strcmp(module->name->data, args[1].data) == 0) { - ecf->use = module->index; + ecf->use = ngx_modules[m]->ctx_index; return NGX_CONF_OK; } } @@ -380,19 +378,19 @@ static char *ngx_event_init_conf(ngx_poo #endif ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS); - ngx_conf_init_value(ecf->use, ngx_kqueue_module_ctx.index); + ngx_conf_init_value(ecf->use, ngx_kqueue_module.ctx_index); #elif (HAVE_DEVPOLL) ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS); - ngx_conf_init_value(ecf->use, ngx_devpoll_module_ctx.index); + ngx_conf_init_value(ecf->use, ngx_devpoll_module.ctx_index); #else /* HAVE_SELECT */ ngx_conf_init_value(ecf->connections, FD_SETSIZE < DEF_CONNECTIONS ? FD_SETSIZE : DEF_CONNECTIONS); - ngx_conf_init_value(ecf->use, ngx_select_module_ctx.index); + ngx_conf_init_value(ecf->use, ngx_select_module.ctx_index); #endif diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -17,9 +17,6 @@ -/* STUB */ -#define NGX_LOWAT 10000 - #define NGX_INVALID_INDEX 0x80000000 @@ -319,10 +316,9 @@ extern int ngx_event_f #endif -#define NGX_EVENT_MODULE_TYPE 0x544E5645 /* "EVNT" */ +#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ #define NGX_EVENT_CONF 0x00200000 -#define NGX_EVENT_MODULE 0 typedef struct { @@ -333,7 +329,6 @@ typedef struct { typedef struct { - int index; ngx_str_t *name; void *(*create_conf)(ngx_pool_t *p); @@ -344,11 +339,11 @@ typedef struct { extern ngx_module_t ngx_events_module; -extern ngx_event_module_t ngx_event_module_ctx; +extern ngx_module_t ngx_event_module; #define ngx_event_get_conf(module) \ - (*(ngx_get_conf(ngx_events_module))) [module.index]; + (*(ngx_get_conf(ngx_events_module))) [module.ctx_index]; diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -162,6 +162,6 @@ void ngx_event_accept(ngx_event_t *ev) } } while (ev->available); - + return; } diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -20,7 +20,7 @@ int ngx_event_timer_init(ngx_log_t *log) int i; ngx_event_conf_t *ecf; - ecf = ngx_event_get_conf(ngx_event_module_ctx); + ecf = ngx_event_get_conf(ngx_event_module); ngx_timer_queue_num = ecf->timer_queues; ngx_timer_cur_queue = 0; diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -1,25 +1,14 @@ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include #include static int ngx_http_index_test_dir(ngx_http_request_t *r); static int ngx_http_index_init(ngx_pool_t *pool); static void *ngx_http_index_create_conf(ngx_pool_t *pool); -static char *ngx_http_index_merge_conf(ngx_pool_t *p, - void *parent, void *child); +static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, + void *child); static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, - char *conf); + void *conf); static ngx_command_t ngx_http_index_commands[] = { @@ -31,13 +20,11 @@ static ngx_command_t ngx_http_index_comm 0, NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_http_module_t ngx_http_index_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -50,10 +37,10 @@ ngx_http_module_t ngx_http_index_module ngx_module_t ngx_http_index_module = { + NGX_MODULE, &ngx_http_index_module_ctx, /* module context */ - 0, /* module index */ ngx_http_index_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_index_init /* init module */ }; @@ -63,42 +50,39 @@ ngx_module_t ngx_http_index_module = { because the valid requests should be many more then invalid ones. If open() failed then stat() should be more quickly because some data is already cached in the kernel. - Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) and - Unix has ENOTDIR error (although it less helpfull). + Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR). + Unix has ENOTDIR error, although it less helpfull - it shows only + that path contains the usual file in place of the directory. */ int ngx_http_index_handler(ngx_http_request_t *r) { - int i, rc, test_dir; - char *name, *file; - ngx_str_t loc, *index; - ngx_err_t err; - ngx_fd_t fd; + int i, rc, test_dir; + char *name, *file; + ngx_str_t loc, *index; + ngx_err_t err; + ngx_fd_t fd; + ngx_http_index_conf_t *icf; + ngx_http_core_loc_conf_t *clcf; - ngx_http_index_conf_t *cf; - ngx_http_core_loc_conf_t *core_cf; - - cf = (ngx_http_index_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx); - - core_cf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_test_null(r->path.data, ngx_palloc(r->pool, - core_cf->doc_root.len + r->uri.len - + cf->max_index_len), + clcf->doc_root.len + r->uri.len + + icf->max_index_len), NGX_HTTP_INTERNAL_SERVER_ERROR); - loc.data = ngx_cpystrn(r->path.data, core_cf->doc_root.data, - core_cf->doc_root.len + 1); + loc.data = ngx_cpystrn(r->path.data, clcf->doc_root.data, + clcf->doc_root.len + 1); file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); r->path.len = file - r->path.data; test_dir = 1; - index = (ngx_str_t *) cf->indices->elts; - for (i = 0; i < cf->indices->nelts; i++) { + index = (ngx_str_t *) icf->indices.elts; + for (i = 0; i < icf->indices.nelts; i++) { if (index[i].data[0] != '/') { ngx_memcpy(file, index[i].data, index[i].len + 1); @@ -147,8 +131,8 @@ ngx_log_error(NGX_LOG_DEBUG, r->connecti return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->file.name.data = name; - r->file.fd = fd; + r->file.name.data = name; + r->file.fd = fd; if (index[i].data[0] == '/') { r->file.name.len = index[i].len; @@ -157,7 +141,7 @@ ngx_log_error(NGX_LOG_DEBUG, r->connecti } else { loc.len = r->uri.len + index[i].len; - r->file.name.len = core_cf->doc_root.len + r->uri.len + r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len; } @@ -178,9 +162,9 @@ static int ngx_http_index_test_dir(ngx_h ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); #if 0 - if (r->path_err == NGX_EACCES) { - return NGX_HTTP_FORBIDDEN; - } + if (r->path_err == NGX_EACCES) { + return NGX_HTTP_FORBIDDEN; + } #endif if (ngx_file_type(r->path.data, &r->file.info) == -1) { @@ -226,76 +210,88 @@ static void *ngx_http_index_create_conf( { ngx_http_index_conf_t *conf; - ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), + ngx_test_null(conf, ngx_palloc(pool, sizeof(ngx_http_index_conf_t)), NGX_CONF_ERROR); - ngx_test_null(conf->indices, - ngx_create_array(pool, 3, sizeof(ngx_str_t)), - NGX_CONF_ERROR); + ngx_init_array(conf->indices, pool, 3, sizeof(ngx_str_t), NGX_CONF_ERROR); + conf->max_index_len = 0; return conf; } -/* STUB */ +/* TODO: remove duplicate indices */ + static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) { -#if 0 - ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; -#endif - ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; - ngx_str_t *index; + ngx_http_index_conf_t *prev = parent; + ngx_http_index_conf_t *conf = child; + + int i; + ngx_str_t *index, *prev_index; if (conf->max_index_len == 0) { - ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR); - index->len = sizeof(NGX_HTTP_INDEX) - 1; - index->data = NGX_HTTP_INDEX; - conf->max_index_len = sizeof(NGX_HTTP_INDEX); + if (prev->max_index_len != 0) { + ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t)); + return NGX_CONF_OK; + } + + ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR); + index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1; + index->data = NGX_HTTP_DEFAULT_INDEX; + conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX); + + return NGX_CONF_OK; } - /* FAIL: if first index is started with '/' */ + if (prev->max_index_len != 0) { - return NULL; + prev_index = prev->indices.elts; + for (i = 0; i < prev->indices.nelts; i++) { + ngx_test_null(index, ngx_push_array(&conf->indices), + NGX_CONF_ERROR); + index->len = prev_index[i].len; + index->data = prev_index[i].data; + } + } + + if (conf->max_index_len < prev->max_index_len) { + conf->max_index_len = prev->max_index_len; + } + + return NGX_CONF_OK; } -#if 0 -static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) +/* TODO: check duplicate indices */ + +static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) { - ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; - ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; - ngx_str_t *index; + ngx_http_index_conf_t *icf = conf; + + int i; + ngx_str_t *index, *value; + + value = cf->args->elts; - if (conf->max_index_len == 0) { - if (prev->max_index_len != 0) { - return prev; + if (value[1].data[0] == '/' && icf->indices.nelts == 0) { + ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, + "first index \"%s\" must not be absolute", value[1].data); + return ngx_conf_errstr; + } + + for (i = 1; i < cf->args->nelts; i++) { + if (value[i].len == 0) { + return "is invalid"; } - ngx_test_null(index, ngx_push_array(conf->indices), NULL); - index->len = sizeof(NGX_HTTP_INDEX) - 1; - index->data = NGX_HTTP_INDEX; - conf->max_index_len = sizeof(NGX_HTTP_INDEX); - } - - return conf; -} -#endif - -static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, - char *conf) -{ - ngx_http_index_conf_t *lcf = (ngx_http_index_conf_t *) conf; - int i; - ngx_str_t *index, *value; - - value = (ngx_str_t *) cf->args->elts; - for (i = 1; i < cf->args->nelts; i++) { - ngx_test_null(index, ngx_push_array(lcf->indices), NGX_CONF_ERROR); + ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); index->len = value[i].len; index->data = value[i].data; - if (lcf->max_index_len < index->len) { - lcf->max_index_len = index->len; + if (icf->max_index_len < index->len + 1) { + icf->max_index_len = index->len + 1; } } diff --git a/src/http/modules/ngx_http_index_handler.h b/src/http/modules/ngx_http_index_handler.h --- a/src/http/modules/ngx_http_index_handler.h +++ b/src/http/modules/ngx_http_index_handler.h @@ -3,16 +3,16 @@ #include -#include +#include #include -#define NGX_HTTP_INDEX "index.html" +#define NGX_HTTP_DEFAULT_INDEX "index.html" typedef struct { - ngx_array_t *indices; - size_t max_index_len; + ngx_array_t indices; + size_t max_index_len; } ngx_http_index_conf_t; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -1,38 +1,22 @@ #include #include -#include -#include -#include #include #include #include #include -ngx_http_module_t ngx_http_static_module; - int ngx_http_static_handler(ngx_http_request_t *r) { - int rc, key, i; - ngx_log_e level; - ngx_err_t err; - ngx_hunk_t *h; - ngx_http_type_t *type; - ngx_http_log_ctx_t *ctx; - ngx_http_core_loc_conf_t *core_lcf; - - core_lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); - -#if 0 - ngx_http_event_static_handler_loc_conf_t *lcf; - - lcf = (ngx_http_event_static_handler_loc_conf_t *) - ngx_get_module_loc_conf(r, &ngx_http_event_static_handler_module_ctx); - -#endif + int rc, key, i; + ngx_log_e level; + ngx_err_t err; + ngx_hunk_t *h; + ngx_http_type_t *type; + ngx_http_log_ctx_t *ctx; + ngx_http_core_loc_conf_t *clcf; rc = ngx_http_discard_body(r); @@ -40,6 +24,10 @@ int ngx_http_static_handler(ngx_http_req return rc; } + if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { + return NGX_HTTP_NOT_ALLOWED; + } + ctx = r->connection->log->data; ctx->action = "sending response"; @@ -102,14 +90,18 @@ int ngx_http_static_handler(ngx_http_req ngx_push_table(r->headers_out.headers), NGX_HTTP_INTERNAL_SERVER_ERROR); - r->headers_out.content_type->key.len = 12; - r->headers_out.content_type->key.data = "Content-Type"; + r->headers_out.content_type->key.len = 0; + r->headers_out.content_type->key.data = NULL; + r->headers_out.content_type->value.len = 0; + r->headers_out.content_type->value.data = NULL; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->exten.len) { ngx_http_types_hash_key(key, r->exten); - type = (ngx_http_type_t *) core_lcf->types[key].elts; - for (i = 0; i < core_lcf->types[key].nelts; i++) { + type = (ngx_http_type_t *) clcf->types[key].elts; + for (i = 0; i < clcf->types[key].nelts; i++) { if (r->exten.len != type[i].exten.len) { continue; } @@ -117,14 +109,15 @@ int ngx_http_static_handler(ngx_http_req if (ngx_strcasecmp(r->exten.data, type[i].exten.data) == 0) { r->headers_out.content_type->value.len = type[i].type.len; r->headers_out.content_type->value.data = type[i].type.data; + + break; } } } if (r->headers_out.content_type->value.len == 0) { - /* STUB: default type */ - r->headers_out.content_type->value.len = 25; - r->headers_out.content_type->value.data = "text/html; charset=koi8-r"; + r->headers_out.content_type->value.len = clcf->default_type.len; + r->headers_out.content_type->value.data = clcf->default_type.data; } /* we need to allocate all before the header would be sent */ @@ -134,9 +127,19 @@ int ngx_http_static_handler(ngx_http_req ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)), NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_http_send_header(r); - if (r->header_only) + + rc = ngx_http_send_header(r); + + if (r->header_only) { + if (rc == NGX_AGAIN) { + ngx_http_set_write_handler(r); + + } else { + ngx_http_finalize_request(r, 0); + } + return NGX_OK; + } h->type = NGX_HUNK_FILE|NGX_HUNK_LAST; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -11,7 +11,7 @@ static void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules); -static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); int ngx_http_max_module; @@ -37,20 +37,20 @@ static ngx_command_t ngx_http_commands[ 0, NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_module_t ngx_http_module = { + NGX_MODULE, &http_name, /* module context */ - 0, /* module index */ ngx_http_commands, /* module directives */ - NGX_CORE_MODULE_TYPE, /* module type */ + NGX_CORE_MODULE, /* module type */ NULL /* init module */ }; -static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int mi, m, s, l, p, a, n; int port_found, addr_found, virtual_names; @@ -81,12 +81,11 @@ static char *ngx_http_block(ngx_conf_t * ngx_http_max_module = 0; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[m]->ctx; - module->index = ngx_http_max_module++; + ngx_modules[m]->ctx_index = ngx_http_max_module++; } /* the main http main_conf, it's the same in the all http contexts */ @@ -108,26 +107,27 @@ static char *ngx_http_block(ngx_conf_t * /* 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) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[m]->ctx; + module = ngx_modules[m]->ctx; + mi = ngx_modules[m]->ctx_index; if (module->create_main_conf) { - ngx_test_null(ctx->main_conf[module->index], + ngx_test_null(ctx->main_conf[mi], module->create_main_conf(cf->pool), NGX_CONF_ERROR); } if (module->create_srv_conf) { - ngx_test_null(ctx->srv_conf[module->index], + ngx_test_null(ctx->srv_conf[mi], module->create_srv_conf(cf->pool), NGX_CONF_ERROR); } if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], + ngx_test_null(ctx->loc_conf[mi], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); } @@ -138,7 +138,7 @@ static char *ngx_http_block(ngx_conf_t * pcf = *cf; cf->ctx = ctx; - cf->module_type = NGX_HTTP_MODULE_TYPE; + cf->module_type = NGX_HTTP_MODULE; cf->cmd_type = NGX_HTTP_MAIN_CONF; rv = ngx_conf_parse(cf, NULL); *cf = pcf; @@ -150,16 +150,16 @@ static char *ngx_http_block(ngx_conf_t * /* 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]; + 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) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } module = (ngx_http_module_t *) ngx_modules[m]->ctx; - mi = module->index; + mi = ngx_modules[m]->ctx_index; /* init http{} main_conf's */ @@ -310,7 +310,7 @@ static char *ngx_http_block(ngx_conf_t * sizeof(ngx_http_in_addr_t)); in_addr[a].addr = lscf[l].addr; - in_addr[a].flags = lscf[l].flags; + in_addr[a].flags = lscf[l].flags; in_addr[a].core_srv_conf = cscfp[s]; /* create the empty list of the server names that @@ -336,7 +336,7 @@ static char *ngx_http_block(ngx_conf_t * NGX_CONF_ERROR); inaddr->addr = lscf[l].addr; - inaddr->flags = lscf[l].flags; + inaddr->flags = lscf[l].flags; inaddr->core_srv_conf = cscfp[s]; /* create the empty list of the server names that @@ -359,6 +359,12 @@ static char *ngx_http_block(ngx_conf_t * in_port->port = lscf[l].port; + ngx_test_null(in_port->port_name.data, ngx_palloc(cf->pool, 7), + NGX_CONF_ERROR); + in_port->port_name.len = ngx_snprintf(in_port->port_name.data, + 7, ":%d", + in_port->port); + /* create list of the addresses that bound to this port ... */ ngx_init_array(in_port->addrs, cf->pool, 10, @@ -371,7 +377,7 @@ static char *ngx_http_block(ngx_conf_t * /* ... and add the address to this list */ inaddr->addr = lscf[l].addr; - inaddr->flags = lscf[l].flags; + inaddr->flags = lscf[l].flags; inaddr->core_srv_conf = cscfp[s]; /* create the empty list of the server names that @@ -484,6 +490,7 @@ static char *ngx_http_block(ngx_conf_t * NGX_CONF_ERROR); inport->port = in_port[p].port; + inport->port_name = in_port[p].port_name; /* init list of the addresses ... */ diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -13,6 +13,8 @@ #include #include +#include +#include typedef struct { @@ -30,12 +32,12 @@ typedef int (*ngx_http_output_body_filte (ngx_http_request_t *r, ngx_chain_t *chain); -#define ngx_http_get_module_ctx(r, module) r->ctx[module.index] +#define ngx_http_get_module_ctx(r, module) r->ctx[module.ctx_index] #define ngx_http_create_ctx(r, cx, module, size, error) \ do { \ ngx_test_null(cx, ngx_pcalloc(r->pool, size), error); \ - r->ctx[module.index] = cx; \ + r->ctx[module.ctx_index] = cx; \ } while (0) diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -20,8 +20,6 @@ typedef struct { typedef struct { - int index; - void *(*create_main_conf)(ngx_pool_t *p); char *(*init_main_conf)(ngx_pool_t *p, void *conf); @@ -33,9 +31,7 @@ typedef struct { } ngx_http_module_t; -#define NGX_HTTP_MODULE_TYPE 0x50545448 /* "HTTP" */ - -#define NGX_HTTP_MODULE 0 +#define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */ #define NGX_HTTP_MAIN_CONF 0x2000000 #define NGX_HTTP_SRV_CONF 0x4000000 @@ -47,13 +43,11 @@ typedef struct { #define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf) -#define ngx_http_get_module_main_conf(r, ctx) r->main_conf[ctx.index] -#define ngx_http_get_module_srv_conf(r, ctx) r->srv_conf[ctx.index] -#define ngx_http_get_module_loc_conf(r, ctx) r->loc_conf[ctx.index] +#define ngx_http_get_module_main_conf(r, module) r->main_conf[module.ctx_index] +#define ngx_http_get_module_srv_conf(r, module) r->srv_conf[module.ctx_index] +#define ngx_http_get_module_loc_conf(r, module) r->loc_conf[module.ctx_index] -int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules); - extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1,29 +1,22 @@ #include +#include +/* ???? */ #include -#include -#include -#include + +#include +#include #include -#include -#include -#include + +/* STUB */ +int ngx_http_static_handler(ngx_http_request_t *r); -/* STUB for r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; */ -#include - -int ngx_http_static_handler(ngx_http_request_t *r); -int ngx_http_proxy_handler(ngx_http_request_t *r); -/**/ - 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); @@ -33,11 +26,12 @@ static void *ngx_http_core_create_loc_co static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, void *parent, void *child); -static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static int ngx_http_core_init(ngx_pool_t *pool); +static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, - char *dummy); -static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); -static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); + void *dummy); +static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_command_t ngx_http_core_commands[] = { @@ -113,6 +107,13 @@ static ngx_command_t ngx_http_core_comm 0, NULL}, + {ngx_string("default_type"), + 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, default_type), + NULL}, + {ngx_string("root"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -155,13 +156,11 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_loc_conf_t, lingering_timeout), NULL}, - {ngx_null_string, 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_http_module_t ngx_http_core_module_ctx = { - NGX_HTTP_MODULE, - ngx_http_core_create_main_conf, /* create main configuration */ ngx_http_core_init_main_conf, /* init main configuration */ @@ -174,108 +173,20 @@ ngx_http_module_t ngx_http_core_module_ ngx_module_t ngx_http_core_module = { + NGX_MODULE, &ngx_http_core_module_ctx, /* module context */ - 0, /* module index */ ngx_http_core_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_core_init /* init module */ }; -int ngx_http_find_server_conf(ngx_http_request_t *r) -{ - int a, n; - socklen_t len; - struct sockaddr_in addr_in; - ngx_http_in_port_t *in_port; - ngx_http_in_addr_t *in_addr; - ngx_http_conf_ctx_t *ctx; - ngx_http_server_name_t *name; - - /* AF_INET only */ - - in_port = (ngx_http_in_port_t *) r->connection->servers; - in_addr = (ngx_http_in_addr_t *) in_port->addrs.elts; - - r->port = in_port->port; - - a = 0; - - if (in_port->addrs.nelts > 1) { - - /* there're the several addresses on this port and one of them - is "*:port" so getsockname() is needed to determine - the server address */ - - len = sizeof(struct sockaddr_in); - if (getsockname(r->connection->fd, (struct sockaddr *) &addr_in, &len) - == -1) { - ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_socket_errno, - "getsockname() failed"); - return NGX_ERROR; - } - - r->in_addr = addr_in.sin_addr.s_addr; - - for ( /* void */ ; a < in_port->addrs.nelts; a++) { - if (in_addr[a].addr == r->in_addr) { -ngx_log_debug(r->connection->log, "FOUND"); - break; - } - } - -/* DEBUG */ -if (a == in_port->addrs.nelts) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "addr not found"); - exit(1); -} - - } else { - r->in_addr = in_addr[0].addr; - } - - /* the default server configuration for this address:port */ - ctx = in_addr[a].core_srv_conf->ctx; - - if (r->headers_in.host_name_len > 0) { - - /* find the name based server configuration */ - - name = (ngx_http_server_name_t *) in_addr[a].names.elts; - for (n = 0; n < in_addr[a].names.nelts; n++) { - if (r->headers_in.host_name_len != name[n].name.len) { - continue; - } - - if (ngx_strncasecmp(r->headers_in.host->value.data, - name[n].name.data, - r->headers_in.host_name_len) == 0) { - ctx = name->core_srv_conf->ctx; - break; - } - } - } - - r->srv_conf = ctx->srv_conf; - r->loc_conf = ctx->loc_conf; - -#if 0 -ngx_log_debug(r->connection->log, "cxt: %08x" _ ctx); -ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf); -ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf); -#endif - - return NGX_OK; -} - - void ngx_http_handler(ngx_http_request_t *r) { int rc, i; ngx_http_handler_pt *h; - ngx_http_core_loc_conf_t *lcf, **lcfp; - ngx_http_core_srv_conf_t *scf; + ngx_http_core_loc_conf_t *clcf, **clcfp; + ngx_http_core_srv_conf_t *cscf; r->connection->unexpected_eof = 0; @@ -293,33 +204,32 @@ void ngx_http_handler(ngx_http_request_t /* find location config */ - scf = (ngx_http_core_srv_conf_t *) - ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - lcfp = (ngx_http_core_loc_conf_t **) scf->locations.elts; - for (i = 0; i < scf->locations.nelts; i++) { + clcfp = cscf->locations.elts; + for (i = 0; i < cscf->locations.nelts; i++) { #if 0 -ngx_log_debug(r->connection->log, "trans: %s" _ lcfp[i]->name.data); +ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); #endif - if (r->uri.len < lcfp[i]->name.len) { + if (r->uri.len < clcfp[i]->name.len) { continue; } - rc = ngx_rstrncmp(r->uri.data, lcfp[i]->name.data, lcfp[i]->name.len); + rc = ngx_rstrncmp(r->uri.data, clcfp[i]->name.data, + clcfp[i]->name.len); if (rc < 0) { break; } if (rc == 0) { - r->loc_conf = lcfp[i]->loc_conf; + r->loc_conf = clcfp[i]->loc_conf; } } - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if ((ngx_io.flags & NGX_IO_SENDFILE) == 0 || lcf->sendfile == 0) { + if ((ngx_io.flags & NGX_IO_SENDFILE) == 0 || clcf->sendfile == 0) { r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; } @@ -355,80 +265,37 @@ ngx_log_debug(r->connection->log, "trans int ngx_http_core_translate_handler(ngx_http_request_t *r) { - int len, port_len, f_offset, l_offset; - char *buf, *location, *last; + char *location, *last; ngx_err_t err; ngx_table_elt_t *h; + ngx_http_in_port_t *in_port; ngx_http_server_name_t *s_name; - ngx_http_core_srv_conf_t *scf; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_srv_conf_t *cscf; + ngx_http_core_loc_conf_t *clcf; - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (lcf->handler) { - r->handler = lcf->handler; + if (clcf->handler) { + r->handler = clcf->handler; return NGX_OK; } - scf = (ngx_http_core_srv_conf_t *) - ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (r->uri.data[r->uri.len - 1] == '/') { r->handler = ngx_http_core_index_handler; return NGX_OK; } -ngx_log_debug(r->connection->log, "doc_root: %08x" _ &lcf->doc_root); - - s_name = (ngx_http_server_name_t *) scf->server_names.elts; - - if (r->port == 0) { -#if 0 - struct sockaddr_in *addr_in; - addr_in = (struct sockaddr_in *) r->connection->sockaddr; - r->port = ntohs(addr_in->sin_port); -#else - ngx_http_in_port_t *in_port; - in_port = (ngx_http_in_port_t *) r->connection->servers; - r->port = in_port->port; -#endif - if (r->port != 80) { - ngx_test_null(r->port_name.data, ngx_palloc(r->pool, 7), - NGX_HTTP_INTERNAL_SERVER_ERROR); - r->port_name.len = ngx_snprintf(r->port_name.data, 7, ":%d", - r->port); - } - } - - port_len = (r->port != 80) ? r->port_name.len : 0; - - /* "+ 7" is "http://" */ - if (lcf->doc_root.len > 7 + s_name[0].name.len + port_len) { - len = lcf->doc_root.len; - f_offset = 0; - l_offset = len - (7 + s_name[0].name.len + port_len); - - } else { - len = 7 + s_name[0].name.len + port_len; - f_offset = len - lcf->doc_root.len; - l_offset = 0; - } - /* "+ 2" is for trailing '/' in redirect and '\0' */ - len += r->uri.len + 2; - - ngx_test_null(buf, ngx_palloc(r->pool, len), + ngx_test_null(r->file.name.data, + ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2), NGX_HTTP_INTERNAL_SERVER_ERROR); - r->file.name.data = buf + f_offset; - location = buf + l_offset; + location = ngx_cpymem(r->file.name.data, clcf->doc_root.data, + clcf->doc_root.len), - last = ngx_cpystrn(ngx_cpystrn(r->file.name.data, lcf->doc_root.data, - lcf->doc_root.len + 1), - r->uri.data, r->uri.len + 1); - - r->file.name.len = last - r->file.name.data; + last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1); ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data); @@ -510,13 +377,6 @@ ngx_log_debug(r->connection->log, "HTTP ngx_test_null(h, ngx_push_table(r->headers_out.headers), NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_memcpy(location, "http://", 7); - ngx_memcpy(location + 7, s_name[0].name.data, s_name[0].name.len); - if (port_len) { - ngx_memcpy(location + 7 + s_name[0].name.len, r->port_name.data, - port_len); - } - *last++ = '/'; *last = '\0'; h->key.len = 8; @@ -584,7 +444,7 @@ int ngx_http_redirect(ngx_http_request_t } -int ngx_http_error(ngx_http_request_t *r, int error) +int ngx_http_error(ngx_http_request_t *r, int error) { /* STUB */ ngx_log_debug(r->connection->log, "http error: %d" _ error); @@ -627,7 +487,7 @@ static int ngx_http_core_init(ngx_pool_t } -static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) +static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { int m; char *rv; @@ -657,20 +517,20 @@ static char *ngx_server_block(ngx_conf_t NGX_CONF_ERROR); for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[m]->ctx; + module = ngx_modules[m]->ctx; if (module->create_srv_conf) { - ngx_test_null(ctx->srv_conf[module->index], + ngx_test_null(ctx->srv_conf[ngx_modules[m]->ctx_index], module->create_srv_conf(cf->pool), NGX_CONF_ERROR); } if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], + ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); } @@ -678,10 +538,10 @@ static char *ngx_server_block(ngx_conf_t /* create links of the srv_conf's */ - cscf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; cscf->ctx = ctx; - cmcf = ctx->main_conf[ngx_http_core_module_ctx.index]; + cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; ngx_test_null(cscfp, ngx_push_array(&cmcf->servers), NGX_CONF_ERROR); *cscfp = cscf; @@ -698,9 +558,9 @@ static char *ngx_server_block(ngx_conf_t } -static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) +static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { - int i; + int m; char *rv; ngx_str_t *location; ngx_http_module_t *module; @@ -721,27 +581,27 @@ static char *ngx_location_block(ngx_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) { + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[i]->ctx; + module = ngx_modules[m]->ctx; if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], + ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); } } - clcf = 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; clcf->name.len = location[1].len; clcf->name.data = location[1].data; clcf->loc_conf = ctx->loc_conf; - cscf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR); *clcfp = clcf; @@ -791,7 +651,7 @@ static char *ngx_set_type(ngx_conf_t *cf } -static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_conf_t pcf; @@ -811,7 +671,7 @@ static void *ngx_http_core_create_main_c ngx_http_core_main_conf_t *cmcf; ngx_test_null(cmcf, - ngx_palloc(pool, sizeof(ngx_http_core_main_conf_t)), + ngx_palloc(pool, sizeof(ngx_http_core_main_conf_t)), NGX_CONF_ERROR); cmcf->connection_pool_size = NGX_CONF_UNSET; @@ -826,7 +686,7 @@ static void *ngx_http_core_create_main_c 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_http_core_main_conf_t *cmcf = conf; ngx_conf_init_size_value(cmcf->connection_pool_size, 16384); ngx_conf_init_msec_value(cmcf->post_accept_timeout, 30000); @@ -840,7 +700,7 @@ static void *ngx_http_core_create_srv_co ngx_http_core_srv_conf_t *cscf; ngx_test_null(cscf, - ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), + ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), NGX_CONF_ERROR); ngx_init_array(cscf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR); @@ -881,12 +741,8 @@ static char *ngx_http_core_merge_srv_con ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN), NGX_CONF_ERROR); if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) { -/* STUB: no log here */ -#if 0 - ngx_log_error(NGX_LOG_EMERG, scf->log, ngx_errno, - "gethostname() failed"); -#endif - return NGX_CONF_ERROR; + /* TODO: need ngx_errno here */ + return "gethostname() failed"; } n->name.len = ngx_strlen(n->name.data); n->core_srv_conf = conf; @@ -910,7 +766,7 @@ static void *ngx_http_core_create_loc_co ngx_http_core_loc_conf_t *lcf; ngx_test_null(lcf, - ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), + ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), NGX_CONF_ERROR); /* set by ngx_pcalloc(): @@ -918,6 +774,8 @@ static void *ngx_http_core_create_loc_co lcf->doc_root.len = 0; lcf->doc_root.data = NULL; lcf->types = NULL; + lcf->default_type.len = 0; + lcf->default_type.data = NULL; */ @@ -950,16 +808,8 @@ static char *ngx_http_core_merge_loc_con int i, key; ngx_http_type_t *t; - if (conf->doc_root.len == 0) { - if (prev->doc_root.len) { - conf->doc_root.len = prev->doc_root.len; - conf->doc_root.data = prev->doc_root.data; - - } else { - conf->doc_root.len = 4; - conf->doc_root.data = "html"; - } - } + ngx_conf_merge_str_value(conf->doc_root, + prev->doc_root, "html"); if (conf->types == NULL) { if (prev->types) { @@ -989,6 +839,9 @@ static char *ngx_http_core_merge_loc_con } } + ngx_conf_merge_str_value(conf->default_type, + prev->default_type, "text/plain"); + ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000); ngx_conf_merge_size_value(conf->discarded_buffer_size, @@ -1004,16 +857,18 @@ static char *ngx_http_core_merge_loc_con } -static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; char *addr; u_int p; + struct hostent *h; ngx_str_t *args; ngx_http_listen_t *ls; - /* TODO: check duplicate 'listen' directives */ + /* TODO: check duplicate 'listen' directives, + add resolved name to server names */ ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR); @@ -1033,8 +888,13 @@ static char *ngx_set_listen(ngx_conf_t * ls->addr = inet_addr(addr); if (ls->addr == INADDR_NONE) { - /* TODO: gethostbyname() */ - return "can not resolve host name"; + h = gethostbyname(addr); + + if (h == NULL || h->h_addr_list[0] == NULL) { + return "can not resolve host name"; + } + + ls->addr = *(u_int32_t *)(h->h_addr_list[0]); } break; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -47,6 +47,7 @@ typedef struct { typedef struct { int port; + ngx_str_t port_name; ngx_array_t addrs; /* array of ngx_http_in_addr_t */ } ngx_http_in_port_t; @@ -56,7 +57,7 @@ typedef struct { ngx_array_t names; /* array of ngx_http_server_name_t */ ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf for this address:port */ - int flags; + int flags; } ngx_http_in_addr_t; /* ngx_http_in_addr_t's flags */ @@ -87,22 +88,23 @@ typedef struct { typedef struct { - ngx_str_t name; /* location name */ - void **loc_conf ; /* pointer to the modules' loc_conf */ + ngx_str_t name; /* location name */ + void **loc_conf ; /* pointer to the modules' loc_conf */ - int (*handler) (ngx_http_request_t *r); + int (*handler) (ngx_http_request_t *r); - ngx_str_t doc_root; /* root */ + ngx_str_t doc_root; /* root */ ngx_array_t *types; + ngx_str_t default_type; - int sendfile; /* sendfile */ - ngx_msec_t send_timeout; /* send_timeout */ - size_t send_lowat; /* send_lowa */ - size_t discarded_buffer_size; /* discarded_buffer_size */ - ngx_msec_t keepalive_timeout; /* keepalive_timeout */ - ngx_msec_t lingering_time; /* lingering_time */ - ngx_msec_t lingering_timeout; /* lingering_timeout */ + int sendfile; /* sendfile */ + ngx_msec_t send_timeout; /* send_timeout */ + size_t send_lowat; /* send_lowat */ + size_t discarded_buffer_size; /* discarded_buffer_size */ + ngx_msec_t keepalive_timeout; /* keepalive_timeout */ + ngx_msec_t lingering_time; /* lingering_time */ + ngx_msec_t lingering_timeout; /* lingering_timeout */ } ngx_http_core_loc_conf_t; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -75,10 +75,9 @@ static ngx_http_header_t headers_in[] = void ngx_http_init_connection(ngx_connection_t *c) { - int event; - ngx_event_t *rev; - ngx_http_log_ctx_t *lcx; - ngx_http_conf_ctx_t *ctx; + int event; + ngx_event_t *rev; + ngx_http_log_ctx_t *lcx; c->addr_text.data = ngx_palloc(c->pool, c->addr_text_max_len); if (c->addr_text.data == NULL) { @@ -139,16 +138,77 @@ void ngx_http_init_connection(ngx_connec static void ngx_http_init_request(ngx_event_t *rev) { + int i; + socklen_t len; + struct sockaddr_in addr_in; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_conf_ctx_t *ctx; + ngx_http_in_port_t *in_port; + ngx_http_in_addr_t *in_addr; + ngx_http_server_name_t *server_name; ngx_http_core_srv_conf_t *cscf; c = rev->data; - ctx = c->ctx; + + r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); + if (r == NULL) { + ngx_http_close_connection(c); + return; + } + + /* find the server configuration for the address:port */ + + /* AF_INET only */ + + in_port = c->servers; + in_addr = in_port->addrs.elts; + + r->port = in_port->port; + r->port_name = &in_port->port_name; + + i = 0; + + if (in_port->addrs.nelts > 1) { + + /* there're the several addresses on this port and one of them + is "*:port" so getsockname() is needed to determine + the server address */ + + /* TODO: AcceptEx() already gave this sockaddr_in */ - cscf = ngx_http_get_module_srv_conf(ctx, ngx_http_core_module_ctx); - cscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_core_module_ctx); + len = sizeof(struct sockaddr_in); + if (getsockname(c->fd, (struct sockaddr *) &addr_in, &len) == -1) { + ngx_log_error(NGX_LOG_CRIT, rev->log, ngx_socket_errno, + "getsockname() failed"); + ngx_http_close_connection(c); + return; + } + + r->in_addr = addr_in.sin_addr.s_addr; + + /* the last in_port->addrs address is "*" */ + + for ( /* void */ ; i < in_port->addrs.nelts - 1; i++) { + if (in_addr[i].addr == r->in_addr) { + break; + } + } + + } else { + r->in_addr = in_addr[0].addr; + } + + r->virtual_names = &in_addr[i].names; + + /* the default server configuration for the address:port */ + cscf = in_addr[i].core_srv_conf; + + r->main_conf = cscf->ctx->main_conf; + r->srv_conf = cscf->ctx->srv_conf; + r->loc_conf = cscf->ctx->loc_conf; + + server_name = cscf->server_names.elts; + r->server_name = &server_name->name; if (c->buffer == NULL) { c->buffer = ngx_create_temp_hunk(c->pool, @@ -160,12 +220,6 @@ static void ngx_http_init_request(ngx_ev } } - r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); - if (r == NULL) { - ngx_http_close_connection(c); - return; - } - r->pool = ngx_create_pool(cscf->request_pool_size, c->log); if (r->pool == NULL) { ngx_http_close_connection(c); @@ -186,10 +240,6 @@ static void ngx_http_init_request(ngx_ev return; } - r->main_conf = ctx->main_conf; - r->srv_conf = ctx->srv_conf; - r->loc_conf = ctx->loc_conf; - c->sent = 0; c->data = r; r->connection = c; @@ -239,7 +289,7 @@ static void ngx_http_process_request_lin /* the request line has been parsed successfully */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (r->http_version >= NGX_HTTP_VERSION_10 && cscf->large_client_header == 0 @@ -269,7 +319,7 @@ static void ngx_http_process_request_lin ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); -#if 1 /* needed to log url on errors in proxy only ? */ +#if 1 /* THINK: needed to log url on errors in proxy only ? */ /* copy unparsed URI */ @@ -353,12 +403,6 @@ static void ngx_http_process_request_lin #endif 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); - ngx_http_close_connection(c); - return; - } - rev->event_handler = ngx_http_block_read; ngx_http_handler(r); return; @@ -400,7 +444,7 @@ static void ngx_http_process_request_lin are enabled otherwise a request line had been already copied to the start of the r->header_in hunk in ngx_http_set_keepalive() */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (cscf->large_client_header) { offset = r->request_start - r->header_in->start; @@ -446,7 +490,7 @@ static void ngx_http_process_request_hea ngx_table_elt_t *h; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_log_ctx_t *ctx; + ngx_http_server_name_t *name; ngx_http_core_srv_conf_t *cscf; c = rev->data; @@ -460,6 +504,8 @@ static void ngx_http_process_request_hea return; } + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + rc = NGX_AGAIN; for ( ;; ) { @@ -490,8 +536,6 @@ static void ngx_http_process_request_hea /* if the large client headers are enabled then we need to copy the header name and value */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); - if (cscf->large_client_header) { h->key.data = ngx_palloc(r->pool, h->key.len + 1 + h->value.len + 1); @@ -532,6 +576,8 @@ static void ngx_http_process_request_hea r->header_in->pos = r->header_in->last = r->header_in->start; } + continue; + } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { /* a whole header has been parsed successfully */ @@ -546,6 +592,24 @@ static void ngx_http_process_request_hea } r->headers_in.host_name_len = len; + /* find the name based server configuration */ + + name = r->virtual_names->elts; + for (i = 0; i < r->virtual_names->nelts; i++) { + if (r->headers_in.host_name_len != name[i].name.len) { + continue; + } + + if (ngx_strncasecmp(r->headers_in.host->value.data, + name[i].name.data, + r->headers_in.host_name_len) == 0) + { + r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; + r->loc_conf = name[i].core_srv_conf->ctx->loc_conf; + break; + } + } + } else { if (r->http_version > NGX_HTTP_VERSION_10) { ngx_http_header_parse_error(r, @@ -568,12 +632,6 @@ static void ngx_http_process_request_hea } } - if (ngx_http_find_server_conf(r) == NGX_ERROR) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_http_close_connection(c); - return; - } - rev->event_handler = ngx_http_block_read; ngx_http_handler(r); return; @@ -595,8 +653,6 @@ static void ngx_http_process_request_hea /* if the large client headers are enabled then we need to compact r->header_in hunk */ - cscf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); - if (cscf->large_client_header) { offset = r->header_name_start - r->header_in->start; @@ -653,7 +709,7 @@ static ssize_t ngx_http_read_request_hea rev->timer_set = 1; } - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); ngx_add_timer(rev, cscf->client_header_timeout); r->header_timeout_set = 1; @@ -758,9 +814,8 @@ void ngx_http_set_write_handler(ngx_http return; } - clcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); ngx_add_timer(wev, clcf->send_timeout); wev->timer_set = 1; @@ -799,10 +854,10 @@ static void ngx_http_writer(ngx_event_t ngx_event_t *rev; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; - c = (ngx_connection_t *) wev->data; - r = (ngx_http_request_t *) c->data; + c = wev->data; + r = c->data; rc = ngx_http_output_filter(r, NULL); @@ -810,16 +865,15 @@ static void ngx_http_writer(ngx_event_t if (rc == NGX_AGAIN) { - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); if (wev->timer_set) { ngx_del_timer(wev); } else { wev->timer_set = 1; } - ngx_add_timer(wev, lcf->send_timeout); + ngx_add_timer(wev, clcf->send_timeout); return; } @@ -941,8 +995,8 @@ static void ngx_http_read_discarded_body ngx_connection_t *c; ngx_http_request_t *r; - c = (ngx_connection_t *) rev->data; - r = (ngx_http_request_t *) c->data; + c = rev->data; + r = c->data; rc = ngx_http_read_discarded_body(r); @@ -957,23 +1011,22 @@ static int ngx_http_read_discarded_body( { size_t size; ssize_t n; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; ngx_log_debug(r->connection->log, "http read discarded body"); - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->discarded_buffer == NULL) { - r->discarded_buffer = ngx_palloc(r->pool, lcf->discarded_buffer_size); + r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size); if (r->discarded_buffer == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } size = r->headers_in.content_length_n; - if (size > lcf->discarded_buffer_size) { - size = lcf->discarded_buffer_size; + if (size > clcf->discarded_buffer_size) { + size = clcf->discarded_buffer_size; } n = ngx_event_recv(r->connection, r->discarded_buffer, size); @@ -1001,7 +1054,7 @@ static void ngx_http_set_keepalive(ngx_h ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; - c = (ngx_connection_t *) r->connection; + c = r->connection; rev = c->read; ngx_log_debug(c->log, "set http keepalive handler"); @@ -1016,8 +1069,7 @@ static void ngx_http_set_keepalive(ngx_h rev->timer_set = 1; } - clcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_add_timer(rev, clcf->keepalive_timeout); @@ -1045,7 +1097,7 @@ static void ngx_http_set_keepalive(ngx_h This copy should be rare because clients that support pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (!cscf->large_client_header) { len = h->last - h->pos; @@ -1054,6 +1106,8 @@ static void ngx_http_set_keepalive(ngx_h h->last = h->start + len; } + ngx_log_debug(c->log, "pipelined request"); + c->pipeline = 1; ctx->action = "reading client pipelined request line"; ngx_http_init_request(rev); @@ -1140,15 +1194,14 @@ static void ngx_http_set_lingering_close { ngx_event_t *rev; ngx_connection_t *c; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; c = r->connection; rev = c->read; - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - r->lingering_time = ngx_time() + lcf->lingering_time / 1000; + r->lingering_time = ngx_time() + clcf->lingering_time / 1000; rev->event_handler = ngx_http_lingering_close_handler; if (rev->timer_set) { @@ -1157,7 +1210,7 @@ static void ngx_http_set_lingering_close rev->timer_set = 1; } - ngx_add_timer(rev, lcf->lingering_timeout); + ngx_add_timer(rev, clcf->lingering_timeout); if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { @@ -1201,10 +1254,10 @@ static void ngx_http_lingering_close_han ngx_msec_t timer; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; - c = (ngx_connection_t *) rev->data; - r = (ngx_http_request_t *) c->data; + c = rev->data; + r = c->data; ngx_log_debug(c->log, "http lingering close handler"); @@ -1221,8 +1274,7 @@ static void ngx_http_lingering_close_han return; } - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->discarded_buffer == NULL) { @@ -1231,12 +1283,12 @@ static void ngx_http_lingering_close_han instead of r->header_in->last */ if ((size_t)(r->header_in->end - r->header_in->last) - >= lcf->discarded_buffer_size) { + >= clcf->discarded_buffer_size) { r->discarded_buffer = r->header_in->last; } else { r->discarded_buffer = ngx_palloc(c->pool, - lcf->discarded_buffer_size); + clcf->discarded_buffer_size); if (r->discarded_buffer) { ngx_http_close_request(r, 0); ngx_http_close_connection(c); @@ -1246,7 +1298,7 @@ static void ngx_http_lingering_close_han } do { - n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size); + n = ngx_event_recv(c, r->discarded_buffer, clcf->discarded_buffer_size); ngx_log_debug(c->log, "lingering read: %d" _ n); @@ -1259,8 +1311,8 @@ static void ngx_http_lingering_close_han } while (rev->ready); timer *= 1000; - if (timer > lcf->lingering_timeout) { - timer = lcf->lingering_timeout; + if (timer > clcf->lingering_timeout) { + timer = clcf->lingering_timeout; } if (rev->timer_set) { @@ -1334,7 +1386,7 @@ void ngx_http_close_connection(ngx_conne c->write->timer_set = 0; } - if (1) { + if (ngx_del_conn) { ngx_del_conn(c); } else { diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -19,8 +19,6 @@ static int ngx_http_header_filter(ngx_ht static ngx_http_module_t ngx_http_header_filter_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -33,10 +31,10 @@ static ngx_http_module_t ngx_http_heade ngx_module_t ngx_http_header_filter_module = { + NGX_MODULE, &ngx_http_header_filter_module_ctx, /* module context */ - 0, /* module index */ NULL, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_header_filter_init /* init module */ }; @@ -47,30 +45,41 @@ static char server_string[] = "Server: " static ngx_str_t http_codes[] = { ngx_string("200 OK"), + ngx_null_string, /* "201 Created" */ + ngx_null_string, /* "202 Accepted" */ + ngx_null_string, /* "203 Non-Authoritative Information" */ + ngx_null_string, /* "204 No Content" */ + ngx_null_string, /* "205 Reset Content" */ + ngx_string("206 Partial Content"), + ngx_null_string, /* "207 Multi-Status" */ + +#if 0 + ngx_null_string, /* "300 Multiple Choices" */ +#endif ngx_string("301 Moved Permanently"), ngx_string("302 Moved Temporarily"), - ngx_null_string, /* 303 */ + ngx_null_string, /* "303 See Other" */ ngx_string("304 Not Modified"), ngx_string("400 Bad Request"), - ngx_null_string, /* 401 */ - ngx_null_string, /* 402 */ + ngx_string("401 Unauthorized"), + ngx_null_string, /* "402 Payment Required" */ ngx_string("403 Forbidden"), ngx_string("404 Not Found"), - ngx_null_string, /* 405 */ - ngx_null_string, /* 406 */ - ngx_null_string, /* 407 */ + ngx_string("405 Not Allowed"), + ngx_null_string, /* "406 Not Acceptable" */ + ngx_null_string, /* "407 Proxy Authentication Required" */ ngx_string("408 Request Time-out"), - ngx_null_string, /* 409 */ - ngx_null_string, /* 410 */ + ngx_null_string, /* "409 Conflict" */ + ngx_null_string, /* "410 Gone" */ ngx_string("411 Length Required"), - ngx_null_string, /* 412 */ + ngx_null_string, /* "412 Precondition Failed" */ ngx_string("413 Request Entity Too Large"), ngx_null_string, /* "414 Request-URI Too Large" but we never send it because we treat such requests as the HTTP/0.9 requests and send only the body without the header */ - ngx_null_string, /* 415 */ + ngx_null_string, /* "415 Unsupported Media Type" */ ngx_string("416 Requested Range Not Satisfiable"), ngx_string("500 Internal Server Error"), @@ -84,7 +93,7 @@ static ngx_str_t http_codes[] = { static int ngx_http_header_filter(ngx_http_request_t *r) { - int len, status, i; + int len, status, text, i; time_t ims; ngx_hunk_t *h; ngx_chain_t *ch; @@ -94,6 +103,10 @@ static int ngx_http_header_filter(ngx_ht return NGX_OK; } + if (r->method == NGX_HTTP_HEAD) { + r->header_only = 1; + } + /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n" and 2 is for end of header */ len = 9 + 2 + 2; @@ -132,17 +145,17 @@ static int ngx_http_header_filter(ngx_ht } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { /* 3XX */ - status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1; + status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 8; r->header_only = 1; } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { /* 4XX */ - status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 4; + status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 8 + 4; } else { /* 5XX */ status = r->headers_out.status - - NGX_HTTP_INTERNAL_SERVER_ERROR + 1 + 4 + 17; + - NGX_HTTP_INTERNAL_SERVER_ERROR + 8 + 4 + 17; } len += http_codes[status].len; @@ -159,31 +172,55 @@ static int ngx_http_header_filter(ngx_ht len += r->headers_out.date->key.len + r->headers_out.date->value.len + 2; } else { - /* "Date: ... \r\n"; */ + /* "Date: ... \r\n" */ len += 37; } - /* 2^64 is 20 characters */ if (r->headers_out.content_length >= 0) { + /* "Content-Length: ... \r\n", 2^64 is 20 characters */ len += 48; } -#if 0 - if (r->headers_out.content_type.len) - len += r->headers_out.content_type.len + 16; -#endif + text = 0; + if (r->headers_out.content_type && r->headers_out.content_type->value.len) { + r->headers_out.content_type->key.len = 0; + len += 16 + r->headers_out.content_type->value.len; + if (ngx_strncasecmp(r->headers_out.content_type->value.data, + "text/", 5) == 0) { + text = 1; + /* "; charset=koi8-r" */ + len += 16; + } + } + + if (r->headers_out.location + && r->headers_out.location->value.len + && r->headers_out.location->value.data[0] == '/') + { + r->headers_out.location->key.len = 0; + /* "Location: http:// ... \r\n" */ + len += 17 + r->server_name->len + + r->headers_out.location->value.len + 2; + + if (r->port != 80) { + len += r->port_name->len; + } + } if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { len += r->headers_out.last_modified->key.len + r->headers_out.last_modified->value.len + 2; + } else if (r->headers_out.last_modified_time != -1) { - /* "Last-Modified: ... \r\n"; */ + /* "Last-Modified: ... \r\n" */ len += 46; } if (r->keepalive == 0) { + /* "Connection: close\r\n" */ len += 19; } else { + /* "Connection: keep-alive\r\n" */ len += 24; } @@ -199,30 +236,25 @@ static int ngx_http_header_filter(ngx_ht ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); /* "HTTP/1.x " */ - ngx_memcpy(h->last, "HTTP/1.1 ", 9); - h->last += 9; + h->last = ngx_cpymem(h->last, "HTTP/1.1 ", 9); /* status line */ if (r->headers_out.status_line.len) { - ngx_memcpy(h->last, r->headers_out.status_line.data, - r->headers_out.status_line.len); - h->last += r->headers_out.status_line.len; + h->last = ngx_cpymem(h->last, r->headers_out.status_line.data, + r->headers_out.status_line.len); } else { - ngx_memcpy(h->last, http_codes[status].data, - http_codes[status].len); - h->last += http_codes[status].len; + h->last = ngx_cpymem(h->last, http_codes[status].data, + http_codes[status].len); } *(h->last++) = CR; *(h->last++) = LF; if (!(r->headers_out.server && r->headers_out.server->key.len)) { - ngx_memcpy(h->last, server_string, sizeof(server_string) - 1); - h->last += sizeof(server_string) - 1; + h->last = ngx_cpymem(h->last, server_string, sizeof(server_string) - 1); } if (!(r->headers_out.date && r->headers_out.date->key.len)) { - ngx_memcpy(h->last, "Date: ", 6); - h->last += 6; + h->last = ngx_cpymem(h->last, "Date: ", 6); h->last += ngx_http_get_time(h->last, time(NULL)); *(h->last++) = CR; *(h->last++) = LF; } @@ -230,39 +262,54 @@ static int ngx_http_header_filter(ngx_ht /* 2^64 is 20 characters */ if (r->headers_out.content_length >= 0) { h->last += ngx_snprintf(h->last, 49, - "Content-Length: " OFF_FMT CRLF, - r->headers_out.content_length); + "Content-Length: " OFF_FMT CRLF, + r->headers_out.content_length); + } + + if (r->headers_out.content_type && r->headers_out.content_type->value.len) { + h->last = ngx_cpymem(h->last, "Content-Type: ", 14); + h->last = ngx_cpymem(h->last, r->headers_out.content_type->value.data, + r->headers_out.content_type->value.len); + + if (text) { + h->last = ngx_cpymem(h->last, "; charset=koi8-r", 16); + } + + *(h->last++) = CR; *(h->last++) = LF; } -#if 0 - if (r->headers_out.content_type.len) { - ngx_memcpy(h->last, "Content-Type: ", 14); - h->last += 14; - ngx_memcpy(h->last, r->headers_out.content_type.data, - r->headers_out.content_type.len); - h->last += r->headers_out.content_type.len; + if (r->headers_out.location + && r->headers_out.location->value.len + && r->headers_out.location->value.data[0] == '/') + { + h->last = ngx_cpymem(h->last, "Location: http://", 17); + h->last = ngx_cpymem(h->last, r->server_name->data, + r->server_name->len); + if (r->port != 80) { + h->last = ngx_cpymem(h->last, r->port_name->data, + r->port_name->len); + } + + h->last = ngx_cpymem(h->last, r->headers_out.location->value.data, + r->headers_out.location->value.len); + *(h->last++) = CR; *(h->last++) = LF; } -#endif - if (!(r->headers_out.last_modified - && r->headers_out.last_modified->key.len) + if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len) && r->headers_out.last_modified_time != -1) { - ngx_memcpy(h->last, "Last-Modified: ", 15); - h->last += 15; + h->last = ngx_cpymem(h->last, "Last-Modified: ", 15); h->last += ngx_http_get_time(h->last, r->headers_out.last_modified_time); *(h->last++) = CR; *(h->last++) = LF; } if (r->keepalive == 0) { - ngx_memcpy(h->last, "Connection: close" CRLF, 19); - h->last += 19; + h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19); } else { - ngx_memcpy(h->last, "Connection: keep-alive" CRLF, 24); - h->last += 24; + h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24); } for (i = 0; i < r->headers_out.headers->nelts; i++) { @@ -270,12 +317,11 @@ static int ngx_http_header_filter(ngx_ht continue; } - ngx_memcpy(h->last, header[i].key.data, header[i].key.len); - h->last += header[i].key.len; + h->last = ngx_cpymem(h->last, header[i].key.data, header[i].key.len); *(h->last++) = ':' ; *(h->last++) = ' ' ; - ngx_memcpy(h->last, header[i].value.data, header[i].value.len); - h->last += header[i].value.len; + h->last = ngx_cpymem(h->last, header[i].value.data, + header[i].value.len); *(h->last++) = CR; *(h->last++) = LF; } @@ -284,7 +330,7 @@ static int ngx_http_header_filter(ngx_ht ngx_log_debug(r->connection->log, "%s\n" _ h->pos); /**/ - /* end of HTTP header */ + /* the end of HTTP header */ *(h->last++) = CR; *(h->last++) = LF; if (r->header_only) { diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -16,8 +16,6 @@ static int ngx_http_output_filter_copy_h static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool); static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, void *parent, void *child); -static void ngx_http_output_filter_init(ngx_pool_t *pool, - ngx_http_conf_filter_t *cf); static ngx_command_t ngx_http_output_filter_commands[] = { @@ -29,13 +27,11 @@ static ngx_command_t ngx_http_output_fi offsetof(ngx_http_output_filter_conf_t, hunk_size), NULL}, - {ngx_null_string, 0, NULL, 0, 0, NULL} + ngx_null_command }; static ngx_http_module_t ngx_http_output_filter_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -48,10 +44,10 @@ static ngx_http_module_t ngx_http_outpu ngx_module_t ngx_http_output_filter_module = { + NGX_MODULE, &ngx_http_output_filter_module_ctx, /* module context */ - 0, /* module index */ ngx_http_output_filter_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ NULL /* init module */ }; @@ -73,12 +69,11 @@ int ngx_http_output_filter(ngx_http_requ ngx_http_output_filter_ctx_t *ctx; ngx_http_output_filter_conf_t *conf; - ctx = (ngx_http_output_filter_ctx_t *) - ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_output_filter_module_ctx); + ctx = ngx_http_get_module_ctx(r->main ? r->main : r, + ngx_http_output_filter_module); if (ctx == NULL) { - ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module_ctx, + ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module, sizeof(ngx_http_output_filter_ctx_t), NGX_ERROR); } @@ -117,9 +112,8 @@ int ngx_http_output_filter(ngx_http_requ /* allocate our hunk if it's needed */ if (ctx->hunk == NULL) { - conf = (ngx_http_output_filter_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_output_filter_module_ctx); + conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_output_filter_module); if (hunk->type & NGX_HUNK_LAST) { if (hunk->type & NGX_HUNK_IN_MEMORY) { @@ -307,22 +301,12 @@ ngx_log_debug(src->file->log, "READ: %qd } -static void ngx_http_output_filter_init(ngx_pool_t *pool, - ngx_http_conf_filter_t *cf) -{ -#if 0 - next_filter = cf->output_body_filter; - cf->output_body_filter = NULL; -#endif -} - - static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool) { ngx_http_output_filter_conf_t *conf; ngx_test_null(conf, - ngx_pcalloc(pool, sizeof(ngx_http_output_filter_conf_t)), + ngx_palloc(pool, sizeof(ngx_http_output_filter_conf_t)), NULL); conf->hunk_size = NGX_CONF_UNSET; @@ -334,10 +318,8 @@ static void *ngx_http_output_filter_crea static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, void *parent, void *child) { - ngx_http_output_filter_conf_t *prev = - (ngx_http_output_filter_conf_t *) parent; - ngx_http_output_filter_conf_t *conf = - (ngx_http_output_filter_conf_t *) child; + ngx_http_output_filter_conf_t *prev = parent; + ngx_http_output_filter_conf_t *conf = child; ngx_conf_merge_size_value(conf->hunk_size, prev->hunk_size, 32768); diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -49,6 +49,7 @@ #define NGX_HTTP_BAD_REQUEST 400 #define NGX_HTTP_FORBIDDEN 403 #define NGX_HTTP_NOT_FOUND 404 +#define NGX_HTTP_NOT_ALLOWED 405 #define NGX_HTTP_REQUEST_TIME_OUT 408 #define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 @@ -154,10 +155,11 @@ struct ngx_http_request_s { ngx_http_request_t *main; - u_int in_addr; - - int port; - ngx_str_t port_name; + u_int in_addr; + int port; + ngx_str_t *port_name; /* ":80" */ + ngx_str_t *server_name; + ngx_array_t *virtual_names; int filter; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -39,6 +39,14 @@ static char error_404_page[] = ; +static char error_405_page[] = +"" CRLF +"405 Not Allowed" CRLF +"" CRLF +"

405 Not Allowed

" CRLF +; + + static char error_408_page[] = "" CRLF "408 Request Time-out" CRLF @@ -89,7 +97,7 @@ static ngx_str_t error_pages[] = { ngx_null_string, /* 402 */ ngx_string(error_403_page), ngx_string(error_404_page), - ngx_null_string, /* 405 */ + ngx_string(error_405_page), ngx_null_string, /* 406 */ ngx_null_string, /* 407 */ ngx_string(error_408_page), diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -28,13 +28,11 @@ static ngx_command_t ngx_http_write_filt offsetof(ngx_http_write_filter_conf_t, buffer_output), NULL}, - {ngx_null_string, 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_http_module_t ngx_http_write_filter_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -47,10 +45,10 @@ ngx_http_module_t ngx_http_write_filter ngx_module_t ngx_http_write_filter_module = { + NGX_MODULE, &ngx_http_write_filter_module_ctx, /* module context */ - 0, /* module index */ ngx_http_write_filter_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_write_filter_init /* init module */ }; @@ -63,12 +61,11 @@ int ngx_http_write_filter(ngx_http_reque ngx_http_write_filter_ctx_t *ctx; ngx_http_write_filter_conf_t *conf; - ctx = ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_write_filter_module_ctx); + ngx_http_write_filter_module); if (ctx == NULL) { - ngx_http_create_ctx(r, ctx, ngx_http_write_filter_module_ctx, + ngx_http_create_ctx(r, ctx, ngx_http_write_filter_module, sizeof(ngx_http_write_filter_ctx_t), NGX_ERROR); } @@ -122,7 +119,7 @@ int ngx_http_write_filter(ngx_http_reque } conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_write_filter_module_ctx); + ngx_http_write_filter_module); #if (NGX_DEBUG_WRITE_FILTER) ngx_log_debug(r->connection->log, diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -15,7 +15,9 @@ #include #include #include +#include /* TCP_NOPUSH */ #include +#include #include diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h --- a/src/os/unix/ngx_freebsd_init.h +++ b/src/os/unix/ngx_freebsd_init.h @@ -13,6 +13,8 @@ ssize_t ngx_unix_recv(ngx_connection_t * ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry); /* */ +ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in); + extern int ngx_freebsd_kern_osreldate; extern int ngx_freebsd_hw_ncpu; diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -1,20 +1,27 @@ #include +#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +/* + sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176 + or in 6 packets: 5x1460 and 892. Besides although sendfile() allows + to pass the header and the trailer it never sends the header or the trailer + with the part of the file in one packet. So we use TCP_NOPUSH (similar + to Linux's TCP_CORK) to postpone the sending - it not only sends the header + and the first part of the file in one packet but also sends 4K pages + in the full packets. + + The turning TCP_NOPUSH off flushes any pending data at least in FreeBSD 4.2, + although there's special fix in src/sys/netinet/tcp_usrreq.c just before + FreeBSD 4.5. +*/ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) { - int rc; + int rc, eintr, tcp_nopush; char *prev; size_t hsize, size; off_t sent; @@ -23,160 +30,208 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( ngx_err_t err; ngx_array_t header, trailer; ngx_hunk_t *file; - ngx_chain_t *ce; + ngx_chain_t *ce, *tail; + + tcp_nopush = 0; + + do { + ce = in; + file = NULL; + hsize = 0; + eintr = 0; + + ngx_init_array(header, c->pool, 10, sizeof(struct iovec), + NGX_CHAIN_ERROR); + ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), + NGX_CHAIN_ERROR); + + /* create the header iovec */ + if (ngx_hunk_in_memory_only(ce->hunk)) { + prev = NULL; + iov = NULL; + + /* create the iovec and coalesce the neighbouring chain entries */ + while (ce && ngx_hunk_in_memory_only(ce->hunk)) { - ce = in; - file = NULL; - hsize = 0; + if (prev == ce->hunk->pos) { + iov->iov_len += ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; + + } else { + ngx_test_null(iov, ngx_push_array(&header), + NGX_CHAIN_ERROR); + iov->iov_base = ce->hunk->pos; + iov->iov_len = ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; + } - ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); - ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); + hsize += ce->hunk->last - ce->hunk->pos; + + ce = ce->next; + } + } + + /* TODO: coalesce the neighbouring file hunks */ + if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { + file = ce->hunk; + ce = ce->next; + } - /* create the header iovec */ - if (ngx_hunk_in_memory_only(ce->hunk)) { - prev = NULL; - iov = NULL; + /* create the trailer iovec */ + if (ce && ngx_hunk_in_memory_only(ce->hunk)) { + prev = NULL; + iov = NULL; + + /* create the iovec and coalesce the neighbouring chain entries */ + while (ce && ngx_hunk_in_memory_only(ce->hunk)) { + + if (prev == ce->hunk->pos) { + iov->iov_len += ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; - /* create the iovec and coalesce the neighbouring chain entries */ - while (ce && ngx_hunk_in_memory_only(ce->hunk)) { + } else { + ngx_test_null(iov, ngx_push_array(&trailer), + NGX_CHAIN_ERROR); + iov->iov_base = ce->hunk->pos; + iov->iov_len = ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; + } + + ce = ce->next; + } + } - if (prev == ce->hunk->pos) { - iov->iov_len += ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; + tail = ce; + + if (file) { - } else { - ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR); - iov->iov_base = ce->hunk->pos; - iov->iov_len = ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; + if (tcp_nopush == 0) { + tcp_nopush = 1; + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH, + (const void *) &tcp_nopush, + sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, + "setsockopt(TCP_NO_PUSH) failed"); + return NGX_CHAIN_ERROR; + } + } + + hdtr.headers = (struct iovec *) header.elts; + hdtr.hdr_cnt = header.nelts; + hdtr.trailers = (struct iovec *) trailer.elts; + hdtr.trl_cnt = trailer.nelts; + + if (ngx_freebsd_sendfile_nbytes_bug == 0) { + hsize = 0; } - if (ngx_freebsd_sendfile_nbytes_bug) { - hsize += ce->hunk->last - ce->hunk->pos; + rc = sendfile(file->file->fd, c->fd, file->file_pos, + (size_t) (file->file_last - file->file_pos) + hsize, + &hdtr, &sent, 0); + + if (rc == -1) { + err = ngx_errno; + + if (err == NGX_EINTR) { + eintr = 1; + } + + if (err == NGX_EAGAIN || err == NGX_EINTR) { + ngx_log_error(NGX_LOG_INFO, c->log, err, + "sendfile() sent only %qd bytes", sent); + + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, + "sendfile() failed"); + return NGX_CHAIN_ERROR; + } + } + +#if (NGX_DEBUG_WRITE_CHAIN) + ngx_log_debug(c->log, "sendfile: %d, @%qd %qd:%d" _ + rc _ file->file_pos _ sent _ + (size_t) (file->file_last - file->file_pos) + hsize); +#endif + + } else { + rc = writev(c->fd, (struct iovec *) header.elts, header.nelts); + + if (rc == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); + + } else if (err == NGX_EINTR) { + eintr = 1; + ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); + + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); + return NGX_CHAIN_ERROR; + } } - ce = ce->next; - } - } + sent = rc > 0 ? rc : 0; - /* TODO: coalesce the neighbouring file hunks */ - if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { - file = ce->hunk; - ce = ce->next; - } +#if (NGX_DEBUG_WRITE_CHAIN) + ngx_log_debug(c->log, "writev: %qd" _ sent); +#endif + } - /* create the trailer iovec */ - if (ce && ngx_hunk_in_memory_only(ce->hunk)) { - prev = NULL; - iov = NULL; + c->sent += sent; - /* create the iovec and coalesce the neighbouring chain entries */ - while (ce && ngx_hunk_in_memory_only(ce->hunk)) { + for (ce = in; ce && sent > 0; ce = ce->next) { - if (prev == ce->hunk->pos) { - iov->iov_len += ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; - + if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { + size = ce->hunk->last - ce->hunk->pos; } else { - ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR); - iov->iov_base = ce->hunk->pos; - iov->iov_len = ce->hunk->last - ce->hunk->pos; - prev = ce->hunk->last; + size = ce->hunk->file_last - ce->hunk->file_pos; } - ce = ce->next; + if (sent >= size) { + sent -= size; + + if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { + ce->hunk->pos = ce->hunk->last; + } + + if (ce->hunk->type & NGX_HUNK_FILE) { + ce->hunk->file_pos = ce->hunk->file_last; + } + + continue; + } + + if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { + ce->hunk->pos += sent; + } + + if (ce->hunk->type & NGX_HUNK_FILE) { + ce->hunk->file_pos += sent; + } + + break; + } + + ngx_destroy_array(&trailer); + ngx_destroy_array(&header); + + in = ce; + + } while ((tail && tail == ce) || eintr); + + if (tcp_nopush == 1) { + tcp_nopush = 0; + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH, + (const void *) &tcp_nopush, + sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, + "setsockopt(!TCP_NO_PUSH) failed"); + return NGX_CHAIN_ERROR; } } - if (file) { - hdtr.headers = (struct iovec *) header.elts; - hdtr.hdr_cnt = header.nelts; - hdtr.trailers = (struct iovec *) trailer.elts; - hdtr.trl_cnt = trailer.nelts; - - rc = sendfile(file->file->fd, c->fd, file->file_pos, - (size_t) (file->file_last - file->file_pos) + hsize, - &hdtr, &sent, 0); - - if (rc == -1) { - err = ngx_errno; - if (err == NGX_EAGAIN || err == NGX_EINTR) { - ngx_log_error(NGX_LOG_INFO, c->log, err, - "sendfile() sent only %qd bytes", sent); - - } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfile() failed"); - return NGX_CHAIN_ERROR; - } - } - -#if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "sendfile: %d, @%qd %qd:%d" _ - rc _ file->file_pos _ sent _ - (size_t) (file->file_last - file->file_pos) + hsize); -#endif - - } else { - rc = writev(c->fd, (struct iovec *) header.elts, header.nelts); - - if (rc == -1) { - err = ngx_errno; - if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); - - } else if (err == NGX_EINTR) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); - - } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); - return NGX_CHAIN_ERROR; - } - } - - sent = rc > 0 ? rc : 0; - } - -#if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "sendv: %qd" _ sent); -#endif - - c->sent += sent; - - for (ce = in; ce && sent > 0; ce = ce->next) { - - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - size = ce->hunk->last - ce->hunk->pos; - } else { - size = ce->hunk->file_last - ce->hunk->file_pos; - } - - if (sent >= size) { - sent -= size; - - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - ce->hunk->pos = ce->hunk->last; - } - - if (ce->hunk->type & NGX_HUNK_FILE) { - ce->hunk->file_pos = ce->hunk->file_last; - } - - continue; - } - - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - ce->hunk->pos += sent; - } - - if (ce->hunk->type & NGX_HUNK_FILE) { - ce->hunk->file_pos += sent; - } - - break; - } - - ngx_destroy_array(&trailer); - ngx_destroy_array(&header); - return ce; } diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -1,94 +1,118 @@ #include #include -#include -#include -#include -#include + +static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err); + + +#if (HAVE_KQUEUE) 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; + ngx_event_t *rev; - ev = c->read; + rev = c->read; -#if (HAVE_KQUEUE) /* DEBUG */ if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { ngx_log_debug(c->log, "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) { + rev->eof _ rev->available _ rev->error); - if (ev->error == 0) { - return 0; - } - - ngx_set_socket_errno(ev->error); - err = ev->error; - n = -1; + if (rev->available == 0) { + if (rev->eof) { + if (rev->error) { + rev->ready = 0; + ngx_set_socket_errno(rev->error); + return ngx_unix_recv_error(rev, rev->error); + } + return 0; - } else { - n = recv(c->fd, buf, size, 0); - -ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size); - - if (n == -1) { - err = ngx_socket_errno; + } else { + return NGX_AGAIN; + } } } -#else /* not kqueue */ + do { + n = recv(c->fd, buf, size, 0); - n = recv(c->fd, buf, size, 0); - -ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size); + ngx_log_debug(c->log, "recv: %d:%d" _ n _ size); - if (n == -1) { - err = ngx_socket_errno; - } - -#endif + if (n >= 0) { + if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + rev->available -= n; + if (rev->available == 0) { + rev->ready = 0; + } - if (n == -1) { - ev->ready = 0; + return n; + } - if (err == NGX_ECONNRESET && ev->ignore_econnreset) { - return 0; + if ((size_t) n < size) { + rev->ready = 0; + } + + return n; } - 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) + rev->ready = 0; + n = ngx_unix_recv_error(rev, ngx_socket_errno); - 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; - } + } while (n == NGX_EINTR); return n; } + +#else /* ! NAVE_KQUEUE */ + +ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size) +{ + ssize_t n; + ngx_event_t *rev; + + rev = c->read; + + do { + n = recv(c->fd, buf, size, 0); + + ngx_log_debug(c->log, "recv: %d:%d" _ n _ size); + + if (n >= 0) { + if ((size_t) n < size) { + rev->ready = 0; + } + return n; + } + + rev->ready = 0; + n = ngx_unix_recv_error(rev, ngx_socket_errno); + + } while (n == NGX_EINTR); + + return n; +} + +#endif /* NAVE_KQUEUE */ + + +static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err) +{ + if (err == NGX_ECONNRESET && rev->ignore_econnreset) { + return 0; + } + + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, rev->log, err, "recv() returned EAGAIN"); + return NGX_AGAIN; + } + + if (err == NGX_EINTR) { + ngx_log_error(NGX_LOG_INFO, rev->log, err, "recv() returned EINTR"); + return NGX_EINTR; + } + + ngx_log_error(NGX_LOG_ERR, rev->log, err, "recv() failed"); + + return NGX_ERROR; +}