1.接受请求事件模块
2.接受请求http模块
<_http_init_connection源码
初始化http连接的源码:
void
ngx_http_init_connection(ngx_connection_t *c)
{ngx_uint_t i;ngx_event_t *rev;struct sockaddr_in *sin;ngx_http_port_t *port;ngx_http_in_addr_t *addr;ngx_http_log_ctx_t *ctx;ngx_http_connection_t *hc;
#if (NGX_HAVE_INET6)struct sockaddr_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)case AF_INET6:sin6 = (struct sockaddr_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 = (struct sockaddr_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)case AF_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;// 设置读事件的回调函数为ngx_http_wait_request_handler,写事件的回调函数为ngx_http_empty_handlerrev = 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) {c->log->action = "SSL handshaking";if (hc->addr_conf->ssl && sscf-& == NULL) {ngx_log_error(NGX_LOG_ERR, c->log, 0,"no "ssl_certificate" is defined ""in server listening on SSL port");ngx_http_close_connection(c);return;}hc->ssl = 1;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 */// 若使用了accept_mutex,将读事件加入到post队列中if (ngx_use_accept_mutex) {ngx_post_event(rev, &ngx_posted_events);return;}// 若没有使用accept_mutex,直接调用ngx_http_wait_request_handlerrev->handler(rev);return;}// 若读事件未准备就绪,将读事件加入到定时器和epoll中ngx_add_timer(rev, c->listening->post_accept_timeout);ngx_reusable_connection(c, 1);if (ngx_handle_read_event(rev, 0) != NGX_OK) {ngx_http_close_connection(c);return;}
}
<_http_wait_request_handler源码
static void
ngx_http_wait_request_handler(ngx_event_t *rev)
{u_char *p;size_t size;ssize_t n;ngx_buf_t *b;ngx_connection_t *c;ngx_http_connection_t *hc;ngx_http_core_srv_conf_t *cscf;c = rev->data;ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");// 如果当前连接的读事件已经超时if (rev->timedout) {ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");ngx_http_close_connection(c);return;}// 如果当前连接要关闭if (c->close) {ngx_http_close_connection(c);return;}hc = c->data;cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);size = cscf->client_header_buffer_size;// 缓冲区b = c->buffer;if (b == NULL) {b = ngx_create_temp_buf(c->pool, size);if (b == NULL) {ngx_http_close_connection(c);return;}c->buffer = b;} else if (b->start == NULL) {b->start = ngx_palloc(c->pool, size);if (b->start == NULL) {ngx_http_close_connection(c);return;}b->pos = b->start;b->last = b->start;b->end = b->last + size;}// 调用recv接收数据,返回值赋值给nn = c->recv(c, b->last, size);/* 如果服务端正在接收数据,但还没接收完(即客户端正在发送数据,但还没发送完)当客户端开始发送数据,套接字准备好读,epoll_wait检测到读事件*/if (n == NGX_AGAIN) {if (!rev->timer_set) {ngx_add_timer(rev, c->listening->post_accept_timeout);ngx_reusable_connection(c, 1);}if (ngx_handle_read_event(rev, 0) != NGX_OK) {ngx_http_close_connection(c);return;}/** We are trying to not hold c->buffer's memory for an idle connection.*/if (ngx_pfree(c->pool, b->start) == NGX_OK) {b->start = NULL;}return;}// 如果当前连接错误if (n == NGX_ERROR) {ngx_http_close_connection(c);return;}// 如果recv返回0表示客户端关闭连接了,服务器端接受到客户端发来的FIN请求if (n == 0) {ngx_log_error(NGX_LOG_INFO, c->log, 0,"client closed connection");ngx_http_close_connection(c);return;}b->last += n;if (hc->proxy_protocol) {hc->proxy_protocol = 0;p = ngx_proxy_protocol_read(c, b->pos, b->last);if (p == NULL) {ngx_http_close_connection(c);return;}b->pos = p;if (b->pos == b->last) {c->log->action = "waiting for request";b->pos = b->start;b->last = b->start;ngx_post_event(rev, &ngx_posted_events);return;}}c->log->action = "reading client request line";ngx_reusable_connection(c, 0);// 创建ngx_http_request_t结构体并初始化部分参数c->data = ngx_http_create_request(c);if (c->data == NULL) {ngx_http_close_connection(c);return;}// 修改当前连接的读事件的回调函数为ngx_http_process_request_line并调用该函数rev->handler = ngx_http_process_request_line;ngx_http_process_request_line(rev);
}
本文发布于:2024-01-28 08:38:21,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17064023076165.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |