当前位置: 首页 > news >正文

ngx_http_process_request_header

1 定义ngx_http_process_request_header 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.cngx_int_tngx_http_process_request_header(ngx_http_request_t*r){if(r-headers_in.server.len0ngx_http_set_virtual_server(r,r-headers_in.server)NGX_ERROR){returnNGX_ERROR;}if(r-headers_in.hostNULLr-http_versionNGX_HTTP_VERSION_10){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent HTTP/1.1 request without \Host\ header);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}if(r-headers_in.content_length){r-headers_in.content_length_nngx_atoof(r-headers_in.content_length-value.data,r-headers_in.content_length-value.len);if(r-headers_in.content_length_nNGX_ERROR){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent invalid \Content-Length\ header);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}}if(r-headers_in.transfer_encoding){if(r-http_versionNGX_HTTP_VERSION_11){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent HTTP/1.0 request with \Transfer-Encoding\ header);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}if(r-headers_in.transfer_encoding-value.len7ngx_strncasecmp(r-headers_in.transfer_encoding-value.data,(u_char*)chunked,7)0){if(r-headers_in.content_length){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent \Content-Length\ and \Transfer-Encoding\ headers at the same time);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}r-headers_in.chunked1;}else{ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent unknown \Transfer-Encoding\: \%V\,r-headers_in.transfer_encoding-value);ngx_http_finalize_request(r,NGX_HTTP_NOT_IMPLEMENTED);returnNGX_ERROR;}}if(r-headers_in.connection_typeNGX_HTTP_CONNECTION_KEEP_ALIVE){if(r-headers_in.keep_alive){r-headers_in.keep_alive_nngx_atotm(r-headers_in.keep_alive-value.data,r-headers_in.keep_alive-value.len);}}if(r-methodNGX_HTTP_CONNECT){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent CONNECT method);ngx_http_finalize_request(r,NGX_HTTP_NOT_ALLOWED);returnNGX_ERROR;}if(r-methodNGX_HTTP_TRACE){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent TRACE method);ngx_http_finalize_request(r,NGX_HTTP_NOT_ALLOWED);returnNGX_ERROR;}returnNGX_OK;}ngx_http_process_request_header 函数 是 Nginx 在解析完 HTTP 请求头后调用的 协议合规性校验与预处理函数。 对已解析的请求头进行合法性、兼容性和语义检查初始化内部标志 拒绝不支持或不合规的请求确保后续处理模块获得合法且可处理的请求。2 详解1 函数签名ngx_int_tngx_http_process_request_header(ngx_http_request_t*r)返回值 用于表示函数执行状态。参数 ngx_http_request_t *r 当前请求的请求结构体2 逻辑流程1 虚拟服务器匹配 2 Host 头检查 3 Content-Length 头处理 4 Transfer-Encoding 头处理 5 长连接 Keep-Alive 参数解析 6 禁止 CONNECT 方法 7 禁止 TRACE 方法 8 校验通过1 虚拟服务器匹配{if(r-headers_in.server.len0ngx_http_set_virtual_server(r,r-headers_in.server)NGX_ERROR){returnNGX_ERROR;}if 条件判断用于设置虚拟服务器。条件有两部分用 连接 r-headers_in.server.len 0 server 字段存放从 Host 头部拷贝的主机名字符串 若长度为0说明 Host 头不存在或为空还未进行虚拟主机匹配。 ngx_http_set_virtual_server(r, r-headers_in.server) NGX_ERROR 调用虚拟主机匹配函数传入请求和主机名即使长度为0也会尝试匹配默认服务器。 若返回 NGX_ERROR 说明匹配过程失败如内存不足等内部错误。 仅当尚未匹配过虚拟主机server 长度0时才调用匹配函数 若匹配过程出错整个请求无法继续直接进入错误处理。2 Host 头检查if(r-headers_in.hostNULLr-http_versionNGX_HTTP_VERSION_10){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent HTTP/1.1 request without \Host\ header);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}检查 HTTP/1.1及更高版本请求是否缺少 Host 头部。 r-headers_in.host NULL host 指针指向原始的 Host 头部结构 若为 NULL 表示请求中完全未出现该头部。 r-http_version NGX_HTTP_VERSION_10 HTTP 版本高于 1.0即 1.1 或 2.0 等。 HTTP/1.1 规范强制要求请求必须包含 Host 头缺失则为错误请求。3 Content-Length 头处理if(r-headers_in.content_length){r-headers_in.content_length_nngx_atoof(r-headers_in.content_length-value.data,r-headers_in.content_length-value.len);if(r-headers_in.content_length_nNGX_ERROR){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent invalid \Content-Length\ header);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}}检查是否存在 Content-Length 头部。 r-headers_in.content_length 是一个指针 若非 NULL 则表示客户端提供了该头部。将 Content-Length 头的字符串值转换成整型off_t文件偏移类型用于表示字节长度。 调用 ngx_atoof传入字符串数据指针和长度。转换结果存入 r-headers_in.content_length_n 后续模块使用该数值读取请求体或进行长度校验。 检查转换是否失败。ngx_atoof 在遇到非数字字符、溢出等非法情况时返回 NGX_ERROR 转换失败记录日志说明客户端发送了非法的 Content-Length 头 返回 400 Bad Request 错误并结束请求。4 Transfer-Encoding 头处理if(r-headers_in.transfer_encoding){if(r-http_versionNGX_HTTP_VERSION_11){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent HTTP/1.0 request with \Transfer-Encoding\ header);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}if(r-headers_in.transfer_encoding-value.len7ngx_strncasecmp(r-headers_in.transfer_encoding-value.data,(u_char*)chunked,7)0){if(r-headers_in.content_length){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent \Content-Length\ and \Transfer-Encoding\ headers at the same time);ngx_http_finalize_request(r,NGX_HTTP_BAD_REQUEST);returnNGX_ERROR;}r-headers_in.chunked1;}else{ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent unknown \Transfer-Encoding\: \%V\,r-headers_in.transfer_encoding-value);ngx_http_finalize_request(r,NGX_HTTP_NOT_IMPLEMENTED);returnNGX_ERROR;}}#1 检查是否存在 Transfer-Encoding 头部。 非 NULL 表示客户端声明了传输编码 若 HTTP 版本低于 1.1即 HTTP/1.0 或更早 规范不允许使用 Transfer-Encoding视为错误。检查 Transfer-Encoding 的值是否为 chunked不区分大小写。 条件 长度等于7正好是 chunked 的长度。 调用 ngx_strncasecmp 比较前7个字符是否与 chunked 相同忽略大小写。 若满足说明客户端使用分块传输编码这是 Nginx 唯一完整支持的传输编码。在 chunked 的情况下再次检查是否同时存在 Content-Length 头部。 HTTP 规范明确禁止二者同时出现因为会产生消息边界歧义。一切正常设置 chunked 标志为1。 后续请求体读取函数会根据该标志采用分块解析模式#2 若传输编码不是 chunked 进入 else 分支 返回 501 Not Implemented 表示服务器不支持该传输编码5 长连接 Keep-Alive 参数解析if(r-headers_in.connection_typeNGX_HTTP_CONNECTION_KEEP_ALIVE){if(r-headers_in.keep_alive){r-headers_in.keep_alive_nngx_atotm(r-headers_in.keep_alive-value.data,r-headers_in.keep_alive-value.len);}}检查 Connection 头是否表示保持长连接。 connection_type 字段在解析 Connection 头时设置 NGX_HTTP_CONNECTION_KEEP_ALIVE 代表请求希望使用持久连接 常见于 HTTP/1.0 的 Connection: keep-alive 或 HTTP/1.1 的默认行为。如果同时存在 Keep-Alive 头则尝试解析其值6 禁止 CONNECT 方法if(r-methodNGX_HTTP_CONNECT){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent CONNECT method);ngx_http_finalize_request(r,NGX_HTTP_NOT_ALLOWED);returnNGX_ERROR;}检查请求方法是否为 CONNECT。 r-method 是解析出的 HTTP 方法常量 NGX_HTTP_CONNECT 对应 CONNECT 方法。返回 405 Not Allowed 状态码 表示服务器默认不允许 CONNECT 方法7 禁止 TRACE 方法if(r-methodNGX_HTTP_TRACE){ngx_log_error(NGX_LOG_INFO,r-connection-log,0,client sent TRACE method);ngx_http_finalize_request(r,NGX_HTTP_NOT_ALLOWED);returnNGX_ERROR;}检查请求方法是否为 TRACE 同样返回 405 Not Allowed 因为 TRACE 方法易引发跨站追踪 (XST) 安全风险Nginx 默认禁用。8 校验通过returnNGX_OK;}所有校验和预处理均已通过返回 NGX_OK
http://www.zskr.cn/news/1387775.html

