fix(mcp): enforce REST bridge body limit

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 07:39:19 +00:00
parent 6adf61e593
commit 27107cd75e
2 changed files with 44 additions and 0 deletions

View file

@ -3,6 +3,7 @@
package mcp
import (
"errors"
"net/http"
core "dappco.re/go/core"
@ -38,8 +39,16 @@ func BridgeToAPI(svc *Service, bridge *api.ToolBridge) {
bridge.Add(desc, func(c *gin.Context) {
var body []byte
if c.Request.Body != nil {
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxBodySize)
r := core.ReadAll(c.Request.Body)
if !r.OK {
if err, ok := r.Value.(error); ok {
var maxBytesErr *http.MaxBytesError
if errors.As(err, &maxBytesErr) || core.Contains(err.Error(), "request body too large") {
c.JSON(http.StatusRequestEntityTooLarge, api.Fail("request_too_large", "Request body exceeds 10 MB limit"))
return
}
}
c.JSON(http.StatusBadRequest, api.Fail("invalid_request", "Failed to read request body"))
return
}

View file

@ -169,6 +169,41 @@ func TestBridgeToAPI_Bad_InvalidJSON(t *testing.T) {
}
}
func TestBridgeToAPI_Bad_OversizedBody(t *testing.T) {
svc, err := New(Options{WorkspaceRoot: t.TempDir()})
if err != nil {
t.Fatal(err)
}
bridge := api.NewToolBridge("/tools")
BridgeToAPI(svc, bridge)
engine := gin.New()
rg := engine.Group(bridge.BasePath())
bridge.RegisterRoutes(rg)
body := strings.Repeat("a", maxBodySize+1)
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodPost, "/tools/file_read", strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
engine.ServeHTTP(w, req)
if w.Code != http.StatusRequestEntityTooLarge {
t.Fatalf("expected 413 for oversized body, got %d: %s", w.Code, w.Body.String())
}
var resp api.Response[any]
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if resp.Success {
t.Fatal("expected Success=false for oversized body")
}
if resp.Error == nil {
t.Fatal("expected error in response")
}
}
func TestBridgeToAPI_Good_EndToEnd(t *testing.T) {
svc, err := New(Options{WorkspaceRoot: t.TempDir()})
if err != nil {