From 0368ed87f28eb07e7c5cca2dbff5585a019b4fa1 Mon Sep 17 00:00:00 2001 From: Masahiro Furudate <178inaba.git@gmail.com> Date: Wed, 11 Dec 2024 19:04:21 +0900 Subject: [PATCH] Add Conditions to Ensure Bind Succeeds with `Transfer-Encoding: chunked` (#2717) * Add conditions to ensure Bind succeeds with `Transfer-Encoding: chunked`. * Revert the ContentLength conditions for BindBody --- bind.go | 2 +- bind_test.go | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/bind.go b/bind.go index acc34650..ed7ca324 100644 --- a/bind.go +++ b/bind.go @@ -67,7 +67,7 @@ func (b *DefaultBinder) BindQueryParams(c Context, i interface{}) error { // See MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseMultipartForm func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) { req := c.Request() - if req.ContentLength <= 0 { + if req.ContentLength == 0 { return } diff --git a/bind_test.go b/bind_test.go index a7e8dbb3..303c8854 100644 --- a/bind_test.go +++ b/bind_test.go @@ -13,6 +13,7 @@ import ( "mime/multipart" "net/http" "net/http/httptest" + "net/http/httputil" "net/url" "reflect" "strconv" @@ -941,6 +942,7 @@ func TestDefaultBinder_BindBody(t *testing.T) { givenMethod string givenContentType string whenNoPathParams bool + whenChunkedBody bool whenBindTarget interface{} expect interface{} expectError string @@ -1061,12 +1063,30 @@ func TestDefaultBinder_BindBody(t *testing.T) { expectError: "code=415, message=Unsupported Media Type", }, { - name: "ok, JSON POST bind to struct with: path + query + http.NoBody", + name: "nok, JSON POST with http.NoBody", givenURL: "/api/real_node/endpoint?node=xxx", givenMethod: http.MethodPost, givenContentType: MIMEApplicationJSON, givenContent: http.NoBody, expect: &Node{ID: 0, Node: ""}, + expectError: "code=400, message=EOF, internal=EOF", + }, + { + name: "ok, JSON POST with empty body", + givenURL: "/api/real_node/endpoint?node=xxx", + givenMethod: http.MethodPost, + givenContentType: MIMEApplicationJSON, + givenContent: strings.NewReader(""), + expect: &Node{ID: 0, Node: ""}, + }, + { + name: "ok, JSON POST bind to struct with: path + query + chunked body", + givenURL: "/api/real_node/endpoint?node=xxx", + givenMethod: http.MethodPost, + givenContentType: MIMEApplicationJSON, + givenContent: httputil.NewChunkedReader(strings.NewReader("18\r\n" + `{"id": 1, "node": "zzz"}` + "\r\n0\r\n")), + whenChunkedBody: true, + expect: &Node{ID: 1, Node: "zzz"}, }, } @@ -1083,6 +1103,10 @@ func TestDefaultBinder_BindBody(t *testing.T) { case MIMEApplicationJSON: req.Header.Set(HeaderContentType, MIMEApplicationJSON) } + if tc.whenChunkedBody { + req.ContentLength = -1 + req.TransferEncoding = append(req.TransferEncoding, "chunked") + } rec := httptest.NewRecorder() c := e.NewContext(req, rec)