forked from eclipse-ee4j/grizzly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue eclipse-ee4j#2016 Better compatibility detection
- can run with any compatible implementation, not only NPN Bootstrap - with new JDK versions after 8u250 uses it's JSSE impl by default - still can use older NPN bootstrap versions if configured - can use also other implementations (openjsse) Signed-off-by: David Matejcek <dmatej@seznam.cz>
- Loading branch information
Showing
4 changed files
with
171 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
144 changes: 144 additions & 0 deletions
144
modules/http2/src/main/java/org/glassfish/grizzly/http2/AplnExtensionCompatibility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* Copyright (c) 2012, 2017 Oracle and/or its affiliates. All rights reserved. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0, which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the | ||
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | ||
* version 2 with the GNU Classpath Exception, which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*/ | ||
|
||
package org.glassfish.grizzly.http2; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Objects; | ||
import java.util.function.BiFunction; | ||
import java.util.logging.Logger; | ||
|
||
import javax.net.ssl.SSLEngine; | ||
|
||
class AplnExtensionCompatibility { | ||
private static final Logger LOG = Logger.getLogger(AplnExtensionCompatibility.class.getName()); | ||
|
||
private static final String IMPL_CLASS_NAME = "sun.security.ssl.SSLEngineImpl"; | ||
private static final String METHOD_NAME = "setHandshakeApplicationProtocolSelector"; | ||
|
||
private static AplnExtensionCompatibility INSTANCE; | ||
|
||
private final boolean alpnExtensionGrizzly; | ||
private final boolean protocolSelectorSetterInApi; | ||
private final boolean protocolSelectorSetterInImpl; | ||
|
||
public static synchronized AplnExtensionCompatibility getInstance() { | ||
if (INSTANCE == null) { | ||
INSTANCE = new AplnExtensionCompatibility(); | ||
} | ||
return INSTANCE; | ||
} | ||
|
||
|
||
public boolean isAlpnExtensionAvailable() { | ||
return isAlpnExtensionGrizzly() || isProtocolSelectorSetterInApi() || isProtocolSelectorSetterInImpl(); | ||
} | ||
|
||
|
||
public boolean isAlpnExtensionGrizzly() { | ||
return alpnExtensionGrizzly; | ||
} | ||
|
||
|
||
public boolean isProtocolSelectorSetterInApi() { | ||
return protocolSelectorSetterInApi; | ||
} | ||
|
||
|
||
public boolean isProtocolSelectorSetterInImpl() { | ||
return protocolSelectorSetterInImpl; | ||
} | ||
|
||
|
||
public Method getProtocolSelectorSetter(final SSLEngine engine) { | ||
Objects.requireNonNull(engine, "engine"); | ||
try { | ||
// newer JSSE versions implement this method. | ||
// some JDK8 versions (Zulu 8u265) don't see the method as public on impl | ||
final Class<? extends SSLEngine> engineClass; | ||
if (isHandshakeSetterInApi()) { | ||
engineClass = SSLEngine.class; | ||
} else { | ||
engineClass = engine.getClass(); | ||
} | ||
return engineClass.getMethod(METHOD_NAME, BiFunction.class); | ||
} catch (final NoSuchMethodException e) { | ||
throw new IllegalArgumentException("The method public void setHandshakeApplicationProtocolSelector(" | ||
+ "BiFunction<SSLEngine, List<String>, String> selector) is not declared by" | ||
+ " the " + engine.getClass().getName() + ".", e); | ||
} | ||
} | ||
|
||
|
||
private AplnExtensionCompatibility() { | ||
this.alpnExtensionGrizzly = isClassAvailableOnBootstrapClasspath("sun.security.ssl.GrizzlyNPN"); | ||
this.protocolSelectorSetterInApi = isHandshakeSetterInApi(); | ||
this.protocolSelectorSetterInImpl = isHandshakeSetterInImpl(); | ||
} | ||
|
||
|
||
private static boolean isClassAvailableOnBootstrapClasspath(final String className) { | ||
try { | ||
ClassLoader.getSystemClassLoader().loadClass(className); | ||
return true; | ||
} catch (final ClassNotFoundException e) { | ||
LOG.config("The class with the name '" + className + "' is not available on the bootstrap classpath."); | ||
return false; | ||
} | ||
} | ||
|
||
|
||
private static boolean isHandshakeSetterInImpl() { | ||
try { | ||
Class.forName(IMPL_CLASS_NAME).getMethod(METHOD_NAME, BiFunction.class); | ||
return true; | ||
} catch (final IllegalAccessError e) { | ||
LOG.config(() -> "The class " + IMPL_CLASS_NAME + " is not accessible."); | ||
return false; | ||
} catch (final ClassNotFoundException | NoClassDefFoundError e) { | ||
LOG.config(() -> "The class " + IMPL_CLASS_NAME + " cloud not be found."); | ||
return false; | ||
} catch (final NoSuchMethodException e) { | ||
LOG.config(() -> "The method public void setHandshakeApplicationProtocolSelector(" | ||
+ "BiFunction<SSLEngine, List<String>, String> selector) is not declared by" | ||
+ " the " + IMPL_CLASS_NAME + " class."); | ||
return false; | ||
} | ||
} | ||
|
||
|
||
private static boolean isHandshakeSetterInApi() { | ||
try { | ||
// new grizzly bootstrap versions implement this method. | ||
SSLEngine.class.getMethod(METHOD_NAME, BiFunction.class); | ||
return true; | ||
} catch (final NoSuchMethodException e) { | ||
LOG.config("The method public void setHandshakeApplicationProtocolSelector(" | ||
+ "BiFunction<SSLEngine, List<String>, String> selector) is not declared by" | ||
+ " the " + SSLEngine.class.getName() + "."); | ||
return false; | ||
} | ||
} | ||
|
||
|
||
@Override | ||
public String toString() { | ||
return super.toString() + "ALPN available: " + isAlpnExtensionAvailable() | ||
+ ", ALPN is Grizzly: " + isAlpnExtensionGrizzly() | ||
+ ", setHandshakeApplicationProtocolSelector in API: " + isProtocolSelectorSetterInApi() | ||
+ ", setHandshakeApplicationProtocolSelector in impl: " + isProtocolSelectorSetterInImpl(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters