# HG changeset patch # User Igor Sysoev # Date 1053013373 0 # Node ID 29bf798b583f50c09ebe985211a8953f4c58aef2 # Parent 674d333f42960c26c4c770d77d5bb1e49b1bc752 nginx-0.0.1-2003-05-15-19:42:53 import 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 @@ -85,8 +85,8 @@ ngx_log_debug(cf->log, "token %d" _ rc); } else { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "%s %s in %s:%d", - name->data, rv, + "%s in %s:%d", + rv, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_CONF_ERROR; @@ -493,8 +493,8 @@ 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) { - int size, total, len, scale, i; - u_int max; + int size, total, len, scale; + u_int max, i; char last, *start; ngx_str_t *value; @@ -584,8 +584,8 @@ 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) { - int size, total, len, scale, i; - u_int max; + int size, total, len, scale; + u_int max, i; char last, *start; ngx_str_t *value; 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 @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -13,20 +14,21 @@ /* - * AAAA number of agruments - * TT command flags - * LL command location + * AAAA number of agruments + * FF command flags + * TT command type, i.e. HTTP "location" or "server" command + * 00 */ -#define NGX_CONF_NOARGS 1 -#define NGX_CONF_TAKE1 2 -#define NGX_CONF_TAKE2 4 -#define NGX_CONF_ARGS_NUMBER 0x00ffff -#define NGX_CONF_ANY 0x010000 -#define NGX_CONF_BLOCK 0x020000 -#define NGX_CONF_FLAG 0x040000 +#define NGX_CONF_NOARGS 0x0000000001 +#define NGX_CONF_TAKE1 0x0000000002 +#define NGX_CONF_TAKE2 0x0000000004 +#define NGX_CONF_ARGS_NUMBER 0x000000ffff +#define NGX_CONF_ANY 0x0000010000 +#define NGX_CONF_BLOCK 0x0000020000 +#define NGX_CONF_FLAG 0x0000040000 -#define NGX_MAIN_CONF 0x1000000 +#define NGX_MAIN_CONF 0x0001000000 @@ -101,8 +103,8 @@ struct ngx_conf_s { } #define ngx_conf_msec_merge(conf, prev, default) \ - if (conf == NGX_CONF_UNSET) { \ - conf = (prev == NGX_CONF_UNSET) ? default : prev; \ + if (conf == (ngx_msec_t) NGX_CONF_UNSET) { \ + conf = (prev == (ngx_msec_t) NGX_CONF_UNSET) ? default : prev; \ } #define ngx_conf_size_merge(conf, prev, default) \ diff --git a/src/event/ngx_event_proxy.c b/src/event/ngx_event_proxy.c --- a/src/event/ngx_event_proxy.c +++ b/src/event/ngx_event_proxy.c @@ -17,6 +17,10 @@ int ngx_event_proxy_read_upstream(ngx_ev ngx_hunk_t *h, *nh; ngx_chain_t *chain, *temp, *entry, *next; +#if (NGX_SUPPRESS_WARN) + entry = NULL; +#endif + #if (NGX_EVENT_COPY_FILTER) if (p->input_filter == NULL) { diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -23,6 +23,11 @@ ngx_inline static void ngx_event_del_tim ngx_log_debug(ev->log, "del timer: %d" _ *(int *)(ev->data)); #endif + if (!ev->timer_next || !ev->timer_prev) { + ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "timer already deleted"); + return; + } + if (ev->timer_prev) { ev->timer_prev->timer_next = ev->timer_next; } 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 @@ -28,9 +28,10 @@ static ngx_command_t ngx_http_index_comm NGX_HTTP_LOC_CONF|NGX_CONF_ANY, ngx_http_index_set_index, NGX_HTTP_LOC_CONF_OFFSET, - 0}, + 0, + NULL}, - {ngx_string(""), 0, NULL, 0, 0} + {ngx_string(""), 0, NULL, 0, 0, NULL} }; 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 @@ -34,7 +34,12 @@ int ngx_http_static_handler(ngx_http_req #endif - ngx_http_discard_body(r); + rc = ngx_http_discard_body(r); + + if (rc != NGX_OK) { + return rc; + } + ctx = r->connection->log->data; ctx->action = "sending response"; @@ -74,7 +79,7 @@ int ngx_http_static_handler(ngx_http_req r->file.info_valid = 1; } -#if !(WIN32) /* not regular files is probably Unix specific */ +#if !(WIN32) /* the not regular files are probably Unix specific */ if (!ngx_is_file(r->file.info)) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, 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 @@ -45,9 +45,10 @@ static ngx_command_t ngx_http_commands[ NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_http_block, 0, - 0}, + 0, + NULL}, - {ngx_string(""), 0, NULL, 0, 0} + {ngx_string(""), 0, NULL, 0, 0, NULL} }; @@ -71,11 +72,11 @@ static char *ngx_http_block(ngx_conf_t * ngx_http_module_t *module; ngx_conf_t prev; ngx_http_conf_ctx_t *ctx; - ngx_http_in_port_t *in_port; + ngx_http_in_port_t *in_port, *inport; ngx_http_in_addr_t *in_addr, *inaddr; ngx_http_core_srv_conf_t **cscf; ngx_http_listen_t *lscf; - ngx_http_server_name_t *s_name, *name;; + ngx_http_server_name_t *s_name, *name; ngx_init_array(ngx_http_servers, cf->pool, 10, sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR); @@ -148,14 +149,18 @@ static char *ngx_http_block(ngx_conf_t * ngx_init_array(ngx_http_index_handlers, cf->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); - /* create lists of the ports, the addresses and the server names */ + + /* create the lists of the ports, the addresses and the server names + to allow quickly find the server core module configuration at run-time */ ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), NGX_CONF_ERROR); + /* "server" directives */ cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; for (s = 0; s < ngx_http_servers.nelts; s++) { + /* "listen" directives */ lscf = (ngx_http_listen_t *) cscf[s]->listen.elts; for (l = 0; l < cscf[s]->listen.nelts; l++) { @@ -168,16 +173,28 @@ static char *ngx_http_block(ngx_conf_t * if (lscf[l].port == in_port[p].port) { + /* the port is already in the port list */ + port_found = 1; addr_found = 0; - in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; - for (a = 0; a < in_port[p].addr.nelts; a++) { + in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; + for (a = 0; a < in_port[p].addrs.nelts; a++) { if (lscf[l].addr == in_addr[a].addr) { + + /* the address is already bound to this port */ + + /* "server_name" directives */ s_name = (ngx_http_server_name_t *) cscf[s]->server_names.elts; for (n = 0; n < cscf[s]->server_names.nelts; n++) { + + /* add the server name and server core module + configuration to the address:port */ + + /* TODO: duplicate names can be checked here */ + ngx_test_null(name, ngx_push_array(&in_addr[a].names), NGX_CONF_ERROR); @@ -186,6 +203,9 @@ static char *ngx_http_block(ngx_conf_t * name->core_srv_conf = s_name[n].core_srv_conf; } + /* check duplicate "default" server that + serves this address:port */ + if (lscf[l].flags & NGX_HTTP_DEFAULT_SERVER) { if (in_addr[a].flags & NGX_HTTP_DEFAULT_SERVER) { @@ -206,18 +226,25 @@ static char *ngx_http_block(ngx_conf_t * break; - /* "*:XX" is the last resort */ - } else if (in_addr[p].addr == INADDR_ANY) { + } else if (in_addr[a].addr == INADDR_ANY) { + + /* "*:port" must be the last resort so move it + to the end of the address list and add + the new address at its place */ + ngx_test_null(inaddr, - ngx_push_array(&in_port[p].addr), + ngx_push_array(&in_port[p].addrs), NGX_CONF_ERROR); ngx_memcpy(inaddr, &in_addr[a], sizeof(ngx_http_in_addr_t)); - inaddr->addr = lscf[l].addr; - inaddr->flags = lscf[l].flags; - inaddr->core_srv_conf = cscf[s]; + in_addr[a].addr = lscf[l].addr; + in_addr[a].flags = lscf[l].flags; + in_addr[a].core_srv_conf = cscf[s]; + + /* create the empty list of the server names that + can be served on this address:port */ ngx_init_array(inaddr->names, cf->pool, 10, sizeof(ngx_http_server_name_t), @@ -230,14 +257,21 @@ static char *ngx_http_block(ngx_conf_t * } if (!addr_found) { + + /* add the address to the addresses list that + bound to this port */ + ngx_test_null(inaddr, - ngx_push_array(&in_port[p].addr), + ngx_push_array(&in_port[p].addrs), NGX_CONF_ERROR); inaddr->addr = lscf[l].addr; inaddr->flags = lscf[l].flags; inaddr->core_srv_conf = cscf[s]; + /* create the empty list of the server names that + can be served on this address:port */ + ngx_init_array(inaddr->names, cf->pool, 10, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); @@ -246,23 +280,33 @@ static char *ngx_http_block(ngx_conf_t * } if (!port_found) { + + /* add the port to the in_port list */ + ngx_test_null(in_port, ngx_push_array(&in_ports), NGX_CONF_ERROR); in_port->port = lscf[l].port; - ngx_init_array(in_port->addr, cf->pool, 10, + /* create list of the addresses that bound to this port ... */ + + ngx_init_array(in_port->addrs, cf->pool, 10, sizeof(ngx_http_in_addr_t), NGX_CONF_ERROR); - ngx_test_null(inaddr, ngx_push_array(&in_port->addr), + ngx_test_null(inaddr, ngx_push_array(&in_port->addrs), NGX_CONF_ERROR); + /* ... and add the address to this list */ + inaddr->addr = lscf[l].addr; inaddr->flags = lscf[l].flags; inaddr->core_srv_conf = cscf[s]; + /* create the empty list of the server names that + can be served on this address:port */ + ngx_init_array(inaddr->names, cf->pool, 10, sizeof(ngx_http_server_name_t), NGX_CONF_ERROR); @@ -270,15 +314,17 @@ static char *ngx_http_block(ngx_conf_t * } } - /* optimzie lists of ports, addresses and server names */ + /* optimize the lists of the ports, the addresses and the server names */ /* AF_INET only */ in_port = (ngx_http_in_port_t *) in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { - in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; - for (a = 0; a < in_port[p].addr.nelts; a++) { + /* check whether the all server names point to the same server */ + + in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; + for (a = 0; a < in_port[p].addrs.nelts; a++) { virtual_names = 0; @@ -290,24 +336,26 @@ static char *ngx_http_block(ngx_conf_t * } } - /* if all server names point to the same server - then we do not need to check them at run time */ + /* if the all server names point to the same server + then we do not need to check them at run-time */ + if (!virtual_names) { in_addr[a].names.nelts = 0; } } - /* if there is binding to "*:XX" then we need to bind to "*:XX" only - and ignore other binding */ + /* if there's the binding to "*:port" then we need to bind() + to "*:port" only and ignore the other bindings */ + if (in_addr[a - 1].addr == INADDR_ANY) { - start = a - 1; + a--; } else { - start = 0; + a = 0; } - in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; - for (a = start; a < in_port[p].addr.nelts; a++) { + in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; + while (a < in_port[p].addrs.nelts) { ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets), NGX_CONF_ERROR); @@ -326,12 +374,12 @@ static char *ngx_http_block(ngx_conf_t * NGX_CONF_ERROR); ls->addr_text.len = - ngx_snprintf(ls->addr_text.data - + ngx_inet_ntop(AF_INET, - (char *) &in_addr[a].addr, - ls->addr_text.data, - INET_ADDRSTRLEN), - 6, ":%d", in_port[p].port); + ngx_snprintf(ls->addr_text.data + + ngx_inet_ntop(AF_INET, + (char *) &in_addr[a].addr, + ls->addr_text.data, + INET_ADDRSTRLEN), + 6, ":%d", in_port[p].port); ls->family = AF_INET; ls->type = SOCK_STREAM; @@ -351,22 +399,49 @@ static char *ngx_http_block(ngx_conf_t * ls->log = cf->log; ls->pool_size = ngx_http_connection_pool_size; ls->ctx = ctx; - ls->servers = &in_port[p]; + + if (in_port[p].addrs.nelts > 1) { + + in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; + if (in_addr[in_port[p].addrs.nelts - 1].addr != INADDR_ANY) { + + /* if this port has not the "*:port" binding then create + the separate ngx_http_in_port_t for the all bindings */ -#if 0 - if (in_port[p].addr.nelts == 1) { - in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; + ngx_test_null(inport, + ngx_palloc(cf->pool, + sizeof(ngx_http_in_port_t)), + NGX_CONF_ERROR); + + inport->port = in_port[p].port; + + /* init list of the addresses ... */ - /* 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_init_array(inport->addrs, cf->pool, 1, + sizeof(ngx_http_in_addr_t), + NGX_CONF_ERROR); + + /* ... and set up it with the first address */ + + inport->addrs.nelts = 1; + inport->addrs.elts = in_port[p].addrs.elts; + + ls->servers = inport; + + /* prepare for the next cycle */ + + in_port[p].addrs.elts += in_port[p].addrs.size; + in_port[p].addrs.nelts--; + + in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; + a = 0; + + continue; } } -#endif -ngx_log_debug(cf->log, "ls ctx: %d:%08x" _ in_port[p].port _ ls->ctx); + + ls->servers = &in_port[p]; + a++; } } @@ -374,8 +449,8 @@ ngx_log_debug(cf->log, "ls ctx: %d:%08x" in_port = (ngx_http_in_port_t *) in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { ngx_log_debug(cf->log, "port: %d" _ in_port[p].port); - in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; - for (a = 0; a < in_port[p].addr.nelts; a++) { + in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; + for (a = 0; a < in_port[p].addrs.nelts; a++) { char ip[20]; ngx_inet_ntop(AF_INET, (char *) &in_addr[a].addr, ip, 20); ngx_log_debug(cf->log, "%s %08x" _ ip _ in_addr[a].core_srv_conf); 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 @@ -31,7 +31,7 @@ #define NGX_HTTP_PARSE_INVALID_METHOD 10 #define NGX_HTTP_PARSE_INVALID_REQUEST 11 #define NGX_HTTP_PARSE_TOO_LONG_URI 12 -#define NGX_HTTP_PARSE_INVALID_HEAD 13 +#define NGX_HTTP_PARSE_INVALID_09_METHOD 13 #define NGX_HTTP_PARSE_INVALID_HEADER 14 #define NGX_HTTP_PARSE_TOO_LONG_HEADER 15 #define NGX_HTTP_PARSE_NO_HOST_HEADER 16 @@ -234,6 +234,7 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ void ngx_http_init_connection(ngx_connection_t *c); int ngx_parse_http_request_line(ngx_http_request_t *r); int ngx_parse_http_header_line(ngx_http_request_t *r, ngx_hunk_t *h); +int ngx_http_find_server_conf(ngx_http_request_t *r); void ngx_http_handler(ngx_http_request_t *r); void ngx_http_finalize_request(ngx_http_request_t *r, int error); void ngx_http_set_write_handler(ngx_http_request_t *r); 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 @@ -40,93 +40,108 @@ static ngx_command_t ngx_http_core_comm NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_server_block, 0, - 0}, + 0, + NULL,}, {ngx_string("post_accept_timeout"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, 0, - addressof(ngx_http_post_accept_timeout)}, + addressof(ngx_http_post_accept_timeout), + NULL}, {ngx_string("connection_pool_size"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, 0, - addressof(ngx_http_connection_pool_size)}, + addressof(ngx_http_connection_pool_size), + NULL}, {ngx_string("request_pool_size"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, 0, - addressof(ngx_http_request_pool_size)}, + addressof(ngx_http_request_pool_size), + NULL}, {ngx_string("client_header_timeout"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, 0, - addressof(ngx_http_client_header_timeout)}, + addressof(ngx_http_client_header_timeout), + NULL}, {ngx_string("client_header_buffer_size"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, 0, - addressof(ngx_http_client_header_buffer_size)}, + addressof(ngx_http_client_header_buffer_size), + NULL}, {ngx_string("large_client_header"), NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, 0, - addressof(ngx_http_large_client_header)}, + addressof(ngx_http_large_client_header), + NULL}, {ngx_string("location"), NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, ngx_location_block, NGX_HTTP_SRV_CONF_OFFSET, - 0}, + 0, + NULL}, {ngx_string("listen"), NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_set_listen, NGX_HTTP_SRV_CONF_OFFSET, - 0}, + 0, + NULL}, {ngx_string("types"), NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_types_block, NGX_HTTP_LOC_CONF_OFFSET, - 0}, + 0, + NULL}, {ngx_string("root"), 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)}, + offsetof(ngx_http_core_loc_conf_t, doc_root), + NULL}, {ngx_string("sendfile"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, sendfile)}, + offsetof(ngx_http_core_loc_conf_t, sendfile), + NULL}, {ngx_string("send_timeout"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, send_timeout)}, + offsetof(ngx_http_core_loc_conf_t, send_timeout), + NULL}, {ngx_string("lingering_time"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, lingering_time)}, + offsetof(ngx_http_core_loc_conf_t, lingering_time), + NULL}, {ngx_string("lingering_timeout"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, lingering_timeout)}, + offsetof(ngx_http_core_loc_conf_t, lingering_timeout), + NULL}, - {ngx_null_string, 0, NULL, 0, 0} + {ngx_null_string, 0, NULL, 0, 0, NULL} }; @@ -150,72 +165,76 @@ ngx_module_t ngx_http_core_module = { }; -void ngx_http_handler(ngx_http_request_t *r) +int ngx_http_find_server_conf(ngx_http_request_t *r) { - int rc, a, n, i; - ngx_http_handler_pt *h; - ngx_http_module_t *module; - 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 *name; - ngx_http_core_srv_conf_t *scf; - ngx_http_core_loc_conf_t *lcf, **plcf; + 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; - r->connection->unexpected_eof = 0; - - r->keepalive = 0; - r->lingering_close = 1; + /* AF_INET only */ -#if 0 -ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers); -#endif + in_port = (ngx_http_in_port_t *) r->connection->servers; + in_addr = (ngx_http_in_addr_t *) in_port->addrs.elts; - /* find server config */ + r->port = in_port->port; + + a = 0; - if (r->connection->servers == NULL) { - ctx = (ngx_http_conf_ctx_t *) r->connection->ctx; - - } else { + if (in_port->addrs.nelts > 1) { - /* AF_INET only */ - - in_port = (ngx_http_in_port_t *) r->connection->servers; - in_addr = (ngx_http_in_addr_t *) in_port->addr.elts; - - a = 0; + /* there're the several addresses on this port and one of them + is "*:port" so getsockname() is needed to determine + the server address */ - if (in_port->addr.nelts > 1) { - /* find r->in_addr, getsockname() */ - - for ( /* void */ ; a < in_port->addr.nelts; a++) { + 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; + } - if (in_addr[a].addr == INADDR_ANY) { - break; - } + r->in_addr = addr_in.sin_addr.s_addr; - if (in_addr[a].addr == r->in_addr) { - break; - } + for ( /* void */ ; a < in_port->addrs.nelts; a++) { + if (in_addr[a].addr == r->in_addr) { +ngx_log_debug(r->connection->log, "FOUND"); + break; } } - ctx = in_addr[a].core_srv_conf->ctx; +if (a == in_port->addrs.nelts) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "addr not found"); + exit(1); +} - if (r->headers_in.host_name_len > 0) { + } else { + r->in_addr = in_addr[0].addr; + } + + /* the default server configuration for this address:port */ + ctx = in_addr[a].core_srv_conf->ctx; - 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 (r->headers_in.host_name_len > 0) { + + /* find the name based server configuration */ - 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; - } + 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; } } } @@ -229,7 +248,30 @@ ngx_log_debug(r->connection->log, "srv_c ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf); #endif - /* run rewrite url phase */ + return NGX_OK; +} + + +void ngx_http_handler(ngx_http_request_t *r) +{ + int rc, i; + ngx_http_handler_pt *h; + ngx_http_module_t *module; + ngx_http_core_loc_conf_t *lcf, **plcf; + ngx_http_core_srv_conf_t *scf; + + r->connection->unexpected_eof = 0; + + r->keepalive = 0; + + if (r->headers_in.content_length_n > 0) { + r->lingering_close = 1; + } + + /* TEST STUB */ r->lingering_close = 1; + + + /* TODO: run rewrite url phase */ /* find location config */ @@ -383,7 +425,6 @@ ngx_log_debug(r->connection->log, "HTTP if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { err = ngx_errno; ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - "ngx_http_core_translate_handler: " ngx_file_type_n " \"%s\" failed", r->file.name.data); if (err == NGX_ENOENT || err == NGX_ENOTDIR) { @@ -406,7 +447,6 @@ ngx_log_debug(r->connection->log, "HTTP if (r->file.fd == NGX_INVALID_FILE) { err = ngx_errno; ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, - "ngx_http_core_handler: " ngx_open_file_n " \"%s\" failed", r->file.name.data); if (err == NGX_ENOENT || err == NGX_ENOTDIR) { @@ -423,12 +463,10 @@ ngx_log_debug(r->connection->log, "HTTP if (!r->file.info_valid) { if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - "ngx_http_core_handler: " ngx_stat_fd_n " \"%s\" failed", r->file.name.data); if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, - "ngx_http_core_handler: " ngx_close_file_n " \"%s\" failed", r->file.name.data); } @@ -446,7 +484,6 @@ ngx_log_debug(r->connection->log, "HTTP #if !(WIN9X) if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, - "ngx_http_core_handler: " ngx_close_file_n " \"%s\" failed", r->file.name.data); } #endif @@ -842,13 +879,13 @@ static void *ngx_http_core_create_loc_co ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), NGX_CONF_ERROR); -/* - ngx_pcalloc(): + /* set by ngx_pcalloc(): lcf->doc_root.len = 0; lcf->doc_root.data = NULL; lcf->types = NULL; -*/ + + */ lcf->sendfile = NGX_CONF_UNSET; @@ -933,23 +970,45 @@ static char *ngx_http_core_merge_loc_con static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { + uint p; + char *addr; ngx_str_t *args; ngx_http_listen_t *ls; ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; + /* TODO: check duplicate 'listen' directives */ + 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->file_name = cf->conf_file->file.name; ls->line = cf->conf_file->line; args = (ngx_str_t *) cf->args->elts; + addr = args[1].data; - ls->port = ngx_atoi(args[1].data, args[1].len); + for (p = 0; p < args[1].len; p++) { + if (addr[p] == ':') { + addr[p++] = '\0'; + + ls->addr = inet_addr(addr); + if (ls->addr == INADDR_NONE) { + return "bad addr"; + } + + break; + } + } + + if (p == args[1].len) { + ls->addr = INADDR_ANY; + p = 0; + } + + ls->port = ngx_atoi(&addr[p], args[1].len - p); if (ls->port < 1 || ls->port > 65536) { return "port must be between 1 and 65535"; } 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 @@ -31,9 +31,10 @@ typedef struct { typedef struct { int port; - ngx_array_t addr; /* array of ngx_http_in_addr_t */ + ngx_array_t addrs; /* array of ngx_http_in_addr_t */ } ngx_http_in_port_t; + typedef struct { u_int32_t addr; ngx_array_t names; /* array of ngx_http_server_name_t */ @@ -42,8 +43,10 @@ typedef struct { int flags; } ngx_http_in_addr_t; +/* ngx_http_in_addr_t's flags */ #define NGX_HTTP_DEFAULT_SERVER 1 + typedef struct { ngx_str_t name; ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */ @@ -54,7 +57,7 @@ typedef struct { #define ngx_http_types_hash_key(key, ext) \ { \ - int n; \ + uint n; \ for (key = 0, n = 0; n < ext.len; n++) { \ key += ext.data[n]; \ } \ @@ -79,10 +82,10 @@ typedef struct { ngx_array_t *types; int sendfile; /* sendfile */ - time_t send_timeout; /* send_timeout */ + ngx_msec_t send_timeout; /* send_timeout */ size_t send_lowat; /* send_lowa */ size_t discarded_buffer_size; /* discarded_buffer_size */ - time_t lingering_time; /* lingering_time */ + 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 @@ -25,8 +25,9 @@ static ssize_t ngx_http_read_request_hea static void ngx_http_writer(ngx_event_t *ev); -static int ngx_http_block_read(ngx_event_t *ev); -static int ngx_http_read_discarded_body(ngx_event_t *ev); +static void ngx_http_block_read(ngx_event_t *ev); +static void ngx_http_read_discarded_body_event(ngx_event_t *rev); +static int ngx_http_read_discarded_body(ngx_http_request_t *r); static void ngx_http_set_keepalive(ngx_http_request_t *r); static void ngx_http_keepalive_handler(ngx_event_t *ev); @@ -43,7 +44,7 @@ static char *header_errors[] = { "client %s sent invalid method", "client %s sent invalid request", "client %s sent too long URI", - "client %s sent HEAD method in HTTP/0.9 request", + "client %s sent invalid method in HTTP/0.9 request", "client %s sent invalid header, URL: %s", "client %s sent too long header line, URL: %s", @@ -338,6 +339,13 @@ static void ngx_http_process_request_lin } 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; } @@ -539,6 +547,13 @@ 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; @@ -605,9 +620,9 @@ static ssize_t ngx_http_read_request_hea r->header_in->end - r->header_in->last); if (n == NGX_AGAIN) { + rev = r->connection->read; + if (!r->header_timeout_set) { - rev = r->connection->read; - if (rev->timer_set) { ngx_del_timer(rev); } else { @@ -666,11 +681,15 @@ void ngx_http_finalize_request(ngx_http_ if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { rev = r->connection->read; - if (rev->timer_set) { ngx_del_timer(rev); - } else { - rev->timer_set = 1; + rev->timer_set = 0; + } + + wev = r->connection->write; + if (wev->timer_set) { + ngx_del_timer(wev); + wev->timer_set = 0; } rc = ngx_http_special_response_handler(r, rc); @@ -811,90 +830,122 @@ static void ngx_http_writer(ngx_event_t } else { ngx_http_close_request(r, 0); + ngx_http_close_connection(r->connection); } } -static int ngx_http_block_read(ngx_event_t *ev) +static void ngx_http_block_read(ngx_event_t *rev) { - ngx_log_debug(ev->log, "http read blocked"); + ngx_connection_t *c; + ngx_http_request_t *r; + + ngx_log_debug(rev->log, "http read blocked"); /* aio does not call this handler */ -#if (USE_KQUEUE) + if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { - return NGX_OK; + /* select, poll, /dev/poll */ -#else + rev->blocked = 1; - if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { /* select, poll, /dev/poll */ - ev->blocked = 1; - return ngx_del_event(ev, NGX_READ_EVENT, 0); - - } else { /* kqueue, epoll */ - return NGX_OK; + if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { + c = (ngx_connection_t *) rev->data; + r = (ngx_http_request_t *) c->data; + ngx_http_close_request(r, 0); + ngx_http_close_connection(c); + } } -#endif /* USE_KQUEUE */ + /* kqueue, epoll */ + + return; } -/* STUB */ -int ngx_http_discard_body(ngx_http_request_t *r) -{ - return NGX_OK; -} - -#if 0 -/* TODO */ int ngx_http_discard_body(ngx_http_request_t *r) { - ngx_event_t *ev; + ssize_t size; + ngx_event_t *rev; - ev = r->connection->read; + rev = r->connection->read; - ngx_log_debug(r->connection->log, "set discard body"); + ngx_log_debug(rev->log, "set discard body"); - if (ev->timer_set) { - ngx_del_timer(ev); - ev->timer_set = 0; + if (rev->timer_set) { + ngx_del_timer(rev); + rev->timer_set = 0; } - if (r->headers_in.content_length_n) { - ev->event_handler = ngx_http_read_discarded_body; - /* if blocked - read */ - /* else add timer */ + if (r->headers_in.content_length_n > 0) { + + size = r->header_in->last - r->header_in->pos; + + if (size) { + if (r->headers_in.content_length_n > size) { + r->headers_in.content_length_n -= size; + + } else { + r->header_in->pos += r->headers_in.content_length_n; + r->headers_in.content_length_n = 0; + return NGX_OK; + } + } + + rev->event_handler = ngx_http_read_discarded_body_event; + + if (rev->blocked) { + if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) + == NGX_ERROR) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } + + rev->blocked = 0; + return ngx_http_read_discarded_body(r); + } } return NGX_OK; } -/* TODO */ -static int ngx_http_read_discarded_body(ngx_event_t *ev) +static void ngx_http_read_discarded_body_event(ngx_event_t *rev) { - size_t size; - ssize_t n; - ngx_connection_t *c; - ngx_http_request_t *r; + int rc; + ngx_connection_t *c; + ngx_http_request_t *r; + + c = (ngx_connection_t *) rev->data; + r = (ngx_http_request_t *) c->data; + + rc = ngx_http_read_discarded_body(r); + + if (rc != NGX_OK) { + ngx_http_close_request(r, rc); + ngx_http_close_connection(c); + } +} + + +static int ngx_http_read_discarded_body(ngx_http_request_t *r) +{ + size_t size; + ssize_t n; ngx_http_core_loc_conf_t *lcf; - ngx_log_debug(ev->log, "http read discarded body"); - - if (ev->timedout) { - return NGX_ERROR; - } - - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; + 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); if (r->discarded_buffer == NULL) { - ngx_test_null(r->discarded_buffer, - ngx_palloc(r->pool, lcf->discarded_buffer_size), - NGX_ERROR); + r->discarded_buffer = ngx_palloc(r->pool, lcf->discarded_buffer_size); + if (r->discarded_buffer == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } } size = r->headers_in.content_length_n; @@ -902,9 +953,9 @@ static int ngx_http_read_discarded_body( size = lcf->discarded_buffer_size; } - n = ngx_event_recv(c, r->discarded_buffer, size); + n = ngx_event_recv(r->connection, r->discarded_buffer, size); if (n == NGX_ERROR) { - return NGX_ERROR; + return NGX_HTTP_BAD_REQUEST; } if (n == NGX_AGAIN) { @@ -912,10 +963,9 @@ static int ngx_http_read_discarded_body( } r->headers_in.content_length_n -= n; - /* XXX: what if r->client_content_length == 0 ? */ + return NGX_OK; } -#endif static void ngx_http_set_keepalive(ngx_http_request_t *r) @@ -1182,7 +1232,7 @@ void ngx_http_close_request(ngx_http_req if (r->pool == NULL) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "http already closed"); + "http request already closed"); return; } diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -314,12 +314,12 @@ int ngx_parse_http_request_line(ngx_http r->http_version = r->http_major * 1000 + r->http_minor; r->state = sw_start; - if (r->http_version == 9 && r->method == NGX_HTTP_HEAD) { - return NGX_HTTP_PARSE_INVALID_HEAD; - } else { - return NGX_OK; + if (r->http_version == 9 && r->method != NGX_HTTP_GET) { + return NGX_HTTP_PARSE_INVALID_09_METHOD; } + return NGX_OK; + } else { r->state = state; return NGX_AGAIN; diff --git a/src/os/unix/ngx_freebsd_write_chain.c b/src/os/unix/ngx_freebsd_write_chain.c --- a/src/os/unix/ngx_freebsd_write_chain.c +++ b/src/os/unix/ngx_freebsd_write_chain.c @@ -54,6 +54,7 @@ ngx_chain_t *ngx_freebsd_write_chain(ngx if (ngx_freebsd_sendfile_nbytes_bug) { hsize += ce->hunk->last - ce->hunk->pos; } + ce = ce->next; } } diff --git a/src/os/unix/ngx_recv_chain.c b/src/os/unix/ngx_recv_chain.c --- a/src/os/unix/ngx_recv_chain.c +++ b/src/os/unix/ngx_recv_chain.c @@ -13,6 +13,10 @@ ssize_t ngx_recv_chain(ngx_connection_t ngx_err_t err; ngx_array_t io; +#if (NGX_SUPPRESS_WARN) + iov = NULL; +#endif + ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR); while (entry) {