ngx_http_read_request_header
1 定义ngx_http_read_request_header 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.cstaticssize_tngx_http_read_request_header(ngx_http_request_t*r){ssize_tn;ngx_event_t*rev;ngx_connection_t*c;ngx_http_core_srv_conf_t*cscf;cr-connection;revc-read;nr-header_in-last-r-header_in-pos;if(n0){returnn;}if(rev-ready){nc-recv(c,r-header_in-last,r-header_in-end-r-header_in-last);}else{nNGX_AGAIN;}if(nNGX_AGAIN){if(!rev-timer_set){cscfngx_http_get_module_srv_conf(r,ngx_http_core_module);ngx_add_timer(rev,cscf-client_header_timeout);}if(ngx_handle_read_event(rev,0)!NGX_OK){ngx_http_close_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_ERROR;}returnNGX_AGAIN;}if(n0){ngx_log_error(NGX_LOG_INFO,c-log,0,client prematurely closed connection);}if(n0||nNGX_ERROR){c-error1;c-log-actionreading client request headers;ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}r-header_in-lastn;returnn;}ngx_http_read_request_header 函数的主要作用是 以非阻塞方式从客户端连接读取 HTTP 请求头原始数据。 它优先检查接收缓冲区中是否已有未处理的数据并直接返回其长度 若无数据且读事件就绪则执行系统调用读入新数据 若读操作尚未就绪则设置客户端请求头超时定时器并注册读事件 然后向上层返回 NGX_AGAIN 等待下次被触发 当读取到数据时更新缓冲区指针并返回字节数 若遇到连接关闭或读取错误则记录日志并以 400 错误结束请求。2 详解1 函数签名staticssize_tngx_http_read_request_header(ngx_http_request_t*r)返回值 正数 0成功读取的字节数或缓冲区中已有的未处理数据长度 调用者可据此继续解析请求头。 NGX_AGAIN通常为 -2 表示操作尚未完成, 没有数据可读需要等待 I/O 事件就绪后再次调用。 NGX_ERROR通常为 -1 发生严重错误如读取失败、连接关闭请求已终结。参数 ngx_http_request_t *r 当前 请求对象2 逻辑流程1 局部变量 2 未处理数据 3 读取数据 3-1 暂无数据 3-2 读取出错 4 更新缓冲区指针并返回1 局部变量{ssize_tn;ngx_event_t*rev;ngx_connection_t*c;ngx_http_core_srv_conf_t*cscf;cr-connection;revc-read;2 未处理数据nr-header_in-last-r-header_in-pos;if(n0){returnn;}#1 header_in 是专门用于接收 HTTP 请求头的缓冲区 pos指向待解析数据的起始位置。 last指向已读入数据的末尾。 end指向缓冲区容量的末尾。 计算 n 为缓冲区中尚未解析的字节数。 意义Nginx 采用边读边解析模式。 每次进入此函数可能是新一轮读事件触发 但有可能上一次 recv 读入的数据尚未被解析完 此时无需执行系统调用直接返回已有长度让上层解析器继续工作。#2 若已有数据则直接返回3 读取数据if(rev-ready){nc-recv(c,r-header_in-last,r-header_in-end-r-header_in-last);}else{nNGX_AGAIN;}#1 rev-ready 读事件已就绪 读取数据#2 未就绪, 无数据可读 直接设 n NGX_AGAIN 表示暂时无数据需等待事件通知3-1 暂无数据if(nNGX_AGAIN){if(!rev-timer_set){cscfngx_http_get_module_srv_conf(r,ngx_http_core_module);ngx_add_timer(rev,cscf-client_header_timeout);}if(ngx_handle_read_event(rev,0)!NGX_OK){ngx_http_close_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_ERROR;}returnNGX_AGAIN;}#1 暂无数据可读 设置读取超时定时器 !rev-timer_set检查该读事件是否已经设置过定时器 未设置则设置定时器#2 注册读事件 失败 直接关闭请求并记录 500 错误 返回 NGX_ERROR 结束函数 确保事件在监控中这样下次收到数据才能收到通知然后去处理#3 返回 NGX_AGAIN 告诉调用链数据尚未读取完毕等待事件3-2 读取出错if(n0){ngx_log_error(NGX_LOG_INFO,c-log,0,client prematurely closed connection);}n 0 表示客户端关闭了连接 记录一条 INFO 级别日志内容为“客户端过早关闭连接”if(n0||nNGX_ERROR){c-error1;c-log-actionreading client request headers;ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}错误处理 标记连接发生错误 结束当前请求传递状态码 400 Bad Request 返回 NGX_ERROR终止函数4 更新缓冲区指针并返回r-header_in-lastn;returnn;}成功读取了 n 个字节到缓冲区中 将缓冲区描述指针 last 向后移动 n 个字节准确标记已填充数据的末尾 返回成功读取的字节数
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2619267.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!