Spring Cloud Gateway 和 Webflux 请求参数非法字符处理
背景
业务接入一些投放,投放请求回调时候会调用我们的服务器,其中经过了 gateway。回调过来的时候,业务反映请求没有打到业务服务器,而是返回了 HTTP CODE 400,去 gateway 也没有任何异常,请求的链接类似于http://localhost:8080/test-like-this?a={{bbb}}
,于是开始排查。
原因
首先确认是 gateway 拦截的,因为层级没有到应用端,中间也没有任何链路了。
然后调试 java 代码进行复现,追着调用栈找到了在下列地方被拦截了,抛了java.net.URISyntaxException: Illegal character in query
异常,拦截原因是 url 有非法字符,其中{}
就是不按照 http 标准规范的非法字符。
经过分析,发现spring-freamwork
使用的ServerHttpRequest
做为请求的包装类,这个对象使用了java.lang.URI
这个对象作为暴漏和操作 Url 的主要手段。内部实现和解析query
都是使用的URI
这个对象。URI
创建的时候会效验传入的 url 是否合法,如果不合法的话就会抛异常。
spring-reactive
整个链路都是使用ServerHttpRequest
封装的请求,上面也可以看到,大概有 102 处引用(有一些注释很少)。所以说就只能接受合法参数了,除非你把代码上下游所有用到 URI 的地方都改了才行,这是难的,而且产出也不大,所以说无法透传原请求到后端了,webflux 底层也用的ServerHttpRequest
所以说是一样的。
解决方案
使用 Webflux 的项目和 spring-cloud-gateway 的项目,在 GET 请求的时候不能加非法字符,如果想处理带有非法字符的请求,只能服务端将非法字符转义,暂时没有其他方案。
类似问题.
spring 开了口子,可以实现WebServerFactoryCustomizer
在请求进来的时候先把请求的query encode
。
版权声明: 本文为 InfoQ 作者【a1vin-tian】的原创文章。
原文链接:【http://xie.infoq.cn/article/aadf2153bd44b2a7c97e31e18】。文章转载请联系作者。
评论