1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.alpn.server;
20
21 import java.util.Collections;
22 import java.util.List;
23
24 import javax.net.ssl.SSLEngine;
25
26 import org.eclipse.jetty.alpn.ALPN;
27 import org.eclipse.jetty.io.EndPoint;
28 import org.eclipse.jetty.server.ConnectionFactory;
29 import org.eclipse.jetty.server.Connector;
30 import org.eclipse.jetty.server.NegotiatingServerConnection;
31 import org.eclipse.jetty.util.log.Log;
32 import org.eclipse.jetty.util.log.Logger;
33
34 public class ALPNServerConnection extends NegotiatingServerConnection implements ALPN.ServerProvider
35 {
36 private static final Logger LOG = Log.getLogger(ALPNServerConnection.class);
37
38 public ALPNServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
39 {
40 super(connector, endPoint, engine, protocols, defaultProtocol);
41 ALPN.put(engine, this);
42 }
43
44 @Override
45 public void unsupported()
46 {
47 select(Collections.<String>emptyList());
48 }
49
50 @Override
51 public String select(List<String> clientProtocols)
52 {
53 SSLEngine sslEngine = getSSLEngine();
54 List<String> serverProtocols = getProtocols();
55 String tlsProtocol = sslEngine.getHandshakeSession().getProtocol();
56 String tlsCipher = sslEngine.getHandshakeSession().getCipherSuite();
57 String negotiated = null;
58
59
60
61 for (String serverProtocol : serverProtocols)
62 {
63 if (clientProtocols.contains(serverProtocol))
64 {
65 ConnectionFactory factory = getConnector().getConnectionFactory(serverProtocol);
66 if (factory instanceof CipherDiscriminator && !((CipherDiscriminator)factory).isAcceptable(serverProtocol, tlsProtocol, tlsCipher))
67 {
68 if (LOG.isDebugEnabled())
69 LOG.debug("{} protocol {} not acceptable to {} for {}/{}", this, serverProtocol, factory, tlsProtocol, tlsCipher);
70 continue;
71 }
72
73 negotiated = serverProtocol;
74 break;
75 }
76 }
77 if (negotiated == null)
78 {
79 if (clientProtocols.isEmpty())
80 {
81 negotiated = getDefaultProtocol();
82 }
83 else
84 {
85 if (LOG.isDebugEnabled())
86 LOG.debug("{} could not negotiate protocol: C{} | S{}", this, clientProtocols, serverProtocols);
87 throw new IllegalStateException();
88 }
89 }
90 if (LOG.isDebugEnabled())
91 LOG.debug("{} protocol selected {}", this, negotiated);
92 setProtocol(negotiated);
93 ALPN.remove(sslEngine);
94 return negotiated;
95 }
96
97 @Override
98 public void close()
99 {
100 ALPN.remove(getSSLEngine());
101 super.close();
102 }
103 }