Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,67 @@ public void http2MaxConcurrentStreams() {
}
}

@Test(groups = { "unit" })
public void http2MaxFrameSizeInBytes() {
final String propName = "COSMOS.HTTP2_MAX_FRAME_SIZE_IN_KB";
final int defaultBytes = 64 * 1024;
final int minBytes = 64 * 1024;
final int maxBytes = 16_383 * 1024;

System.clearProperty(propName);

// Default (64 KB)
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(defaultBytes);

// Valid value at lower bound
System.setProperty(propName, "64");
try {
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(minBytes);
} finally {
System.clearProperty(propName);
}

// Valid value at upper bound (16383 KB)
System.setProperty(propName, "16383");
try {
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(maxBytes);
} finally {
System.clearProperty(propName);
}

// Valid value within range (1 MB)
System.setProperty(propName, "1024");
try {
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(1024 * 1024);
} finally {
System.clearProperty(propName);
}

// Below lower bound -> clamped up to 64 KB
System.setProperty(propName, "32");
try {
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(minBytes);
} finally {
System.clearProperty(propName);
}

// Above upper bound -> clamped down to 16383 KB
System.setProperty(propName, String.valueOf(32 * 1024));
try {
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(maxBytes);
} finally {
System.clearProperty(propName);
}

// Unparseable -> falls back to default
System.setProperty(propName, "not-a-number");
try {
assertThat(Configs.getHttp2MaxFrameSizeInBytes()).isEqualTo(defaultBytes);
} finally {
System.clearProperty(propName);
}
}

@Test(groups = { "emulator" })
public void thinClientEnabledTest() {
assertThat(isThinClientEnabled()).isFalse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,16 @@ public class Configs {
private static final String HTTP2_MAX_CONCURRENT_STREAMS = "COSMOS.HTTP2_MAX_CONCURRENT_STREAMS";
private static final String HTTP2_MAX_CONCURRENT_STREAMS_VARIABLE = "COSMOS_HTTP2_MAX_CONCURRENT_STREAMS";

// Config to indicate the SETTINGS_MAX_FRAME_SIZE advertised by the HTTP/2 client to the remote peer.
// The value is expressed in kilobytes (KB) and is clamped to [64 KB, 16383 KB] — the lower bound matches
// the SDK's historical default so users can only grow the frame size, and the upper bound is the
// largest whole-KB value below the HTTP/2 spec max (RFC 7540: 2^24 - 1 bytes).
private static final int MIN_HTTP2_MAX_FRAME_SIZE_IN_KB = 64; // 64 KB
private static final int MAX_HTTP2_MAX_FRAME_SIZE_IN_KB = 16_383; // 16383 KB
private static final int DEFAULT_HTTP2_MAX_FRAME_SIZE_IN_KB = 64; // 64 KB
private static final String HTTP2_MAX_FRAME_SIZE_IN_KB = "COSMOS.HTTP2_MAX_FRAME_SIZE_IN_KB";
private static final String HTTP2_MAX_FRAME_SIZE_IN_KB_VARIABLE = "COSMOS_HTTP2_MAX_FRAME_SIZE_IN_KB";

private static final boolean DEFAULT_IS_NON_PARSEABLE_DOCUMENT_LOGGING_ENABLED = false;
private static final String IS_NON_PARSEABLE_DOCUMENT_LOGGING_ENABLED = "COSMOS.IS_NON_PARSEABLE_DOCUMENT_LOGGING_ENABLED";
private static final String IS_NON_PARSEABLE_DOCUMENT_LOGGING_ENABLED_VARIABLE = "COSMOS_IS_NON_PARSEABLE_DOCUMENT_LOGGING_ENABLED";
Expand Down Expand Up @@ -1485,6 +1495,54 @@ public static int getHttp2MaxConcurrentStreams() {
return Integer.parseInt(http2MaxConcurrentStreams);
}

/**
* Returns the HTTP/2 SETTINGS_MAX_FRAME_SIZE to advertise to the remote peer, in bytes.
*
* The customer-facing configuration is expressed in kilobytes (KB) via system property
* {@code COSMOS.HTTP2_MAX_FRAME_SIZE_IN_KB} or environment variable
* {@code COSMOS_HTTP2_MAX_FRAME_SIZE_IN_KB}. Resolution order is system property, then environment
* variable, then the SDK default of 64 KB. The configured value is clamped to the inclusive range
* [64 KB, 16383 KB]; an unparseable or out-of-range value falls back to the default (or is clamped)
* and a warning is logged. The returned value is converted to bytes for downstream Netty
* consumption.
*/
public static int getHttp2MaxFrameSizeInBytes() {
String configuredValue = System.getProperty(
HTTP2_MAX_FRAME_SIZE_IN_KB,
firstNonNull(
emptyToNull(System.getenv().get(HTTP2_MAX_FRAME_SIZE_IN_KB_VARIABLE)),
String.valueOf(DEFAULT_HTTP2_MAX_FRAME_SIZE_IN_KB)));

int parsedInKb;
try {
parsedInKb = Integer.parseInt(configuredValue);
} catch (NumberFormatException ex) {
logger.warn(
"Invalid value '{}' for {} / {}; falling back to default {} KB.",
configuredValue,
HTTP2_MAX_FRAME_SIZE_IN_KB,
HTTP2_MAX_FRAME_SIZE_IN_KB_VARIABLE,
DEFAULT_HTTP2_MAX_FRAME_SIZE_IN_KB);
return DEFAULT_HTTP2_MAX_FRAME_SIZE_IN_KB * 1024;
}

if (parsedInKb < MIN_HTTP2_MAX_FRAME_SIZE_IN_KB || parsedInKb > MAX_HTTP2_MAX_FRAME_SIZE_IN_KB) {
int clampedInKb = Math.min(
MAX_HTTP2_MAX_FRAME_SIZE_IN_KB,
Math.max(MIN_HTTP2_MAX_FRAME_SIZE_IN_KB, parsedInKb));
logger.warn(
"Configured HTTP/2 max frame size {} KB is outside the allowed range [{}, {}] KB; "
+ "clamping to {} KB.",
parsedInKb,
MIN_HTTP2_MAX_FRAME_SIZE_IN_KB,
MAX_HTTP2_MAX_FRAME_SIZE_IN_KB,
clampedInKb);
return clampedInKb * 1024;
}

return parsedInKb * 1024;
}

public static boolean isEmulatorServerCertValidationDisabled() {
String certVerificationDisabledConfig = System.getProperty(
EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private void configureChannelPipelineHandlers() {
.protocol(HttpProtocol.H2, HttpProtocol.HTTP11)
.http2Settings(settings -> settings
.initialWindowSize(1024 * 1024) // 1MB initial window size
.maxFrameSize(64 * 1024) // 64KB max frame size
.maxFrameSize(Configs.getHttp2MaxFrameSizeInBytes()) // 64KB default; overridable via COSMOS.HTTP2_MAX_FRAME_SIZE_IN_KB / COSMOS_HTTP2_MAX_FRAME_SIZE_IN_KB (clamped to [64KB, 16383KB])
.maxConcurrentStreams(http2CfgAccessor().getEffectiveMaxConcurrentStreams(http2Cfg)) // Increased from default 30
)
.doOnConnected((connection -> {
Expand Down
Loading