blob: 804c838a83e38fab81b2ef5bba4b9290cf90cb48 [file]
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF 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.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" version="-//W3C//DTDXHTML1.1//EN">
<head>
<meta http-equiv="content-type" content=""/>
<title>HTTP/2 Transport</title>
</head>
<body lang="en">
<a name="H2TransportSender"></a>
<h2>H2TransportSender (HTTP/2 Transport)</h2>
<h3>🚀 TL;DR - Quick Start for Large Payloads (50MB+)</h3>
<p><strong>Most Common Use Case:</strong> Processing 50MB+ JSON payloads with optimal performance</p>
<p><strong>Production Configuration (axis2.xml) - AWS/Cloudflare Ready:</strong></p>
<pre>
&lt;transportSender name="h2" class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/2.0&lt;/parameter&gt;
&lt;!-- ALPN Support (Required for AWS ALB, Cloudflare) --&gt;
&lt;parameter name="alpnProtocols"&gt;h2,http/1.1&lt;/parameter&gt;
&lt;parameter name="tlsRequired"&gt;true&lt;/parameter&gt;
&lt;!-- Large Payload Optimization --&gt;
&lt;parameter name="maxConcurrentStreams"&gt;20&lt;/parameter&gt;
&lt;parameter name="initialWindowSize"&gt;2097152&lt;/parameter&gt; &lt;!-- 2MB window --&gt;
&lt;!-- Timeouts --&gt;
&lt;parameter name="connectionTimeout"&gt;30000&lt;/parameter&gt; &lt;!-- 30s connect --&gt;
&lt;parameter name="responseTimeout"&gt;300000&lt;/parameter&gt; &lt;!-- 5min response --&gt;
&lt;!-- HTTP/2 fallback to HTTP/1.1 is automatic via TLS ALPN --&gt;
&lt;/transportSender&gt;
</pre>
<p><strong>Client Access for 50MB JSON Payloads:</strong></p>
<p>Most JSON clients will use <strong>curl</strong> or <strong>Apache HTTP Components</strong> directly:</p>
<pre>
# curl with HTTP/2 for large JSON payloads (AWS/Cloudflare compatible)
curl --http2-prior-knowledge -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "User-Agent: MyApp/1.0" \
--max-time 300 --connect-timeout 30 \
--compressed \
--data @large-payload.json \
https://server:8443/services/BigDataService
# Apache HTTP Components 5.x (Java clients)
CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
.build();
httpClient.start();
HttpPost request = new HttpPost("https://server:8443/services/BigDataService");
request.setEntity(new StringEntity(jsonPayload, ContentType.APPLICATION_JSON));
</pre>
<p><strong>Expected Performance:</strong> 40-70% faster than HTTP/1.1 for 50MB+ JSON payloads with 20% less memory usage</p>
<p><strong>Note:</strong> Server push is disabled by default as it's not beneficial for JSON APIs
(see "Server Push Capabilities" section below for detailed explanation).</p>
<hr/>
<p>H2TransportSender provides enterprise-grade HTTP/2 transport capabilities using HttpClient 5.x
with advanced features for large payload processing, connection multiplexing, and performance optimization.
This transport is specifically designed for big data applications requiring 50MB+ JSON payload support
with memory-efficient 64 KB flush intervals.</p>
<p>HTTP/2 offers significant advantages over HTTP/1.1:</p>
<ul>
<li>Binary protocol with header compression (HPACK)</li>
<li>Stream multiplexing - multiple concurrent requests over single connection</li>
<li>Server push capabilities (configurable)</li>
<li>Improved flow control with window scaling</li>
<li>Enhanced performance for large payloads</li>
<li>Reduced connection overhead and latency</li>
</ul>
<h3>Basic HTTP/2 Configuration</h3>
<p>The &lt;transportSender/&gt; element for HTTP/2 transport:</p>
<pre>
&lt;transportSender name="h2" class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/2.0&lt;/parameter&gt;
&lt;parameter name="maxConcurrentStreams"&gt;100&lt;/parameter&gt;
&lt;parameter name="initialWindowSize"&gt;2097152&lt;/parameter&gt; &lt;!-- 2MB -- see note below --&gt;
&lt;parameter name="serverPushEnabled"&gt;false&lt;/parameter&gt;
&lt;parameter name="memoryOptimized"&gt;true&lt;/parameter&gt;
&lt;/transportSender&gt;
</pre>
<div style="background-color: #fff8e1; border: 1px solid #f9a825; padding: 15px; margin: 15px 0;">
<h4>Flow-control window vs. streaming flush interval</h4>
<p><code>initialWindowSize</code> and the <code>FlushingOutputStream</code>
64 KB flush interval are <strong>independent settings that should not be
"aligned"</strong> to the same value.</p>
<ul>
<li><strong>FlushingOutputStream flush (server-side, 64 KB)</strong> —
controls when serialized bytes are pushed into the HTTP/2 framing
layer. 64 KB is a good cadence: it gives early time-to-first-byte
and prevents reverse proxy timeouts on long-running serializations.
This value is correct and should not change.</li>
<li><strong>initialWindowSize (client-side, per-stream)</strong> —
controls how much data a stream may have in-flight before the
sender pauses for a WINDOW_UPDATE acknowledgement from the
receiver. A 10 MB response with a 64 KB window requires ~156
WINDOW_UPDATE round-trips; with a 2 MB window it requires ~5.
Under concurrent load, these round-trips serialize on each TCP
connection, adding significant latency.</li>
</ul>
<p>A server flushing at 64 KB works well with a client whose
window is 2 MB — the server sends 64 KB, the framing layer
accumulates up to 2 MB of in-flight data, and the client
acknowledges in bulk. Setting both to 64 KB forces the client to
acknowledge every single flush, converting each 64 KB chunk into a
synchronous round-trip.</p>
</div>
<h3>HTTP/2 Configuration Parameters</h3>
<table border="1">
<tr><th>Parameter</th><th>Description</th><th>Default</th><th>Range</th></tr>
<tr><td>maxConcurrentStreams</td><td>Maximum concurrent streams per connection. Lower values (4-8) force the connection pool to spread streams across multiple TCP connections — better for workloads with few concurrent large payloads. Higher values (50-100) maximize multiplexing efficiency for many small concurrent requests.</td><td>100</td><td>1-1000</td></tr>
<tr><td>initialWindowSize</td><td>HTTP/2 per-stream flow-control window (bytes). Determines how much data can be in-flight per stream before the sender waits for a WINDOW_UPDATE. For payloads above 1 MB, use at least 1-2 MB to avoid excessive round-trips. Not related to the server-side FlushingOutputStream 64 KB flush interval.</td><td>2097152</td><td>64KB-16MB</td></tr>
<tr><td>streamingBufferSize</td><td>Buffer size for streaming flush interval</td><td>65536</td><td>8KB-1MB</td></tr>
<tr><td>connectionTimeout</td><td>Connection establishment timeout (ms)</td><td>30000</td><td>1000-60000</td></tr>
<tr><td>responseTimeout</td><td>Response timeout for large payloads (ms)</td><td>300000</td><td>30000-600000</td></tr>
</table>
<h3>Tuning for Different Workloads</h3>
<p>The optimal <code>maxConcurrentStreams</code> and
<code>initialWindowSize</code> depend on your traffic pattern. With
Apache HttpComponents 5.x, the <code>PoolingAsyncClientConnectionManager</code>
only opens a new TCP connection when all existing connections have reached
their <code>maxConcurrentStreams</code> limit. If this value is higher
than your typical concurrency, the pool will multiplex all streams onto a
single connection — which is efficient for many small requests but creates
flow-control contention for concurrent large payloads.</p>
<table border="1">
<tr><th>Workload</th><th>Example</th><th>maxConcurrentStreams</th><th>initialWindowSize</th><th>maxConnPerRoute</th></tr>
<tr><td>Many small concurrent requests</td><td>Microservice mesh, API gateway</td><td>50-100</td><td>2 MB</td><td>10</td></tr>
<tr><td>Few large concurrent payloads</td><td>Batch processing, ETL, report generation</td><td>4-8</td><td>8 MB</td><td>16-32</td></tr>
<tr><td>Mixed traffic</td><td>General-purpose service client</td><td>8-16</td><td>2 MB</td><td>16</td></tr>
</table>
<h4>Client-side vs. server-side window: where tuning matters</h4>
<p>HTTP/2 flow control is bidirectional — both client and server
advertise an <code>initialWindowSize</code>. For typical Axis2
deployments where the server produces large JSON responses and the
client sends smaller requests (query parameters, filter criteria),
the <strong>client-side window is the critical tuning point</strong>.
It governs how much response data the server can push before pausing
for a WINDOW_UPDATE from the client. A 64 KB client window on a
10 MB response means ~156 pause-and-acknowledge cycles.</p>
<p>The server's inbound window (configured in the application server —
e.g., WildFly's <code>http2-initial-window-size</code>, Tomcat's
<code>http2InitialWindowSize</code>) controls how much
<em>request</em> data the server allows in-flight. Since requests
are typically small relative to responses, the server-side default
(64 KB per the HTTP/2 spec) is usually adequate. Focus tuning effort
on the <code>H2TransportSender</code> client-side
<code>initialWindowSize</code> shown above.</p>
<p>If a single client consumes both small and large payload endpoints on
different hosts, consider configuring separate
<code>CloseableHttpAsyncClient</code> instances with per-workload tuning.
The connection pool's <code>maxConnPerRoute</code> already isolates
traffic by host, but <code>maxConcurrentStreams</code> and
<code>initialWindowSize</code> apply to the entire client.</p>
<h3>Enterprise Big Data Configuration</h3>
<p>For enterprise applications processing large JSON datasets (50MB+), use the following optimized configuration.
Note the lower <code>maxConcurrentStreams</code> (forces the pool to open multiple TCP connections under concurrent
load) and larger <code>initialWindowSize</code> (eliminates per-stream flow-control round-trips):</p>
<pre>
&lt;transportSender name="h2" class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/2.0&lt;/parameter&gt;
&lt;!-- Stream Management: low stream count forces connection pooling
instead of multiplexing all large payloads onto one TCP connection --&gt;
&lt;parameter name="maxConcurrentStreams"&gt;4&lt;/parameter&gt;
&lt;parameter name="initialWindowSize"&gt;8388608&lt;/parameter&gt; &lt;!-- 8MB -- a 50MB payload completes in ~6 window updates --&gt;
&lt;parameter name="maxFrameSize"&gt;32768&lt;/parameter&gt;
&lt;!-- Large Payload Optimization --&gt;
&lt;parameter name="streamingBufferSize"&gt;65536&lt;/parameter&gt;
&lt;parameter name="memoryOptimized"&gt;true&lt;/parameter&gt;
&lt;!-- Connection Management: sized for concurrent large-payload fan-out --&gt;
&lt;parameter name="maxConnTotal"&gt;64&lt;/parameter&gt;
&lt;parameter name="maxConnPerRoute"&gt;32&lt;/parameter&gt;
&lt;!-- Timeouts for Large Payloads --&gt;
&lt;parameter name="connectionTimeout"&gt;30000&lt;/parameter&gt;
&lt;parameter name="responseTimeout"&gt;300000&lt;/parameter&gt;
&lt;/transportSender&gt;
</pre>
<h3>HTTPS with HTTP/2 (ALPN)</h3>
<p>HTTP/2 over HTTPS requires Application-Layer Protocol Negotiation (ALPN). The H2TransportSender
automatically handles ALPN negotiation when used with HTTPS endpoints:</p>
<pre>
&lt;transportSender name="h2" class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/2.0&lt;/parameter&gt;
&lt;parameter name="tlsRequired"&gt;true&lt;/parameter&gt;
&lt;parameter name="alpnProtocols"&gt;h2,http/1.1&lt;/parameter&gt;
&lt;/transportSender&gt;
</pre>
<h3>Stream Multiplexing Configuration</h3>
<p>HTTP/2 stream multiplexing allows multiple concurrent requests over a single connection,
significantly improving performance for concurrent operations:</p>
<pre>
// Enable HTTP/2 multiplexing in client code
Options options = new Options();
options.setProperty(HTTPConstants.TRANSPORT_NAME, "h2");
// HTTP/2 multiplexing is automatic when using the h2 transport.
// No additional boolean flags are needed.
</pre>
<h3>Large Payload Processing</h3>
<p>The H2TransportSender provides three processing modes optimized for different payload sizes:</p>
<ul>
<li><strong>Standard Processing</strong> (0MB-10MB): Regular HTTP/2 features</li>
<li><strong>Multiplexing Mode</strong> (10-50MB): Enhanced concurrent processing</li>
<li><strong>Streaming Mode</strong> (50MB+): Memory-efficient streaming with chunked processing</li>
</ul>
<p>Streaming and memory optimization are controlled by the message formatter
selected in axis2.xml (e.g. <code>MoshiStreamingMessageFormatter</code>).
No client-side <code>Options</code> properties are required — the transport
sender negotiates HTTP/2 framing and flow control automatically.</p>
<h3>Performance Monitoring</h3>
<p>For production monitoring, use Micrometer with Prometheus/Grafana or
Spring Boot Actuator endpoints. Application-level logging via the
Axis2 log configuration provides per-request timing details.</p>
<p>Available metrics include:</p>
<ul>
<li>Stream allocation and utilization</li>
<li>Memory usage and buffer efficiency</li>
<li>Processing time and throughput</li>
<li>Compression ratios and bandwidth savings</li>
<li>Connection reuse statistics</li>
</ul>
<h3>Flow Control</h3>
<p>HTTP/2 flow control is handled automatically by the transport layer.
The <code>initialWindowSize</code> parameter on the transport sender controls
the initial flow-control window; beyond that, the HTTP/2 implementation
manages window updates and back-pressure without additional configuration.</p>
<h3>Compression</h3>
<p>Response compression is handled by the servlet container (Tomcat, WildFly, etc.),
not by the Axis2 transport. Configure compression in your container's server
configuration (e.g., Tomcat's <code>server.xml</code> <code>compression</code>
attribute, or WildFly's Undertow content-encoding filter). HTTP/2 header
compression (HPACK) is always active and requires no Axis2 configuration.</p>
<h3>Memory Management</h3>
<p>Buffer management is handled internally by Apache HttpComponents 5.x.
The JVM's default direct memory limit (equal to <code>-Xmx</code>) is
sufficient for most deployments. No additional JVM flags are needed
for HTTP/2 buffer management.</p>
<h3>Error Handling and Fallback</h3>
<p>When the remote server does not support HTTP/2, the TLS ALPN negotiation
falls back to HTTP/1.1 automatically. No explicit fallback parameters are
required — Apache HttpComponents handles protocol negotiation.</p>
<h3>Server Push</h3>
<p>Server push is <strong>disabled by default</strong> — REST/JSON APIs follow
request-response patterns where push provides no benefit. Enable only
for web-app use cases with predictable resource dependencies:</p>
<pre>
&lt;parameter name="serverPushEnabled"&gt;false&lt;/parameter&gt; &lt;!-- default --&gt;
</pre>
<h3>Service-Level HTTP/2 Configuration</h3>
<p>Individual services can specify HTTP/2 preferences in their services.xml:</p>
<p>HTTP/2 is enabled at the transport level in axis2.xml, not per-service.
Select the H2TransportSender in the <code>&lt;transportSender&gt;</code> section
and configure its parameters there. For streaming large payloads, use the
streaming message formatter (e.g. <code>MoshiStreamingMessageFormatter</code>
or <code>JSONStreamingMessageFormatter</code>) in the service's message
receiver configuration. No service-level parameters are required.</p>
<h3>Client-Side HTTP/2 Usage for SOAP (for JSON, see curl and Apache HTTPComponents section)</h3>
<p>Complete client configuration example:</p>
<pre>
// Create HTTP/2 enabled service client
ConfigurationContext configContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(null, null);
ServiceClient serviceClient = new ServiceClient(configContext, null);
// Configure HTTP/2 transport
Options options = new Options();
options.setProperty(HTTPConstants.TRANSPORT_NAME, "h2");
options.setTo(new EndpointReference("https://localhost:8443/services/BigDataService"));
// HTTP/2 is negotiated by the transport sender selected in axis2.xml.
// No additional boolean flags are needed — the h2 transport handles
// multiplexing, streaming, and flow control automatically.
// Timeout settings for large payloads
options.setTimeOutInMilliSeconds(300000); // 5 minutes
options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, 30000);
options.setProperty(HTTPConstants.SO_TIMEOUT, 300000);
serviceClient.setOptions(options);
</pre>
<h3>Performance Comparison: HTTP/1.1 vs HTTP/2</h3>
<p>HTTP/2 transport can provide substantial improvements over HTTP/1.1.
The following are illustrative estimates — actual results depend on payload size,
network conditions, and JVM configuration:</p>
<table border="1">
<tr><th>Metric</th><th>HTTP/1.1</th><th>HTTP/2</th><th>Improvement</th></tr>
<tr><td>Connection Multiplexing</td><td>6-8 connections</td><td>100 concurrent streams</td><td>1,150-1,567%</td></tr>
<tr><td>Memory Efficiency</td><td>Standard allocation</td><td>Pooled buffers</td><td>30-50%</td></tr>
<tr><td>Large Payload (50MB)</td><td>Baseline</td><td>Streaming optimization</td><td>50-200%</td></tr>
<tr><td>Compression</td><td>Basic gzip</td><td>JSON-aware optimization</td><td>50-70%</td></tr>
<tr><td>Overall Throughput</td><td>Baseline</td><td>Combined optimizations</td><td>70-150%</td></tr>
</table>
<h3>Troubleshooting HTTP/2</h3>
<p>Common HTTP/2 configuration issues and solutions:</p>
<h4>ALPN Not Available</h4>
<pre>
// Ensure ALPN support is available
System.setProperty("java.security.properties", "jdk.tls.alpnCharset=UTF-8");
</pre>
<h4>Memory Issues with Large Payloads</h4>
<pre>
// Increase heap size for large JSON payloads
-Xmx4g -XX:+UseG1GC
</pre>
<h4>Connection Issues</h4>
<p>HTTP/2 fallback to HTTP/1.1 is automatic via TLS ALPN negotiation.
If the server does not advertise h2, the client falls back transparently.
Increase <code>connectionTimeout</code> on the transport sender if ALPN
negotiation is slow on your network.</p>
<h3>Migration from HTTP/1.1 to HTTP/2</h3>
<p>To migrate existing HTTP/1.1 configurations to HTTP/2:</p>
<ol>
<li>Change transport sender class to H2TransportSender</li>
<li>Update protocol parameter to HTTP/2.0</li>
<li>Add HTTP/2 specific parameters</li>
<li>Configure HTTPS with ALPN support</li>
<li>Test with fallback enabled</li>
</ol>
<p>Example migration:</p>
<pre>
&lt;!-- HTTP/1.1 Configuration --&gt;
&lt;transportSender name="http" class="org.apache.axis2.transport.http.impl.httpclient5.HTTPClient5TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/1.1&lt;/parameter&gt;
&lt;parameter name="Transfer-Encoding"&gt;chunked&lt;/parameter&gt;
&lt;/transportSender&gt;
&lt;!-- HTTP/2 Configuration --&gt;
&lt;transportSender name="h2" class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/2.0&lt;/parameter&gt;
&lt;parameter name="maxConcurrentStreams"&gt;100&lt;/parameter&gt;
&lt;parameter name="initialWindowSize"&gt;2097152&lt;/parameter&gt;
&lt;!-- Fallback to HTTP/1.1 is automatic via TLS ALPN negotiation --&gt;
&lt;/transportSender&gt;
</pre>
<h3>SSL Client Authentication (2-Way SSL) with HTTP/2</h3>
<p>HTTP/2 transport supports SSL client authentication (mutual TLS) similar to HTTP/1.1, with enhanced
features for certificate management and ALPN negotiation. You can configure your own HttpAsyncClient
with custom SSL context and certificate handling.</p>
<p>The HTTP/2 transport supports the same certificate management as HTTP/1.1 but uses async client
architecture. To control max connections per host, SSL configuration, or other advanced parameters,
set the cached HTTP/2 client using the CACHED_HTTP2_ASYNC_CLIENT property before making requests.</p>
<p>The following example shows SSL client authentication configuration tested with Axis2 on WildFly 32:</p>
<pre>
// Certificate and TrustStore setup (same as HTTP/1.1)
String wildflyserver_cert_path = "src/wildflyserver.crt";
Certificate certificate = CertificateFactory.getInstance("X.509")
.generateCertificate(new FileInputStream(new File(wildflyserver_cert_path)));
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("server", certificate);
TrustManagerFactory trustManagerFactory = null;
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new Exception("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
// SSL Context with TLS 1.3 support for HTTP/2
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, trustManagers, new SecureRandom());
// HTTP/2 specific TLS strategy with ALPN support
TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
.setSslContext(sslContext)
.setHostnameVerifier(NoopHostnameVerifier.INSTANCE) // For self-signed certificates
.setTlsDetailsFactory(sslEngine -&gt; {
// Configure ALPN protocols for HTTP/2 negotiation
SSLParameters sslParams = sslEngine.getSSLParameters();
sslParams.setApplicationProtocols(new String[]{"h2", "http/1.1"});
sslEngine.setSSLParameters(sslParams);
return null;
})
.build();
// HTTP/2 async connection manager with SSL configuration
PoolingAsyncClientConnectionManager connManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(tlsStrategy)
.setMaxConnTotal(100)
.setMaxConnPerRoute(100)
.build();
// Create HTTP/2 async client with SSL configuration
CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients.custom()
.setConnectionManager(connManager)
.setConnectionManagerShared(true)
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE) // Allow HTTP/2 negotiation
.build();
httpAsyncClient.start(); // Important: Start the async client
// Configure service client with HTTP/2 SSL client
Options options = new Options();
options.setTo(new EndpointReference("https://myserver:8443/services/MyService"));
options.setProperty(HTTPConstants.TRANSPORT_NAME, "h2"); // Use HTTP/2 transport
options.setTimeOutInMilliSeconds(120000);
// Set the cached HTTP/2 async client (HTTP/2 equivalent of CACHED_HTTP_CLIENT)
options.setProperty("CACHED_HTTP2_ASYNC_CLIENT", httpAsyncClient);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
</pre>
<h3>HTTP/2 SSL Configuration Parameters</h3>
<p>The HTTP/2 transport provides additional SSL-specific parameters:</p>
<table border="1">
<tr><th>Parameter</th><th>Description</th><th>Default</th><th>HTTP/1.1 Equivalent</th></tr>
<tr><td>CACHED_HTTP2_ASYNC_CLIENT</td><td>Custom HTTP/2 async client with SSL config</td><td>None</td><td>CACHED_HTTP_CLIENT</td></tr>
<tr><td>tlsRequired</td><td>Enforce HTTPS-only for HTTP/2</td><td>true</td><td>N/A</td></tr>
<tr><td>alpnProtocols</td><td>ALPN protocol preferences</td><td>h2,http/1.1</td><td>N/A</td></tr>
<tr><td>supportedTLSVersions</td><td>Supported TLS versions</td><td>TLSv1.2,TLSv1.3</td><td>Similar</td></tr>
<tr><td>cipherSuites</td><td>Allowed cipher suites</td><td>TLS 1.3 defaults</td><td>Similar</td></tr>
</table>
<h3>Advanced SSL Configuration for HTTP/2</h3>
<p>For enterprise deployments requiring specific SSL configurations:</p>
<pre>
&lt;transportSender name="h2" class="org.apache.axis2.transport.h2.impl.httpclient5.H2TransportSender"&gt;
&lt;parameter name="PROTOCOL"&gt;HTTP/2.0&lt;/parameter&gt;
&lt;!-- SSL/TLS Configuration --&gt;
&lt;parameter name="tlsRequired"&gt;true&lt;/parameter&gt;
&lt;parameter name="supportedTLSVersions"&gt;TLSv1.2,TLSv1.3&lt;/parameter&gt;
&lt;parameter name="alpnProtocols"&gt;h2,http/1.1&lt;/parameter&gt;
&lt;!-- ALPN Configuration --&gt;
&lt;parameter name="alpnTimeout"&gt;5000&lt;/parameter&gt;
&lt;parameter name="alpnFallbackEnabled"&gt;true&lt;/parameter&gt;
&lt;!-- Certificate Validation --&gt;
&lt;parameter name="hostnameVerification"&gt;strict&lt;/parameter&gt;
&lt;parameter name="certificateValidation"&gt;strict&lt;/parameter&gt;
&lt;/transportSender&gt;
</pre>
<h3>Client Certificate Authentication</h3>
<p>For mutual TLS (client certificate authentication) with HTTP/2:</p>
<pre>
// Load client certificate and private key
KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
clientKeyStore.load(new FileInputStream("client-cert.p12"), "password".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, "password".toCharArray());
// SSL Context with client certificate
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, new SecureRandom());
// Configure HTTP/2 client with client certificate authentication
TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
.setSslContext(sslContext)
.setTlsDetailsFactory(sslEngine -&gt; {
SSLParameters sslParams = sslEngine.getSSLParameters();
sslParams.setApplicationProtocols(new String[]{"h2", "http/1.1"});
sslParams.setNeedClientAuth(true); // Require client authentication
sslEngine.setSSLParameters(sslParams);
return null;
})
.build();
</pre>
<h3>HTTP/2 vs HTTP/1.1 SSL Differences</h3>
<p>Key differences in SSL handling between HTTP/1.1 and HTTP/2:</p>
<ul>
<li><strong>ALPN Support</strong>: HTTP/2 requires ALPN negotiation for protocol selection</li>
<li><strong>TLS Version</strong>: HTTP/2 requires TLS 1.2 or higher (TLS 1.3 recommended)</li>
<li><strong>Cipher Suites</strong>: HTTP/2 has specific cipher suite requirements (RFC 7540)</li>
<li><strong>Async Architecture</strong>: Uses CloseableHttpAsyncClient instead of CloseableHttpClient</li>
<li><strong>Connection Multiplexing</strong>: Single SSL connection handles multiple streams</li>
<li><strong>Fallback Handling</strong>: Automatic fallback to HTTP/1.1 if HTTP/2 negotiation fails</li>
</ul>
<h3>SSL Notes</h3>
<p>HTTP/2 requires TLS 1.2+ with ALPN. Use OpenJDK 11+ (ALPN built in).
If ALPN negotiation fails, the transport falls back to HTTP/1.1
automatically (no configuration flag required).</p>
</body>
</html>