Skip to content

[Feature] Unified HTTP Request Body Size Limit #6604

@bladehan1

Description

@bladehan1

Problem Statement

  The current HTTP service layer of java-tron lacks a unified pre-ingress limit for request body size. The issues include: lack of early rejection; validation only occurs after the full request body is read (post-read validation); risk of memory amplification, where oversized requests consume memory even if ultimately rejected; scattered validation logic (e.g., JSON-RPC and broadcasthex use Util.checkBodySize, leading to inconsistent implementation and easy omission); inconsistency between HTTP and gRPC behavior (gRPC already has maxInboundMessageSize, while HTTP lacks an equivalent mechanism).

Proposed Solution

  Introduce a unified HTTP body pre-ingress limit at the Jetty layer to enable early rejection, align with gRPC limit strategies, and provide independent configuration capabilities for HTTP and JSON-RPC.

Specification

  Core mechanism: Introduce a SizeLimitHandler at the top of the Jetty handler chain, performing size checks during streaming (streaming enforcement). Requests exceeding the limit are rejected immediately without entering the application layer.
  Unified configuration: Introduce node.http.maxMessageSize and node.jsonrpc.maxMessageSize, which apply independently to HTTP and JSON-RPC respectively; gRPC continues to use node.rpc.maxMessageSize, and the three are independent of each other; the default values of the two new configuration items are set to 4 times node.rpc.maxMessageSize, as HTTP request bodies are generally 2–6 times larger than JSON-RPC, and the average is used here.
  Application layer adjustment: Remove body size validation responsibility from the application layer; retain Util.checkBodySize as deprecated for compatibility.

API Changes (if applicable)
  Requests exceeding the limit will uniformly return 413 Payload Too Large, no longer relying on application-layer handling.

Configuration Changes (if applicable)
  New configuration items: node.http.maxMessageSize, node.jsonrpc.maxMessageSize; node.rpc.maxMessageSize remains unchanged and is only used for gRPC.

Scope of Impact

Breaking Changes
  Requests exceeding the configured protocol limits (node.http.maxMessageSize or node.jsonrpc.maxMessageSize) will be rejected early (413), and calls relying on large request bodies will no longer be available; mitigation: adjust configurations or split requests.

Backward Compatibility
  Behavior is controlled independently per protocol configuration, allowing flexible operational tuning; Util.checkBodySize is temporarily retained (deprecated).

Implementation

Do you have ideas regarding the implementation?
  Implementation: Construct SizeLimitHandler in HttpService.start() or its subclass methods. Select the corresponding limit based on request path or entry type (HTTP uses node.http.maxMessageSize, JSON-RPC uses node.jsonrpc.maxMessageSize), and insert it at the very beginning of the handler chain; it must execute before servlet/filter, enforce streaming processing to avoid full buffering, and intercept at an early connection stage.

Are you willing to implement this feature?
  Yes.

Estimated Complexity
  Low → Medium, changes are concentrated at the HTTP ingress layer, involving multi-entry limit selection logic with controllable risk.

Testing Strategy

Test Scenarios
  Oversized requests: HTTP > node.http.maxMessageSize or JSON-RPC > node.jsonrpc.maxMessageSize → return 413, do not enter application layer, no significant memory growth; normal requests are unaffected; JSON-RPC is independently controlled by node.jsonrpc.maxMessageSize; stress test with continuous large requests to verify stable memory usage without amplification.

Performance Considerations
  Streaming-based enforcement avoids full loading, reduces memory allocation compared to application-layer validation, lowers GC pressure, and improves DoS resistance.

Alternatives Considered (Optional)

  Per-endpoint application-layer validation: high redundancy, easy to miss, cannot prevent memory amplification; Servlet Filter: executed too late, cannot intercept at the connection layer; single unified configuration: cannot satisfy independent governance requirements across different protocols.

Additional Context (Optional)

  Essentially ingress hardening: validate after read → reject before read, scattered logic → centralized control, application-layer fallback → container-layer protection; also enables independent governance boundaries across multiple protocols, improving DoS resistance and reducing operational and ecosystem communication costs.

Related Issues/PRs
  (To be added)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions