新手 求助(关于net/http包request对象请求体内容解析字节丢失问题)

Septemberrrrrr · 2023-05-26 13:16:31 · 2076 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2023-05-26 13:16:31 的主题,其中的信息可能已经有所发展或是发生改变。

最近开始学习使用go,刚好公司有个需求,使用jir调用webhook后做一些操作,我使用go的http包新建了一个web服务,在获取请求体是遇到了一下问题: 使用

data, err := ioutil.ReadAll(r.Body)
if err != nil {
    fmt.Println("Error reading request body:", err)
    return
}

body := string(data)
fmt.Println("Request body:", body)

读取整个请求体(请求体为json格式),发现会少一两个字符,导致结果无法用json解析。 使用

bufReader := bufio.NewReader(r.Body)
defer r.Body.Close()

data := make([]byte, r.ContentLength)
_, err := bufReader.Read(data)
if err != nil {
    fmt.Println("Error reading request body:", err)
    return
}

body := string(data)
fmt.Println("Request body:", body)

请求体打印出出来直接少了很多内容。

不解应该从何方向入手。 PS:我也尝试使用python flask搭建一样的服务,收到的内容是正常的


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2076 次点击  
加入收藏 微博
7 回复  |  直到 2023-05-29 09:52:32
a984120978
a984120978 · #1 · 2年之前

data := make([]byte, r.ContentLength + 200) 解决

Septemberrrrrr
Septemberrrrrr · #2 · 2年之前

1楼 @a984120978

func webhook(w http.ResponseWriter, r *http.Request) {
    bufReader := bufio.NewReader(r.Body)
    defer r.Body.Close()

    data := make([]byte, r.ContentLength+200)
    n, err := bufReader.Read(data)
    fmt.Println("总长度为", r.ContentLength)
    fmt.Println("定义的buff长度", len(data))
    fmt.Println("读取的长度", n)
    if err != nil {
        fmt.Println("Error reading request body:", err)
        return
    }
}

输出:

总长度为 5900
定义的buff长度 6100
读取的长度 3759

我不理解,为什么实际读取的数据和ContentLength的长度不一致

GGXXLL
GGXXLL · #3 · 2年之前

r.ContentLength 是接口的 Response Header 返回的, 也就是 r.Header.Get("Content-Length"),由服务端决定。你可以看一下 net/http/transfer.go:523

看错了,以为是 http 请求响应的

zzustu
zzustu · #4 · 2年之前

如果服务端拿到的 ContentLength 是 5900,但是只读取了 3759 的字节,

  1. 可能是客户端未发送够 5900 个字节就关闭了连接

  2. 服务端的读取超时时间到了,客户端还没发送完毕。

看看 Go 服务端的 ReadTimeout 是不是设置短了。 https://github.com/golang/go/blob/f90b4cd6554f4f20280aa5229cf42650ed47221d/src/net/http/server.go#L2637-L2645

或者看看是不是客户端 WriteTimeout 设置太短了。

lxzan
lxzan · #5 · 2年之前

有没有可能, 客户端发送的数据不完整

zzustu
zzustu · #6 · 2年之前
lxzanlxzan #5 回复

有没有可能, 客户端发送的数据不完整

如果客户端发送的不完整,服务端会阻塞在 n, err := bufReader.Read(data) 这里,直至读取到完整字节,或者客户端关闭了,或者是 ReadTimeout 超时。UP 要贴上 err 的错误信息。如果读取的字节数不够 ContentLength,read 又没错误,那就奇了怪了

lxzan
lxzan · #7 · 2年之前
zzustuzzustu #6 回复

#5楼 @lxzan 如果客户端发送的不完整,服务端会阻塞在 `n, err := bufReader.Read(data)` 这里,直至读取到完整字节,或者客户端关闭了,或者是 `ReadTimeout` 超时。UP 要贴上 `err` 的错误信息。如果读取的字节数不够 `ContentLength`,read 又没错误,那就奇了怪了

我的意思是客户端发送的JSON数据格式有问题

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传