fix: pre-read bodies with unknown length

This commit is contained in:
MiMoCode
2026-07-10 19:36:49 +08:00
parent f27382c33a
commit 32988b6367
2 changed files with 25 additions and 1 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ import (
// readRequestBody 在转发前完整读取请求体,确保读取失败时不会向上游发送损坏请求。 // readRequestBody 在转发前完整读取请求体,确保读取失败时不会向上游发送损坏请求。
func readRequestBody(r *http.Request, max int64) (captured []byte, truncated bool, err error) { func readRequestBody(r *http.Request, max int64) (captured []byte, truncated bool, err error) {
if r.Body == nil || r.ContentLength == 0 { if r.Body == nil || r.Body == http.NoBody {
return nil, false, nil return nil, false, nil
} }
body, err := io.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
+24
View File
@@ -100,6 +100,30 @@ func TestRequestBodyReadFailureReturnsFixed400WithoutUpstream(t *testing.T) {
} }
} }
func TestRequestBodyReadFailureWithZeroContentLengthDoesNotReachUpstream(t *testing.T) {
var upstreamCalls atomic.Int32
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
upstreamCalls.Add(1)
w.WriteHeader(http.StatusOK)
}))
defer upstream.Close()
u, _ := url.Parse(upstream.URL)
h := newTestHandler(t, u, &captureSubmitter{}, proxy.Options{})
req := httptest.NewRequest(http.MethodPost, "http://proxy.test/v1/chat", nil)
req.Body = failingBody{err: errors.New("secret read failure")}
req.ContentLength = 0
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != http.StatusBadRequest || rec.Body.String() != "bad request\n" {
t.Fatalf("response=(%d, %q), want fixed 400 bad request", rec.Code, rec.Body.String())
}
if upstreamCalls.Load() != 0 {
t.Fatalf("upstream called %d times", upstreamCalls.Load())
}
}
func TestRequestBodyReadFailureAfterCaptureLimitDoesNotReachUpstream(t *testing.T) { func TestRequestBodyReadFailureAfterCaptureLimitDoesNotReachUpstream(t *testing.T) {
var upstreamCalls atomic.Int32 var upstreamCalls atomic.Int32
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {