1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.ssl;
17
18 import io.netty5.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener;
19 import io.netty5.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
20 import io.netty5.util.internal.PlatformDependent;
21 import org.eclipse.jetty.npn.NextProtoNego;
22 import org.eclipse.jetty.npn.NextProtoNego.ClientProvider;
23 import org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
24
25 import javax.net.ssl.SSLEngine;
26 import javax.net.ssl.SSLException;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29
30 import static java.util.Objects.requireNonNull;
31
32 final class JettyNpnSslEngine extends JdkSslEngine {
33 private static boolean available;
34
35 static boolean isAvailable() {
36 updateAvailability();
37 return available;
38 }
39
40 private static void updateAvailability() {
41 if (available) {
42 return;
43 }
44 try {
45
46 Class.forName("sun.security.ssl.NextProtoNegoExtension", true, null);
47 available = true;
48 } catch (Exception ignore) {
49
50 }
51 }
52
53 JettyNpnSslEngine(SSLEngine engine, final JdkApplicationProtocolNegotiator applicationNegotiator, boolean server) {
54 super(engine);
55 requireNonNull(applicationNegotiator, "applicationNegotiator");
56
57 if (server) {
58 final ProtocolSelectionListener protocolListener = requireNonNull(applicationNegotiator
59 .protocolListenerFactory().newListener(this, applicationNegotiator.protocols()),
60 "protocolListener");
61 NextProtoNego.put(engine, new ServerProvider() {
62 @Override
63 public void unsupported() {
64 protocolListener.unsupported();
65 }
66
67 @Override
68 public List<String> protocols() {
69 return applicationNegotiator.protocols();
70 }
71
72 @Override
73 public void protocolSelected(String protocol) {
74 try {
75 protocolListener.selected(protocol);
76 } catch (Throwable t) {
77 PlatformDependent.throwException(t);
78 }
79 }
80 });
81 } else {
82 final ProtocolSelector protocolSelector = requireNonNull(applicationNegotiator.protocolSelectorFactory()
83 .newSelector(this, new LinkedHashSet<>(applicationNegotiator.protocols())),
84 "protocolSelector");
85 NextProtoNego.put(engine, new ClientProvider() {
86 @Override
87 public boolean supports() {
88 return true;
89 }
90
91 @Override
92 public void unsupported() {
93 protocolSelector.unsupported();
94 }
95
96 @Override
97 public String selectProtocol(List<String> protocols) {
98 try {
99 return protocolSelector.select(protocols);
100 } catch (Throwable t) {
101 PlatformDependent.throwException(t);
102 return null;
103 }
104 }
105 });
106 }
107 }
108
109 @Override
110 public void closeInbound() throws SSLException {
111 NextProtoNego.remove(getWrappedEngine());
112 super.closeInbound();
113 }
114
115 @Override
116 public void closeOutbound() {
117 NextProtoNego.remove(getWrappedEngine());
118 super.closeOutbound();
119 }
120 }