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