fix(rest/httpc): reject request body for HEAD method in buildRequest (#5457)

Co-authored-by: 1911860538 <alxps1911@gmail.com>
This commit is contained in:
Name
2026-03-28 22:16:53 +08:00
committed by GitHub
parent f59a1cb0de
commit 8c47c01739
3 changed files with 113 additions and 3 deletions

View File

@@ -84,8 +84,11 @@ func buildRequest(ctx context.Context, method, url string, data any) (*http.Requ
var reader io.Reader
jsonVars, hasJsonBody := val[jsonKey]
if hasJsonBody {
if method == http.MethodGet {
switch method {
case http.MethodGet:
return nil, ErrGetWithBody
case http.MethodHead:
return nil, ErrHeadWithBody
}
var buf bytes.Buffer

View File

@@ -229,3 +229,106 @@ func TestDo_WithClientHttpTrace(t *testing.T) {
assert.Nil(t, err)
assert.True(t, enter)
}
func TestBuildRequestWithBody(t *testing.T) {
testBody := struct {
Key string `json:"key"`
Value int `json:"value"`
}{
Key: "foo",
Value: 10,
}
testcases := []struct {
testName string
method string
url string
body any
wantedErr error
}{
{
testName: "GET Request with Body",
method: http.MethodGet,
url: "/ping",
body: testBody,
wantedErr: ErrGetWithBody,
},
{
testName: "GET Request without Body",
method: http.MethodGet,
url: "/ping",
body: nil,
wantedErr: nil,
},
{
testName: "HEAD Request with Body",
method: http.MethodHead,
url: "/ping",
body: testBody,
wantedErr: ErrHeadWithBody,
},
{
testName: "HEAD Request without Body",
method: http.MethodHead,
url: "/ping",
body: nil,
wantedErr: nil,
},
{
testName: "POST Request with Body",
method: http.MethodPost,
url: "/ping",
body: testBody,
wantedErr: nil,
},
{
testName: "PUT Request with Body",
method: http.MethodPut,
url: "/ping",
body: testBody,
wantedErr: nil,
},
{
testName: "PATCH Request with Body",
method: http.MethodPatch,
url: "/ping",
body: testBody,
wantedErr: nil,
},
{
testName: "DELETE Request with Body",
method: http.MethodDelete,
url: "/ping",
body: testBody,
wantedErr: nil,
},
{
testName: "CONNECT Request with Body",
method: http.MethodConnect,
url: "/ping",
body: testBody,
wantedErr: nil,
},
{
testName: "OPTIONS Request with Body",
method: http.MethodOptions,
url: "/ping",
body: testBody,
wantedErr: nil,
},
{
testName: "TRACE Request with Body",
method: http.MethodTrace,
url: "/ping",
body: testBody,
wantedErr: nil,
},
}
for _, tc := range testcases {
t.Run(tc.testName, func(t *testing.T) {
_, err := buildRequest(context.Background(), tc.method, tc.url, tc.body)
assert.Equal(t, tc.wantedErr, err)
})
}
}

View File

@@ -11,5 +11,9 @@ const (
colon = ':'
)
// ErrGetWithBody indicates that GET request with body.
var ErrGetWithBody = errors.New("HTTP GET should not have body")
var (
// ErrGetWithBody indicates that GET request with body.
ErrGetWithBody = errors.New("HTTP GET should not have body")
// ErrHeadWithBody indicates that HEAD request with body.
ErrHeadWithBody = errors.New("HTTP HEAD should not have body")
)