Skip to content

Commit 4e39324

Browse files
committed
Add http protocols list configuration
The default setting prefers H2, but fallback to Http/1.1
1 parent 5ddaf98 commit 4e39324

File tree

12 files changed

+93
-113
lines changed

12 files changed

+93
-113
lines changed

driver/src/main/java/oracle/nosql/driver/NoSQLHandleConfig.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import oracle.nosql.driver.Region.RegionProvider;
2323
import oracle.nosql.driver.iam.SignatureProvider;
24+
import io.netty.handler.ssl.ApplicationProtocolNames;
2425
import io.netty.handler.ssl.SslContext;
2526

2627
/**
@@ -143,11 +144,11 @@ public class NoSQLHandleConfig implements Cloneable {
143144
private int maxChunkSize = 0;
144145

145146
/**
146-
* Use http2 protocol
147+
* Default http protocols
147148
*
148-
* Default: false (use http_1_1)
149+
* Default: prefer H2 but fallback to Http1.1
149150
*/
150-
private boolean http2 = false;
151+
private List<String> httpProtocols = new ArrayList<>(Arrays.asList(ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1));
151152

152153
/**
153154
* A RetryHandler, or null if not configured by the user.
@@ -562,10 +563,19 @@ public int getDefaultRequestTimeout() {
562563

563564
/**
564565
*
565-
* @return http2 setting
566+
* @return Http protocol settings
567+
*/
568+
public List<String> getHttpProtocols() {
569+
return httpProtocols;
570+
}
571+
572+
/**
573+
* Check if "h2" is in the protocols list
574+
*
575+
* @return true if "h2" is in the protocols list
566576
*/
567577
public boolean useHttp2() {
568-
return http2;
578+
return this.httpProtocols.contains(ApplicationProtocolNames.HTTP_2);
569579
}
570580

571581
/**
@@ -646,6 +656,14 @@ public NoSQLHandleConfig setRequestTimeout(int timeout) {
646656
return this;
647657
}
648658

659+
public NoSQLHandleConfig setHttpProtocols(String ... protocols) {
660+
this.httpProtocols = new ArrayList<>(2);
661+
for (String p : protocols) {
662+
this.httpProtocols.add(p);
663+
}
664+
return this;
665+
}
666+
649667
/**
650668
* Sets the default table request timeout.
651669
* The table request timeout can be specified independently
@@ -803,15 +821,6 @@ public NoSQLHandleConfig setMaxContentLength(int maxContentLength) {
803821
return this;
804822
}
805823

806-
/**
807-
* Enables http2 protocol
808-
* @return this
809-
*/
810-
public NoSQLHandleConfig useHttp2(boolean enable) {
811-
this.http2 = enable;
812-
return this;
813-
}
814-
815824
/**
816825
* Returns the maximum size, in bytes, of a request operation payload.
817826
* On-premise only. This value is ignored for cloud operations.

driver/src/main/java/oracle/nosql/driver/http/Client.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,12 @@ public Client(Logger logger,
244244
httpConfig.getNumThreads(),
245245
httpConfig.getConnectionPoolMinSize(),
246246
httpConfig.getConnectionPoolInactivityPeriod(),
247-
httpConfig.useHttp2(),
248247
httpConfig.getMaxContentLength(),
249248
httpConfig.getMaxChunkSize(),
250249
sslCtx,
251250
config.getSSLHandshakeTimeout(),
252251
"NoSQL Driver",
252+
config.getHttpProtocols(),
253253
logger);
254254
if (httpConfig.getProxyHost() != null) {
255255
httpClient.configureProxy(httpConfig);

driver/src/main/java/oracle/nosql/driver/http/NoSQLHandleImpl.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,12 @@ private void configSslContext(NoSQLHandleConfig config) {
130130
builder.sessionCacheSize(config.getSSLSessionCacheSize());
131131
if (config.useHttp2()) {
132132
builder.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE);
133-
builder.applicationProtocolConfig(
134-
new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN,
135-
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
136-
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
137-
ApplicationProtocolNames.HTTP_2));
138-
} else {
139-
builder.applicationProtocolConfig(
140-
new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN,
141-
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
142-
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
143-
ApplicationProtocolNames.HTTP_1_1));
144133
}
134+
builder.applicationProtocolConfig(
135+
new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN,
136+
ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,
137+
ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT,
138+
config.getHttpProtocols()));
145139
config.setSslContext(builder.build());
146140
} catch (SSLException se) {
147141
throw new IllegalStateException(
@@ -155,7 +149,7 @@ private void configAuthProvider(Logger logger, NoSQLHandleConfig config) {
155149
if (ap instanceof StoreAccessTokenProvider) {
156150
final StoreAccessTokenProvider stProvider =
157151
(StoreAccessTokenProvider) ap;
158-
stProvider.useHttp2(config.useHttp2());
152+
stProvider.setHttpProtocols(config.getHttpProtocols());
159153
if (stProvider.getLogger() == null) {
160154
stProvider.setLogger(logger);
161155
}

driver/src/main/java/oracle/nosql/driver/httpclient/Http2SettingsHandler.java

Lines changed: 0 additions & 46 deletions
This file was deleted.

driver/src/main/java/oracle/nosql/driver/httpclient/HttpClient.java

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import static oracle.nosql.driver.util.LogUtil.logWarning;
1818

1919
import java.io.IOException;
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.List;
2023
import java.util.concurrent.ExecutionException;
2124
import java.util.concurrent.TimeUnit;
2225
import java.util.concurrent.TimeoutException;
@@ -97,7 +100,8 @@ public class HttpClient {
97100
private final String host;
98101
private final int port;
99102
private final String name;
100-
private final boolean http2;
103+
private final List<String> httpProtocols;
104+
private final String httpFallbackProtocol;
101105

102106
/*
103107
* Amount of time to wait for acquiring a channel before timing
@@ -132,29 +136,28 @@ public class HttpClient {
132136
*
133137
* @param host the hostname for the HTTP server
134138
* @param port the port for the HTTP server
135-
* @param useHttp2 if set to true, use http2 connections.
136139
* @param sslCtx if non-null, SSL context to use for connections.
137140
* @param handshakeTimeoutMs if not zero, timeout to use for SSL handshake
138141
* @param name A name to use in logging messages for this client.
139142
* @param logger A logger to use for logging messages.
143+
* @param httpProtocols A list of preferred http protocols (H2 and Http1.1)
140144
*/
141145
public static HttpClient createMinimalClient(String host,
142146
int port,
143-
boolean useHttp2,
144147
SslContext sslCtx,
145148
int handshakeTimeoutMs,
146149
String name,
150+
List<String> httpProtocols,
147151
Logger logger) {
148152
return new HttpClient(host,
149153
port,
150154
1, /* nThreads */
151155
0, /* pool min */
152156
0, /* pool inactivity period */
153157
true, /* minimal client */
154-
useHttp2,
155158
DEFAULT_MAX_CONTENT_LENGTH,
156159
DEFAULT_MAX_CHUNK_SIZE,
157-
sslCtx, handshakeTimeoutMs, name, logger);
160+
sslCtx, handshakeTimeoutMs, name, httpProtocols, logger);
158161
}
159162

