diff --git a/ballerina-tests/http-advanced-tests/Ballerina.toml b/ballerina-tests/http-advanced-tests/Ballerina.toml
index abac096173..5f986f9455 100644
--- a/ballerina-tests/http-advanced-tests/Ballerina.toml
+++ b/ballerina-tests/http-advanced-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_advanced_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-advanced-tests/Dependencies.toml b/ballerina-tests/http-advanced-tests/Dependencies.toml
index c64fffe1c9..8861ee9951 100644
--- a/ballerina-tests/http-advanced-tests/Dependencies.toml
+++ b/ballerina-tests/http-advanced-tests/Dependencies.toml
@@ -72,7 +72,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -105,7 +105,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_advanced_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "crypto"},
{org = "ballerina", name = "file"},
@@ -125,7 +125,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-client-tests/Ballerina.toml b/ballerina-tests/http-client-tests/Ballerina.toml
index 02cd6b0934..3cb8de0356 100644
--- a/ballerina-tests/http-client-tests/Ballerina.toml
+++ b/ballerina-tests/http-client-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_client_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-client-tests/Dependencies.toml b/ballerina-tests/http-client-tests/Dependencies.toml
index 3dcdde63e8..fee578ba2a 100644
--- a/ballerina-tests/http-client-tests/Dependencies.toml
+++ b/ballerina-tests/http-client-tests/Dependencies.toml
@@ -69,7 +69,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -102,7 +102,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_client_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "constraint"},
{org = "ballerina", name = "http"},
@@ -121,7 +121,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-dispatching-tests/Ballerina.toml b/ballerina-tests/http-dispatching-tests/Ballerina.toml
index 94d1a843c4..2f7f254860 100644
--- a/ballerina-tests/http-dispatching-tests/Ballerina.toml
+++ b/ballerina-tests/http-dispatching-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_dispatching_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-dispatching-tests/Dependencies.toml b/ballerina-tests/http-dispatching-tests/Dependencies.toml
index 578cb34c89..7da7da330a 100644
--- a/ballerina-tests/http-dispatching-tests/Dependencies.toml
+++ b/ballerina-tests/http-dispatching-tests/Dependencies.toml
@@ -69,7 +69,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -102,7 +102,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_dispatching_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "constraint"},
{org = "ballerina", name = "http"},
@@ -124,7 +124,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-interceptor-tests/Ballerina.toml b/ballerina-tests/http-interceptor-tests/Ballerina.toml
index d20d2c41fd..b0c6c2f6a5 100644
--- a/ballerina-tests/http-interceptor-tests/Ballerina.toml
+++ b/ballerina-tests/http-interceptor-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_interceptor_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-interceptor-tests/Dependencies.toml b/ballerina-tests/http-interceptor-tests/Dependencies.toml
index e979fc61ee..16d8c98ca4 100644
--- a/ballerina-tests/http-interceptor-tests/Dependencies.toml
+++ b/ballerina-tests/http-interceptor-tests/Dependencies.toml
@@ -66,7 +66,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -99,7 +99,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_interceptor_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "http"},
{org = "ballerina", name = "http_test_common"},
@@ -115,7 +115,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-misc-tests/Ballerina.toml b/ballerina-tests/http-misc-tests/Ballerina.toml
index 1cfe9104ac..6ae2de7755 100644
--- a/ballerina-tests/http-misc-tests/Ballerina.toml
+++ b/ballerina-tests/http-misc-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_misc_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-misc-tests/Dependencies.toml b/ballerina-tests/http-misc-tests/Dependencies.toml
index a5c9b5cf8e..c0fb3700a4 100644
--- a/ballerina-tests/http-misc-tests/Dependencies.toml
+++ b/ballerina-tests/http-misc-tests/Dependencies.toml
@@ -66,7 +66,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -99,7 +99,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_misc_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "http"},
{org = "ballerina", name = "http_test_common"},
@@ -118,7 +118,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-resiliency-tests/Ballerina.toml b/ballerina-tests/http-resiliency-tests/Ballerina.toml
index 640819e0ce..108106df20 100644
--- a/ballerina-tests/http-resiliency-tests/Ballerina.toml
+++ b/ballerina-tests/http-resiliency-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_resiliency_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-resiliency-tests/Dependencies.toml b/ballerina-tests/http-resiliency-tests/Dependencies.toml
index 7139df5ddb..28f3c5a1d5 100644
--- a/ballerina-tests/http-resiliency-tests/Dependencies.toml
+++ b/ballerina-tests/http-resiliency-tests/Dependencies.toml
@@ -66,7 +66,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -99,7 +99,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_resiliency_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "http"},
{org = "ballerina", name = "http_test_common"},
@@ -116,7 +116,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-resiliency-tests/tests/resiliency_passthrough_test.bal b/ballerina-tests/http-resiliency-tests/tests/resiliency_passthrough_test.bal
new file mode 100644
index 0000000000..189aa6272b
--- /dev/null
+++ b/ballerina-tests/http-resiliency-tests/tests/resiliency_passthrough_test.bal
@@ -0,0 +1,202 @@
+// Copyright (c) 2023 WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
+//
+// WSO2 LLC. licenses this file to you under the Apache License,
+// Version 2.0 (the "License"); you may not use this file except
+// in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import ballerina/http;
+import ballerina/test;
+
+public type Data record {|
+ string name;
+ int age;
+ string[] address;
+|};
+
+final http:Client passthroughRetryClient = check new (string`http://localhost:${passthroughTestPort1}`,
+ retryConfig = {
+ count: 3,
+ interval: 10
+ }
+);
+
+final http:LoadBalanceClient passthroughLoadBalancerClient = check new ({
+ targets: [
+ {url: string`http://localhost:${passthroughTestPort1}`}
+ ],
+ timeout: 5
+}
+);
+
+final http:FailoverClient passthroughFailoverClient = check new ({
+ timeout: 5,
+ failoverCodes: [501, 502, 503],
+ interval: 5,
+ targets: [
+ {url: "http://nonexistentEP"},
+ {url: string`http://localhost:${passthroughTestPort1}`}
+ ]
+});
+
+final http:Client passthroughRedirectClient = check new (string`http://localhost:${passthroughTestPort1}`,
+ followRedirects = {
+ enabled: true,
+ maxCount: 5
+ }
+);
+
+service on new http:Listener(passthroughTestPort2) {
+
+ resource function post passRetryWithReq(http:Request req) returns http:Response|error {
+ return passthroughRetryClient->/echo.post(req);
+ }
+
+ resource function post passRetryWithPayload(@http:Payload Data[]|xml|string payload) returns Data[]|xml|string|error {
+ return passthroughRetryClient->/echo.post(payload);
+ }
+
+ resource function post passLoadBalancerWithReq(http:Request req) returns http:Response|error {
+ return passthroughLoadBalancerClient->/echo.post(req);
+ }
+
+ resource function post passLoadBalancerWithPayload(@http:Payload Data[]|xml|string payload) returns Data[]|xml|string|error {
+ return passthroughLoadBalancerClient->/echo.post(payload);
+ }
+
+ resource function post passFailoverWithReq(http:Request req) returns http:Response|error {
+ return passthroughFailoverClient->/echo.post(req);
+ }
+
+ resource function post passFailoverWithPayload(@http:Payload Data[]|xml|string payload) returns Data[]|xml|string|error {
+ return passthroughFailoverClient->/echo.post(payload);
+ }
+
+ resource function post passRedirectWithReq(http:Request req) returns http:Response|error {
+ return passthroughRedirectClient->/echo.post(req);
+ }
+
+ resource function post passRedirectWithPayload(@http:Payload Data[]|xml|string payload) returns Data[]|xml|string|error {
+ return passthroughRedirectClient->/echo.post(payload);
+ }
+}
+
+service on new http:Listener(passthroughTestPort1) {
+
+ resource function post echo(@http:Payload Data[]|xml|string payload) returns Data[]|xml|string {
+ return payload;
+ }
+}
+
+@test:Config {}
+function testPassthroughRetryClientWithReq() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passRetryWithReq.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passRetryWithReq.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passRetryWithReq.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughRetryClientWithPayload() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passRetryWithPayload.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passRetryWithPayload.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passRetryWithPayload.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughLoadBalancerClientWithReq() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passLoadBalancerWithReq.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passLoadBalancerWithReq.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passLoadBalancerWithReq.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughLoadBalancerClientWithPayload() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passLoadBalancerWithPayload.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passLoadBalancerWithPayload.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passLoadBalancerWithPayload.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughFailoverClientWithReq() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passFailoverWithReq.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passFailoverWithReq.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passFailoverWithReq.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughFailoverClientWithPayload() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passFailoverWithPayload.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passFailoverWithPayload.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passFailoverWithPayload.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughRedirectClientWithReq() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passRedirectWithReq.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passRedirectWithReq.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passRedirectWithReq.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
+
+@test:Config {}
+function testPassthroughRedirectClientWithPayload() returns error? {
+ http:Client clientEP = check new(string`http://localhost:${passthroughTestPort2}`);
+ string stringResp = check clientEP->/passRedirectWithPayload.post("Hello World");
+ test:assertEquals(stringResp, "Hello World");
+
+ json jsonResp = check clientEP->/passRedirectWithPayload.post([{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+ test:assertEquals(jsonResp, [{name:"John", age:30, address:["Colombo", "Sri Lanka"]}]);
+
+ xml xmlResp = check clientEP->/passRedirectWithPayload.post(xml`Hello World`);
+ test:assertEquals(xmlResp, xml`Hello World`);
+}
diff --git a/ballerina-tests/http-resiliency-tests/tests/test_service_ports.bal b/ballerina-tests/http-resiliency-tests/tests/test_service_ports.bal
index 1938bc8f4f..a375f36d84 100644
--- a/ballerina-tests/http-resiliency-tests/tests/test_service_ports.bal
+++ b/ballerina-tests/http-resiliency-tests/tests/test_service_ports.bal
@@ -24,3 +24,6 @@ const int foClientWithoutStatusCodeTestPort1 = 9571;
const int foClientWithoutStatusCodeTestPort2 = 9572;
const int http2RetryFunctionTestPort = 9706;
+
+const int passthroughTestPort1 = 9543;
+const int passthroughTestPort2 = 9544;
diff --git a/ballerina-tests/http-security-tests/Ballerina.toml b/ballerina-tests/http-security-tests/Ballerina.toml
index 493bc7424d..258ce2eb26 100644
--- a/ballerina-tests/http-security-tests/Ballerina.toml
+++ b/ballerina-tests/http-security-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_security_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-security-tests/Dependencies.toml b/ballerina-tests/http-security-tests/Dependencies.toml
index 9b7caf85f7..c99dd280a5 100644
--- a/ballerina-tests/http-security-tests/Dependencies.toml
+++ b/ballerina-tests/http-security-tests/Dependencies.toml
@@ -69,7 +69,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -102,7 +102,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_security_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "http"},
@@ -120,7 +120,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-service-tests/Ballerina.toml b/ballerina-tests/http-service-tests/Ballerina.toml
index 27b26f6ad4..28a8d9f889 100644
--- a/ballerina-tests/http-service-tests/Ballerina.toml
+++ b/ballerina-tests/http-service-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http_service_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http-service-tests/Dependencies.toml b/ballerina-tests/http-service-tests/Dependencies.toml
index 4fdd307ed1..ff728fe3a7 100644
--- a/ballerina-tests/http-service-tests/Dependencies.toml
+++ b/ballerina-tests/http-service-tests/Dependencies.toml
@@ -69,7 +69,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -102,7 +102,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_service_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "file"},
{org = "ballerina", name = "http"},
@@ -121,7 +121,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina-tests/http-test-common/Ballerina.toml b/ballerina-tests/http-test-common/Ballerina.toml
index 9474c9470b..4be036178c 100644
--- a/ballerina-tests/http-test-common/Ballerina.toml
+++ b/ballerina-tests/http-test-common/Ballerina.toml
@@ -1,4 +1,4 @@
[package]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
diff --git a/ballerina-tests/http-test-common/Dependencies.toml b/ballerina-tests/http-test-common/Dependencies.toml
index 79e94210a6..16836de70b 100644
--- a/ballerina-tests/http-test-common/Dependencies.toml
+++ b/ballerina-tests/http-test-common/Dependencies.toml
@@ -10,7 +10,7 @@ distribution-version = "2201.8.0"
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "lang.string"},
{org = "ballerina", name = "mime"},
diff --git a/ballerina-tests/http2-tests/Ballerina.toml b/ballerina-tests/http2-tests/Ballerina.toml
index 346c9cd396..8e52d00325 100644
--- a/ballerina-tests/http2-tests/Ballerina.toml
+++ b/ballerina-tests/http2-tests/Ballerina.toml
@@ -1,17 +1,17 @@
[package]
org = "ballerina"
name = "http2_tests"
-version = "2.10.0"
+version = "2.10.2"
[[dependency]]
org = "ballerina"
name = "http_test_common"
repository = "local"
-version = "2.10.0"
+version = "2.10.2"
[platform.java17]
graalvmCompatible = true
[[platform.java17.dependency]]
scope = "testOnly"
-path = "../../test-utils/build/libs/http-test-utils-2.10.0.jar"
+path = "../../test-utils/build/libs/http-test-utils-2.10.2.jar"
diff --git a/ballerina-tests/http2-tests/Dependencies.toml b/ballerina-tests/http2-tests/Dependencies.toml
index 32e39848b1..ea53d2c74c 100644
--- a/ballerina-tests/http2-tests/Dependencies.toml
+++ b/ballerina-tests/http2-tests/Dependencies.toml
@@ -69,7 +69,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "auth"},
@@ -102,7 +102,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http2_tests"
-version = "2.10.0"
+version = "2.10.2"
dependencies = [
{org = "ballerina", name = "file"},
{org = "ballerina", name = "http"},
@@ -121,7 +121,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http_test_common"
-version = "2.10.0"
+version = "2.10.2"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "lang.string"},
diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml
index 87c8ea3ef2..8944df027a 100644
--- a/ballerina/Ballerina.toml
+++ b/ballerina/Ballerina.toml
@@ -1,7 +1,7 @@
[package]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.3"
authors = ["Ballerina"]
keywords = ["http", "network", "service", "listener", "client"]
repository = "https://github.com/ballerina-platform/module-ballerina-http"
@@ -16,8 +16,8 @@ graalvmCompatible = true
[[platform.java17.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "http-native"
-version = "2.10.0"
-path = "../native/build/libs/http-native-2.10.0.jar"
+version = "2.10.3"
+path = "../native/build/libs/http-native-2.10.3-SNAPSHOT.jar"
[[platform.java17.dependency]]
groupId = "io.ballerina.stdlib"
@@ -34,56 +34,56 @@ path = "./lib/constraint-native-1.4.0.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-common"
-version = "4.1.94.Final"
-path = "./lib/netty-common-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-common-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-buffer"
-version = "4.1.94.Final"
-path = "./lib/netty-buffer-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-buffer-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-transport"
-version = "4.1.94.Final"
-path = "./lib/netty-transport-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-transport-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-resolver"
-version = "4.1.94.Final"
-path = "./lib/netty-resolver-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-resolver-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-handler"
-version = "4.1.94.Final"
-path = "./lib/netty-handler-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-handler-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-codec-http"
-version = "4.1.94.Final"
-path = "./lib/netty-codec-http-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-codec-http-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-codec"
-version = "4.1.94.Final"
-path = "./lib/netty-codec-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-codec-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-handler-proxy"
-version = "4.1.94.Final"
-path = "./lib/netty-handler-proxy-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-handler-proxy-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-codec-http2"
-version = "4.1.94.Final"
-path = "./lib/netty-codec-http2-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-codec-http2-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "commons-pool.wso2"
@@ -94,8 +94,8 @@ path = "./lib/commons-pool-1.5.6.wso2v1.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-transport-native-unix-common"
-version = "4.1.94.Final"
-path = "./lib/netty-transport-native-unix-common-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-transport-native-unix-common-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "org.bouncycastle"
@@ -112,29 +112,29 @@ path = "./lib/bcpkix-jdk18on-1.74.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-tcnative-boringssl-static"
-version = "2.0.61.Final"
-path = "./lib/netty-tcnative-boringssl-static-2.0.61.Final.jar"
+version = "2.0.62.Final"
+path = "./lib/netty-tcnative-boringssl-static-2.0.62.Final.jar"
[[platform.java17.dependency]]
-path = "./lib/netty-tcnative-boringssl-static-2.0.61.Final-windows-x86_64.jar"
+path = "./lib/netty-tcnative-boringssl-static-2.0.62.Final-windows-x86_64.jar"
[[platform.java17.dependency]]
-path = "./lib/netty-tcnative-boringssl-static-2.0.61.Final-linux-aarch_64.jar"
+path = "./lib/netty-tcnative-boringssl-static-2.0.62.Final-linux-aarch_64.jar"
[[platform.java17.dependency]]
-path = "./lib/netty-tcnative-boringssl-static-2.0.61.Final-linux-x86_64.jar"
+path = "./lib/netty-tcnative-boringssl-static-2.0.62.Final-linux-x86_64.jar"
[[platform.java17.dependency]]
-path = "./lib/netty-tcnative-boringssl-static-2.0.61.Final-osx-aarch_64.jar"
+path = "./lib/netty-tcnative-boringssl-static-2.0.62.Final-osx-aarch_64.jar"
[[platform.java17.dependency]]
-path = "./lib/netty-tcnative-boringssl-static-2.0.61.Final-osx-x86_64.jar"
+path = "./lib/netty-tcnative-boringssl-static-2.0.62.Final-osx-x86_64.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-tcnative-classes"
-version = "2.0.61.Final"
-path = "./lib/netty-tcnative-classes-2.0.61.Final.jar"
+version = "2.0.62.Final"
+path = "./lib/netty-tcnative-classes-2.0.62.Final.jar"
[[platform.java17.dependency]]
groupId = "org.jvnet.mimepull"
@@ -145,8 +145,8 @@ path = "./lib/mimepull-1.9.11.jar"
[[platform.java17.dependency]]
groupId = "io.netty"
artifactId = "netty-codec-socks"
-version = "4.1.94.Final"
-path = "./lib/netty-codec-socks-4.1.94.Final.jar"
+version = "4.1.100.Final"
+path = "./lib/netty-codec-socks-4.1.100.Final.jar"
[[platform.java17.dependency]]
groupId = "org.jboss.marshalling"
diff --git a/ballerina/CompilerPlugin.toml b/ballerina/CompilerPlugin.toml
index 464016ca36..ab38795c5d 100644
--- a/ballerina/CompilerPlugin.toml
+++ b/ballerina/CompilerPlugin.toml
@@ -3,4 +3,4 @@ id = "http-compiler-plugin"
class = "io.ballerina.stdlib.http.compiler.HttpCompilerPlugin"
[[dependency]]
-path = "../compiler-plugin/build/libs/http-compiler-plugin-2.10.0.jar"
+path = "../compiler-plugin/build/libs/http-compiler-plugin-2.10.3-SNAPSHOT.jar"
diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml
index a34047c02a..6e26ed9026 100644
--- a/ballerina/Dependencies.toml
+++ b/ballerina/Dependencies.toml
@@ -76,7 +76,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
-version = "2.10.0"
+version = "2.10.3"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "cache"},
diff --git a/ballerina/http_request.bal b/ballerina/http_request.bal
index 1c4f6f4fc0..38ad126bf2 100644
--- a/ballerina/http_request.bal
+++ b/ballerina/http_request.bal
@@ -587,6 +587,13 @@ public class Request {
return externCheckReqEntityBodyAvailability(self);
}
+ # Check whether the message data source is already built.
+ #
+ # + return - A boolean indicating the availability of the message data source
+ isolated function hasMsgDataSource() returns boolean {
+ return externHasMsgDataSource(self);
+ }
+
# Adds cookies to the request.
#
# + cookiesToAdd - Represents the cookies to be added
@@ -692,6 +699,12 @@ isolated function externCheckReqEntityBodyAvailability(Request request) returns
name: "checkEntityBodyAvailability"
} external;
+isolated function externHasMsgDataSource(Request request) returns boolean =
+@java:Method {
+ 'class: "io.ballerina.stdlib.http.api.nativeimpl.ExternRequest",
+ name: "hasMsgDataSource"
+} external;
+
# A record for providing mutual SSL handshake results.
#
# + status - Status of the handshake.
diff --git a/ballerina/redirect_http_client.bal b/ballerina/redirect_http_client.bal
index 661deb89f8..e892e9e977 100644
--- a/ballerina/redirect_http_client.bal
+++ b/ballerina/redirect_http_client.bal
@@ -316,9 +316,11 @@ client isolated class RedirectClient {
if !(httpOperation is safeHttpOperation) {
// When performing redirect operation for non-safe method, message needs to be built before sending out the
// to keep the request message to subsequent redirect.
- byte[]|error binaryPayload = check inRequest.getBinaryPayload();
- if binaryPayload is error {
- log:printDebug("Error building datasource for request redirect: " + binaryPayload.message());
+ if !inRequest.hasMsgDataSource() {
+ byte[]|error binaryPayload = inRequest.getBinaryPayload();
+ if binaryPayload is error {
+ log:printDebug("Error building datasource for request redirect: " + binaryPayload.message());
+ }
}
// Build message for for multipart requests
inRequest = check populateMultipartRequest(inRequest);
diff --git a/ballerina/resiliency_failover_client.bal b/ballerina/resiliency_failover_client.bal
index 527e308697..76cb7283e9 100644
--- a/ballerina/resiliency_failover_client.bal
+++ b/ballerina/resiliency_failover_client.bal
@@ -523,9 +523,11 @@ public client isolated class FailoverClient {
} else {
// When performing passthrough scenarios using Failover connector, message needs to be built before trying
// out the failover endpoints to keep the request message to failover the messages.
- byte[]|error binaryPayload = failoverRequest.getBinaryPayload();
- if binaryPayload is error {
- log:printDebug("Error building payload for request failover: " + binaryPayload.message());
+ if !failoverRequest.hasMsgDataSource() {
+ byte[]|error binaryPayload = failoverRequest.getBinaryPayload();
+ if binaryPayload is error {
+ log:printDebug("Error building payload for request failover: " + binaryPayload.message());
+ }
}
requestEntity = check failoverRequest.getEntity();
}
diff --git a/ballerina/resiliency_http_retry_client.bal b/ballerina/resiliency_http_retry_client.bal
index 8348936dee..fe1c19d6b6 100644
--- a/ballerina/resiliency_http_retry_client.bal
+++ b/ballerina/resiliency_http_retry_client.bal
@@ -304,9 +304,11 @@ isolated function performRetryAction(string path, Request request, HttpOperation
Request inRequest = request;
// When performing passthrough scenarios using retry client, message needs to be built before sending out the
// to keep the request message to retry.
- byte[]|error binaryPayload = check inRequest.getBinaryPayload();
- if binaryPayload is error {
- log:printDebug("Error building payload for request retry: " + binaryPayload.message());
+ if !inRequest.hasMsgDataSource() {
+ byte[]|error binaryPayload = inRequest.getBinaryPayload();
+ if binaryPayload is error {
+ log:printDebug("Error building payload for request retry: " + binaryPayload.message());
+ }
}
while (currentRetryCount < (retryCount + 1)) {
diff --git a/ballerina/resiliency_load_balance_client.bal b/ballerina/resiliency_load_balance_client.bal
index f1f74d88ab..790c18ad4c 100644
--- a/ballerina/resiliency_load_balance_client.bal
+++ b/ballerina/resiliency_load_balance_client.bal
@@ -424,9 +424,11 @@ public client isolated class LoadBalanceClient {
// When performing passthrough scenarios using Load Balance connector,
// message needs to be built before trying out the load balance endpoints to keep the request message
// to load balance the messages in case of failure.
- byte[]|error binaryPayload = loadBalancerInRequest.getBinaryPayload();
- if binaryPayload is error {
- log:printDebug("Error building payload for request load balance: " + binaryPayload.message());
+ if !loadBalancerInRequest.hasMsgDataSource() {
+ byte[]|error binaryPayload = loadBalancerInRequest.getBinaryPayload();
+ if binaryPayload is error {
+ log:printDebug("Error building payload for request load balance: " + binaryPayload.message());
+ }
}
requestEntity = check loadBalancerInRequest.getEntity();
}
diff --git a/changelog.md b/changelog.md
index ff2a5fdcb8..8d005bdfda 100644
--- a/changelog.md
+++ b/changelog.md
@@ -5,6 +5,18 @@ This file contains all the notable changes done to the Ballerina HTTP package th
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2.10.2] - 2023-10-09
+
+### Fixed
+
+- [Fix HTTP2 mTLS issue when certs and keys are provided](https://github.com/ballerina-platform/ballerina-standard-library/issues/4890)
+
+## [2.10.1] - 2023-09-27
+
+### Fixed
+
+- [Fix resilient client failure in passthrough scenarios](https://github.com/ballerina-platform/ballerina-standard-library/issues/4824)
+
## [2.10.0] - 2023-09-15
### Fixed
diff --git a/gradle.properties b/gradle.properties
index bbcce671e1..a2692725f3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,11 +1,11 @@
org.gradle.caching=true
group=io.ballerina.stdlib
-version=2.10.1-SNAPSHOT
+version=2.10.3-SNAPSHOT
ballerinaLangVersion=2201.8.0
ballerinaTomlParserVersion=1.2.2
commonsLang3Version=3.12.0
-nettyVersion=4.1.94.Final
-nettyTcnativeVersion=2.0.61.Final
+nettyVersion=4.1.100.Final
+nettyTcnativeVersion=2.0.62.Final
bouncycastleVersion=1.74
slf4jVersion=1.7.30
jakartaXmlBindVersion=4.0.0
diff --git a/load-tests/h1_h1_passthrough/results/summary.csv b/load-tests/h1_h1_passthrough/results/summary.csv
index c6459af8f7..3ed54da4b9 100644
--- a/load-tests/h1_h1_passthrough/results/summary.csv
+++ b/load-tests/h1_h1_passthrough/results/summary.csv
@@ -370,3 +370,12 @@ HTTP Request,10370771,18,13,39,51,83,0,606,0.00%,2980.1,715.9,16.79,1690308920,5
HTTP Request,9822431,19,14,41,54,86,0,429,0.00%,2822.6,678.1,17.51,1690395330,50,60
HTTP Request,10365420,18,14,39,51,83,0,437,0.00%,2978.6,715.6,16.80,1690481741,50,60
HTTP Request,10313129,18,14,39,51,84,0,595,0.00%,2963.6,711.9,16.98,1690568102,50,60
+HTTP Request,9795757,19,14,41,55,90,0,621,0.00%,2814.9,676.2,18.26,1696356854,50,60
+HTTP Request,9902022,19,14,41,55,89,0,529,0.00%,2845.5,683.6,18.01,1696443242,50,60
+HTTP Request,12171619,15,11,34,45,74,0,630,0.00%,3497.7,840.2,15.09,1696529666,50,60
+HTTP Request,10532111,18,13,39,51,84,0,505,0.00%,3026.5,727.1,17.07,1696616047,50,60
+HTTP Request,10071362,19,14,40,53,87,0,565,0.00%,2894.1,695.3,17.73,1696702472,50,60
+HTTP Request,9574579,20,15,42,56,92,0,568,0.00%,2751.4,661.0,18.70,1696788809,50,60
+HTTP Request,9901924,19,14,41,54,88,0,651,0.00%,2845.4,683.6,17.97,1696875324,50,60
+HTTP Request,10268693,18,14,39,52,86,0,504,0.00%,2950.8,708.9,17.35,1696961728,50,60
+HTTP Request,12427947,15,11,33,44,73,0,576,0.00%,3571.3,857.9,14.77,1697048074,50,60
diff --git a/load-tests/h1_transformation/results/summary.csv b/load-tests/h1_transformation/results/summary.csv
index 5c858476d1..453bb768a0 100644
--- a/load-tests/h1_transformation/results/summary.csv
+++ b/load-tests/h1_transformation/results/summary.csv
@@ -374,3 +374,12 @@ HTTP Request,8398463,24,22,41,47,62,1,284,0.00%,2413.4,659.9,12.56,1690312935,50
HTTP Request,7807005,26,24,44,52,68,1,333,0.00%,2243.4,613.4,13.95,1690399349,50,60
HTTP Request,8416785,24,22,41,48,62,1,293,0.00%,2418.7,661.3,12.81,1690485700,50,60
HTTP Request,8323165,24,22,42,48,64,1,332,0.00%,2391.8,654.0,13.07,1690572076,50,60
+HTTP Request,7558433,26,25,45,52,71,1,473,0.00%,2172.0,593.9,14.30,1696360749,50,60
+HTTP Request,7797763,26,24,44,52,70,1,381,0.00%,2240.8,612.7,14.24,1696447174,50,60
+HTTP Request,9833258,20,19,34,40,54,1,301,0.00%,2825.7,772.6,10.73,1696533564,50,60
+HTTP Request,8271858,24,22,41,48,65,1,334,0.00%,2377.0,649.9,13.09,1696619982,50,60
+HTTP Request,7944823,25,23,43,50,67,1,417,0.00%,2283.0,624.2,13.52,1696706365,50,60
+HTTP Request,7782534,26,24,44,51,69,1,465,0.00%,2236.4,611.5,13.91,1696792722,50,60
+HTTP Request,7968274,25,23,43,50,67,1,347,0.00%,2289.8,626.1,13.41,1696879253,50,60
+HTTP Request,8372594,24,22,41,47,63,1,344,0.00%,2406.0,657.9,12.65,1696965628,50,60
+HTTP Request,9885110,20,19,34,40,53,1,292,0.00%,2840.6,776.7,10.48,1697052002,50,60
diff --git a/load-tests/h1c_h1c_passthrough/results/summary.csv b/load-tests/h1c_h1c_passthrough/results/summary.csv
index 2f2dbaa177..a2bf999d67 100644
--- a/load-tests/h1c_h1c_passthrough/results/summary.csv
+++ b/load-tests/h1c_h1c_passthrough/results/summary.csv
@@ -372,3 +372,12 @@ HTTP Request,11550008,16,14,33,41,59,0,268,0.00%,3319.0,589.9,12.35,1690316952,5
HTTP Request,10877246,17,15,35,43,63,0,298,0.00%,3125.7,555.5,13.21,1690403371,50,60
HTTP Request,11599485,16,14,33,41,59,0,277,0.00%,3333.2,592.4,12.34,1690489667,50,60
HTTP Request,11512890,16,14,33,41,60,0,297,0.00%,3308.4,588.0,12.52,1690576040,50,60
+HTTP Request,10791321,18,15,35,43,66,0,412,0.00%,3101.0,551.1,13.41,1696364689,50,60
+HTTP Request,10983204,17,15,34,42,64,0,309,0.00%,3156.2,560.9,13.08,1696451100,50,60
+HTTP Request,14052191,14,11,27,34,53,0,304,0.00%,4038.0,717.7,10.76,1696537478,50,60
+HTTP Request,11709660,16,13,32,41,62,0,284,0.00%,3364.9,598.0,12.67,1696623884,50,60
+HTTP Request,11308861,17,14,33,41,63,0,308,0.00%,3249.7,577.6,12.85,1696710263,50,60
+HTTP Request,10694123,18,15,35,43,66,0,277,0.00%,3073.1,546.2,13.53,1696796691,50,60
+HTTP Request,11203528,17,14,34,42,64,0,310,0.00%,3219.4,572.2,12.98,1696883191,50,60
+HTTP Request,11714508,16,14,32,40,62,0,320,0.00%,3366.3,598.3,12.52,1696969635,50,60
+HTTP Request,14393277,13,11,26,34,52,0,346,0.00%,4136.1,735.1,10.56,1697055923,50,60
diff --git a/load-tests/h1c_transformation/results/summary.csv b/load-tests/h1c_transformation/results/summary.csv
index c87ee53290..4bbe7fca08 100644
--- a/load-tests/h1c_transformation/results/summary.csv
+++ b/load-tests/h1c_transformation/results/summary.csv
@@ -369,3 +369,11 @@ HTTP Request,8799797,23,21,36,42,69,1,205,0.00%,2528.7,533.4,11.55,1690320976,50
HTTP Request,8033335,25,23,40,47,74,1,254,0.00%,2308.5,486.9,12.61,1690407337,50,60
HTTP Request,8747008,23,21,36,43,70,0,216,0.00%,2513.6,530.2,11.67,1690493645,50,60
HTTP Request,8794569,23,21,36,43,68,1,266,0.00%,2527.2,533.1,11.53,1690579998,50,60
+HTTP Request,7438174,27,25,43,58,78,1,294,0.00%,2137.5,450.9,14.22,1696368631,50,60
+HTTP Request,9799107,20,19,33,44,59,0,225,0.00%,2815.9,594.0,10.78,1696541378,50,60
+HTTP Request,8729338,23,21,37,48,65,1,248,0.00%,2508.5,529.1,11.89,1696627796,50,60
+HTTP Request,7925752,25,23,40,55,74,1,411,0.00%,2277.6,480.4,13.37,1696714180,50,60
+HTTP Request,7674971,26,24,42,55,73,1,291,0.00%,2205.5,465.2,13.41,1696800581,50,60
+HTTP Request,8014682,25,23,40,53,71,1,244,0.00%,2303.1,485.8,13.00,1696887114,50,60
+HTTP Request,8391677,24,22,38,51,68,1,281,0.00%,2411.4,508.7,12.46,1696973561,50,60
+HTTP Request,9894116,20,18,33,45,59,0,185,0.00%,2843.2,599.7,10.79,1697059850,50,60
diff --git a/load-tests/h2_h1c_passthrough/results/summary.csv b/load-tests/h2_h1c_passthrough/results/summary.csv
index d3d19eac75..c66bb0ff91 100644
--- a/load-tests/h2_h1c_passthrough/results/summary.csv
+++ b/load-tests/h2_h1c_passthrough/results/summary.csv
@@ -326,3 +326,12 @@ H2-H1C Passthrough,5862,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1690321932,0,1
H2-H1C Passthrough,5863,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1690408307,0,1
H2-H1C Passthrough,5861,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1690494583,0,1
H2-H1C Passthrough,5858,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1690580917,0,1
+H2-H1C Passthrough,5843,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696369491,0,1
+H2-H1C Passthrough,5819,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696452159,0,1
+H2-H1C Passthrough,5891,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696542278,0,1
+H2-H1C Passthrough,5876,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696628711,0,1
+H2-H1C Passthrough,5851,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696715053,0,1
+H2-H1C Passthrough,5856,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696801470,0,1
+H2-H1C Passthrough,5857,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696887993,0,1
+H2-H1C Passthrough,5872,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1696974434,0,1
+H2-H1C Passthrough,5896,0.0,0,0,0,0,0,0,1.0,0.0,0,0,1697060729,0,1
diff --git a/load-tests/interceptors_passthrough/results/summary.csv b/load-tests/interceptors_passthrough/results/summary.csv
index e357e4d4f8..6d3835f6fe 100644
--- a/load-tests/interceptors_passthrough/results/summary.csv
+++ b/load-tests/interceptors_passthrough/results/summary.csv
@@ -76,3 +76,12 @@ Test Request,236955,884,29,131,238,30023,1,30035,3.58%,67.7,9.7,4733.20,16903258
Test Request,248225,843,32,155,1274,20090,1,30037,5.59%,70.7,9.5,3815.01,1690412287,50,60
Test Request,245518,852,29,150,1281,24289,1,30043,5.27%,70.0,9.4,3948.97,1690498537,50,60
Test Request,247880,845,29,134,262,30023,1,30035,3.77%,70.7,10.2,4535.24,1690584898,50,60
+Test Request,252588,829,29,139,254,30025,1,56722,3.16%,72.1,10.5,4606.95,1696373369,50,60
+Test Request,241193,868,30,145,295,29156,1,49998,3.74%,69.0,7.6,4718.71,1696456040,50,60
+Test Request,233263,898,23,130,322,28552,1,45732,4.06%,66.6,8.3,4654.13,1696546189,50,60
+Test Request,240006,872,27,163,8199,22063,1,46570,5.87%,68.4,9.5,3889.95,1696632607,50,60
+Test Request,241806,865,28,137,273,30023,1,51879,3.69%,69.1,9.9,4672.50,1696718977,50,60
+Test Request,251063,835,30,147,292,30022,1,48650,3.76%,71.6,10.2,4578.50,1696805363,50,60
+Test Request,247159,847,28,146,282,28892,1,30033,3.65%,70.6,8.5,4556.20,1696891897,50,60
+Test Request,234857,891,28,161,1169,30019,1,49975,5.73%,66.9,9.8,4130.24,1696978336,50,60
+Test Request,225092,930,23,131,406,30026,1,51293,4.71%,64.2,9.8,4756.01,1697064640,50,60
diff --git a/load-tests/observability_enabled/results/summary.csv b/load-tests/observability_enabled/results/summary.csv
index 0d8b8a9e63..576445261c 100644
--- a/load-tests/observability_enabled/results/summary.csv
+++ b/load-tests/observability_enabled/results/summary.csv
@@ -357,3 +357,12 @@ HTTP Request,15268585,12,7,29,43,87,0,678,0.00%,4387.6,655.5,17.80,1690329908,50
HTTP Request,14409648,13,7,31,46,91,0,600,0.00%,4140.8,618.7,18.55,1690416294,50,60
HTTP Request,15217240,12,7,29,44,90,0,535,0.00%,4372.9,653.3,18.22,1690502575,50,60
HTTP Request,15131134,12,7,29,43,86,0,546,0.00%,4348.1,649.6,17.55,1690588926,50,60
+HTTP Request,13957461,14,7,33,50,98,0,517,0.00%,4010.8,599.3,19.93,1696377273,50,60
+HTTP Request,13918990,14,7,34,52,104,0,681,0.00%,3999.8,597.6,21.22,1696459952,50,60
+HTTP Request,17278157,11,6,27,42,86,0,540,0.00%,4965.1,741.8,17.55,1696550136,50,60
+HTTP Request,14838512,13,6,32,48,99,0,543,0.00%,4264.0,637.1,20.11,1696636515,50,60
+HTTP Request,14092068,13,7,34,52,106,0,658,0.00%,4049.5,605.0,21.53,1696722889,50,60
+HTTP Request,13610082,14,8,33,48,93,0,594,0.00%,3911.0,584.3,18.98,1696809290,50,60
+HTTP Request,14232703,13,7,33,50,102,0,743,0.00%,4089.9,611.1,20.85,1696895836,50,60
+HTTP Request,14536001,13,6,33,50,102,0,654,0.00%,4177.1,624.1,20.80,1696982268,50,60
+HTTP Request,17754215,11,5,26,40,84,0,528,0.00%,5101.9,762.3,17.02,1697068574,50,60
diff --git a/load-tests/snowpeak_passthrough/results/summary.csv b/load-tests/snowpeak_passthrough/results/summary.csv
index c242a38d8e..a3ad8a6934 100644
--- a/load-tests/snowpeak_passthrough/results/summary.csv
+++ b/load-tests/snowpeak_passthrough/results/summary.csv
@@ -208,3 +208,12 @@ Retrieve Available Locations,6535891,31,20,68,72,85,0,367,0.00%,1878.1,181.6,23.
Retrieve Available Locations,6130231,33,22,69,74,88,1,299,0.00%,1761.6,170.3,24.16,1690420347,50,60
Retrieve Available Locations,6631056,31,19,67,72,83,0,303,0.00%,1905.5,184.2,23.37,1690506531,50,60
Retrieve Available Locations,6565549,31,20,67,72,84,1,389,0.00%,1886.5,182.4,23.54,1690592878,50,60
+Retrieve Available Locations,6671448,30,19,66,71,87,0,553,0.00%,1917.0,185.3,23.22,1696381149,50,60
+Retrieve Available Locations,6724332,30,19,66,71,88,0,291,0.00%,1932.3,186.8,23.17,1696463833,50,60
+Retrieve Available Locations,8237631,24,15,60,65,75,0,382,0.00%,2367.1,228.8,20.90,1696554022,50,60
+Retrieve Available Locations,7143685,28,18,64,70,84,0,406,0.00%,2052.8,198.5,22.80,1696640404,50,60
+Retrieve Available Locations,6864709,29,19,65,71,87,0,355,0.00%,1972.6,190.7,23.05,1696726826,50,60
+Retrieve Available Locations,6404061,31,21,67,72,89,0,291,0.00%,1840.3,177.9,23.46,1696813192,50,60
+Retrieve Available Locations,6728880,30,19,66,71,87,0,674,0.00%,1933.6,186.9,23.32,1696899743,50,60
+Retrieve Available Locations,6746893,30,19,66,72,87,0,483,0.00%,1938.8,187.4,23.57,1696986174,50,60
+Retrieve Available Locations,8196448,25,15,61,65,76,0,395,0.00%,2355.2,227.7,21.17,1697072505,50,60
diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternRequest.java b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternRequest.java
index 1c06fe794d..9f983561aa 100644
--- a/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternRequest.java
+++ b/native/src/main/java/io/ballerina/stdlib/http/api/nativeimpl/ExternRequest.java
@@ -32,6 +32,8 @@
import io.ballerina.stdlib.http.uri.URIUtil;
import io.ballerina.stdlib.mime.util.EntityBodyHandler;
+import java.util.Objects;
+
import static io.ballerina.stdlib.http.api.HttpConstants.QUERY_PARAM_MAP;
import static io.ballerina.stdlib.http.api.HttpConstants.TRANSPORT_MESSAGE;
import static io.ballerina.stdlib.http.api.HttpUtil.checkRequestBodySizeHeadersAvailability;
@@ -103,6 +105,11 @@ public static boolean checkEntityBodyAvailability(BObject requestObj) {
return lengthHeaderCheck(requestObj) || EntityBodyHandler.checkEntityBodyAvailability(entityObj);
}
+ public static boolean hasMsgDataSource(BObject requestObj) {
+ BObject entityObj = (BObject) requestObj.get(REQUEST_ENTITY_FIELD);
+ return Objects.nonNull(EntityBodyHandler.getMessageDataSource(entityObj));
+ }
+
private static boolean lengthHeaderCheck(BObject requestObj) {
Object outboundMsg = requestObj.getNativeData(TRANSPORT_MESSAGE);
if (outboundMsg == null) {
diff --git a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/ssl/SSLHandlerFactory.java b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/ssl/SSLHandlerFactory.java
index b04607e8fc..921d9f9988 100644
--- a/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/ssl/SSLHandlerFactory.java
+++ b/native/src/main/java/io/ballerina/stdlib/http/transport/contractimpl/common/ssl/SSLHandlerFactory.java
@@ -353,6 +353,9 @@ public SslContext createHttp2TLSContextForClient(boolean enableOcsp) throws SSLE
} else {
sslContextBuilder = clientContextBuilderWithCerts(provider);
}
+ if (sslConfig.getClientKeyFile() != null) {
+ sslContextBuilder = clientContextBuilderWithCerts(provider);
+ }
setCiphers(sslContextBuilder, ciphers);
setSslProtocol(sslContextBuilder);
setAlpnConfigs(sslContextBuilder);
diff --git a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/ssl/Http2ALPNwithCertsTest.java b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/ssl/Http2AlpnWithCertsTest.java
similarity index 88%
rename from native/src/test/java/io/ballerina/stdlib/http/transport/http2/ssl/Http2ALPNwithCertsTest.java
rename to native/src/test/java/io/ballerina/stdlib/http/transport/http2/ssl/Http2AlpnWithCertsTest.java
index e70b0f2032..ad01fe98e6 100644
--- a/native/src/test/java/io/ballerina/stdlib/http/transport/http2/ssl/Http2ALPNwithCertsTest.java
+++ b/native/src/test/java/io/ballerina/stdlib/http/transport/http2/ssl/Http2AlpnWithCertsTest.java
@@ -38,13 +38,14 @@
import static io.ballerina.stdlib.http.transport.contract.Constants.HTTPS_SCHEME;
import static io.ballerina.stdlib.http.transport.contract.Constants.HTTP_2_0;
+import static io.ballerina.stdlib.http.transport.contract.Constants.REQUIRE;
/**
- * Test ALPN protocol negotiation for HTTP2 with Certificates and keys.
+ * Test mTLS with certs and keys in HTTP2.
*/
-public class Http2ALPNwithCertsTest {
+public class Http2AlpnWithCertsTest {
- private static final Logger LOG = LoggerFactory.getLogger(Http2ALPNwithCertsTest.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Http2AlpnWithCertsTest.class);
private ServerConnector serverConnector;
private HttpClientConnector httpClientConnector;
private HttpWsConnectorFactory connectorFactory;
@@ -64,7 +65,7 @@ public void setup() throws InterruptedException {
}
@Test
- public void testHttp2ALPNwithCerts() {
+ public void testHttp2AlpnWithcerts() {
TestUtil.testHttpsPost(httpClientConnector, TestUtil.SERVER_PORT1);
}
@@ -77,12 +78,16 @@ private ListenerConfiguration getListenerConfigs() {
listenerConfiguration.setSslHandshakeTimeOut(TestUtil.SSL_HANDSHAKE_TIMEOUT);
listenerConfiguration.setServerKeyFile(TestUtil.getAbsolutePath(TestUtil.KEY_FILE));
listenerConfiguration.setServerCertificates(TestUtil.getAbsolutePath(TestUtil.CERT_FILE));
+ listenerConfiguration.setVerifyClient(REQUIRE);
+ listenerConfiguration.setServerTrustCertificates(TestUtil.getAbsolutePath(TestUtil.CERT_FILE));
return listenerConfiguration;
}
private SenderConfiguration getSenderConfigs() {
SenderConfiguration senderConfiguration = new SenderConfiguration();
senderConfiguration.setClientTrustCertificates(TestUtil.getAbsolutePath(TestUtil.CERT_FILE));
+ senderConfiguration.setClientKeyFile(TestUtil.getAbsolutePath(TestUtil.KEY_FILE));
+ senderConfiguration.setClientCertificates(TestUtil.getAbsolutePath(TestUtil.CERT_FILE));
senderConfiguration.setHttpVersion(HTTP_2_0);
senderConfiguration.setScheme(HTTPS_SCHEME);
senderConfiguration.setSslSessionTimeOut(TestUtil.SSL_SESSION_TIMEOUT);
diff --git a/native/src/test/resources/testng.xml b/native/src/test/resources/testng.xml
index 899f33ba7b..6f7dbcd813 100644
--- a/native/src/test/resources/testng.xml
+++ b/native/src/test/resources/testng.xml
@@ -174,7 +174,7 @@
-
+