ngx_http_set_response_header阅读
1.关于设置头的一些函数指针初始化
typedef struct {ngx_str_t name;ngx_uint_t offset;// 本文中搜索 h[i].handler(r, &h[i], &value,就是回调函数执行的地方ngx_http_set_header_pt handler;
} ngx_http_set_header_t;static ngx_http_set_header_t ngx_http_set_headers[] = {{ ngx_string("Cache-Control"),offsetof(ngx_http_headers_out_t, cache_control),ngx_http_add_multi_header_lines },{ ngx_string("Link"),offsetof(ngx_http_headers_out_t, link),ngx_http_add_multi_header_lines },{ ngx_string("Last-Modified"),offsetof(ngx_http_headers_out_t, last_modified),ngx_http_set_last_modified },{ ngx_string("ETag"),offsetof(ngx_http_headers_out_t, etag),ngx_http_set_response_header },{ ngx_null_string, 0, NULL }
};
2.设置header的初始化函数
static char *
ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ngx_http_headers_conf_t *hcf = conf;ngx_str_t *value;ngx_uint_t i;ngx_array_t **headers; // 指向headers数组的指针ngx_http_header_val_t *hv; // headers数组中的元素ngx_http_set_header_t *set;ngx_http_compile_complex_value_t ccv; // 这个需要关注一下/*`ngx_http_compile_complex_value_t` 是一个结构体,它在Nginx的源代码中用于编译复杂的HTTP变量值。在Nginx配置文件中,可以使用变量来动态地生成或引用值。有时,变量的值需要通过一系列的操作、表达式或条件来计算。这时候就需要使用复杂的HTTP变量值。`ngx_http_compile_complex_value_t` 结构体定义了一个编译复杂HTTP变量值的上下文。通过该结构体,Nginx可以将配置文件中的变量值编译成可执行的代码,以便在实际处理请求时动态地计算变量的值。这个结构体的使用是在Nginx的模块开发中,当开发者需要在自定义模块中处理复杂的HTTP变量值时,可以使用该结构体进行编译和计算。总结起来,`ngx_http_compile_complex_value_t` 结构体用于编译复杂的HTTP变量值,以实现在Nginx的模块开发中对变量值的动态计算和处理。*/value = cf->args->elts; // 获取配置文件中的参数值headers = (ngx_array_t **) ((char *) hcf + cmd->offset); // 根据offset找到headers数组的指针if (*headers == NULL) {*headers = ngx_array_create(cf->pool, 1,sizeof(ngx_http_header_val_t)); // 如果headers数组为空,创建一个数组if (*headers == NULL) {return NGX_CONF_ERROR;}}hv = ngx_array_push(*headers); // 在headers数组中添加一个元素if (hv == NULL) {return NGX_CONF_ERROR;}hv->key = value[1]; // 设置headers元素的key值hv->handler = NULL;hv->offset = 0;hv->always = 0;if (headers == &hcf->headers) {hv->handler = ngx_http_add_header; // 如果是headers数组,设置handler为ngx_http_add_header函数set = ngx_http_set_headers;for (i = 0; set[i].name.len; i++) {if (ngx_strcasecmp(value[1].data, set[i].name.data) != 0) {continue;}hv->offset = set[i].offset; // 根据name值设置offset和handlerhv->handler = set[i].handler;break;}}if (value[2].len == 0) {ngx_memzero(&hv->value, sizeof(ngx_http_complex_value_t));} else {ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));ccv.cf = cf;ccv.value = &value[2];ccv.complex_value = &hv->value;if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {return NGX_CONF_ERROR;}}if (cf->args->nelts == 3) {return NGX_CONF_OK;}if (ngx_strcmp(value[3].data, "always") != 0) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"invalid parameter \"%V\"", &value[3]);return NGX_CONF_ERROR;}hv->always = 1; // 如果有第四个参数,将always设置为1return NGX_CONF_OK;
}
```该函数的作用是向Nginx配置中添加HTTP头部信息。
它会解析配置文件中的参数值,然后将这些值设置到相应的结构体中,
最终将结构体添加到headers数组中。
函数还会根据参数值设置相应的处理函数和偏移量,
以便在处理请求时使用。
如果配置中有第四个参数并且值为"always",则将always标志设置为1。
最后,根据处理结果返回相应的状态码。
3.ngx_http_set_response_header阅读理解
static ngx_int_t
ngx_http_set_response_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,ngx_str_t *value)
{ngx_table_elt_t *h, **old;// 获取要设置的响应头指针的地址old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);// 如果值的长度为0,则表示删除该响应头if (value->len == 0) {if (*old) {// 如果原来存在该响应头,则将其哈希值设为0,并将其指针置为空(*old)->hash = 0;*old = NULL;}return NGX_OK;}// 如果原来已经存在该响应头,则直接使用,否则创建一个新的响应头if (*old) {h = *old;} else {h = ngx_list_push(&r->headers_out.headers);if (h == NULL) {return NGX_ERROR;}*old = h;}h->hash = 1;h->key = hv->key;h->value = *value;return NGX_OK;
}这段代码是一个函数,用于设置HTTP响应头的值。
它接受一个HTTP请求结构体指针 `r`,
一个响应头结构体指针 `hv`,
和一个字符串指针 `value`。
函数首先通过偏移量找到要设置的响应头的指针地址。
然后,根据传入的 `value` 的长度,判断是否需要删除该响应头。
如果长度为0,则表示删除该响应头,将其哈希值设为0,并将其指针置为空。
如果长度不为0,则判断是否已经存在该响应头,
如果存在,则直接使用,否则创建一个新的响应头并将其加入到 `headers_out` 中。
最后,设置响应头的哈希值、键和值。函数返回 `NGX_OK` 表示成功,返回 `NGX_ERROR` 表示失败。
4.最终的执行是在ngx_http_headers_filter函数中
static ngx_int_t
ngx_http_headers_filter(ngx_http_request_t *r)
{// ...if (h[i].handler(r, &h[i], &value) != NGX_OK) {return NGX_ERROR;}// ...
}
5.ngx_array_t的定义
typedef struct {void *elts;ngx_uint_t nelts;size_t size;ngx_uint_t nalloc;ngx_pool_t *pool;
} ngx_array_t;
相关文章:
ngx_http_set_response_header阅读
1.关于设置头的一些函数指针初始化 typedef struct {ngx_str_t name;ngx_uint_t offset;// 本文中搜索 h[i].handler(r, &h[i], &value,就是回调函数执行的地方ngx_http_set_header_pt handler; } ngx_http_set_hea…...

词典查询工具django-mdict
什么是 django-mdict ? django-mdict 不是词典软件,是词典查询的脚本工具,主要目的是解决词典数量多,手机容量不足的问题,是对其他词典软件局域网在线查询功能的补充,是用 django 实现的 mdict 词典查询工具…...

Ubuntu20.04搭建RISC-V和qemu环境
1. 前言 risc-v是一个非常有潜力的指令集框架,最近对其产生了浓厚的兴趣,由于之前对于这方面的知识储备很少,在加上网上的教程都是点到为止,所以安装过程异常曲折。好在最后一步一步积累摸索,终于利用源码安装完成。看…...

代码生成器
Easycode Entity ##导入宏定义 $!{define.vm}##保存文件(宏定义) #save("/entity", ".java")##包路径(宏定义) #setPackageSuffix("entity")##自动导入包(全局变量) $!{au…...
AndroidMonitor - 基于AndroidLocalService实现的抓取OKHTTP请求的工具
官网 GitHub - lygttpod/AndroidMonitor: easy show android okhttp request data 项目简介 Demo下载体验 文章介绍---->Android抓包从未如此简单 切记:monitor需要配合monitor-plugin使用 1、monitor接入 添加依赖 debugImplementation io.github.lygttp…...
LuatOS-SOC接口文档(air780E)--nbiot - NB-IOT操作库
nbiot.isReady()# 网络是否就绪 参数 无 返回值 返回值类型 解释 boolean 已联网返回true,否则返回false 例子 -- 判断是否已经联网 if nbiot.isReady() then log.info("nbiot", "net is ready") endnbiot.imsi() 读取IMSI 参数 无 返回值 …...

大数据之LibrA数据库系统告警处理(ALM-12017 磁盘容量不足)
告警解释 系统每30秒周期性检测磁盘使用率,并把磁盘使用率和阈值相比较。磁盘使用率有一个默认阈值,当检测到磁盘使用率超过阈值时产生该告警。 平滑次数为1,主机磁盘某一分区使用率小于或等于阈值时,告警恢复;平滑次…...

Python算法例4 求平方根
1. 问题描述 实现int sqrt(int x)函数,计算并返回x的平方根。 2. 问题示例 sqrt(3)1;sqrt(4)2;sqrt(5)2;sqrt(17&#…...

LVGL_多界面切换
LVGL_多界面切换 1、创建多个界面(create_page1();) 2、加载一个界面显示(lv_scr_load(page1);) 3、切换不同界面显示(lv_scr_load_anim(page2, LV_SCR_LOAD_ANIM_OVER_LEFT, 300, 0, false);) static lv_…...

C/C++输出字符菱形 2021年3月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
目录 C/C输出字符菱形 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C输出字符菱形 2021年3月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 给定一个字符,用它构造一个对角线长…...

DI93a HESG440355R3 通过其Achilles级认证提供网络安全
DI93a HESG440355R3 通过其Achilles级认证提供网络安全 施耐德电气宣布推出Modicon M580以太网PAC (ePAC)自动化控制器,该控制器采用开放式以太网标准,通过其Achilles级认证提供网络安全。M580 ePAC使工厂操作员能够设计、实施和运行一个积极利用开放网…...
Go中Panic and Recover
什么是Panic? 在 Go 程序中处理异常情况的惯用方法是使用errors.。errors足以应对程序中出现的大多数异常情况。 **但有些情况下,程序在出现异常情况后无法继续执行。在这种情况下,我们使用panic提前终止程序。当函数遇到恐慌时,…...
webpack 与 grunt、gulp 的不同?
结论先行: Webpack、Grunt 和 Gulp 都是前端开发中常用的构建工具,但是 Webpack 是基于模块化打包的工具,并支持模块化开发。而 Grunt 和 Gulp 都是基于任务的构建工具,自动执行指定的任务,但不支持模块化开发。 1、相…...

园区网真实详细配置大全案例
实现要求: 1、只允许行政部电脑对全网telnet管理 2、所有dhcp都在核心 3、wifi用户只能上外网,不能访问局域网其它电脑 4、所有接入交换机上bpdu保护 5、只允许vlan 10-40上网 5、所有接入交换机开dhcp snoop 6、所有的交换机指定核心交换机为ntp时间服务…...
小程序video标签在底部出现1px无法去除的黑色线
问题描述 参见社区问题详情 此问题只会在ios手机真机中出现,视频底部出现1px无法去除的黑色线 解决方法 1.尝试过video各种配置,以为是设置参数导致 2.尝试过父元素设置height:200px;overflow:hidden;vi…...

渗透工具使用及思路总结(持续更新)
扫描类 nmap 快速扫描开放端口 nmap --min-rate 10000 -p- 10.129.252.63扫描详细全服务 nmap -sV -A -p 22,80 10.129.252.63 nmap -sV -A -p- 10.129.252.63-l:显示正在监听的 TCP 和 UDP 端口; -a:显示所有活动的 TCP 连接; -A <网络类型>或 - <网络类型&g…...

速卖通新卖家有必要测评吗?
大家都知道通过测评可以提升产品的转化率,提升产品的销量,那么做速卖通的卖家有必要测评吗? 测评就是类似于国内电商的补单,而一个类目里面竞争很大很卷的话,不去补销量来提升产品的权重,凭借着平台给的自…...

从lc114. 二叉树展开为链表到lc-LCR 155二叉搜索树转化为排序的双向链表
1 lc114. 二叉树展开为链表 1.1 描述 进阶:你可以使用原地算法(O(1) 额外空间)展开这棵树吗? 1.2 解法一: 先序遍历这棵树并且将节点加入到一个list中,随后按顺序将list中的每一个元素的left指针置换为…...

做读书笔记时的一个高效小技巧
你好,我是 EarlGrey,一名双语学习者,会一点编程,目前已翻译出版《Python 无师自通》、《Python 并行编程手册》等书籍。 在这里,我会持续和大家分享好书、好工具和高效生活、工作技巧,欢迎大家一起提升认知…...

Redis7.x 高级篇
Redis7.x 高级篇 Redis版本发行时间Redis单线程说的是什么东西 Redis版本发行时间 Redis单线程说的是什么东西...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...