diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c index 67a25425e..e11200114 100644 --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -375,11 +375,11 @@ char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { ngx_str_t *field, *value; - field = (ngx_str_t *) conf + cmd->offset; + field = (ngx_str_t *) (conf + cmd->offset); value = (ngx_str_t *) cf->args->elts; - field->len = value->len; - field->data = value->data; + field->len = value[1].len; + field->data = value[1].data; return NGX_CONF_OK; } diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index ea255ba2f..83ca4ba15 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -18,6 +18,7 @@ typedef struct { #define ngx_memzero ZeroMemory +#define ngx_strncasecmp strnicmp #define ngx_strcasecmp stricmp #define ngx_strncmp strncmp #define ngx_strcmp strcmp @@ -31,6 +32,7 @@ typedef struct { #define ngx_memzero bzero +#define ngx_strncasecmp strncasecmp #define ngx_strcasecmp strcasecmp #define ngx_strncmp strncmp #define ngx_strcmp strcmp diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index a6addd568..04036d430 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -32,7 +32,7 @@ ngx_event_t *ngx_read_events, *ngx_write_events; #if 0 ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT; -#elif 1 +#elif 0 ngx_event_type_e ngx_event_type = NGX_POLL_EVENT; #else ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT; diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 76e31672b..71895a0be 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -119,11 +119,12 @@ typedef struct { /* No nedd to add or delete event filters - overlapped, aio_read, aioread */ #define NGX_HAVE_AIO_EVENT 8 -/* Event filter is deleted before closing file. Has no meaning for select, poll. +/* Event filter is deleted before closing file. Has no meaning + for select, poll, epoll. + kqueue: kqueue deletes event filters for file that closed so we need only to delete filters in user-level batch array - /dev/poll: we need to flush POLLREMOVE event before closing file - epoll: ??? */ + /dev/poll: we need to flush POLLREMOVE event before closing file */ #define NGX_CLOSE_EVENT 1 diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c index 78a058b63..d3b4901e9 100644 --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -25,7 +25,7 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, static ngx_command_t ngx_http_index_commands[] = { {ngx_string("index"), - NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_ANY, + NGX_HTTP_LOC_CONF|NGX_CONF_ANY, ngx_http_index_set_index, NGX_HTTP_LOC_CONF_OFFSET, 0}, diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index eb551cd28..4e7f8cad0 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -121,12 +121,31 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) if (rv != NGX_CONF_OK) return rv; + +#if 0 + /* DEBUG STUFF */ + cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; + for (s = 0; s < ngx_http_servers.nelts; s++) { + ngx_http_core_loc_conf_t **loc; + + ngx_log_debug(cf->log, "srv: %08x" _ cscf[s]); + loc = (ngx_http_core_loc_conf_t **) cscf[s]->locations.elts; + for (l = 0; l < cscf[s]->locations.nelts; l++) { + ngx_log_debug(cf->log, "loc: %08x:%s, %08x:%s" _ + loc[l] _ loc[l]->name.data _ + &loc[l]->doc_root _ loc[l]->doc_root.data); + } + } + /**/ +#endif + ngx_init_array(ngx_http_index_handlers, cf->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); ngx_http_init_filters(cf->pool, ngx_modules); -#if 1 + /* create lists of ports, addresses and server names */ + ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), NGX_CONF_ERROR); @@ -233,7 +252,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) sizeof(ngx_http_in_addr_t), NGX_CONF_ERROR); - ngx_test_null(inaddr, ngx_push_array(&in_port[p].addr), + ngx_test_null(inaddr, ngx_push_array(&in_port->addr), NGX_CONF_ERROR); inaddr->addr = lscf[l].addr; @@ -247,6 +266,8 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) } } + /* optimzie lists of ports, addresses and server names */ + /* AF_INET only */ in_port = (ngx_http_in_port_t *) in_ports.elts; @@ -330,14 +351,17 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) if (in_port[p].addr.nelts == 1) { in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; + /* if there is the single address for this port and no virtual + name servers so we do not need to check addresses + at run time */ if (in_addr[a].names.nelts == 0) { ls->ctx = in_addr->core_srv_conf->ctx; ls->servers = NULL; } } +ngx_log_debug(cf->log, "ls ctx: %d:%08x" _ in_port[p].port _ ls->ctx); } } -#endif return NGX_CONF_OK; } diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index bdef89995..810fda2a4 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -74,6 +74,8 @@ typedef struct { typedef struct { + ngx_str_t host_name; + ngx_table_elt_t *host; ngx_table_elt_t *connection; ngx_table_elt_t *if_modified_since; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 972b461e7..b667e3c3a 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1,6 +1,8 @@ #include +#include + #include #include @@ -20,7 +22,8 @@ int ngx_http_proxy_handler(ngx_http_request_t *r); /**/ static int ngx_http_core_index_handler(ngx_http_request_t *r); - +static ngx_http_conf_ctx_t *ngx_http_find_server_conf(ngx_http_request_t *r, + void *addr); static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, @@ -28,6 +31,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool); static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf); static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool); +static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); static ngx_command_t ngx_http_core_commands[] = { @@ -44,14 +48,20 @@ static ngx_command_t ngx_http_core_commands[] = { 0, 0}, + {ngx_string("listen"), + NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_set_listen, + 0, + 0}, + {ngx_string("root"), - NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, doc_root)}, {ngx_string("send_timeout"), - NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_time_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, send_timeout)}, @@ -96,19 +106,28 @@ int ngx_http_handler(ngx_http_request_t *r) r->lingering_close = 1; r->keepalive = 1; - ctx = (ngx_http_conf_ctx_t *) r->connection->ctx; +ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers); + + if (r->connection->servers == NULL) { + ctx = (ngx_http_conf_ctx_t *) r->connection->ctx; + + } else { + ctx = ngx_http_find_server_conf(r, r->connection->servers); + } + r->srv_conf = ctx->srv_conf; r->loc_conf = ctx->loc_conf; +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); -ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers); #if 1 r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; #endif + /* run translation phase */ for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { @@ -181,6 +200,8 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); loc_conf = (ngx_http_core_loc_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); +ngx_log_debug(r->connection->log, "doc_root: %08x" _ &loc_conf->doc_root); + s_name = (ngx_http_server_name_t *) scf->server_names.elts; /* "+ 7" is "http://" */ @@ -433,57 +454,38 @@ int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri) } -#if 0 -void *ngx_http_find_server_conf(ngx_http_request_t *r) +static ngx_http_conf_ctx_t *ngx_http_find_server_conf(ngx_http_request_t *r, + void *addr) { - int i; - ngx_http_listen_t *fs, *ls; - ngx_http_server_name_t *n; + int i, len; + ngx_http_in_addr_t *in_addr; + ngx_http_server_name_t *name; - fs = NULL; - ls = (ngx_http_listen_t *) http->ports.elts; + /* AF_INET only */ - for (i = 0; i < http->ports.nelts; i++) { - if (s->family != ls[i].family || s->port != ls[i].port) { + /* BUG: need cycle thru addr[]->elts */ + + in_addr = (ngx_http_in_addr_t *) addr; + + if (r->headers_in.host == NULL) { + return in_addr->core_srv_conf->ctx; + } + + len = r->headers_in.host_name.len; + name = (ngx_http_server_name_t *) in_addr->names.elts; + for (i = 0; i < in_addr->names.nelts; i++) { + if (len != name->name.len) { continue; } - if (s->family == AF_INET) { - - if (ls[i].addr == INADDR_ANY || ls[i].addr == s->addr) { - fs = &ls[i]; - break; - } - - } else { - /* STUB: AF_INET only */ + if (ngx_strncasecmp(r->headers_in.host_name.data, + name->name.data, len) == 0) { + return name->core_srv_conf->ctx; } } - if (fs == NULL) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "unknown local socket %s:%d", - s->addr_text.data, s->port); - return NULL; - } - - if (r->headers_in.host && fs->server_names.nelts) { - - n = (ngx_http_server_name_t *) fs->server_names.elts; - for (i = 0; i < fs->server_names.nelts; i++) { - if (r->headers_in.host->value.len != n[i].name.len) { - continue; - } - - if (ngx_strcmp(r->headers_in.host->value.data, n[i].name.data) == 0) { - return n[i].srv_conf; - } - } - } - - return fs->srv_conf; + return in_addr->core_srv_conf->ctx; } -#endif static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) @@ -520,16 +522,12 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) ngx_test_null(ctx->srv_conf[module->index], module->create_srv_conf(cf->pool), NGX_CONF_ERROR); -ngx_log_debug(cf->log, "srv_conf: %d:%0x" _ - module->index _ ctx->loc_conf[module->index]); } if (module->create_loc_conf) { ngx_test_null(ctx->loc_conf[module->index], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); -ngx_log_debug(cf->log, "srv loc_conf: %d:%0x" _ - module->index _ ctx->loc_conf[module->index]); } } @@ -571,8 +569,6 @@ ngx_log_debug(cf->log, "srv loc_conf: %d:%0x" _ } for (j = 0; j < scf->locations.nelts; j++) { -ngx_log_debug(cf->log, "%d:%0x" _ j _ lcf[j]); -ngx_log_debug(cf->log, "%d:'%s'" _ lcf[j]->name.len _ lcf[j]->name.data); if (module->merge_loc_conf(cf->pool, ctx->loc_conf[module->index], lcf[j]->loc_conf[module->index]) @@ -591,12 +587,11 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) { int i; char *rv; - void **loc; ngx_str_t *location; ngx_http_module_t *module; ngx_http_conf_ctx_t *ctx, *prev; ngx_http_core_srv_conf_t *scf; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *lcf, **loc; ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), @@ -620,25 +615,21 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) ngx_test_null(ctx->loc_conf[module->index], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); -ngx_log_debug(cf->log, "loc_conf: %d:%0x" _ - module->index _ ctx->loc_conf[module->index]); } } lcf = (ngx_http_core_loc_conf_t *) - ctx->loc_conf[ngx_http_core_module_ctx.index]; + ctx->loc_conf[ngx_http_core_module.index]; location = (ngx_str_t *) cf->args->elts; lcf->name.len = location[1].len; lcf->name.data = location[1].data; lcf->loc_conf = ctx->loc_conf; scf = (ngx_http_core_srv_conf_t *) - ctx->srv_conf[ngx_http_core_module_ctx.index]; + ctx->srv_conf[ngx_http_core_module.index]; ngx_test_null(loc, ngx_push_array(&scf->locations), NGX_CONF_ERROR); *loc = lcf; -ngx_log_debug(cf->log, "%0x:%s" _ lcf _ lcf->name.data); - cf->ctx = ctx; rv = ngx_conf_parse(cf, NULL); cf->ctx = prev; @@ -791,3 +782,29 @@ static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool) return lcf; } + +static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +{ + ngx_str_t *args; + ngx_http_listen_t *ls; + ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; + + ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR); + + /* AF_INET only */ + + ls->family = AF_INET; + ls->addr = INADDR_ANY; + ls->flags = 0; + ls->conf_file = cf->conf_file; + ls->line = cf->conf_file->line; + + args = (ngx_str_t *) cf->args->elts; + + ls->port = atoi(args[1].data); + if (ls->port < 0) { + return "port must be greater or equal to zero"; + } + + return NGX_CONF_OK; +} diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 48b1ced73..37fe17e79 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -51,7 +51,8 @@ typedef struct { typedef struct { ngx_str_t name; /* location name */ - void **loc_conf; /* used in translation handler */ + void **loc_conf; /* pointer to modules loc_conf, + used in translation handler */ ngx_str_t doc_root; /* 'root' */ diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index 5856ebff6..82f0d2d26 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -373,7 +373,7 @@ static int ngx_http_process_request_line(ngx_http_request_t *r) static int ngx_http_process_request_headers(ngx_http_request_t *r) { - int rc; + int rc, len; ngx_http_log_ctx_t *ctx; for ( ;; ) { @@ -381,21 +381,34 @@ static int ngx_http_process_request_headers(ngx_http_request_t *r) /* TODO: check too long header, compact buffer */ - if (rc == NGX_OK) { - if (ngx_http_process_request_header_line(r) == NGX_ERROR) + if (rc == NGX_OK) { /* header line is ready */ + if (ngx_http_process_request_header_line(r) == NGX_ERROR) { return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); + } + + return NGX_AGAIN; } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { ngx_log_debug(r->connection->log, "HTTP header done"); - if (r->http_version > NGX_HTTP_VERSION_10 - && r->headers_in.host == NULL) - { - return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); + if (r->headers_in.host) { + for (len = 0; len < r->headers_in.host->value.len; len++) { + if (r->headers_in.host->value.data[len] == ':') { + break; + } + } + r->headers_in.host_name.len = len; + r->headers_in.host_name.data = r->headers_in.host->value.data; + } else { - return NGX_OK; + if (r->http_version > NGX_HTTP_VERSION_10) { + return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); + } + r->headers_in.host_name.len = 0; } + return NGX_OK; + } else if (rc == NGX_AGAIN) { return NGX_AGAIN; @@ -429,11 +442,13 @@ static int ngx_http_process_request_header_line(ngx_http_request_t *r) ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); for (i = 0; headers_in[i].len != 0; i++) { - if (headers_in[i].len == h->key.len) { - if (ngx_strcasecmp(headers_in[i].data, h->key.data) == 0) { - *((ngx_table_elt_t **) - ((char *) &r->headers_in + headers_in[i].offset)) = h; - } + if (headers_in[i].len != h->key.len) { + continue; + } + + if (ngx_strcasecmp(headers_in[i].data, h->key.data) == 0) { + *((ngx_table_elt_t **) + ((char *) &r->headers_in + headers_in[i].offset)) = h; } } diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c index b2eec279d..8b382e325 100644 --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -21,7 +21,7 @@ static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, static ngx_command_t ngx_http_output_filter_commands[] = { {ngx_string("output_buffer"), - NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_output_filter_conf_t, hunk_size)}, diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index 917c044d5..2453934ca 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -20,7 +20,7 @@ static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool, static ngx_command_t ngx_http_write_filter_commands[] = { {ngx_string("write_buffer"), - NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_write_filter_conf_t, buffer_output)},