voidngx_http_init_connection(ngx_connection_t*c){ngx_uint_ti;ngx_event_t*rev;structsockaddr_in*sin;ngx_http_port_t*port;ngx_http_in_addr_t*addr;ngx_http_log_ctx_t*ctx;ngx_http_connection_t*hc;ngx_http_core_srv_conf_t*cscf;#if(NGX_HAVE_INET6)structsockaddr_in6*sin6;ngx_http_in6_addr_t*addr6;#endifhc=ngx_pcalloc(c->pool,sizeof(ngx_http_connection_t));if(hc==NULL){ngx_http_close_connection(c);return;}c->data=hc;/* find the server configuration for the address:port */port=c->listening->servers;if(port->naddrs>1){/* * there are several addresses on this port and one of them * is an "*:port" wildcard so getsockname() in ngx_http_server_addr() * is required to determine a server address */if(ngx_connection_local_sockaddr(c,NULL,0)!=NGX_OK){ngx_http_close_connection(c);return;}switch(c->local_sockaddr->sa_family){#if(NGX_HAVE_INET6)caseAF_INET6:sin6=(structsockaddr_in6*)c->local_sockaddr;addr6=port->addrs;/* the last address is "*" */for(i=0;i<port->naddrs-1;i++){if(ngx_memcmp(&addr6[i].addr6,&sin6->sin6_addr,16)==0){break;}}hc->addr_conf=&addr6[i].conf;break;#endifdefault:/* AF_INET */sin=(structsockaddr_in*)c->local_sockaddr;addr=port->addrs;/* the last address is "*" */for(i=0;i<port->naddrs-1;i++){if(addr[i].addr==sin->sin_addr.s_addr){break;}}hc->addr_conf=&addr[i].conf;break;}}else{switch(c->local_sockaddr->sa_family){#if(NGX_HAVE_INET6)caseAF_INET6:addr6=port->addrs;hc->addr_conf=&addr6[0].conf;break;#endifdefault:/* AF_INET */addr=port->addrs;hc->addr_conf=&addr[0].conf;break;}}/* the default server configuration for the address:port */hc->conf_ctx=hc->addr_conf->default_server->ctx;ctx=ngx_palloc(c->pool,sizeof(ngx_http_log_ctx_t));if(ctx==NULL){ngx_http_close_connection(c);return;}ctx->connection=c;ctx->request=NULL;ctx->current_request=NULL;c->log->connection=c->number;c->log->handler=ngx_http_log_error;c->log->data=ctx;c->log->action="waiting for request";c->log_error=NGX_ERROR_INFO;rev=c->read;rev->handler=ngx_http_wait_request_handler;c->write->handler=ngx_http_empty_handler;#if(NGX_HTTP_V2)if(hc->addr_conf->http2){rev->handler=ngx_http_v2_init;}#endif#if(NGX_HTTP_SSL){ngx_http_ssl_srv_conf_t*sscf;sscf=ngx_http_get_module_srv_conf(hc->conf_ctx,ngx_http_ssl_module);if(sscf->enable||hc->addr_conf->ssl){hc->ssl=1;c->log->action="SSL handshaking";rev->handler=ngx_http_ssl_handshake;}}#endifif(hc->addr_conf->proxy_protocol){hc->proxy_protocol=1;c->log->action="reading PROXY protocol";}if(rev->ready){/* the deferred accept(), iocp */if(ngx_use_accept_mutex){ngx_post_event(rev,&ngx_posted_events);return;}rev->handler(rev);return;}cscf=ngx_http_get_module_srv_conf(hc->conf_ctx,ngx_http_core_module);ngx_add_timer(rev,cscf->client_header_timeout);ngx_reusable_connection(c,1);if(ngx_handle_read_event(rev,0)!=NGX_OK){ngx_http_close_connection(c);return;}}
`ngx_http_init_connection` 函数的作用是: 为刚建立的 TCP 连接初始化 HTTP 层处理环境。 它分配连接专属的 HTTP 上下文, 根据本地 IP 与端口匹配对应的 server 配置块,设置日志、读/写事件回调 添加客户端请求超时,并将读事件注册到底层事件驱动模块, 使连接正式进入等待接收客户端请求的状态。
/* find the server configuration for the address:port */port=c->listening->servers;if(port->naddrs>1){/* * there are several addresses on this port and one of them * is an "*:port" wildcard so getsockname() in ngx_http_server_addr() * is required to determine a server address */if(ngx_connection_local_sockaddr(c,NULL,0)!=NGX_OK){ngx_http_close_connection(c);return;}switch(c->local_sockaddr->sa_family){#if(NGX_HAVE_INET6)caseAF_INET6:sin6=(structsockaddr_in6*)c->local_sockaddr;addr6=port->addrs;/* the last address is "*" */for(i=0;i<port->naddrs-1;i++){if(ngx_memcmp(&addr6[i].addr6,&sin6->sin6_addr,16)==0){break;}}hc->addr_conf=&addr6[i].conf;break;#endifdefault:/* AF_INET */sin=(structsockaddr_in*)c->local_sockaddr;addr=port->addrs;/* the last address is "*" */for(i=0;i<port->naddrs-1;i++){if(addr[i].addr==sin->sin_addr.s_addr){break;}}hc->addr_conf=&addr[i].conf;break;}}else{switch(c->local_sockaddr->sa_family){#if(NGX_HAVE_INET6)caseAF_INET6:addr6=port->addrs;hc->addr_conf=&addr6[0].conf;break;#endifdefault:/* AF_INET */addr=port->addrs;hc->addr_conf=&addr[0].conf;break;}}
ctx=ngx_palloc(c->pool,sizeof(ngx_http_log_ctx_t));if(ctx==NULL){ngx_http_close_connection(c);return;}ctx->connection=c;ctx->request=NULL;ctx->current_request=NULL;c->log->connection=c->number;c->log->handler=ngx_http_log_error;c->log->data=ctx;c->log->action="waiting for request";c->log_error=NGX_ERROR_INFO;