mirror of
https://github.com/labstack/echo.git
synced 2025-11-25 22:32:23 +02:00
Fix DefaultBinder empty body handling for unknown ContentLength
Fix issue where POST requests with empty bodies and ContentLength=-1 (unknown/chunked encoding) incorrectly fail with 415 Unsupported Media Type. The DefaultBinder.BindBody method now properly detects truly empty bodies when ContentLength=-1 by peeking at the first byte. If no content is found, it returns early without error. If content exists, it reconstructs the body to preserve the original data. Fixes #2813 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
17
bind.go
17
bind.go
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"reflect"
|
||||
@@ -71,6 +72,22 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// For unknown ContentLength (-1), check if body is actually empty
|
||||
if req.ContentLength == -1 {
|
||||
// Peek at the first byte to see if there's any content
|
||||
var buf [1]byte
|
||||
n, readErr := req.Body.Read(buf[:])
|
||||
if readErr != nil && readErr != io.EOF {
|
||||
return NewHTTPError(http.StatusBadRequest, readErr.Error()).SetInternal(readErr)
|
||||
}
|
||||
if n == 0 {
|
||||
// Body is empty, return without error
|
||||
return
|
||||
}
|
||||
// There's content, put the byte back by creating a new reader
|
||||
req.Body = io.NopCloser(io.MultiReader(strings.NewReader(string(buf[:n])), req.Body))
|
||||
}
|
||||
|
||||
// mediatype is found like `mime.ParseMediaType()` does it
|
||||
base, _, _ := strings.Cut(req.Header.Get(HeaderContentType), ";")
|
||||
mediatype := strings.TrimSpace(base)
|
||||
|
||||
@@ -1082,6 +1082,14 @@ func TestDefaultBinder_BindBody(t *testing.T) {
|
||||
givenContent: strings.NewReader(""),
|
||||
expect: &Node{ID: 0, Node: ""},
|
||||
},
|
||||
{
|
||||
name: "ok, POST with empty body and ContentLength -1 (Issue #2813)",
|
||||
givenURL: "/api/real_node/endpoint?node=xxx",
|
||||
givenMethod: http.MethodPost,
|
||||
givenContent: strings.NewReader(""),
|
||||
whenChunkedBody: true, // This sets ContentLength to -1
|
||||
expect: &Node{ID: 0, Node: ""},
|
||||
},
|
||||
{
|
||||
name: "ok, JSON POST bind to struct with: path + query + chunked body",
|
||||
givenURL: "/api/real_node/endpoint?node=xxx",
|
||||
|
||||
Reference in New Issue
Block a user