ngx_http_set_exten
2026/6/7 14:51:35 网站建设 项目流程

1 定义

ngx_http_set_exten 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.c
voidngx_http_set_exten(ngx_http_request_t*r){ngx_int_ti;ngx_str_null(&r->exten);for(i=r->uri.len-1;i>1;i--){if(r->uri.data[i]=='.'&&r->uri.data[i-1]!='/'){r->exten.len=r->uri.len-i-1;r->exten.data=&r->uri.data[i+1];return;}elseif(r->uri.data[i]=='/'){return;}}return;}
ngx_http_set_exten 函数的作用是 从请求的 URI 中提取文件扩展名(如 `html`、`jpg`), 并存储到 `r->exten` 字段中,供后续模块(如 MIME 类型设置)使用。 如果 URI 没有扩展名,则 `r->exten` 被置空。

2 详解

1 函数签名·

voidngx_http_set_exten(ngx_http_request_t*r)
返回值 函数无返回值 该函数的唯一职责是修改请求结构体 r 内部的 exten 字段
参数 ngx_http_request_t *r 指向当前请求的结构体 作为函数输入来源: 函数从 r->uri 读取当前请求的 URI 字符串及其长度,作为提取扩展名的源数据。 作为函数输出目标: 函数直接修改 r->exten 的两个成员(len 和 data),将结果写回请求结构体。 如果找到了扩展名,r->exten.data 会指向 r->uri.data 中的某个位置, 不分配新内存,实现零拷贝。

2 逻辑流程

1 初始化 2 从后向前 循环查找 2-1 成功匹配 2-2 遇到 / 前未匹配 3 查找结束未匹配

1 初始化
{ngx_int_ti;ngx_str_null(&r->exten);
将请求的 exten 字段初始化为空字符串

2 从后向前 循环查找
for(i=r->uri.len-1;i>1;i--){if(r->uri.data[i]=='.'&&r->uri.data[i-1]!='/'){r->exten.len=r->uri.len-i-1;r->exten.data=&r->uri.data[i+1];return;}elseif(r->uri.data[i]=='/'){return;}}
从 URI 字符串的最后一个字符开始,向前遍历,索引递减。 循环条件 i > 1 保证 i 最小为 2,循环体中 i-1 最小为 1,绝对防数组越界 后缀必在 URI 尾部,所以倒序扫描 条件是 i > 1 ,因为 URI 的第一个字符是 '/', 而 '.' 之前 '/' 之后至少需要一个字符来作为文件名 保证 i - 1 不会越界
#2-1 判断当前字符是否为点号(.),并且其前一个字符不是斜杠(/) r->uri.data[i] == '.': 找到了一个点号,可能是扩展名的开始。 r->uri.data[i - 1] != '/': 排除点号紧跟在路径分隔符之后的情况,即隐藏文件或目录名(如 /home/.hidden)。 如果点号前是 /,则该点是文件名的第一个字符,不是扩展名分隔符。 意义: 准确识别扩展名分隔符
设置扩展名字符串的长度。 r->uri.len 是 URI 总长度, i 是点号的索引, 所以 r->uri.len - i - 1 是点号之后所有字符的数量。 将扩展名的数据指针指向点号之后的下一个字符,即扩展名的第一个字符。 成功提取扩展名后,立即从函数返回,无需继续扫描剩余字符
#2-2 如果当前字符不是符合条件的点号,则检查是否是斜杠 / 从后向前扫描,如果先遇到 /,说明这个路径段已经结束, 而在此之前没有遇到合法的点号,因此该 URI 没有扩展名 直接返回,扩展名保持为空

3 查找结束未匹配
return;}
如果循环正常结束而未提前返回, 则执行此语句,函数结束

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询