案例分享-丢失的请求头

news/2024/10/1 15:17:40

 拍摄于富平中华郡
 

 

背景

今天组内一个小哥找我协助看一个问题,现象是他开放了一个Api给第三方调用,需要在http中传递一个名字为access_token的头,但是发布到测试环境以后却怎么也获取不到这个头,本地调试是没有问题的,希望协助看看。

排查

http传递头还会出问题,这都是很成熟的东西了,大概率是代码写的有问题。我提出看一眼代码,就一行request.getHeader,也不应该出问题,那是哪里出了问题呢?

“弄清楚请求链路,从外到内,从内到外逐个分析”。

冷静下来分析一番以后我觉得可能是请求链路上的其他节点没有正确传递access_token导致,所以我带着小哥大概梳理了一下请求链路,大致是这样(可能和真实的不同,只是按我了解到的):

浏览器->外网nginx->k8s ingress->springboot服务。

接下来就开始从内到外逐个逐个节点测试分析,找出元凶。

1.先进入springboot服务所属的容器内使用curl 127.0.0.1测试,等于自己访问自己,排除其他节点的干扰,结果是可以正常拿到access_token的值,排除代码问题

curl -H 'access_token: xxxx' http://127.0.0.1:8080/xxx

  

2.进入ingress的容器内依然是curl 127.0.0.1测试,这时的请求链路相当于curl->k8s ingress->springboot服务,目的是验证k8s ingress是否会影响请求头的传递。

#这里有个细节是多加了Host: 域名,至于为什么这里留个思考题
curl -H 'Host: 域名' -H 'access_token: xxxx' http://127.0.0.1:8080/xxx

 

3.以此类推测试&分析。

其实在做完第一步的时候我脑袋里突然闪过了答案(很久之前遇到过,一开始没想起来),后面的步骤就没有进行,写在这里只是想把自己排查这类问题的思路和大伙做一个交流,至于答案是什么我先卖个关子,我接下来先普及一个冷知识。

http请求头规范

https://www.rfc-editor.org/rfc/rfc9110.html#name-field-names

 

 

大概意思是请求头的名称应该是由字母(特指英文字母)、数字、- 组成,最好是以字母开头,还特别说了如果请求头包含_可能带来一些问题,有兴趣的可以去了解,这里就不啰嗦了。

真凶

到这里也许你已经发现了一些端倪,前面提到的access_token不正是包含_吗,从rfc文档来看这个头是不符合规范的,所以就在nginx那里翻了车,一起来看下官网的介绍。

https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers

 

解读下这段文字的意思:nginx会将带有_的请求头丢弃,不会往后传递,如果不希望丢弃可以修改underscores_in_headers的值为on或者将ignore_invalid_headers修改为off。

最终处理

1.梳理链路上的nginx,修改underscores_in_headers或者ignore_invalid_headers的值;

2.将access_token修改为access-token,使其符合规范;

最终采用方案2解决,原因很简单,修改请求链路上的参数影响较大,而且不一定能覆盖全,已知的有nginx,保不齐还有slb、iis、apache等,不可控因素太多。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/44998.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Mac常用sh文件

压缩多个文件夹到一个ZIP #!/bin/bash# 定义目标目录 target_dir="/Users/yuqiu/****/" output_dir="$target_dir/ZIPDIR"# 获取当前日期 current_date=$(date +"%Y-%m-%d")# 定义压缩文件名 zip_filename="XX_${current_date}.zip"# …

【线程基础】【七】UncaughtExceptionHandler 的使用

1 前言 我们平时在 Java 中处理异常的时候,通常的做法是使用try-catch-finally来包含代码块,但是Java自身还有一种方式可以处理就是使用UncaughtExceptionHandler,本节我们就来看看。 2 UncaughtExceptionHandler 2.1 认识 当 JVM 检测出某个线程由于未捕获的异常而终结的…

探索Semantic Kernel内置插件:深入了解ConversationSummaryPlugin的应用

前言 经过前几章的学习我们已经熟悉了Semantic Kernel 插件的概念,以及基于Prompts构造的Semantic Plugins和基于本地方法构建的Native Plugins。本章我们来讲解一下在Semantic Kernel 中内置的一些插件,让我们避免重复造轮子。 内置插件 Semantic Kernel 有非常多的预定义插…

攀登不止,华为数据库论文入选SIGMOD 2024,技术创新再谱新篇

继ICDE 17篇论文入选后,华为多篇论文再次入选SIGMOD 2024, 顶会入选论文已超过100篇。本文分享自华为云社区《攀登不止,华为数据库论文入选SIGMOD 2024,技术创新再谱新篇》,作者:GaussDB 数据库。 6月9日-14日,2024年数据管理国际会议SIGMOD(ACM SIGMOD/PODS Internati…

Rust性能分析之测试及火焰图,附(lru,lfu,arc)测试

好的测试用例及性能测试是对一个库的稳定及优秀的重要标准,尽量的覆盖全的单元测试,能及早的发现bug,使程序更稳定。性能测试,在编写代码后,单元测试及性能测试是重要的验收点,好的性能测试可以让我们提前发现程序中存在的问题。 测试用例 在Rust中,测试通常有两部分,一…

FreeRTOS简单内核实现7 阻塞链表

增加阻塞链表和溢出阻塞链表,完善 RTOS 内核调度流程0、思考与回答 0.1、思考一 如何处理进入阻塞状态的任务? 为了让 RTOS 支持多优先级,我们创建了多个就绪链表(数组形式),用每一个就绪链表表示一个优先级,对于阻塞状态的任务显然要从就绪链表中移除,但是阻塞状态的任…

零基础写框架(3): Serilog.NET 中的日志使用技巧

.NET 中的日志使用技巧 Serilog Serilog 是 .NET 社区中使用最广泛的日志框架,所以笔者使用一个小节单独讲解使用方法。 示例项目在 Demo2.Console 中。 创建一个控制台程序,引入两个包: Serilog.Sinks.Console Serilog.Sinks.File除此之外,还有 Serilog.Sinks.Elasticsear…