一次使用自定义 Http Header 引发的血案
一次使用自定义 Http Header 引发的血案
起因
最近在整理我们产品的 OpenAPI Demo (Python、C#、Java),为使各语言 Demo 表现一致,使用同样的测试数据和同样的请求封装方式。
在 Python、C# 都特别顺利写完后,Java 遇到问题了:其中有一个接口返回 HTTP 400 错误,而其他接口都正常
环境
- JDK 1.8
- JAVA 调用接口使用 Apache HttpClient 4.2.1
排查
疑因1
由于 HTTP 400 Bad Request 很明显的是客户请求不满足服务端的要求,是客户端的问题,所以最先怀疑是客户端参数没传。
经过再三确认后,确认参数传递没有问题。
疑因2
排除疑因1后,有点陷入死局,不知如何下手。最后,有可能是请求通过 nginx 转发时,nginx 破坏了请求,导致应用服务器报 400.
于是,登录服务器,查看 Nginx 日志,发现请求没有被转发,如下图:

与正常的的请求相比,如下图:

未被转发的请求缺少了 Http Header : Host,也就是说错误的请求的 Host Header 被客户端丢弃,通过 Wireshark 抓包也确认是客户端的请求中没有 Host Header

疑因3
通过排除疑因2的过程,明确了问题出在请求调用方,而请求方式都是统一的封装接口,那么最有可能的原因就是请求的参数不一致导致。
于是,逐个去掉该请求的参数,发现其中一个 key 为 “productName”, value 为“测试修改产品名称” 的参数导致。将 value 改为其它值进行测试,发现没有问题,于是逐个去掉 value 的汉字,发现只要去掉“名”字就可测试通过。
这就奇了怪了,为什么有“名”字就测试不通过呢,又为什么其它语言能测试通过?!!!
思考。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
然后,对比有“名”字和无“名”字两次 wireshark 的抓包。


哇哇哇,为什么有“名”字的 Header 有换行
然后,将“名”字转换成 Unicode ,其值为 \u540d
然后对照 ASCCI 码表发现,发现 0D 表示“回车键”
至此就清楚了,请求封装的代码将请求数据也放到了 Header ,而恰巧“名”字导致了 Header 头不合规范,从而导致 Host Header 丢失。而对比其它语言的请求封装类,并没有将请求数据放到 Header 中,这也解释了其它语言为什么可以测试通过。
经查 OpenAPI 的协议文档,并没有要求将请求数据放到 Header,而当时为什么这么做了,也无从考查。。。。。。
总结
虽然这次问题解决了,但却花费了半天的时间,在排查问题的时候,还是要再细心一些,多抓包并仔细分析,多对比正常情况与异常情况的不同,可能会事半功倍。
谨记!!!
一次使用自定义 Http Header 引发的血案的更多相关文章
- 自定义 Preference Header 布局
1. Preference Header 概述: 对于什么是 Preference Header,以及何时使用 Preference Header,请参考我的另一篇博文: 何时使用 Preferenc ...
- iOS-AFNetworking封装Get(自定义HTTP Header)和Post请求及文件下载
前面提到AFNetworking是一个很强大的网络三方库,首先你需要引入AFNetworking三方库:如封装的有误还请指出,谢谢! 1.Get请求 /**Get请求 url 服务器请求地址 succ ...
- Vuejs中slot实现自定义组件header、footer等
Vuejs中slot实现自定义组件header.footer等 vue中的slot主要负责内容分发,之前有介绍过slot的内容,具体链接:http://www.cnblogs.com/vipzhou/ ...
- Nginx获取自定义头部header的值
http://blog.csdn.net/xbynet/article/details/51899286?_t=t http://shift-alt-ctrl.iteye.com/blog/23314 ...
- [WCF]缺少一行代码引发的血案
这是今天作项目支持的发现的一个关于WCF的问题,虽然最终我只是添加了一行代码就解决了这个问题,但是整个纠错过程是痛苦的,甚至最终发现这个问题都具有偶然性.具体来说,这是一个关于如何自动为服务接口(契约 ...
- 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器
1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...
- dubbox微服务实例及引发的“血案”
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...
- Integer.parseInt 引发的血案
Integer.parseInt 处理一个空字符串, 结果出错了, 程序没有注意到,搞了很久, 引发了血案啊!! 最后,终于 观察到了, 最后的部分: Caused by: java.lang.NoC ...
- Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)
<Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...
随机推荐
- 关于MYSQL安装踩的坑
前提:本人装的版本是mysql-8.0.18-winx64,win10系统,如果你安装的是其他版本的MYSQL,语法会跟下面有些许区别: 一,安装 https://dev.mysql.com/down ...
- Java判断指定日期是否为工作日
Java判断指定日期是否为工作日 转自:https://www.jianshu.com/p/966659492f2f 转:https://www.jianshu.com/p/05ccb5783f65转 ...
- php+lottery.js制作九宫格抽奖实例
php+lottery.js制作九宫格抽奖实例,本抽奖功能效果表现好,定制方便简单,新手学习跟直接拿来用都非常不错,兼容IE.火狐.谷歌等浏览器. 引入抽奖插件lottery.js <scrip ...
- with上下文管理 python魔法方法
with语法在Python里很常见, 主要的利好是使用代码更简洁. 常见的使用场景有: 1. 资源对象的获取与释放. 使用with可以简化try...finally ... 2. 在不修改函数代码的前 ...
- 如何编写正确且高效的 OpenResty 应用
本文内容,由我在 OpenResty Con 2018 上的同名演讲的演讲稿整理而来. PPT 可以在 这里 下载,因为内容比较多,我就不在这里一张张贴出来了.有些内容需要结合 PPT 才能理解,请多 ...
- 学生管理系统利用arrayList第二次优化
package StuManage; public class Student { private String name;//姓名 private String stuNum;//学号 privat ...
- aspose导出数据
注意 aspose合并单元格后设置单元格样式要一格一格的设置 public class InvoiceAsposeExcel { /// <summary> /// 导出数据 /// &l ...
- 服务端相关知识学习(五)之Zookeeper leader选举
在上一篇文章中我们大致浏览了zookeeper的启动过程,并且提到在Zookeeper的启动过程中leader选举是非常重要而且最复杂的一个环节.那么什么是leader选举呢?zookeeper为什么 ...
- vue2.0关于for循环 index的使用方法
<!DOCTYPE html> <html> <head> <title>for循环</title> </head> <b ...
- jdk中集成的jre和单独安装的jre有什么区别?
jdk 和 jre 是什么? 有什么区别? jre Jre 是java runtime environment, 是java程序的运行环境.既然是运行,当然要包含jvm,也就是大家熟悉的虚拟机啦,还有 ...