ngx_http_set_content_type

发布时间:2026/7/5 23:23:58
ngx_http_set_content_type 1 定义ngx_http_set_content_type 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.cngx_int_tngx_http_set_content_type(ngx_http_request_t*r){u_char c,*exten;ngx_str_t*type;ngx_uint_ti,hash;ngx_http_core_loc_conf_t*clcf;if(r-headers_out.content_type.len){returnNGX_OK;}clcfngx_http_get_module_loc_conf(r,ngx_http_core_module);if(r-exten.len){hash0;for(i0;ir-exten.len;i){cr-exten.data[i];if(cAcZ){extenngx_pnalloc(r-pool,r-exten.len);if(extenNULL){returnNGX_ERROR;}hashngx_hash_strlow(exten,r-exten.data,r-exten.len);r-exten.dataexten;break;}hashngx_hash(hash,c);}typengx_hash_find(clcf-types_hash,hash,r-exten.data,r-exten.len);if(type){r-headers_out.content_type_lentype-len;r-headers_out.content_type*type;returnNGX_OK;}}r-headers_out.content_type_lenclcf-default_type.len;r-headers_out.content_typeclcf-default_type;returnNGX_OK;}2 目的ngx_http_set_content_type 是 Nginx 在发送 HTTP 响应前 自动设置 Content-Type 头部的核心函数。为什么 HTTP 响应需要 Content-Type HTTP 协议规定服务器返回的每一个响应都应当包含一个 Content-Type 头部 用于告诉客户端“响应体里是什么类型的数据”。 常见的值如 - text/htmlHTML 文档 - image/pngPNG 图片 - application/jsonJSON 数据 - application/octet-stream未知的二进制流 客户端浏览器、下载工具、代码库会根据这个头部决定如何处理响应体 渲染成网页、显示图片、启动下载还是交给某个应用程序。 如果没有这个头部客户端只能靠猜测行为可能不符合预期。 因此一个 Web 服务器必须能够为它返回的每个响应设置正确的 Content-Type。 ngx_http_set_content_type 就是 Nginx 用来完成这项工作的函数。总之ngx_http_set_content_type 的存在是为了 以高效、可配置且符合 HTTP 规范的方式 为每一个响应自动提供正确的媒体类型标识。 它是 Nginx 从“能传输字节”升级为“能正确服务内容”的关键一环。3 详解1 函数签名ngx_int_tngx_http_set_content_type(ngx_http_request_t*r)1. 返回值类型ngx_int_t 这个函数返回的不是 MIME 类型字符串或查找结果 而是一个 状态码用于向调用者报告函数的执行结果。 可能的返回值只有两种 NGX_OK表示函数执行成功。 此时响应的 Content-Type 头部已被正确设置无论是通过扩展名匹配找到的还是使用了默认类型。 NGX_ERROR 表示执行过程中出现了严重错误例如扩展名字符串转为小写时内存分配失败。 此时Content-Type 可能未被设置调用者应当终止当前请求的处理。 调用者通过检查返回值是否为 NGX_OK即可判断函数是否正常完成。2. 函数名ngx_http_set_content_type 函数名由下划线分隔的多个部分组成遵循 Nginx 的命名惯例 ngx 全局前缀表明这是 Nginx 源代码的一部分。 http 表明该函数属于 Nginx 的 HTTP 核心模块处理与 HTTP 协议相关的逻辑。 set 动词意为“设置、赋值”。这里指设置 HTTP 响应头部的某个字段。 content_type 直接对应 HTTP 响应头部中的 Content-Type 字段。 该字段用于告知客户端响应体中数据的媒体类型例如 text/html、image/png。 因此ngx_http_set_content_type 的完整含义是 在 HTTP 模块中根据请求信息如文件扩展名和配置 自动设置响应 Content-Type 头部的函数。3. 参数列表(ngx_http_request_t *r) 指向 当前 HTTP 请求的上下文结构体 它包含了 Nginx 处理一个 HTTP 请求所需的全部信息2 逻辑流程1 已设置检查 如果响应中已有 Content-Type由其他模块设置则保留它直接返回。 2 获取配置 拿到当前 location 下的核心配置 包含 MIME 类型映射表 (types_hash) 和默认类型 (default_type)。 3 扩展名匹配 如果请求有文件扩展名则尝试通过扩展名查找对应的 MIME 类型。 计算扩展名的哈希值 如果扩展名包含大写字母先将其转换为全小写同时得到哈希值 否则逐字符计算哈希。 4 查找 使用哈希值和可能转小写的扩展名在哈希表中查找。 如果找到将响应的 Content-Type 设置为该类型并返回。 5 默认回退 如果没有扩展名或查找失败使用配置中的 default_type 作为 Content-Type。 返回成功 整个设置过程结束后返回 NGX_OK出错时返回 NGX_ERROR。 这个函数的设计目的是自动且高效地为每个 HTTP 响应设置合适的 Content-Type 头部 从而让浏览器或客户端能够正确解析响应内容。 它将扩展名映射、大小写转换、哈希查找、默认值回退等逻辑集中实现 使得 Nginx 的其他部分无需关心这些细节。{u_char c,*exten;ngx_str_t*type;ngx_uint_ti,hash;ngx_http_core_loc_conf_t*clcf;声明局部变量1 已设置检查if(r-headers_out.content_type.len){returnNGX_OK;}检查是否已经设置过 Content-Type已设置则直接返回成功2 获取配置clcfngx_http_get_module_loc_conf(r,ngx_http_core_module);获取当前 location 的核心配置3 扩展名if(r-exten.len){检查请求是否有文件扩展名hash0;初始化哈希值为 0for(i0;ir-exten.len;i){cr-exten.data[i];开始遍历扩展名的每个字符if(cAcZ){extenngx_pnalloc(r-pool,r-exten.len);if(extenNULL){returnNGX_ERROR;}hashngx_hash_strlow(exten,r-exten.data,r-exten.len);r-exten.dataexten;break;}检查当前字符是否为大写字母为小写扩展名分配内存将扩展名转为小写并计算哈希值ngx_hash_strlow是 Nginx 的内部函数。它做两件事将源字符串r-exten.data的前r-exten.len个字节复制到目标缓冲区exten中同时将所有大写字母转换为小写字母。计算整个字符串的哈希值并返回这个哈希值。执行后exten缓冲区中存放了全小写的扩展名hash保存了对应的哈希值。这样后续查找时就可以使用小写字符串与哈希值。将扩展名字段更新为小写版本一旦进行了大小写转换并得到完整的哈希值就不需要继续遍历剩余的字符了因为ngx_hash_strlow已经处理了整个字符串。break立即退出for循环。hashngx_hash(hash,c);}果字符不是大写字母则累加哈希值4 查找typengx_hash_find(clcf-types_hash,hash,r-exten.data,r-exten.len);if(type){r-headers_out.content_type_lentype-len;r-headers_out.content_type*type;returnNGX_OK;}}在 MIME 类型哈希表中查找扩展名对应的类型ngx_hash_find是 Nginx 哈希表的查找函数。第一个参数clcf-types_hash指向配置中保存 MIME 类型映射的哈希表。这个哈希表的键是扩展名字符串小写值是对应的 MIME 类型字符串。第二个参数hash之前计算出的扩展名哈希值用于在哈希表中快速定位可能的桶。第三个参数r-exten.data扩展名字符串数据可能是原样如果无大写或者是刚转换的小写版本。第四个参数r-exten.len扩展名长度。该函数会在哈希表中搜索与给定键完全匹配的条目。如果找到返回指向该条目值的指针即 MIME 类型 ngx_str_t如果没找到返回 NULL。将返回值赋给 type 指针。检查是否找到匹配的类型如果 type 不为 NULL表示根据扩展名成功找到了对应的 MIME 类型设置 Content-Type 值的长度设置 Content-Type 值返回成功5 默认回退r-headers_out.content_type_lenclcf-default_type.len;r-headers_out.content_typeclcf-default_type;如果没有扩展名或者有扩展名但在哈希表中找不到匹配的类型程序会执行到这里接下来设置默认类型。设置 Content-Type 长度为默认类型的长度clcf-default_type是核心配置中default_type指令设定的值默认为 “text/plain”。这里将响应Content-Type的长度设置为默认类型的长度。设置 Content-Type 值为默认类型将响应的 Content-Type 值设置为默认类型的字符串。这样响应至少会有一个合理的 MIME 类型客户端可以据此处理响应体。returnNGX_OK;}返回成功最终返回NGX_OK表示函数执行成功。