From de887ab8a44a3fdf6bb8169ced838f73476aa670 Mon Sep 17 00:00:00 2001 From: RekCuy63 Date: Thu, 7 May 2026 11:33:01 +0800 Subject: [PATCH] cmd, node, rpc: make HTTP body limit configurable --- cmd/geth/main.go | 1 + cmd/utils/flags.go | 10 ++++++++++ node/api.go | 2 ++ node/config.go | 3 +++ node/defaults.go | 1 + node/node.go | 1 + node/rpcstack_test.go | 14 ++++++++++++++ rpc/http.go | 6 ++++-- 8 files changed, 36 insertions(+), 2 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index c8d7abc65b..a4ace0863d 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -193,6 +193,7 @@ var ( utils.AllowUnprotectedTxs, utils.BatchRequestLimit, utils.BatchResponseMaxSize, + utils.HTTPBodyLimitFlag, utils.RPCTxSyncDefaultTimeoutFlag, utils.RPCTxSyncMaxTimeoutFlag, utils.RPCGlobalRangeLimitFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index cc4c3bff5c..39ee1c7da1 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -850,6 +850,12 @@ var ( Value: node.DefaultConfig.BatchResponseMaxSize, Category: flags.APICategory, } + HTTPBodyLimitFlag = &cli.IntFlag{ + Name: "http.bodylimit", + Usage: "Maximum size of an HTTP RPC request body in bytes", + Value: node.DefaultConfig.HTTPBodyLimit, + Category: flags.APICategory, + } // Network Settings MaxPeersFlag = &cli.IntFlag{ @@ -1350,6 +1356,10 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) { if ctx.IsSet(BatchResponseMaxSize.Name) { cfg.BatchResponseMaxSize = ctx.Int(BatchResponseMaxSize.Name) } + + if ctx.IsSet(HTTPBodyLimitFlag.Name) { + cfg.HTTPBodyLimit = ctx.Int(HTTPBodyLimitFlag.Name) + } } // setGraphQL creates the GraphQL listener interface string from the set diff --git a/node/api.go b/node/api.go index e5dda5ac4d..5d066dce3d 100644 --- a/node/api.go +++ b/node/api.go @@ -181,6 +181,7 @@ func (api *adminAPI) StartHTTP(host *string, port *int, cors *string, apis *stri rpcEndpointConfig: rpcEndpointConfig{ batchItemLimit: api.node.config.BatchRequestLimit, batchResponseSizeLimit: api.node.config.BatchResponseMaxSize, + httpBodyLimit: api.node.config.HTTPBodyLimit, }, } if cors != nil { @@ -259,6 +260,7 @@ func (api *adminAPI) StartWS(host *string, port *int, allowedOrigins *string, ap rpcEndpointConfig: rpcEndpointConfig{ batchItemLimit: api.node.config.BatchRequestLimit, batchResponseSizeLimit: api.node.config.BatchResponseMaxSize, + httpBodyLimit: api.node.config.HTTPBodyLimit, }, } if apis != nil { diff --git a/node/config.go b/node/config.go index 255b0f0aa9..c0cd28cbf0 100644 --- a/node/config.go +++ b/node/config.go @@ -134,6 +134,9 @@ type Config struct { // interface. HTTPTimeouts rpc.HTTPTimeouts + // HTTPBodyLimit is the maximum size of an HTTP request body in bytes. + HTTPBodyLimit int `toml:",omitempty"` + // HTTPPathPrefix specifies a path prefix on which http-rpc is to be served. HTTPPathPrefix string `toml:",omitempty"` diff --git a/node/defaults.go b/node/defaults.go index 403a7f88a3..2cdc0d8091 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -63,6 +63,7 @@ var DefaultConfig = Config{ HTTPModules: []string{"net", "web3"}, HTTPVirtualHosts: []string{"localhost"}, HTTPTimeouts: rpc.DefaultHTTPTimeouts, + HTTPBodyLimit: rpc.DefaultHTTPBodyLimit, WSPort: DefaultWSPort, WSModules: []string{"net", "web3"}, BatchRequestLimit: 1000, diff --git a/node/node.go b/node/node.go index 01318881d4..7998b49670 100644 --- a/node/node.go +++ b/node/node.go @@ -395,6 +395,7 @@ func (n *Node) startRPC() error { rpcConfig := rpcEndpointConfig{ batchItemLimit: n.config.BatchRequestLimit, batchResponseSizeLimit: n.config.BatchResponseMaxSize, + httpBodyLimit: n.config.HTTPBodyLimit, } initHttp := func(server *httpServer, port int) error { diff --git a/node/rpcstack_test.go b/node/rpcstack_test.go index bd75dac4eb..e2e1099342 100644 --- a/node/rpcstack_test.go +++ b/node/rpcstack_test.go @@ -324,6 +324,20 @@ func baseRpcRequest(t *testing.T, url, bodyStr string, extraHeaders ...string) * return resp } +func TestHTTPBodyLimit(t *testing.T) { + body := `{"jsonrpc":"2.0","id":1,"method":"rpc_modules","params":[]}` + cfg := &httpConfig{ + rpcEndpointConfig: rpcEndpointConfig{ + httpBodyLimit: len(body) - 1, + }, + } + srv := createAndStartServer(t, cfg, false, &wsConfig{}, nil) + defer srv.stop() + + resp := baseRpcRequest(t, "http://"+srv.listenAddr(), body) + assert.Equal(t, http.StatusRequestEntityTooLarge, resp.StatusCode) +} + type testClaim map[string]interface{} func (testClaim) Valid() error { diff --git a/rpc/http.go b/rpc/http.go index 55f0abfa72..70928cb432 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -36,8 +36,10 @@ import ( ) const ( - defaultBodyLimit = 5 * 1024 * 1024 - contentType = "application/json" + // DefaultHTTPBodyLimit is the default maximum size of an HTTP request body. + DefaultHTTPBodyLimit = 5 * 1024 * 1024 + defaultBodyLimit = DefaultHTTPBodyLimit + contentType = "application/json" ) // https://www.jsonrpc.org/historical/json-rpc-over-http.html#id13