背景
curl --location 'http://127.0.0.1:5555/album/enjoy/list' \
--header 'content-type: application/json' \
--header 'Authorization: Basic ZHJlYW1lX2FwcHYxOkFQXmR2QHpAU1FZVnhOODg=' \
--header 'Tenant-Id: 000000' \
--header 'Dreame-Auth: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJ6UTQwMTMxOTA4IiwiVXNlck5hbWUiOiIiLCJOaWNrTmFtZSI6IiIsIkVtYWlsIjoid2FuZ2t1bkBkcmVhbWUudGVjaCIsIkJ1ZmZlclRpbWUiOjg2NDAwLCJpc3MiOiJxbVBsdXMiLCJhdWQiOlsiR1ZBIl0sImV4cCI6MTcyMjgyMzkyMCwibmJmIjoxNzIyMjE5MTIwfQ.QxeLdiO2RDHKTaE8SuVG0zAj2yCPFplqJwMpd0F4mdE' \
--header 'Dreame-RLC: HICzcGYiZncM7QQKlxynIoLYEsIXq23r' \
--header 'Plan: B' \
--header 'dreame-api-sign: 981ccb65923b38ec2a93e6cdd344d38b' \
--header 'dreame-api-timestamp: 1722231686659' \
--header 'content-length: 102' \
--data '{
"ids":[6579],
"report_status":2,
"timestamp":"1722231686660",
"sign":"f09d2a383b9781e15274bdeddc47ceea"
}'
if c.Request.Body != nil {
bodyBytes, _ := io.ReadAll(c.Request.Body)
defer c.Request.Body.Close()
if len(bodyBytes) > 0 {
//err := json.Unmarshal(bodyBytes, &formParams)
d := json.NewDecoder(bytes.NewReader([]byte(bodyBytes)))
d.UseNumber()
err := d.Decode(&formParams)
if err != nil {
return "", err
}
}
// 创建新的reader,使用bytes.NewReader
// 恢复r.Body,以便可以多次读取
r.Body = io.NopCloser(bytes.NewReader(bodyBytes))
}
程序中有个地方需要读取body内容,打印bodyBytes的内容总是少了一截。接口还返回了unexpected EOF这个错误。之前遇到这个错误都是因为传参不是个json格式,用json在线工具验证了一下,是个正确的json格式。
问题定位
查了一下,程序中没有其他的地方执行了io.ReadAll(c.Request.Body)这个方法的地方,也不存在并发读取的情况。我把这个请求体拷贝到我的另一个程序中,没有出现读取出来的body内容被截断的情形。
这种情况可以说明传参是没有问题的,问题还是出在http底层获取body的地方。
把这个有问题的请求和调用我程序的请求对比,发现了一个不一样的地方,有问题的请求中多了一个头文件:content-length。
于是乎怀疑是这个头文件导致的。把这个头文件去掉,果然问题得以解决。
到net/http的源码中找了半天,没有找到这个逻辑。后续有时间再来寻找这个逻辑。
问题原因
确保HTTP请求头中的Content-Length
字段正确反映了请求体的长度。如果Content-Length
不正确,服务器可能无法读取完整的请求体。