/*
* Copyright (C) 2016 Square, Inc.
*
* Licensed 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.
*/
package okhttp3.internal.platform;
import java.lang.reflect.
InvocationTargetException;
import java.lang.reflect.
Method;
import java.util.
List;
import javax.annotation.
Nullable;
import javax.net.ssl.
SSLParameters;
import javax.net.ssl.
SSLSocket;
import javax.net.ssl.
SSLSocketFactory;
import javax.net.ssl.
X509TrustManager;
import okhttp3.
Protocol;
import static okhttp3.internal.
Util.assertionError;
/**
* OpenJDK 9+.
*/
final class
Jdk9Platform extends
Platform {
final
Method setProtocolMethod;
final
Method getProtocolMethod;
Jdk9Platform(
Method setProtocolMethod,
Method getProtocolMethod) {
this.
setProtocolMethod =
setProtocolMethod;
this.
getProtocolMethod =
getProtocolMethod;
}
@
Override
public void
configureTlsExtensions(
SSLSocket sslSocket,
String hostname,
List<
Protocol>
protocols) {
try {
SSLParameters sslParameters =
sslSocket.
getSSLParameters();
List<
String>
names =
alpnProtocolNames(
protocols);
setProtocolMethod.
invoke(
sslParameters,
new
Object[] {
names.
toArray(new
String[
names.
size()])});
sslSocket.
setSSLParameters(
sslParameters);
} catch (
IllegalAccessException |
InvocationTargetException e) {
throw
assertionError("unable to set ssl parameters",
e);
}
}
@
Override
public @
Nullable String getSelectedProtocol(
SSLSocket socket) {
try {
String protocol = (
String)
getProtocolMethod.
invoke(
socket);
// SSLSocket.getApplicationProtocol returns "" if application protocols values will not
// be used. Observed if you didn't specify SSLParameters.setApplicationProtocols
if (
protocol == null ||
protocol.
equals("")) {
return null;
}
return
protocol;
} catch (
IllegalAccessException |
InvocationTargetException e) {
throw
assertionError("unable to get selected protocols",
e);
}
}
@
Override public
X509TrustManager trustManager(
SSLSocketFactory sslSocketFactory) {
// Not supported due to access checks on JDK 9+:
// java.lang.reflect.InaccessibleObjectException: Unable to make member of class
// sun.security.ssl.SSLSocketFactoryImpl accessible: module java.base does not export
// sun.security.ssl to unnamed module @xxx
throw new
UnsupportedOperationException(
"clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on JDK 9+");
}
public static
Jdk9Platform buildIfSupported() {
// Find JDK 9 new methods
try {
Method setProtocolMethod =
SSLParameters.class.
getMethod("setApplicationProtocols",
String[].class);
Method getProtocolMethod =
SSLSocket.class.
getMethod("getApplicationProtocol");
return new
Jdk9Platform(
setProtocolMethod,
getProtocolMethod);
} catch (
NoSuchMethodException ignored) {
// pre JDK 9
}
return null;
}
}