【线上问题】feign对get请求中⼤括号的处理
问题场景
url编码处理现在服务上⾯有⼀个get请求,这个请求⽐较特殊,他的URL⾥⾯有⼀个属性的值包含⼤括号。现在这个请求通过postman把⼤括号进⾏⼀次encode然后调⽤到⽹关是没问题的。但是如果在内⽹环境通过ribbon去调⽤的话我进⾏⼀次encode以后⽹关这边会报400,也就是Bad Request。
排查
1. 先确定⼀下这个请求是否到了⽹关
状态码为400的场景出现⽐较少,⼀般都会定性为⽹络问题,但是我们可以其他请求可以打过来,可以确定不是⽹络问题,但是⽹关没有任何⽇志输出,所以我们降低了⽹关输⼊⽇志的级别,发现在⽹关源码⾥⾯报错了,⽽且没有抛出来。但我们达到了⽬的,⾄少这个请求到了⽹关。
2. ⽹关收到的请求有什么不⼀样的
我们对⽐了Postman和ribbon请求的不同,发现ribbon请求的URL根本没有进⾏编码,那这个时候就怀疑是不是feign进⾏了⼀次解码操作,如果进⾏了⼀次解码操作我们进⾏两次编码即可,但是经过测试发现
两次编码以后他传到⽹关的时候,feign就不在进⾏解码操作了,这个时候就⽐较奇怪了,feign是如何知道编码⼀次还是两次呢?幸好可以本地调试,于是打上断点开始调试,最主要查看URL 是从什么时候发⽣改变的。
3. 定位解码位置
⾸先我们使⽤的feign的版本是8.18.0,最终定位到是在feign的RequestTemplate中的pullAnyQueriesOutOfUrl⽅法中
我们⾸先看到在548⾏,在这⾥queryLine⾥⾯存放了请求地址问号以后的请求参数,⽽parseAndDecodeQueries⽅法就是先对这些内容进⾏了⼀次解密操作,然后通过&符号进⾏切割得到⼀个map。接着在566⾏的时候他会把key和value放到⼀个全局的变量中,也就是queries。但是这⾥的query⽅法最终对调⽤到encodeIfNotVariable⽅法
我们可以看到如果value⾥⾯包含了⼤括号,他就不会进⾏再次编码了,这⾥就是我们上⾯现象的根本问题。
但是为什么要这么处理呢?我看到github上⾯也有好⼏个⼈提了这个问题,不过我看最新的版本依然没有修复。后来我看到⾥⾯有规定我们可以看到对于⼀些不安全字符是原封传递的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论