Apache瞎猫碰到死耗子(uri双//竞调用成功)

203 阅读1分钟

今天汪汪大队的帅汪分享一个有趣的事情。

事情的起因是这样的,我们要经常调用一个接口,以前使用的是Apache的CloseableHttpClient,但是现在出现逻辑问题(其实是我不会),需要用其他http工具进行替代,所以我选择了okhttp.

但是有意思的是,原先的接口使用Apache调用没问题,换成了okhttp就报Bad Requset了.

这让我很纳闷,然后就大量翻阅资料,找到了问题的原因,下面有请我(帅气又知识渊博)给大家分享一下:

请求的地址是:http://127.0.0.1//order/query

使用的是:httpclient-4.5.14.jar

原因:

image.png

从调用的地方进入execute方法。

image.png

然后一直往下,到InternalHttpClient类里面。

image.png

然后进入execChain的execute,选择ProtocolExec类。

image.png

在这里就能看到这边有一个方法,叫rewriteRequestURI,注释为:如果需要,重写请求URI,他的开关在 RequestConfig.setNormalizeUri(false)设置

image.png

这里在进入

image.png

这里就能看到有一个三目运算,如果没有设置RequestConfig.setNormalizeUri(false),则默认为true,所以这里会将 DROP_FRAGMENT_AND_NORMALIZE 传入rewirteURI方法

image.png

DROP_FRAGMENT_AND_NORMALIZE 这个枚举值为数组,有DROP_FRAGMENT和NORMALIZE

image.png

到这里就能看到,如果传过来的参数包含 NORMALIZE 这个枚举值,就会重新排序 PathSegments,而这个地方就进行了非空判断,如果//中间为空的话,就会remove掉。

这样就把请求地址的//给转化为了/。

image.png

这个地方就是三目运算的变量获取处。

image.png

从这里能看到创建的RequestConfig.normalizeUri为true,也就是默认重写URI

image.png

这样就可以关掉重写URI。

如果不想自己动手,我给大家写个hello world。

image.png

在这里就能看到,PathSegments重写后将//为空的给剔除掉,只保留/后有数据的值。