8309910: Introduce jdk.internal.net.http.HttpConnection.getSNIServerNames() method

Reviewed-by: dfuchs
This commit is contained in:
Jaikiran Pai 2023-06-14 01:37:45 +00:00
parent 5d193193a3
commit ba837b4bfa
3 changed files with 41 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.util.ArrayDeque;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
@ -61,8 +62,8 @@ import static jdk.internal.net.http.common.Utils.ServerName;
abstract class AbstractAsyncSSLConnection extends HttpConnection
{
protected final SSLEngine engine;
protected final String serverName;
protected final SSLParameters sslParameters;
private final List<SNIServerName> sniServerNames;
// Setting this property disables HTTPS hostname verification. Use with care.
private static final boolean disableHostnameVerification
@ -73,11 +74,11 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection
ServerName serverName, int port,
String[] alpn) {
super(addr, client);
this.serverName = serverName.getName();
this.sniServerNames = formSNIServerNames(serverName);
SSLContext context = client.theSSLContext();
sslParameters = createSSLParameters(client, serverName, alpn);
sslParameters = createSSLParameters(client, this.sniServerNames, alpn);
Log.logParams(sslParameters);
engine = createEngine(context, serverName.getName(), port, sslParameters);
engine = createEngine(context, serverName.name(), port, sslParameters);
}
abstract SSLTube getConnectionFlow();
@ -88,6 +89,11 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection
final SSLEngine getEngine() { return engine; }
@Override
public final List<SNIServerName> getSNIServerNames() {
return this.sniServerNames;
}
private static boolean contains(String[] rr, String target) {
for (String s : rr)
if (target.equalsIgnoreCase(s))
@ -96,7 +102,7 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection
}
private static SSLParameters createSSLParameters(HttpClientImpl client,
ServerName serverName,
List<SNIServerName> sniServerNames,
String[] alpn) {
SSLParameters sslp = client.sslParameters();
SSLParameters sslParameters = Utils.copySSLParameters(sslp);
@ -116,20 +122,27 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
if (alpn != null) {
Log.logSSL("AbstractAsyncSSLConnection: Setting application protocols: {0}",
Arrays.toString(alpn));
Arrays.toString(alpn));
sslParameters.setApplicationProtocols(alpn);
} else {
Log.logSSL("AbstractAsyncSSLConnection: no applications set!");
}
if (!serverName.isLiteral()) {
String name = serverName.getName();
if (name != null && name.length() > 0) {
sslParameters.setServerNames(List.of(new SNIHostName(name)));
}
}
sslParameters.setServerNames(sniServerNames);
return sslParameters;
}
private static List<SNIServerName> formSNIServerNames(final ServerName serverName) {
if (serverName == null) {
return List.of();
}
if (!serverName.isLiteral()) {
String name = serverName.name();
if (name != null && name.length() > 0) {
return List.of(new SNIHostName(name));
}
}
return List.of();
}
private static SSLEngine createEngine(SSLContext context, String serverName, int port,
SSLParameters sslParameters) {

View File

@ -44,6 +44,9 @@ import java.util.function.Predicate;
import java.net.http.HttpClient;
import java.net.http.HttpClient.Version;
import java.net.http.HttpHeaders;
import javax.net.ssl.SNIServerName;
import jdk.internal.net.http.common.Demand;
import jdk.internal.net.http.common.FlowTube;
import jdk.internal.net.http.common.Logger;
@ -424,6 +427,17 @@ abstract class HttpConnection implements Closeable {
return address;
}
/**
* Returns an unmodifiable list of {@link SNIServerName}s that were used during TLS handshake
* of this connection. If this connection doesn't represent a TLS based connection or if no SNI
* server names were used during the handshake, then this method returns an empty list.
*
* @return the SNI server names
*/
public List<SNIServerName> getSNIServerNames() {
return List.of();
}
abstract ConnectionPool.CacheKey cacheKey();
/**

View File

@ -477,22 +477,7 @@ public final class Utils {
return !token.isEmpty();
}
public static class ServerName {
ServerName(String name, boolean isLiteral) {
this.name = name;
this.isLiteral = isLiteral;
}
final String name;
final boolean isLiteral;
public String getName() {
return name;
}
public boolean isLiteral() {
return isLiteral;
}
public record ServerName (String name, boolean isLiteral) {
}
/**