• 【线上问题】feign对get请求中大括号的处理


    问题场景

    现在服务上面有一个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上面也有好几个人提了这个问题,不过我看最新的版本依然没有修复。后来我看到RFC6570里面有规定

      我们可以看到对于一些不安全字符是原封传递的。

  • 相关阅读:
    微软解决方案框架MSF4.0的预发布版本支持敏捷过程了
    Jackson 框架,轻易转换JSON
    [ lucene扩展 ] Spelling Checker using Lucene
    [ solr扩展 ] Solr Spellchecker internals (now with tests!)
    [ lucene扩展 ] An Introduction to Apache Lucene for FullText Search
    linux中 jdk 的卸载和安装[转]
    hadoop入门之单机版环境搭建[转]
    Redhat上两台服务器建立SSH信任关系[转]
    MYSQL常用命令[转]
    linux下vi命令大全
  • 原文地址:https://www.cnblogs.com/colin-xun/p/14273406.html
Copyright © 2020-2023  润新知