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

ngx_http_gzip_header_filter

1 定义

ngx_http_gzip_header_filter 函数 定义在 src/http/modules/ngx_http_gzip_filter_module.c
staticngx_int_tngx_http_gzip_header_filter(ngx_http_request_t*r){ngx_table_elt_t*h;ngx_http_gzip_ctx_t*ctx;ngx_http_gzip_conf_t*conf;conf=ngx_http_get_module_loc_conf(r,ngx_http_gzip_filter_module);if(!conf->enable||(r->headers_out.status!=NGX_HTTP_OK&&r->headers_out.status!=NGX_HTTP_FORBIDDEN&&r->headers_out.status!=NGX_HTTP_NOT_FOUND)||(r->headers_out.content_encoding&&r->headers_out.content_encoding->value.len)||(r->headers_out.content_length_n!=-1&&r->headers_out.content_length_n<conf->min_length)||ngx_http_test_content_type(r,&conf->types)==NULL||r->header_only){returnngx_http_next_header_filter(r);}r->gzip_vary=1;#if(NGX_HTTP_DEGRADATION){ngx_http_core_loc_conf_t*clcf;clcf=ngx_http_get_module_loc_conf(r,ngx_http_core_module);if(clcf->gzip_disable_degradation&&ngx_http_degraded(r)){returnngx_http_next_header_filter(r);}}#endifif(!r->gzip_tested){if(ngx_http_gzip_ok(r)!=NGX_OK){returnngx_http_next_header_filter(r);}}elseif(!r->gzip_ok){returnngx_http_next_header_filter(r);}ctx=ngx_pcalloc(r->pool,sizeof(ngx_http_gzip_ctx_t));if(ctx==NULL){returnNGX_ERROR;}ngx_http_set_ctx(r,ctx,ngx_http_gzip_filter_module);ctx->request=r;ctx->buffering=(conf->postpone_gzipping!=0);ngx_http_gzip_filter_memory(r,ctx);h=ngx_list_push(&r->headers_out.headers);if(h==NULL){returnNGX_ERROR;}h->hash=1;h->next=NULL;ngx_str_set(&h->key,"Content-Encoding");ngx_str_set(&h->value,"gzip");r->headers_out.content_encoding=h;r->main_filter_need_in_memory=1;ngx_http_clear_content_length(r);ngx_http_clear_accept_ranges(r);ngx_http_weak_etag(r);returnngx_http_next_header_filter(r);}

2 目的

ngx_http_gzip_header_filter是 Nginx Gzip 压缩模块的头部过滤器。
它的设计目的和必要性紧密围绕 HTTP 内容压缩这一核心功能。


这个函数的核心任务是:
在响应头发送之前,决定是否对当前响应启用 Gzip 压缩。
如果启用,则做好所有的初始化和响应头修改工作,
为后续的响应体压缩(由ngx_http_gzip_body_filter完成)
准备好运行环境。


3 详解

1 函数签名

staticngx_int_tngx_http_gzip_header_filter(ngx_http_request_t*r)

1 返回值类型ngx_int_t

返回一个整数状态码,表示执行结果(NGX_OK 成功,NGX_ERROR 出错)。


2ngx_http_gzip_header_filter

函数名,表示 HTTP Gzip 模块的头部过滤器。


3ngx_http_request_t *r

参数r是指向当前 HTTP 请求结构体的指针,包含请求的所有信息。


2 逻辑流程

1 条件过滤 筛选掉不需要 gzip 压缩的请求 2 处理需要 gzip 压缩的请求

{ngx_table_elt_t*h;ngx_http_gzip_ctx_t*ctx;ngx_http_gzip_conf_t*conf;

局部变量声明


conf=ngx_http_get_module_loc_conf(r,ngx_http_gzip_filter_module);

获取 location 配置


1 条件过滤

if(!conf->enable||(r->headers_out.status!=NGX_HTTP_OK&&r->headers_out.status!=NGX_HTTP_FORBIDDEN&&r->headers_out.status!=NGX_HTTP_NOT_FOUND)||(r->headers_out.content_encoding&&r->headers_out.content_encoding->value.len)||(r->headers_out.content_length_n!=-1&&r->headers_out.content_length_n<conf->min_length)||ngx_http_test_content_type(r,&conf->types)==NULL||r->header_only){returnngx_http_next_header_filter(r);}

快速退出条件检查

只要任何一个条件为真,就不进行Gzip压缩,
直接调用下一个头部过滤器并返回。各条件详解:

!conf->enable:配置中gzip未开启(值为 off 或 0)。

(r->headers_out.status != NGX_HTTP_OK && ...)
响应状态码不是 200、403、404 之一。
Gzip只对少数成功或部分错误状态的响应体进行压缩,
避免浪费资源于无意义的响应(如 301 重定向没有响应体)。

(r->headers_out.content_encoding && r->headers_out.content_encoding->value.len)
响应头中已经存在Content-Encoding(例如上游已经压缩过),
不能再压缩,否则会损坏数据。

(r->headers_out.content_length_n != -1 && r->headers_out.content_length_n < conf->min_length)
如果 Content-Length 已知(不是 -1)且其值小于 min_length 配置(默认 20 字节),
压缩没有意义,还可能增大体积,跳过。

ngx_http_test_content_type(r, &conf->types) == NULL:响应的 Content-Type 不在 gzip_types 指定的类型列表中(默认只有 text/html)。

r->header_only
这是一个 HEAD 请求,只要求返回响应头,没有响应体,无需压缩。

这些检查在头部过滤器执行,此时响应状态码、内容长度、内容类型等均已确定,
因此能够准确判断。任何条件不满足,都会导致函数直接放行,开销极低。


2 处理需要 gzip 压缩的请求

r->gzip_vary=1;#if(NGX_HTTP_DEGRADATION){ngx_http_core_loc_conf_t*clcf;clcf=ngx_http_get_module_loc_conf(r,ngx_http_core_module);if(clcf->gzip_disable_degradation&&ngx_http_degraded(r)){returnngx_http_next_header_filter(r);}}#endifif(!r->gzip_tested){if(ngx_http_gzip_ok(r)!=NGX_OK){returnngx_http_next_header_filter(r);}}elseif(!r->gzip_ok){returnngx_http_next_header_filter(r);}ctx=ngx_pcalloc(r->pool,sizeof(ngx_http_gzip_ctx_t));if(ctx==NULL){returnNGX_ERROR;}ngx_http_set_ctx(r,ctx,ngx_http_gzip_filter_module);ctx->request=r;ctx->buffering=(conf->postpone_gzipping!=0);ngx_http_gzip_filter_memory(r,ctx);h=ngx_list_push(&r->headers_out.headers);if(h==NULL){returnNGX_ERROR;}h->hash=1;h->next=NULL;ngx_str_set(&h->key,"Content-Encoding");ngx_str_set(&h->value,"gzip");r->headers_out.content_encoding=h;r->main_filter_need_in_memory=1;ngx_http_clear_content_length(r);ngx_http_clear_accept_ranges(r);ngx_http_weak_etag(r);returnngx_http_next_header_filter(r);}
http://www.jsqmd.com/news/1165443/

相关文章:

  • Boson Netsim 思科路由器 OSPF 多区域配置:3 区域划分与 LSA 类型解析
  • 可灵AI NEXTGEN技术解析:多模态生成与推理优化实践指南
  • ATmega8 分立元件 125kHz RFID 阅读器:3 大核心电路模块与 15cm 读距实测
  • Cocos2d-x 4.0 Windows开发环境搭建与CocosUI入门实战
  • 华为视角C++实战:从语法到工程,构建高性能系统开发能力
  • 点对点接口开发6大核心痛点与集成平台式解决方案
  • Codex 桌面端第三方 API 暂无 GPT-5.6 选项?手动修改新旧会话模型的方法(附详细教程)
  • 男子在无空调室内干一天活,肾坏了!夏天干活的兄弟,别再拿命硬
  • STM32F407与ADS127L11高精度ADC信号采集方案
  • 2026年电钢琴选购指南:十款高性价比推荐(含三款派德拉)
  • 2026年7月最新徐州宝珀官方售后维修服务网点地址与客服电话 - 宝珀官方售后服务中心
  • 【小白也能轻松玩转龙虾】虾壳云一键部署文档 AI,表格自动处理 OpenClaw(附最新安装包)
  • 卡地亚中国官方售后服务中心|服务热线及门店详细地址权威信息通告(2026年7月更新) - 卡地亚官方售后中心
  • 2026 年当下,丽水比较好的耐候钢板树篦子批发厂家选哪家,别再用普通材料!这玩意儿如何让你的树篦子寿命翻倍? - 领域鉴赏官
  • 劳力士回收价格查询及各大回收平台实测排行(2026年7月最新) - 尊奢回收二奢平台
  • Kling AI视频生成模型:物理模拟与细节表现的技术解析
  • 2026年7月最新杭州雷达官方售后联系电话与客户服务中心网点地址 - 亨得利钟表维修中心
  • Hermes Desktop 安装与 DeepSeek 模型配置:新手一篇跑通
  • 3种 PWM 生成方案对比:MCU 硬件定时器 vs 软件模拟 vs 专用 IC
  • Gemma 4移动端部署实战:Android原生跑大模型全链路指南
  • 高精度数据采集系统设计与实现:基于ADS122U04与PIC18F46K20
  • 深海采矿 ROV 技术 2024:3类矿产(结核/SMS/结壳)的采掘系统与效率对比
  • Linux使用结构化命令
  • 2026年国内语音芯片行业供应商调研:3家长期合作靠谱语音芯片厂家推荐
  • 激光器长导通 1ms 驱动电路设计:电容储能方案解决 5V 电源 0.8m 线压降
  • SpaceXAI与Cursor合作:AI编程助手从辅助工具迈向核心生产力
  • SAP PI开发手册-ERP发布服务供外部系统调用(sproxy代理类)
  • Unity XR开发环境搭建:从导入包到多平台适配全攻略
  • Python AI数据分析实战:从环境搭建到机器学习项目完整指南
  • C++深度学习特征匹配库Light_Glue_CPP:原理、部署与性能优化实战