Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonRpcHttpService - Add BodyHandler limit size #5467

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 23.4.1

### Breaking Changes
- Add request content length limit for the JSON-RPC API (5MB) [#5467](https://github.com/hyperledger/besu/pull/5467)

### Additions and Improvements
- Set the retention policy for RocksDB log files to maintain only the logs from the last week [#5428](https://github.com/hyperledger/besu/pull/5428)
Expand Down
8 changes: 8 additions & 0 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,12 @@ static class JsonRPCHttpOptionGroup {
description =
"Specifies the maximum number of requests in a single RPC batch request via RPC. -1 specifies no limit (default: ${DEFAULT-VALUE})")
private final Integer rpcHttpMaxBatchSize = DEFAULT_HTTP_MAX_BATCH_SIZE;

@CommandLine.Option(
names = {"--rpc-http-max-request-content-length"},
paramLabel = MANDATORY_LONG_FORMAT_HELP,
description = "Specifies the maximum request content length. (default: ${DEFAULT-VALUE})")
private final Long rpcHttpMaxRequestContentLength = DEFAULT_MAX_REQUEST_CONTENT_LENGTH;
}

// JSON-RPC Websocket Options
Expand Down Expand Up @@ -2379,6 +2385,8 @@ && rpcHttpAuthenticationCredentialsFile() == null
jsonRpcConfiguration.setTlsConfiguration(rpcHttpTlsConfiguration());
jsonRpcConfiguration.setHttpTimeoutSec(unstableRPCOptions.getHttpTimeoutSec());
jsonRpcConfiguration.setMaxBatchSize(jsonRPCHttpOptionGroup.rpcHttpMaxBatchSize);
jsonRpcConfiguration.setMaxRequestContentLength(
jsonRPCHttpOptionGroup.rpcHttpMaxRequestContentLength);
return jsonRpcConfiguration;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ public interface DefaultCommandValues {
int DEFAULT_HTTP_MAX_CONNECTIONS = 80;
/** The constant DEFAULT_HTTP_MAX_BATCH_SIZE. */
int DEFAULT_HTTP_MAX_BATCH_SIZE = 1024;
/** The constant DEFAULT_MAX_REQUEST_CONTENT_LENGTH. */
long DEFAULT_MAX_REQUEST_CONTENT_LENGTH = 5 * 1024 * 1024; // 5MB
/** The constant DEFAULT_WS_MAX_CONNECTIONS. */
int DEFAULT_WS_MAX_CONNECTIONS = 80;
/** The constant DEFAULT_WS_MAX_FRAME_SIZE. */
Expand Down
16 changes: 16 additions & 0 deletions besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,22 @@ public void rpcHttpMaxBatchSizeOptionMustBeUsed() {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}

@Test
public void rpcHttpMaxRequestContentLengthOptionMustBeUsed() {
final int rpcHttpMaxRequestContentLength = 1;
parseCommand(
"--rpc-http-max-request-content-length", Long.toString(rpcHttpMaxRequestContentLength));

verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
verify(mockRunnerBuilder).build();

assertThat(jsonRpcConfigArgumentCaptor.getValue().getMaxRequestContentLength())
.isEqualTo(rpcHttpMaxRequestContentLength);

assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}

@Test
public void maxpeersSet_p2pPeerLowerBoundSet() {

Expand Down
1 change: 1 addition & 0 deletions besu/src/test/resources/everything_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ rpc-ws-authentication-jwt-algorithm="RS256"
rpc-http-tls-protocols=["TLSv1.2,TlSv1.1"]
rpc-http-tls-cipher-suites=["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"]
rpc-http-max-batch-size=1
rpc-http-max-request-content-length = 5242880
rpc-max-logs-range=100

# PRIVACY TLS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class JsonRpcConfiguration {
public static final int DEFAULT_ENGINE_JSON_RPC_PORT = 8551;
public static final int DEFAULT_MAX_ACTIVE_CONNECTIONS = 80;
public static final int DEFAULT_MAX_BATCH_SIZE = 1024;
public static final long DEFAULT_MAX_REQUEST_CONTENT_LENGTH = 5 * 1024 * 1024; // 5MB

private boolean enabled;
private int port;
Expand All @@ -53,6 +54,7 @@ public class JsonRpcConfiguration {
private long httpTimeoutSec = TimeoutOptions.defaultOptions().getTimeoutSeconds();
private int maxActiveConnections;
private int maxBatchSize;
private long maxRequestContentLength;

public static JsonRpcConfiguration createDefault() {
final JsonRpcConfiguration config = new JsonRpcConfiguration();
Expand All @@ -63,6 +65,7 @@ public static JsonRpcConfiguration createDefault() {
config.httpTimeoutSec = TimeoutOptions.defaultOptions().getTimeoutSeconds();
config.setMaxActiveConnections(DEFAULT_MAX_ACTIVE_CONNECTIONS);
config.setMaxBatchSize(DEFAULT_MAX_BATCH_SIZE);
config.setMaxRequestContentLength(DEFAULT_MAX_REQUEST_CONTENT_LENGTH);
return config;
}

Expand Down Expand Up @@ -263,4 +266,12 @@ public int getMaxBatchSize() {
public void setMaxBatchSize(final int maxBatchSize) {
this.maxBatchSize = maxBatchSize;
}

public long getMaxRequestContentLength() {
return maxRequestContentLength;
}

public void setMaxRequestContentLength(final long maxRequestContentLength) {
this.maxRequestContentLength = maxRequestContentLength;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ private Router buildRouter() {
.route()
.handler(
BodyHandler.create()
.setBodyLimit(config.getMaxRequestContentLength())
.setUploadsDirectory(dataDir.resolve("uploads").toString())
.setDeleteUploadedFilesOnEnd(true));
router.route("/").method(HttpMethod.GET).handler(this::handleEmptyRequest);
Expand Down