1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.spdy.server;
20
21 import java.io.IOException;
22 import java.util.List;
23
24 import javax.net.ssl.SSLEngine;
25 import javax.net.ssl.SSLEngineResult;
26
27 import org.eclipse.jetty.io.AbstractConnection;
28 import org.eclipse.jetty.io.Connection;
29 import org.eclipse.jetty.io.EndPoint;
30 import org.eclipse.jetty.npn.NextProtoNego;
31 import org.eclipse.jetty.server.ConnectionFactory;
32 import org.eclipse.jetty.server.Connector;
33 import org.eclipse.jetty.util.BufferUtil;
34 import org.eclipse.jetty.util.log.Log;
35 import org.eclipse.jetty.util.log.Logger;
36
37 public class NextProtoNegoServerConnection extends AbstractConnection implements NextProtoNego.ServerProvider
38 {
39 private final Logger LOG = Log.getLogger(getClass());
40 private final Connector connector;
41 private final SSLEngine engine;
42 private final List<String> protocols;
43 private final String defaultProtocol;
44 private String nextProtocol;
45
46 public NextProtoNegoServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, List<String>protocols, String defaultProtocol)
47 {
48 super(endPoint, connector.getExecutor());
49 this.connector = connector;
50 this.protocols = protocols;
51 this.defaultProtocol = defaultProtocol;
52 this.engine = engine;
53 NextProtoNego.put(engine, this);
54 }
55
56 @Override
57 public void onOpen()
58 {
59 super.onOpen();
60 fillInterested();
61 }
62
63 @Override
64 public void onFillable()
65 {
66 while (true)
67 {
68 int filled = fill();
69 if (filled == 0 && nextProtocol == null)
70 fillInterested();
71 if (filled <= 0 || nextProtocol != null)
72 break;
73 }
74
75 if (nextProtocol == null && engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
76 {
77
78
79 LOG.debug("{} missing next protocol. SSLEngine: {}", this, engine);
80 close();
81 }
82
83 if (nextProtocol != null)
84 {
85 ConnectionFactory connectionFactory = connector.getConnectionFactory(nextProtocol);
86 EndPoint endPoint = getEndPoint();
87 Connection oldConnection = endPoint.getConnection();
88 oldConnection.onClose();
89 Connection connection = connectionFactory.newConnection(connector, endPoint);
90 LOG.debug("{} switching from {} to {}", this, oldConnection, connection);
91 endPoint.setConnection(connection);
92 getEndPoint().getConnection().onOpen();
93 }
94 }
95
96 private int fill()
97 {
98 try
99 {
100 return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
101 }
102 catch (IOException x)
103 {
104 LOG.debug(x);
105 NextProtoNego.remove(engine);
106 getEndPoint().close();
107 return -1;
108 }
109 }
110
111 @Override
112 public void unsupported()
113 {
114 protocolSelected(defaultProtocol);
115 }
116
117 @Override
118 public List<String> protocols()
119 {
120 return protocols;
121 }
122
123 @Override
124 public void protocolSelected(String protocol)
125 {
126 LOG.debug("{} protocol selected {}", this, protocol);
127 nextProtocol = protocol != null ? protocol : defaultProtocol;
128 NextProtoNego.remove(engine);
129 }
130 }