1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.client.io;
20
21 import java.io.IOException;
22 import java.nio.channels.SelectionKey;
23 import java.nio.channels.SocketChannel;
24 import java.util.concurrent.Executor;
25 import javax.net.ssl.SSLEngine;
26
27 import org.eclipse.jetty.io.ByteBufferPool;
28 import org.eclipse.jetty.io.Connection;
29 import org.eclipse.jetty.io.EndPoint;
30 import org.eclipse.jetty.io.SelectChannelEndPoint;
31 import org.eclipse.jetty.io.SelectorManager;
32 import org.eclipse.jetty.io.ssl.SslConnection;
33 import org.eclipse.jetty.util.log.Log;
34 import org.eclipse.jetty.util.log.Logger;
35 import org.eclipse.jetty.util.ssl.SslContextFactory;
36 import org.eclipse.jetty.websocket.api.WebSocketPolicy;
37 import org.eclipse.jetty.websocket.client.WebSocketClient;
38
39 public class WebSocketClientSelectorManager extends SelectorManager
40 {
41 private static final Logger LOG = Log.getLogger(WebSocketClientSelectorManager.class);
42 private final WebSocketPolicy policy;
43 private final ByteBufferPool bufferPool;
44 private SslContextFactory sslContextFactory;
45
46 public WebSocketClientSelectorManager(WebSocketClient client)
47 {
48 super(client.getExecutor(),client.getScheduler());
49 this.bufferPool = client.getBufferPool();
50 this.policy = client.getPolicy();
51 }
52
53 @Override
54 protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
55 {
56 if (LOG.isDebugEnabled())
57 LOG.debug("Connection Failed",ex);
58 ConnectPromise connect = (ConnectPromise)attachment;
59 connect.failed(ex);
60 }
61
62 public SslContextFactory getSslContextFactory()
63 {
64 return sslContextFactory;
65 }
66
67 @Override
68 public Connection newConnection(final SocketChannel channel, EndPoint endPoint, final Object attachment) throws IOException
69 {
70 if (LOG.isDebugEnabled())
71 LOG.debug("newConnection({},{},{})",channel,endPoint,attachment);
72 ConnectPromise connectPromise = (ConnectPromise)attachment;
73
74 try
75 {
76 String scheme = connectPromise.getRequest().getRequestURI().getScheme();
77
78 if ("wss".equalsIgnoreCase(scheme))
79 {
80
81 SslContextFactory sslContextFactory = getSslContextFactory();
82 if (sslContextFactory != null)
83 {
84 SSLEngine engine = newSSLEngine(sslContextFactory,channel);
85 SslConnection sslConnection = new SslConnection(bufferPool,getExecutor(),endPoint,engine);
86 sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
87 EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
88
89 Connection connection = newUpgradeConnection(channel,sslEndPoint,connectPromise);
90 sslEndPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
91 sslEndPoint.setConnection(connection);
92 return sslConnection;
93 }
94 else
95 {
96 throw new IOException("Cannot init SSL");
97 }
98 }
99 else
100 {
101
102 endPoint.setIdleTimeout(connectPromise.getDriver().getPolicy().getIdleTimeout());
103 return newUpgradeConnection(channel,endPoint,connectPromise);
104 }
105 }
106 catch (IOException e)
107 {
108 LOG.ignore(e);
109 connectPromise.failed(e);
110
111 throw e;
112 }
113 }
114
115 @Override
116 protected EndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException
117 {
118 if (LOG.isDebugEnabled())
119 LOG.debug("newEndPoint({}, {}, {})",channel,selectSet,selectionKey);
120 return new SelectChannelEndPoint(channel,selectSet,selectionKey,getScheduler(),policy.getIdleTimeout());
121 }
122
123 public SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel)
124 {
125 String peerHost = channel.socket().getInetAddress().getHostName();
126 int peerPort = channel.socket().getPort();
127 SSLEngine engine = sslContextFactory.newSSLEngine(peerHost,peerPort);
128 engine.setUseClientMode(true);
129 return engine;
130 }
131
132 public UpgradeConnection newUpgradeConnection(SocketChannel channel, EndPoint endPoint, ConnectPromise connectPromise)
133 {
134 WebSocketClient client = connectPromise.getClient();
135 Executor executor = client.getExecutor();
136 UpgradeConnection connection = new UpgradeConnection(endPoint,executor,connectPromise);
137 return connection;
138 }
139
140 public void setSslContextFactory(SslContextFactory sslContextFactory)
141 {
142 this.sslContextFactory = sslContextFactory;
143 }
144
145 public WebSocketPolicy getPolicy()
146 {
147 return policy;
148 }
149 }