160163
/**
@@ -183,23 +186,24 @@ public static HttpClient createMinimalClient(String host,
183186
* @param handshakeTimeoutMs if not zero, timeout to use for SSL handshake
184187
* @param name A name to use in logging messages for this client.
185188
* @param logger A logger to use for logging messages.
189+
* @param httpProtocols A list of preferred http protocols (H2 and Http1.1)
186190
*/
187191
public HttpClient(String host,
188192
int port,
189193
int numThreads,
190194
int connectionPoolMinSize,
191195
int inactivityPeriodSeconds,
192-
boolean isHttp2,
193196
int maxContentLength,
194197
int maxChunkSize,
195198
SslContext sslCtx,
196199
int handshakeTimeoutMs,
197200
String name,
201+
List<String> httpProtocols,
198202
Logger logger) {
199203

200204
this(host, port, numThreads, connectionPoolMinSize,
201-
inactivityPeriodSeconds, false /* not minimal */, isHttp2,
202-
maxContentLength, maxChunkSize, sslCtx, handshakeTimeoutMs, name, logger);
205+
inactivityPeriodSeconds, false /* not minimal */,
206+
maxContentLength, maxChunkSize, sslCtx, handshakeTimeoutMs, name, httpProtocols, logger);
203207
}
204208

205209
/*
@@ -211,20 +215,25 @@ private HttpClient(String host,
211215
int connectionPoolMinSize,
212216
int inactivityPeriodSeconds,
213217
boolean isMinimalClient,
214-
boolean isHttp2,
215218
int maxContentLength,
216219
int maxChunkSize,
217220
SslContext sslCtx,
218221
int handshakeTimeoutMs,
219222
String name,
223+
List<String> httpProtocols,
220224
Logger logger) {
221225

222226
this.logger = logger;
223227
this.sslCtx = sslCtx;
224228
this.host = host;
225229
this.port = port;
226230
this.name = name;
227-
this.http2 = isHttp2;
231+
232+
this.httpProtocols = httpProtocols.size() > 0 ?
233+
httpProtocols :
234+
new ArrayList<>(Arrays.asList(ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1));
235+
236+
this.httpFallbackProtocol = this.httpProtocols.get(this.httpProtocols.size() - 1);
228237

229238
this.maxContentLength = (maxContentLength == 0 ?
230239
DEFAULT_MAX_CONTENT_LENGTH : maxContentLength);
@@ -300,8 +309,12 @@ String getName() {
300309
return name;
301310
}
302311

303-
boolean isHttp2() {
304-
return http2;
312+
List<String> getHttpProtocols() {
313+
return httpProtocols;
314+
}
315+
316+
public String getHttpFallbackProtocol() {
317+
return httpFallbackProtocol;
305318
}
306319

307320
Logger getLogger() {
@@ -312,10 +325,6 @@ int getHandshakeTimeoutMs() {
312325
return handshakeTimeoutMs;
313326
}
314327

315-
public String getFallbackProtocol() {
316-
return ApplicationProtocolNames.HTTP_1_1;
317-
}
318-
319328
public int getMaxContentLength() {
320329
return maxContentLength;
321330
}

driver/src/main/java/oracle/nosql/driver/httpclient/HttpClientChannelPoolHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void channelCreated(Channel ch) {
7777
p.addLast(new ChannelLoggingHandler(client));
7878
// Handle ALPN protocol negotiation result, and configure the pipeline accordingly
7979
p.addLast(new HttpProtocolNegotiationHandler(
80-
client.getFallbackProtocol(), new HttpClientHandler(client.getLogger()), client.getMaxChunkSize(),
80+
client.getHttpFallbackProtocol(), new HttpClientHandler(client.getLogger()), client.getMaxChunkSize(),
8181
client.getMaxContentLength(), client.getLogger()));
8282
} else {
8383
// TODO: H2C upgrade

driver/src/main/java/oracle/nosql/driver/httpclient/HttpProtocolNegotiationHandler.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* Handle TLS protocol negotiation result, either Http1.1 or H2
3737
*
3838
* The channel initialization process:
39-
* 1. Channel aquired from {@link ConnectionPool} after channel is active.
39+
* 1. Channel acquired from {@link ConnectionPool} after channel is active.
4040
* 2. SSL negotiation started, pipeline is not ready.
4141
* 3. {@link HttpProtocolNegotiationHandler} holds all {@link HttpMessage} while waiting for the negotiation result.
4242
* 4. Negotiation finished, {@link HttpProtocolNegotiationHandler} changes the pipeline according to the protocol selected.
@@ -121,7 +121,7 @@ protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
121121
/*
122122
* User can write requests right after the channel is active, while protocol
123123
* negotiation is still in progress. At this stage the pipeline is not ready
124-
* to write http request so we must hold them here.
124+
* to write http requests, so we must hold them here.
125125
*/
126126
@Override
127127
public void write(ChannelHandlerContext ctx, Object o, ChannelPromise channelPromise) throws Exception {
@@ -137,7 +137,7 @@ public void write(ChannelHandlerContext ctx, Object o, ChannelPromise channelPro
137137

138138
/*
139139
* Protocol negotiation finish, handler removed, the pipeline is
140-
* ready to handle http messages. Write previousely buffered http messages.
140+
* ready to handle http messages. Write previously buffered http messages.
141141
*/
142142
@Override
143143
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
@@ -196,8 +196,9 @@ public String toString() {
196196

197197
public boolean equals(Object other) {
198198
if (other instanceof Pair<?, ?>) {
199-
return Objects.equals(first, ((Pair<?, ?>) other).first) &&
200-
Objects.equals(second, ((Pair<?, ?>) other).second);
199+
Pair<?,?> pair = (Pair<?,?>) other;
200+
return Objects.equals(first, pair.first) &&
201+
Objects.equals(second, pair.second);
201202
}
202203
return false;
203204
}

driver/src/main/java/oracle/nosql/driver/iam/InstancePrincipalsProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
import java.io.InputStream;
2020
import java.net.MalformedURLException;
2121
import java.net.URL;
22+
import java.util.Arrays;
2223
import java.util.HashSet;
2324
import java.util.Set;
2425
import java.util.logging.Logger;
2526

27+
import io.netty.handler.ssl.ApplicationProtocolNames;
2628
import oracle.nosql.driver.NoSQLHandleConfig;
2729
import oracle.nosql.driver.Region;
2830
import oracle.nosql.driver.Region.RegionProvider;
@@ -295,10 +297,10 @@ private void autoDetectEndpointUsingMetadataUrl() {
295297
try {
296298
client = HttpClient.createMinimalClient(METADATA_SERVICE_HOST,
297299
80,
298-
false,
299300
null,
300301
0,
301302
"InstanceMDClient",
303+
Arrays.asList(ApplicationProtocolNames.HTTP_1_1),
302304
logger);
303305

304306
HttpResponse response = HttpRequestUtil.doGetRequest

0 commit comments

Comments
 (0)