相关文章:

  • ARM调试寄存器体系与CLAIM标签机制详解
  • 国产多模态大模型:重塑游戏开发的“中国引擎”
  • 渐进式披露:AI产品人机交互设计实践与工程实现
  • Stripe支付集成实战:5大策略构建在线业务增长引擎
  • 基于gws+ChromaDB的私有RAG知识库构建实战
  • 电压驱动还是电流驱动?一次讲透PHY芯片与网络变压器的三种经典接法(含Altium Designer实战布线)
  • 单数字口读取双电位器:PWM编码与单片机解码实战
  • R语言矩阵底层原理与高性能数据处理实战
  • 智慧树自动化学习助手:3步配置实现视频自动连播与倍速播放终极方案
  • Unity 2D怪物动画系统:预集成、可驱动、生产就绪
  • 终极HsMod配置指南:60+功能全面解锁炉石传说高级体验
  • PySpark groupBy 原理与高可用实践:从数据倾斜到AQE调优
  • C++日志库选型实战:为什么我最终选择了Log4cpp而不是spdlog或glog?
  • 别再只盯着大模型了,2026年真正拉开AI体验差距的是资料后勤系统
  • 别再傻傻分不清了!一文搞懂UART串口和TTL电平到底啥关系(附CP2102实测波形分析)
  • VR与机器学习如何为神经多样性群体构建个性化安全训练沙盒
  • 目视初检+万用表快测,PCB元件损坏快速定位法
  • AI代理开始替人干活后,最先掉链子的不是模型,而是你的向量引擎
  • C#猜数字游戏:从控制台Demo到工程级实践
  • Claude微服务安全加固手册:OAuth2.1+SPIFFE双向mTLS实施,通过等保三级认证的4项硬核配置
  • FAQ Schema对AI搜索可见性的真实影响与双层优化实战
  • 精通 Android NDK/JNI:从入门到精通实战与面试精粹
  • C#游戏物理引擎的SIMD向量加速实战
  • Spark框架:数据流驱动的Unity无代码游戏开发范式
  • ComfyUI-WanVideoWrapper架构设计与企业级视频生成实现原理
  • Unity 2D地牢程序化生成:约束满足+区域生长+拓扑校验三重落地方案
  • Unity移动端输入框键盘自适应解决方案
  • Android热修复与插件化原理深度解析:Tinker与RePlugin实践指南
  • ESP-01/03一键编程器设计:从电平转换到在线烧录全解析
  • 你的无人机为什么飞不稳?从APM/PIX飞控参数调试到云台增稳的实战排查手册