Go';s http.MaxBytesReader,为什么传入writer?

Go';s http.MaxBytesReader,为什么传入writer?,http,go,Http,Go,直观地说,我认为当您创建一个MaxByterReader并传入http.ResponseWriter时,它会为您写出状态代码。但事实并非如此,作者究竟在做什么 例如: func maxBytesMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesRea

直观地说,我认为当您创建一个MaxByterReader并传入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())
    }
}

那么,这个writer到底是干什么的呢?

如果MaxBytesReader在读取整个正文之前停止,它会在writer上设置一些标志,确保在发送响应后关闭HTTP连接。通常情况下,服务器会愿意从同一个连接(HTTP keepalive)读取另一个请求,但如果管道中仍有前一个请求的未读位,则服务器无法读取,因此它必须关闭连接,如果客户端希望发送更多请求,则强制客户端建立新连接


这是通过使用http.ResponseWriter的private
requestTooLarge
方法实现的,这正是我想知道的,谢谢。我试着深入挖掘以找出答案,但运气不好。