1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23 import java.util.List;
24
25 import javax.net.ssl.SSLEngine;
26 import javax.net.ssl.SSLEngineResult;
27
28 import org.eclipse.jetty.io.AbstractConnection;
29 import org.eclipse.jetty.io.Connection;
30 import org.eclipse.jetty.io.EndPoint;
31 import org.eclipse.jetty.util.BufferUtil;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34
35 public abstract class NegotiatingServerConnection extends AbstractConnection
36 {
37 private static final Logger LOG = Log.getLogger(NegotiatingServerConnection.class);
38
39 private final Connector connector;
40 private final SSLEngine engine;
41 private final List<String> protocols;
42 private final String defaultProtocol;
43 private String protocol;
44
45 protected NegotiatingServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
46 {
47 super(endPoint, connector.getExecutor());
48 this.connector = connector;
49 this.protocols = protocols;
50 this.defaultProtocol = defaultProtocol;
51 this.engine = engine;
52 }
53
54 protected List<String> getProtocols()
55 {
56 return protocols;
57 }
58
59 protected String getDefaultProtocol()
60 {
61 return defaultProtocol;
62 }
63
64 protected SSLEngine getSSLEngine()
65 {
66 return engine;
67 }
68
69 protected String getProtocol()
70 {
71 return protocol;
72 }
73
74 protected void setProtocol(String protocol)
75 {
76 this.protocol = protocol;
77 }
78
79 @Override
80 public void onOpen()
81 {
82 super.onOpen();
83 fillInterested();
84 }
85
86 @Override
87 public void onFillable()
88 {
89 int filled = fill();
90
91 if (filled == 0)
92 {
93 if (protocol == null)
94 {
95 if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
96 {
97
98 if (LOG.isDebugEnabled())
99 LOG.debug("{} could not negotiate protocol, SSLEngine: {}", this, engine);
100 close();
101 }
102 else
103 {
104
105
106 fillInterested();
107 }
108 }
109 else
110 {
111 ConnectionFactory connectionFactory = connector.getConnectionFactory(protocol);
112 if (connectionFactory == null)
113 {
114 if (LOG.isDebugEnabled())
115 LOG.debug("{} application selected protocol '{}', but no correspondent {} has been configured",
116 this, protocol, ConnectionFactory.class.getName());
117 close();
118 }
119 else
120 {
121 EndPoint endPoint = getEndPoint();
122 Connection newConnection = connectionFactory.newConnection(connector, endPoint);
123 endPoint.upgrade(newConnection);
124 }
125 }
126 }
127 else if (filled < 0)
128 {
129
130 if (LOG.isDebugEnabled())
131 LOG.debug("{} closing on client close", this);
132 close();
133 }
134 else
135 {
136
137 throw new IllegalStateException();
138 }
139 }
140
141 private int fill()
142 {
143 try
144 {
145 return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
146 }
147 catch (IOException x)
148 {
149 LOG.debug(x);
150 close();
151 return -1;
152 }
153 }
154
155 @Override
156 public void close()
157 {
158
159 getEndPoint().shutdownOutput();
160 super.close();
161 }
162 }