42
42
import java .util .concurrent .ExecutionException ;
43
43
import java .util .concurrent .TimeUnit ;
44
44
import java .util .concurrent .TimeoutException ;
45
+ import java .util .function .Consumer ;
45
46
import org .slf4j .Logger ;
46
47
import org .slf4j .LoggerFactory ;
47
48
import software .amazon .awssdk .annotations .SdkPublicApi ;
@@ -77,6 +78,7 @@ public final class NettyNioAsyncHttpClient implements SdkAsyncHttpClient {
77
78
78
79
private static final Logger log = LoggerFactory .getLogger (NettyNioAsyncHttpClient .class );
79
80
private static final long MAX_STREAMS_ALLOWED = 4294967295L ; // unsigned 32-bit, 2^32 -1
81
+ private static final int DEFAULT_INITIAL_WINDOW_SIZE = 1_048_576 ; // 1MiB
80
82
81
83
// Override connection idle timeout for Netty http client to reduce the frequency of "server failed to complete the
82
84
// response error". see https://github.com/aws/aws-sdk-java-v2/issues/1122
@@ -91,13 +93,19 @@ public final class NettyNioAsyncHttpClient implements SdkAsyncHttpClient {
91
93
private NettyNioAsyncHttpClient (DefaultBuilder builder , AttributeMap serviceDefaultsMap ) {
92
94
this .configuration = new NettyConfiguration (serviceDefaultsMap );
93
95
Protocol protocol = serviceDefaultsMap .get (SdkHttpConfigurationOption .PROTOCOL );
94
- long maxStreams = builder .maxHttp2Streams == null ? MAX_STREAMS_ALLOWED : builder .maxHttp2Streams ;
95
96
this .sdkEventLoopGroup = eventLoopGroup (builder );
97
+
98
+ Http2Configuration http2Configuration = builder .http2Configuration ;
99
+
100
+ long maxStreams = resolveMaxHttp2Streams (builder .maxHttp2Streams , http2Configuration );
101
+ int initialWindowSize = resolveInitialWindowSize (http2Configuration );
102
+
96
103
this .pools = AwaitCloseChannelPoolMap .builder ()
97
104
.sdkChannelOptions (builder .sdkChannelOptions )
98
105
.configuration (configuration )
99
106
.protocol (protocol )
100
107
.maxStreams (maxStreams )
108
+ .initialWindowSize (initialWindowSize )
101
109
.sdkEventLoopGroup (sdkEventLoopGroup )
102
110
.sslProvider (resolveSslProvider (builder ))
103
111
.proxyConfiguration (builder .proxyConfiguration )
@@ -149,6 +157,25 @@ private SslProvider resolveSslProvider(DefaultBuilder builder) {
149
157
return SslContext .defaultClientProvider ();
150
158
}
151
159
160
+ private long resolveMaxHttp2Streams (Integer topLevelValue , Http2Configuration http2Configuration ) {
161
+ if (topLevelValue != null ) {
162
+ return topLevelValue ;
163
+ }
164
+
165
+ if (http2Configuration == null || http2Configuration .maxStreams () == null ) {
166
+ return MAX_STREAMS_ALLOWED ;
167
+ }
168
+
169
+ return Math .min (http2Configuration .maxStreams (), MAX_STREAMS_ALLOWED );
170
+ }
171
+
172
+ private int resolveInitialWindowSize (Http2Configuration http2Configuration ) {
173
+ if (http2Configuration == null || http2Configuration .initialWindowSize () == null ) {
174
+ return DEFAULT_INITIAL_WINDOW_SIZE ;
175
+ }
176
+ return http2Configuration .initialWindowSize ();
177
+ }
178
+
152
179
private SdkEventLoopGroup nonManagedEventLoopGroup (SdkEventLoopGroup eventLoopGroup ) {
153
180
return SdkEventLoopGroup .create (new NonManagedEventLoopGroup (eventLoopGroup .eventLoopGroup ()),
154
181
eventLoopGroup .channelFactory ());
@@ -343,6 +370,9 @@ public interface Builder extends SdkAsyncHttpClient.Builder<NettyNioAsyncHttpCli
343
370
*
344
371
* @param maxHttp2Streams Max concurrent HTTP/2 streams per connection.
345
372
* @return This builder for method chaining.
373
+ *
374
+ * @deprecated Use {@link #http2Configuration(Http2Configuration)} along with
375
+ * {@link Http2Configuration.Builder#maxStreams(Integer)} instead.
346
376
*/
347
377
Builder maxHttp2Streams (Integer maxHttp2Streams );
348
378
@@ -380,6 +410,28 @@ public interface Builder extends SdkAsyncHttpClient.Builder<NettyNioAsyncHttpCli
380
410
* @return The builder for method chaining.
381
411
*/
382
412
Builder tlsKeyManagersProvider (TlsKeyManagersProvider keyManagersProvider );
413
+
414
+ /**
415
+ * Set the HTTP/2 specific configuration for this client.
416
+ * <p>
417
+ * <b>Note:</b>If {@link #maxHttp2Streams(Integer)} and {@link Http2Configuration#maxStreams()} are both set,
418
+ * the value set using {@link #maxHttp2Streams(Integer)} takes precedence.
419
+ *
420
+ * @param http2Configuration The HTTP/2 configuration object.
421
+ * @return the builder for method chaining.
422
+ */
423
+ Builder http2Configuration (Http2Configuration http2Configuration );
424
+
425
+ /**
426
+ * Set the HTTP/2 specific configuration for this client.
427
+ * <p>
428
+ * <b>Note:</b>If {@link #maxHttp2Streams(Integer)} and {@link Http2Configuration#maxStreams()} are both set,
429
+ * the value set using {@link #maxHttp2Streams(Integer)} takes precedence.
430
+ *
431
+ * @param http2ConfigurationBuilderConsumer The consumer of the HTTP/2 configuration builder object.
432
+ * @return the builder for method chaining.
433
+ */
434
+ Builder http2Configuration (Consumer <Http2Configuration .Builder > http2ConfigurationBuilderConsumer );
383
435
}
384
436
385
437
/**
@@ -394,6 +446,7 @@ private static final class DefaultBuilder implements Builder {
394
446
private SdkEventLoopGroup eventLoopGroup ;
395
447
private SdkEventLoopGroup .Builder eventLoopGroupBuilder ;
396
448
private Integer maxHttp2Streams ;
449
+ private Http2Configuration http2Configuration ;
397
450
private SslProvider sslProvider ;
398
451
private ProxyConfiguration proxyConfiguration ;
399
452
@@ -568,6 +621,23 @@ public Builder tlsKeyManagersProvider(TlsKeyManagersProvider tlsKeyManagersProvi
568
621
return this ;
569
622
}
570
623
624
+ @ Override
625
+ public Builder http2Configuration (Http2Configuration http2Configuration ) {
626
+ this .http2Configuration = http2Configuration ;
627
+ return this ;
628
+ }
629
+
630
+ @ Override
631
+ public Builder http2Configuration (Consumer <Http2Configuration .Builder > http2ConfigurationBuilderConsumer ) {
632
+ Http2Configuration .Builder builder = Http2Configuration .builder ();
633
+ http2ConfigurationBuilderConsumer .accept (builder );
634
+ return http2Configuration (builder .build ());
635
+ }
636
+
637
+ public void setHttp2Configuration (Http2Configuration http2Configuration ) {
638
+ http2Configuration (http2Configuration );
639
+ }
640
+
571
641
@ Override
572
642
public SdkAsyncHttpClient buildWithDefaults (AttributeMap serviceDefaults ) {
573
643
return new NettyNioAsyncHttpClient (this , standardOptions .build ()
0 commit comments