关于wireshark:自己能调通接口别人调不通

9次阅读

共计 2296 个字符,预计需要花费 6 分钟才能阅读完成。

原创:打码日记(微信公众号 ID:codelogs),欢送分享,转载请保留出处。

场景

有时咱们开发了一个 api 接口,本人调得好好的,接口文档也写好了,但他人调用时就是有问题,而当咱们调试时,发现申请基本没进来或进来了却取不到调用参数,该怎么告知对方调用姿态哪不对呢?

解决办法

对于编码老手,个别会和对方撕扯一会,而后甚至去 review 对方的代码,这样兴许能解决问题,但本人毕竟不相熟他人零碎的实现,消耗工夫较长。

另外 api 调用端可能因为封装形式不同或者加过一些拦截器,导致你看调用端的代码基本看不到什么问题,或者因为调用参数有一些不易分辨或不可见的特殊字符,让你无奈察觉到这里有问题。

其实这种问题,咱们从网络层登程,比照本人正确调用时的数据包与对方谬误调用时的数据包内容,以此来诊断问题所在更加高效,毕竟任何封装或拦截器的解决,最终都会反馈在底层的交互数据上。

这里,我应用 springmvc 开发一个简略的接口,如下:

@RestController
public class TestController {@RequestMapping(value = "/test",produces = MimeTypeUtils.TEXT_PLAIN_VALUE)
    @ResponseBody
    public String test(@RequestParam(name = "name") String name){return name;}
}

这个接口就是间接将 name 参数的值返回了,而后我应用 curl 模仿正确与谬误的调用形式,如下:

# 正确调用形式
$ curl http://localhost:8081/test --data-urlencode 'name=a+b'
a+b
#谬误调用形式
$ curl http://localhost:8081/test --data 'name=a+b' 
a b

假如调用方的代码实现的逻辑相似下面谬误的调用形式,传递 name 参数为 a +b,失去的却是 a b,接下来咱们来定位看看,谬误的调用办法问题在哪?

办法 1:应用 wireshark 抓包软件
关上 wireshark,先后抓包两次失常的以及不失常的申请数据,拿到申请数据后通过文本差别比照工具来比照。

  1. 如下为 wireshark 两次抓包后果,应用追踪流 -> TCP,查看 HTTP 申请数据
  2. 如下为正确的 HTTP 申请数据,其中红色为申请数据,蓝色为响应数据
  3. 如下为谬误的 HTTP 申请数据
  4. 比照申请数据差别

能够看出,一个申请 name 参数为 a%2Bb,一个申请 name 参数为 a +b,显然这是因为 name 参数值没有 url_encode 导致的。
另外或者你会奇怪,为啥谬误申请值为 a +b,为啥代码外面获取到的却是 a b?起因是 tomcat 接管到申请参数后,会做一次 url_decode,而 + 号会被 decode 为空格,java 的 URLDecoder.decode("a+b", "UTF-8") 也是如此。

办法 2:应用 socat 命令
在抓包工具无奈应用的状况下,能够尝试 socat 命令,应用 socat 命令来直达申请,调用端将申请先发给 socat,socat 再把申请转给服务端,如下:

# 应用 socat 直达申请
$ socat -v TCP4-LISTEN:8080,bind=0.0.0.0,reuseaddr,fork TCP4:localhost:8081

# 调用端拜访 socat 监听的 8080 端口
# 正确调用形式
$ curl http://localhost:8080/test --data-urlencode 'name=a+b'
a+b
# 谬误调用形式
$ curl http://localhost:8080/test --data 'name=a+b' 
a b

再去看 socat,会发现如下后果:

其中 socat 增加 - v 参数后,会主动将直达的数据流以明文显示进去,其中相似 > 2020/10/11 13:05:03.536294 length=162 from=0 to=161 之后的局部,就是申请数据,而相似 < 2020/10/11 13:05:03.740585 length=116 from=0 to=115 之后的局部,就是响应数据,同样的,你能够将两次申请数据复制到文本比照工具中去发现差别。

有时这种调用差别是特殊字符导致的,比方空白字符、零宽字符,下面的形式可能看不出差别,这时你能够将 - v 参数替换为 - x 参数,来比照数据的十六进制,同样的 wireshark 也能够查看数据包的十六进制,置信你摸索一下也能够找到。

触类旁通

此外,有些时候,咱们写的代码去查询数据库时,查不到数据,但咱们把 SQL 拿到数据库客户端工具中,却能够查到数据,这种问题极有可能是 SQL 被底层一些拦截器改写了,这时,咱们也能够应用下面的办法来确认,这里仅仅介绍应用 socat 的形式,如下,应用 socat 直达数据库连贯:

# 1. 直达数据库连贯
$ socat -v TCP4-LISTEN:3307,bind=0.0.0.0,reuseaddr,fork TCP4:localhost:3306 2>&1 | tee data.log
# 2. 而后咱们代码中连贯数据库的中央,将端口改成 3307,而后执行咱们的 SQL 查问

# 3. 查看实在发送给数据库的 SQL
cat data.log |grep -i 'select'

后果如下:

我置信到这一步,大略能发现 SQL 差别了,接下来就是找到底层批改 SQL 的代码在哪,以及如何处理了。

总结

遇到这种网络调用上的差别问题,多多思考应用 wireshark、socat、ncat 之类的网络工具来解决,置信问题解决效率会大大增加。

往期内容

还在胡乱设置连贯闲暇工夫?
应用 socat 批量操作多台机器

正文完
 0