KrakenD转发POST请求时请求体前出现额外数字的原因排查
问题描述
使用KrakenD作为API网关发送POST请求时,后端收到的请求体前多了一个数字。
示例请求:
curl -X POST -H "Content-Type: application/json" -d '{"username":"***","password":"***"}' http://127.0.0.1:8000/api/v1/token
后端收到的请求源:
b'POST /api/v1/token HTTP/1.1\r\nHost: host.docker.internal:8000\r\nUser-Agent: KrakenD Version 2.4.3\r\nTransfer-Encoding: chunked\r\nContent-Type: application/json\r\nX-Forwarded-For: 172.17.0.1\r\nX-Forwarded-Host: 127.0.0.1:8080\r\nAccept-Encoding: gzip\r\n\r\n' b'23\r\n{"username":"***","password":"***"}\r\n' b'0\r\n\r\n'
krakend.json配置:
{ "version": 3, "debug_endpoint": true, "endpoints": [ { "endpoint": "/api/v1/token", "method": "POST", "backend": [ { "url_pattern": "/api/v1/token", "method": "POST", "host": [ "http://host.docker.internal:8000" ] } ] } ] }
直接请求后端时不会出现该前置数字,请问通过KrakenD网关后出现该数字的原因是什么?
原因分析
这个前置数字是HTTP**分块传输编码(Chunked Transfer Encoding)**的一部分,并非KrakenD的异常,而是它默认使用分块编码向后端发送请求导致的。
从后端收到的请求头里能看到Transfer-Encoding: chunked字段,这代表请求体采用分块传输:
23是十六进制数字,对应后续数据块的字节长度(十进制为35,正好是{"username":"***","password":"***"}的字符数)- 数据块后的
\r\n是分块的分隔符 - 最后的
0\r\n\r\n表示分块传输结束
直接用curl请求后端时,curl会自动处理请求体编码,一般不会使用分块编码(除非请求体极大),所以后端看不到这个数字。如果后端没有正确实现分块编码的解析逻辑,就会把分块长度标识当成请求体的一部分。
要解决这个问题,可在KrakenD的后端配置中添加disable_chunked_encoding: true,强制关闭分块传输,修改后的配置如下:
{ "version": 3, "debug_endpoint": true, "endpoints": [ { "endpoint": "/api/v1/token", "method": "POST", "backend": [ { "url_pattern": "/api/v1/token", "method": "POST", "host": [ "http://host.docker.internal:8000" ], "disable_chunked_encoding": true } ] } ] }
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

