char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_int_t level; ngx_uint_t i, n; ngx_str_t *value; ngx_path_t *path, **pp; pp = (ngx_path_t **) (p + cmd->offset); if (*pp) { return "is duplicate"; } /* TODO: check duplicate in cf->cycle->pathes */ ngx_test_null(path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)), NGX_CONF_ERROR); *pp = path; ngx_test_null(pp, ngx_push_array(&cf->cycle->pathes), NGX_CONF_ERROR); *pp = path; value = (ngx_str_t *) cf->args->elts; path->name = value[1]; path->len = 0; for (i = 0, n = 2; n < cf->args->nelts; i++, n++) { level = ngx_atoi(value[n].data, value[n].len); if (level == NGX_ERROR || level == 0) { return "invalid value"; } path->level[i] = level; path->len += level + 1; } while (i < 3) { path->level[i++] = 0; } path->gc_handler = (ngx_gc_handler_pt) cmd->post; return NGX_CONF_OK; }
ngx_array_t *ngx_create_array(ngx_pool_t *p, ngx_uint_t n, size_t size) { ngx_array_t *a; ngx_test_null(a, ngx_palloc(p, sizeof(ngx_array_t)), NULL); ngx_test_null(a->elts, ngx_palloc(p, n * size), NULL); a->pool = p; a->nelts = 0; a->nalloc = n; a->size = size; return a; }
ngx_int_t ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in) { ngx_chain_t *cl, **ll; ll = chain; for (cl = *chain; cl; cl = cl->next) { ll = &cl->next; } while (in) { ngx_test_null(cl, ngx_alloc_chain_link(pool), NGX_ERROR); cl->buf = in->buf; *ll = cl; ll = &cl->next; in = in->next; } *ll = NULL; return NGX_OK; }
static void *ngx_epoll_create_conf(ngx_cycle_t *cycle) { ngx_epoll_conf_t *epcf; ngx_test_null(epcf, ngx_palloc(cycle->pool, sizeof(ngx_epoll_conf_t)), NGX_CONF_ERROR); epcf->events = NGX_CONF_UNSET; return epcf; }
static void *ngx_devpoll_create_conf(ngx_cycle_t *cycle) { ngx_devpoll_conf_t *dpcf; ngx_test_null(dpcf, ngx_palloc(cycle->pool, sizeof(ngx_devpoll_conf_t)), NGX_CONF_ERROR); dpcf->changes = NGX_CONF_UNSET; dpcf->events = NGX_CONF_UNSET; return dpcf; }
static void *ngx_event_create_conf(ngx_cycle_t *cycle) { ngx_event_conf_t *ecf; ngx_test_null(ecf, ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t)), NGX_CONF_ERROR); ecf->connections = NGX_CONF_UNSET_UINT; ecf->use = NGX_CONF_UNSET_UINT; ecf->multi_accept = NGX_CONF_UNSET; ecf->accept_mutex = NGX_CONF_UNSET; ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC; ecf->name = (void *) NGX_CONF_UNSET; #if (NGX_DEBUG) ngx_init_array(ecf->debug_connection, cycle->pool, 5, sizeof(in_addr_t), NGX_CONF_ERROR); #endif return ecf; }
static ngx_int_t ngx_select_init(ngx_cycle_t *cycle) { ngx_event_t **index; if (event_index == NULL) { FD_ZERO(&master_read_fd_set); FD_ZERO(&master_write_fd_set); nevents = 0; } if (ngx_process == NGX_PROCESS_WORKER || cycle->old_cycle == NULL || cycle->old_cycle->connection_n < cycle->connection_n) { ngx_test_null(index, ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, cycle->log), NGX_ERROR); if (event_index) { ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents); ngx_free(event_index); } event_index = index; } ngx_io = ngx_os_io; ngx_event_actions = ngx_select_module_ctx.actions; ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_ONESHOT_EVENT; max_fd = -1; return NGX_OK; }
int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, int persistent) { int num; ngx_err_t err; file->name.len = path->name.len + 1 + path->len + 10; ngx_test_null(file->name.data, ngx_palloc(pool, file->name.len + 1), NGX_ERROR); #if 0 for (i = 0; i < file->name.len; i++) { file->name.data[i] = 'X'; } #endif ngx_memcpy(file->name.data, path->name.data, path->name.len); num = ngx_next_temp_number(0); for ( ;; ) { ngx_snprintf((char *) (file->name.data + path->name.len + 1 + path->len), 11, "%010u", num); ngx_create_hashed_filename(file, path); #if 1 file->fd = ngx_open_tempfile(file->name.data, persistent); #else file->fd = ngx_open_tempfile(file->name.data, 1); #endif ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, "temp fd:%d", file->fd); if (file->fd != NGX_INVALID_FILE) { return NGX_OK; } err = ngx_errno; if (err == NGX_EEXIST) { num = ngx_next_temp_number(1); continue; } if ((path->level[0] == 0) || (err != NGX_ENOENT #if (WIN32) && err != NGX_ENOTDIR #endif )) { ngx_log_error(NGX_LOG_CRIT, file->log, err, ngx_open_tempfile_n " \"%s\" failed", file->name.data); return NGX_ERROR; } if (ngx_create_path(file, path) == NGX_ERROR) { return NGX_ERROR; } } }
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_uint_t mi, m, s, l, p, a, n; ngx_uint_t port_found, addr_found, virtual_names; ngx_conf_t pcf; ngx_array_t in_ports; ngx_listening_t *ls; ngx_http_listen_t *lscf; ngx_http_module_t *module; ngx_http_handler_pt *h; ngx_http_conf_ctx_t *ctx; ngx_http_in_port_t *in_port, *inport; ngx_http_in_addr_t *in_addr, *inaddr; ngx_http_server_name_t *s_name, *name; ngx_http_core_srv_conf_t **cscfp, *cscf; ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf; #if (WIN32) ngx_iocp_conf_t *iocpcf; #endif /* the main http context */ ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); *(ngx_http_conf_ctx_t **) conf = ctx; // 把新创建的配置上下文挂钩起来 /* count the number of the http modules and set up their indices */ ngx_http_max_module = 0; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } ngx_modules[m]->ctx_index = ngx_http_max_module++; } /* the main http main_conf, it's the same in the all http contexts */ ngx_test_null(ctx->main_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); /* the http null srv_conf, it's used to merge the server{}s' srv_conf's */ ngx_test_null(ctx->srv_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); /* the http null loc_conf, it's used to merge the server{}s' loc_conf's */ ngx_test_null(ctx->loc_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); /* 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) { continue; } module = ngx_modules[m]->ctx; mi = ngx_modules[m]->ctx_index; if (module->pre_conf) { if (module->pre_conf(cf) != NGX_OK) { return NGX_CONF_ERROR; } } if (module->create_main_conf) { ngx_test_null(ctx->main_conf[mi], module->create_main_conf(cf), NGX_CONF_ERROR); } if (module->create_srv_conf) { ngx_test_null(ctx->srv_conf[mi], module->create_srv_conf(cf), NGX_CONF_ERROR); } if (module->create_loc_conf) { ngx_test_null(ctx->loc_conf[mi], module->create_loc_conf(cf), NGX_CONF_ERROR); } } /* parse inside the http{} block */ pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_HTTP_MODULE; cf->cmd_type = NGX_HTTP_MAIN_CONF; rv = ngx_conf_parse(cf, NULL); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } /* * init http{} main_conf's, merge the server{}s' srv_conf's * and its location{}s' loc_conf's */ cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; cscfp = cmcf->servers.elts; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } module = ngx_modules[m]->ctx; mi = ngx_modules[m]->ctx_index; /* init http{} main_conf's */ if (module->init_main_conf) { rv = module->init_main_conf(cf, ctx->main_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } for (s = 0; s < cmcf->servers.nelts; s++) { /* merge the server{}s' srv_conf's */ if (module->merge_srv_conf) { rv = module->merge_srv_conf(cf, ctx->srv_conf[mi], cscfp[s]->ctx->srv_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } if (module->merge_loc_conf) { /* merge the server{}'s loc_conf */ rv = module->merge_loc_conf(cf, ctx->loc_conf[mi], cscfp[s]->ctx->loc_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } /* merge the locations{}' loc_conf's */ rv = ngx_http_merge_locations(cf, &cscfp[s]->locations, cscfp[s]->ctx->loc_conf, module, mi); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } #if 0 clcfp = (ngx_http_core_loc_conf_t **) cscfp[s]->locations.elts; for (l = 0; l < cscfp[s]->locations.nelts; l++) { rv = module->merge_loc_conf(cf, cscfp[s]->ctx->loc_conf[mi], clcfp[l]->loc_conf[mi]); if (rv != NGX_CONF_OK) { *cf = pcf; return rv; } } #endif } } } /* we needed "http"'s cf->ctx while merging configuration */ *cf = pcf; /* init lists of the handlers */ ngx_init_array(cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers, cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_REWRITE_PHASE].type = NGX_OK; /* the special find config phase for single handler */ ngx_init_array(cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers, cf->cycle->pool, 1, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].type = NGX_OK; ngx_test_null(h, ngx_push_array( &cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers), NGX_CONF_ERROR); *h = ngx_http_find_location_config; ngx_init_array(cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers, cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_ACCESS_PHASE].type = NGX_DECLINED; ngx_init_array(cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers, cf->cycle->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); cmcf->phases[NGX_HTTP_CONTENT_PHASE].type = NGX_OK; /* * 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 */ cscfp = cmcf->servers.elts; for (s = 0; s < cmcf->servers.nelts; s++) { /* "listen" directives */ lscf = cscfp[s]->listen.elts; for (l = 0; l < cscfp[s]->listen.nelts; l++) { port_found = 0; /* AF_INET only */ in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { if (lscf[l].port == in_port[p].port) { /* the port is already in the port list */ port_found = 1; addr_found = 0; in_addr = 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 = cscfp[s]->server_names.elts; for (n = 0; n < cscfp[s]->server_names.nelts; n++) { /* * add the server name and server core module * configuration to the address:port */ /* TODO: duplicate names can be checked here */ ngx_test_null(name, ngx_push_array(&in_addr[a].names), NGX_CONF_ERROR); name->name = s_name[n].name; name->core_srv_conf = s_name[n].core_srv_conf; } /* * check duplicate "default" server that * serves this address:port */ if (lscf[l].default_server) { if (in_addr[a].default_server) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, "duplicate default server in %s:%d", lscf[l].file_name.data, lscf[l].line); return NGX_CONF_ERROR; } in_addr[a].core_srv_conf = cscfp[s]; in_addr[a].default_server = 1; } addr_found = 1; break; } 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].addrs), NGX_CONF_ERROR); ngx_memcpy(inaddr, &in_addr[a], sizeof(ngx_http_in_addr_t)); in_addr[a].addr = lscf[l].addr; in_addr[a].default_server = lscf[l].default_server; in_addr[a].core_srv_conf = cscfp[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); addr_found = 1; break; } } 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].addrs), NGX_CONF_ERROR); inaddr->addr = lscf[l].addr; inaddr->default_server = lscf[l].default_server; inaddr->core_srv_conf = cscfp[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); } } } 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_test_null(in_port->port_text.data, ngx_palloc(cf->pool, 7), NGX_CONF_ERROR); in_port->port_text.len = ngx_snprintf((char *) in_port->port_text.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, sizeof(ngx_http_in_addr_t), NGX_CONF_ERROR); 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->default_server = lscf[l].default_server; inaddr->core_srv_conf = cscfp[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); } } } /* optimize the lists of the ports, the addresses and the server names */ /* AF_INET only */ in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { /* check whether the all server names point to the same server */ in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { virtual_names = 0; name = in_addr[a].names.elts; for (n = 0; n < in_addr[a].names.nelts; n++) { if (in_addr[a].core_srv_conf != name[n].core_srv_conf) { virtual_names = 1; break; } } /* * 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'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) { a--; } else { a = 0; } in_addr = in_port[p].addrs.elts; while (a < in_port[p].addrs.nelts) { ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr, in_port[p].port); if (ls == NULL) { return NGX_CONF_ERROR; } ls->backlog = -1; #if 0 #if 0 ls->nonblocking = 1; #else ls->nonblocking = 0; #endif #endif ls->addr_ntop = 1; ls->handler = ngx_http_init_connection; cscf = in_addr[a].core_srv_conf; ls->pool_size = cscf->connection_pool_size; ls->post_accept_timeout = cscf->post_accept_timeout; clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; ls->log = clcf->err_log; #if (WIN32) iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module); if (iocpcf->acceptex_read) { ls->post_accept_buffer_size = cscf->client_header_buffer_size; } #endif ls->ctx = ctx; if (in_port[p].addrs.nelts > 1) { in_addr = 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 */ ngx_test_null(inport, ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t)), NGX_CONF_ERROR); inport->port = in_port[p].port; inport->port_text = in_port[p].port_text; /* init list of the addresses ... */ 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 = (char *) 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; } } ls->servers = &in_port[p]; a++; } } #if (NGX_DEBUG) in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "port: %d %08x", in_port[p].port, &in_port[p]); in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { u_char ip[20]; ngx_inet_ntop(AF_INET, &in_addr[a].addr, ip, 20); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "%s %08x", ip, in_addr[a].core_srv_conf); s_name = in_addr[a].names.elts; for (n = 0; n < in_addr[a].names.nelts; n++) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "%s %08x", s_name[n].name.data, s_name[n].core_srv_conf); } } } #endif return NGX_CONF_OK; }
static int ngx_devpoll_init(ngx_cycle_t *cycle) { size_t n; ngx_devpoll_conf_t *dpcf; dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module); if (dp == -1) { dp = open("/dev/poll", O_RDWR); if (dp == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "open(/dev/poll) failed"); return NGX_ERROR; } } if (max_changes < dpcf->changes) { if (nchanges) { n = nchanges * sizeof(struct pollfd); if (write(dp, change_list, n) != (ssize_t) n) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "write(/dev/poll) failed"); return NGX_ERROR; } nchanges = 0; } if (change_list) { ngx_free(change_list); } ngx_test_null(change_list, ngx_alloc(sizeof(struct pollfd) * dpcf->changes, cycle->log), NGX_ERROR); if (change_index) { ngx_free(change_index); } ngx_test_null(change_index, ngx_alloc(sizeof(ngx_event_t *) * dpcf->changes, cycle->log), NGX_ERROR); } max_changes = dpcf->changes; if (nevents < dpcf->events) { if (event_list) { ngx_free(event_list); } ngx_test_null(event_list, ngx_alloc(sizeof(struct pollfd) * dpcf->events, cycle->log), NGX_ERROR); } nevents = dpcf->events; ngx_io = ngx_os_io; ngx_event_actions = ngx_devpoll_module_ctx.actions; ngx_event_flags = NGX_USE_LEVEL_EVENT; return NGX_OK; }
/* * 当遇到event{...}配置块时调用此接口 */ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int m; char *rv; void ***ctx; ngx_conf_t pcf; ngx_event_module_t *module; /* count the number of the event modules and set up their indices */ /* 统计事件模块的编号 */ ngx_event_max_module = 0; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } ngx_modules[m]->ctx_index = ngx_event_max_module++; } /* (ctx) type is (void ***) */ ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(void *)), NGX_CONF_ERROR); /* (*ctx) type is (void **) */ ngx_test_null(*ctx, ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)), NGX_CONF_ERROR); *(void **) conf = ctx; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } module = ngx_modules[m]->ctx; /* create configure context: * epoll module is ngx_epoll_create_conf() */ if (module->create_conf) { ngx_test_null((*ctx)[ngx_modules[m]->ctx_index], module->create_conf(cf->cycle), NGX_CONF_ERROR); } } pcf = *cf; cf->ctx = ctx; cf->module_type = NGX_EVENT_MODULE; cf->cmd_type = NGX_EVENT_CONF; rv = ngx_conf_parse(cf, NULL); *cf = pcf; if (rv != NGX_CONF_OK) return rv; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } module = ngx_modules[m]->ctx; /* call event module's init configure callback * epoll module is ngx_epoll_init_conf() */ if (module->init_conf) { rv = module->init_conf(cf->cycle, (*ctx)[ngx_modules[m]->ctx_index]); if (rv != NGX_CONF_OK) { return rv; } } } return NGX_CONF_OK; }