为了账号安全,请及时绑定邮箱和手机立即绑定

Go 的 http.MaxBytesReader,为什么要传入 writer?

Go 的 http.MaxBytesReader,为什么要传入 writer?

Go
Cats萌萌 2022-06-21 17:01:55
直观地说,我认为当您创建 MaxByteReader 并传入 http.ResponseWriter 时,它会为您写出状态代码。但事实并非如此,作者实际上在做什么?例子:func maxBytesMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        r.Body = http.MaxBytesReader(w, r.Body, 1)        next.ServeHTTP(w, r)    })}func mainHandler(w http.ResponseWriter, r *http.Request) {    var i interface{}    err := json.NewDecoder(r.Body).Decode(&i)    if err != nil {        fmt.Println(err.Error())    }}func TestMaxBytesMiddleware(t *testing.T) {    handlerToTest := maxBytesMiddleware(http.HandlerFunc(mainHandler))    req := httptest.NewRequest(http.MethodPost, "http://test.com", bytes.NewReader(json.RawMessage(`{"hello":"world"}`)))    recorder := httptest.NewRecorder()    handlerToTest.ServeHTTP(recorder, req)    if recorder.Result().StatusCode != http.StatusRequestEntityTooLarge {        t.Errorf("expected %d got %d", http.StatusRequestEntityTooLarge, recorder.Result().StatusCode)    }}但是当这个测试运行时,我得到了这个:http: request body too large--- FAIL: TestMaxBytesMiddleware (0.00s)    main_test.go:37: expected 413 got 200如果我想要我认为这个函数所做的所需功能,我需要将我的 mainHandler 更改为如下所示:func mainHandler(w http.ResponseWriter, r *http.Request) {    var i interface{}    err := json.NewDecoder(r.Body).Decode(&i)    if err != nil {        if err.Error() == "http: request body too large" {            w.WriteHeader(http.StatusRequestEntityTooLarge)            return        }        fmt.Println(err.Error())    }}那么那个作家到底是为了什么?
查看完整描述

1 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

如果 MaxBytesReader 在读取整个正文之前停止,它会在 writer 上设置一些标志,以确保在发送响应后关闭 HTTP 连接。通常服务器愿意从同一个连接中读取另一个请求(HTTP keepalive),但是如果前一个请求的未读位仍在管道中,它就不能这样做,所以它必须关闭连接,强制客户端如果要发送更多请求,则建立新连接。

这是使用私有requestTooLarge方法完成的http.ResponseWriter


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 496 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号