首页 > 后端开发 > Golang > 为什么 `json.NewDecoder().Decode()` 不遵守 HTTP 上下文截止日期?

为什么 `json.NewDecoder().Decode()` 不遵守 HTTP 上下文截止日期?

Mary-Kate Olsen
发布: 2024-10-29 09:34:29
原创
741 人浏览过

Why doesn't `json.NewDecoder().Decode()` respect HTTP Context Deadlines?

HTTP 上下文截止日期被 json.NewDecoder().Decode() 忽略

问题:

当使用 context.WithTimeout 为 HTTP 请求建立时间限制时,ioutil.ReadAll 方法会在超过超时时中断请求并返回相应的错误。但是, json.NewDecoder(resp.Body).Decode 似乎忽略了截止日期,返回 nil 错误而不是 context.DeadlineExceeded。这是一个错误吗?

答案:

不,这不是一个错误。 net/http 包利用缓冲区来处理请求,因此有可能在程序读取响应正文之前将其部分或全部读入缓冲区。因此,过期的上下文不一定会阻止程序完成读取操作。

示例:

考虑一个故意延迟响应的修改后的 HTTP 测试服务器。当使用 readDoesntFail 时,服务器发送部分响应(10 个字节),刷新它,并等待 6 秒,然后发送剩余部分。

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    s := []byte(`{"ip":"12.34.56.78"}`)
    w.Write(s[:10])
    if f, ok := w.(http.Flusher); ok {
        f.Flush()
    }
    time.Sleep(time.Second * 6)
    w.Write(s[10:])}))
defer ts.Close()
登录后复制

在这种情况下,json.Decoder.Decode() 尝试读取由于数据尚未缓冲,因此无法连接。一旦上下文过期,从连接中进一步读取会触发 context.DeadlineExceeded 错误。

结论:

json.Decoder.Decode() 将遵守上下文截止时间数据尚未缓冲。然而,如果数据被部分或全部缓冲,则上下文截止时间可能不会阻止程序完成读取操作。建议使用 ioutil.ReadAll 或类似方法,以获得与上下文截止日期更一致的行为。

以上是为什么 `json.NewDecoder().Decode()` 不遵守 HTTP 上下文截止日期?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板