diff --git a/ballerina/http_client_config.bal b/ballerina/http_client_config.bal index c94f3b53b7..c427cd87bf 100644 --- a/ballerina/http_client_config.bal +++ b/ballerina/http_client_config.bal @@ -62,8 +62,10 @@ public type ResponseLimitConfigs record {| # Provides settings related to HTTP/2 protocol. # # + http2PriorKnowledge - Configuration to enable HTTP/2 prior knowledge +# + http2InitialWindowSize - Configuration to change the initial window size public type ClientHttp2Settings record {| boolean http2PriorKnowledge = false; + int http2InitialWindowSize = 65535; |}; # Provides configurations for controlling the retrying behavior in failure scenarios. diff --git a/ballerina/http_service_endpoint.bal b/ballerina/http_service_endpoint.bal index 7596b4b2ec..0dcff0b7b8 100644 --- a/ballerina/http_service_endpoint.bal +++ b/ballerina/http_service_endpoint.bal @@ -154,6 +154,7 @@ public type Local record {| # + interceptors - An array of interceptor services # + gracefulStopTimeout - Grace period of time in seconds for listener gracefulStop # + socketConfig - Provides settings related to server socket configuration +# + http2InitialWindowSize - Configuration to change the initial window size in HTTP/2 public type ListenerConfiguration record {| string host = "0.0.0.0"; ListenerHttp1Settings http1Settings = {}; @@ -165,6 +166,7 @@ public type ListenerConfiguration record {| Interceptor|Interceptor[] interceptors?; decimal gracefulStopTimeout = DEFAULT_GRACEFULSTOP_TIMEOUT; ServerSocketConfig socketConfig = {}; + int http2InitialWindowSize = 65535; |}; # Provides a set of cloneable configurations for HTTP listener. diff --git a/changelog.md b/changelog.md index f140986535..843c7f800a 100644 --- a/changelog.md +++ b/changelog.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - [Add runtime support for type referenced type in path parameters](https://github.com/ballerina-platform/ballerina-standard-library/issues/4372) - [Add finite type support for query, header and path parameters](https://github.com/ballerina-platform/ballerina-standard-library/issues/4374) - [Support for service level interceptors using `http:InterceptableService`](https://github.com/ballerina-platform/ballerina-standard-library/issues/4401) +- [Allow changing initial window size value for client and the server](https://github.com/ballerina-platform/ballerina-standard-library/issues/490) ### Changed diff --git a/docs/spec/spec.md b/docs/spec/spec.md index b88ee4ca68..ccbcfb4ef7 100644 --- a/docs/spec/spec.md +++ b/docs/spec/spec.md @@ -162,6 +162,7 @@ public type ListenerConfiguration record {| string? server = (); RequestLimitConfigs requestLimits = {}; Interceptor|Interceptor[] interceptors?; + int http2InitialWindowSize = 65535; |}; ``` @@ -1087,6 +1088,18 @@ public type ClientConfiguration record {| ProxyConfig? proxy = (); boolean validation = true; |}; + +public type ClientHttp1Settings record {| + KeepAlive keepAlive = KEEPALIVE_AUTO; + Chunking chunking = CHUNKING_AUTO; + ProxyConfig? proxy = (); +|}; + +public type ClientHttp2Settings record {| + boolean http2PriorKnowledge = false; + int http2InitialWindowSize = 65535; +|}; + ``` Based on the config, the client object will be accompanied by following client behaviours. Following clients cannot be diff --git a/native/spotbugs-exclude.xml b/native/spotbugs-exclude.xml index 533d717970..1f870b31da 100644 --- a/native/spotbugs-exclude.xml +++ b/native/spotbugs-exclude.xml @@ -76,4 +76,8 @@ + + + + diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpConstants.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpConstants.java index f37cebc362..6a132b7d3f 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpConstants.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpConstants.java @@ -415,6 +415,8 @@ public class HttpConstants { public static final BString ENDPOINT_CONFIG_VERSION = StringUtils.fromString("httpVersion"); public static final String ENDPOINT_REQUEST_LIMITS = "requestLimits"; public static final BString ENDPOINT_CONFIG_GRACEFUL_STOP_TIMEOUT = StringUtils.fromString("gracefulStopTimeout"); + public static final BString ENDPOINT_CONFIG_HTTP2_INITIAL_WINDOW_SIZE = StringUtils + .fromString("http2InitialWindowSize"); public static final BString MAX_URI_LENGTH = StringUtils.fromString("maxUriLength"); public static final BString MAX_STATUS_LINE_LENGTH = StringUtils.fromString("maxStatusLineLength"); @@ -486,6 +488,8 @@ public class HttpConstants { public static final BString HTTP2_SETTINGS = StringUtils.fromString("http2Settings"); public static final BString REQUEST_LIMITS = StringUtils.fromString("requestLimits"); public static final BString RESPONSE_LIMITS = StringUtils.fromString("responseLimits"); + public static final BString CLIENT_EP_HTTP2_INITIAL_WINDOW_SIZE = StringUtils + .fromString("http2InitialWindowSize"); //Connection Throttling field names public static final String CONNECTION_THROTTLING_STRUCT_REFERENCE = "connectionThrottling"; diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/HttpUtil.java b/native/src/main/java/io/ballerina/stdlib/http/api/HttpUtil.java index 4277c277b6..aed668b5a5 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/HttpUtil.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/HttpUtil.java @@ -130,6 +130,7 @@ import static io.ballerina.runtime.observability.ObservabilityConstants.TAG_KEY_PEER_ADDRESS; import static io.ballerina.stdlib.http.api.HttpConstants.ANN_CONFIG_ATTR_COMPRESSION_CONTENT_TYPES; import static io.ballerina.stdlib.http.api.HttpConstants.ANN_CONFIG_ATTR_SSL_ENABLED_PROTOCOLS; +import static io.ballerina.stdlib.http.api.HttpConstants.ENDPOINT_CONFIG_HTTP2_INITIAL_WINDOW_SIZE; import static io.ballerina.stdlib.http.api.HttpConstants.HTTP_HEADERS; import static io.ballerina.stdlib.http.api.HttpConstants.RESOLVED_REQUESTED_URI; import static io.ballerina.stdlib.http.api.HttpConstants.RESPONSE_CACHE_CONTROL; @@ -1554,6 +1555,8 @@ public static ListenerConfiguration getListenerConfig(long port, BMap endpointCo } listenerConfiguration.setPipeliningEnabled(true); //Pipelining is enabled all the time + listenerConfiguration.setHttp2InitialWindowSize(endpointConfig + .getIntValue(ENDPOINT_CONFIG_HTTP2_INITIAL_WINDOW_SIZE).intValue()); return listenerConfiguration; } diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/endpoint/CreateSimpleHttpClient.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/endpoint/CreateSimpleHttpClient.java index f65a9d72f3..a22b0ca0fd 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/endpoint/CreateSimpleHttpClient.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/endpoint/CreateSimpleHttpClient.java @@ -35,6 +35,7 @@ import java.net.URL; import java.util.Map; +import static io.ballerina.stdlib.http.api.HttpConstants.CLIENT_EP_HTTP2_INITIAL_WINDOW_SIZE; import static io.ballerina.stdlib.http.api.HttpConstants.HTTP2_PRIOR_KNOWLEDGE; import static io.ballerina.stdlib.http.api.HttpConstants.SOCKET_CONFIG_CONNECT_TIMEOUT; import static io.ballerina.stdlib.http.api.HttpConstants.SOCKET_CONFIG_KEEP_ALIVE; @@ -100,6 +101,8 @@ public static Object createSimpleHttpClient(BObject httpClient, BMap globalPoolC get(HttpConstants.HTTP2_SETTINGS); boolean http2PriorKnowledge = (boolean) http2Settings.get(HTTP2_PRIOR_KNOWLEDGE); senderConfiguration.setForceHttp2(http2PriorKnowledge); + senderConfiguration.setHttp2InitialWindowSize(http2Settings + .getIntValue(CLIENT_EP_HTTP2_INITIAL_WINDOW_SIZE).intValue()); } else { BMap http1Settings = (BMap) clientEndpointConfig.get( HttpConstants.HTTP1_SETTINGS); diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/ListenerConfiguration.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/ListenerConfiguration.java index 0c80f6db81..53d4c885df 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/ListenerConfiguration.java +++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/ListenerConfiguration.java @@ -63,6 +63,7 @@ public static ListenerConfiguration getDefault() { private boolean tcpNoDelay; private boolean socketReuse; private boolean socketKeepAlive; + private int http2InitialWindowSize = 65535; public ListenerConfiguration() { } @@ -273,4 +274,12 @@ public boolean isSocketKeepAlive() { public void setSocketKeepAlive(boolean keepAlive) { this.socketKeepAlive = keepAlive; } + + public int getHttp2InitialWindowSize() { + return http2InitialWindowSize; + } + + public void setHttp2InitialWindowSize(int http2InitialWindowSize) { + this.http2InitialWindowSize = http2InitialWindowSize; + } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/SenderConfiguration.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/SenderConfiguration.java index 2b89a99386..9c6b41022b 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/SenderConfiguration.java +++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contract/config/SenderConfiguration.java @@ -55,6 +55,7 @@ public static SenderConfiguration getDefault() { private boolean tcpNoDelay = true; private boolean socketReuse = false; private boolean socketKeepAlive = true; + private int http2InitialWindowSize = 65535; public SenderConfiguration() { this.poolConfiguration = new PoolConfiguration(); @@ -205,4 +206,12 @@ public boolean isSocketKeepAlive() { public void setSocketKeepAlive(boolean socketKeepAlive) { this.socketKeepAlive = socketKeepAlive; } + + public int getHttp2InitialWindowSize() { + return http2InitialWindowSize; + } + + public void setHttp2InitialWindowSize(int http2InitialWindowSize) { + this.http2InitialWindowSize = http2InitialWindowSize; + } } diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/DefaultHttpWsConnectorFactory.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/DefaultHttpWsConnectorFactory.java index bca7825d7d..146e78ed62 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/DefaultHttpWsConnectorFactory.java +++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/DefaultHttpWsConnectorFactory.java @@ -90,6 +90,7 @@ public ServerConnector createServerConnector(ServerBootstrapConfiguration server serverConnectorBootstrap.addIdleTimeout(listenerConfig.getSocketIdleTimeout()); if (Constants.HTTP_2_0.equals(listenerConfig.getVersion())) { serverConnectorBootstrap.setHttp2Enabled(true); + serverConnectorBootstrap.setHttp2InitialWindowSize(listenerConfig.getHttp2InitialWindowSize()); } serverConnectorBootstrap.addHttpTraceLogHandler(listenerConfig.isHttpTraceLogEnabled()); serverConnectorBootstrap.addHttpAccessLogHandler(listenerConfig.isHttpAccessLogEnabled()); diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpServerChannelInitializer.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpServerChannelInitializer.java index 233f238305..184731c93b 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpServerChannelInitializer.java +++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/listener/HttpServerChannelInitializer.java @@ -108,6 +108,7 @@ public class HttpServerChannelInitializer extends ChannelInitializer