游戏迷提供最新游戏下载和手游攻略!

URL参数特殊字符影响下 Gateway 网关转发问题及解决策略

发布时间:2024-10-21浏览:53

响应400错误码的2种场景:

1.参数带空格,Gateway会误认为该空格是切割符,如?phone= 135****6862&type=44,不能正常解析协议,直接异常

一、问题分析

1.可用性<99的问题接口:

质量组反馈的可用性文档中,显示错误码(4xx)特别多,如下图

2.排查:

根据错误码匹配应用日志,未发现异常日志

根据错误码匹配Gateway网关日志,未发现异常日志

根据错误码匹配nginx日志,发现异常日志(基本都是响应400错误码)

{"clientip": "100.xxx.xxx.250","timestamp": "2024-01-03T00:52:10+08:00","request_method": "POST","response": "400","byte": "131","uri": "/api/xxx/xxx/smsCode","param": "phone= 135****6862&type=44","referrer": "-","agent": "Mozilla/5.0 (Linux; U; Android 4.4.1; zh-cn; R815T Build/JOP40D) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/4.5 Mobile Safari/533.1","httpx_for": "221.xx.xx.60","http_host": "domain.com","upstream_addr": "172.xxx.xxx.123:8280","request_time": "0.011","upstream_response_time": "0.010","ssl_protocol": "-"}

3.分析:

4.排查与复现:

问题复现测试用例

断点排查发现经过代码HttpObjectDecoder.splitInitialLine后将sb内容切割为一个3个元素的数组,切割规则中空格就是其中一个切割符。

注意:这里不能使用hutool http工具请求,因为会对url进行urlencode,无法复现效果

sb样本为:

GET http://localhost:8280/api/xxx/xxx/smsCode?phone= 135****6862 HTTP/1.1

数组样本为:

["GET","http://localhost:8280/api/xxx/xxx/smsCode?phone=","135****6862 HTTP/1.1"]

后续代码中取第三个元素‘135****6862 HTTP/1.1’作为http协议转换导致异常,所以响应400

二、解决方案

1.思路:

想办法改写HttpObjectDecoder.splitInitialLine的逻辑,上述情况数组样本为:

["GET","http://localhost:8280/api/xxx/xxx/smsCode?phone=135****6862","HTTP/1.1"]

2.实现:

经网络资料查询,可以通过以下代码在Netty ChannelPipeline中添加ChannelHandler

经源码分析,ChannelPipeline会有默认的http处理器NettyPipeline.HttpCodec(其实现类为HttpServerCodec),而HttpObjectDecoder.splitInitialLine的逻辑就是通过HttpServerCodec实现类来调用的

所以,想办法替换NettyPipeline.HttpCodec的实现类即可

将这3个类(Custom*)中用到HttpObjectDecoder、HttpRequestDecoder、HttpServerCodec的地方,全部修改为加Custom前缀的类,如

修改CustomHttpObjectDecoder.splitInitialLine的逻辑

核心思想:将sb按切割符切割出所有元素,数组组装逻辑改为取第一个、取最后一个、中间部分拼接在一起

sb样本为:

GET http://localhost:8280/api/xxx/xxx/smsCode?phone= 135****6862 HTTP/1.1

list样本为:

["GET","http://localhost:8280/api/xxx/xxx/smsCode?phone=","135****6862","HTTP/1.1"]

数组样本为:

["GET","http://localhost:8280/api/xxx/xxx/smsCode?phone=135****6862","HTTP/1.1"]

保险起见(非必要逻辑):

1)在异常情况下执行旧逻辑

2)增加开关控制(可通过apollo动态修改)

3.url带特殊字符处理:

某些情况下,参数带特殊字符,如下,Gateway也会响应400

http://localhost:8280/api/xxx/xxx/smsCode?phone=|135****6862

http://localhost:8280/api/xxx/xxx/smsCode?phone=?135****6862

解决方案是增加UrlParamHandler,获取url对其参数做urlencode

注意:hutool工具的URLUtil.encodeQuery会对一些RSA加密的+转换为空格,需要用URLUtil.encodeAll或者java原生java.net.URLEncoder,这2个又会把所有的路径参数、=、?之类的也转换,所以下面写了个复杂的逻辑去获取参数值,仅参数值做urlencode

怎么样?如果你觉得有用的话,还不快快收藏起来!!!

附:涉及的代码目录

github: https://github.com/897665787/springcloud-template

gitee:https://gitee.com/jq_di/springcloud-template

用户评论

不相忘

感觉这游戏的系统对URL参数处理得很不成熟啊。

    有6位网友表示赞同!

巴黎盛开的樱花

玩着玩着遇到这个问题,真心影响体验啊!

    有5位网友表示赞同!

别伤我i

特殊字符的处理是开发中常见的问题,希望他们能早点修复。

    有17位网友表示赞同!

入骨相思

我试了几个不同的链接,都是400错误,有点头大。

    有20位网友表示赞同!

来自火星的我

这个网关问题是不是很多人都有?我觉得应该上报官方。

    有10位网友表示赞同!

素衣青丝

游戏还没正式上线就出现这种问题,真让人担忧。

    有20位网友表示赞同!

烟花巷陌

有时候为了玩一下这个游戏的某个特殊模式,结果遇到这个问题...

    有11位网友表示赞同!

淡写薰衣草的香

不知道是因为服务器压力大还是编程缺陷,希望尽快解决。

    有15位网友表示赞同!

凉城°

我的好友组队进不去,都是因为这个网关转发失败的问题。

    有19位网友表示赞同!

热点资讯