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
26 import javax.net.ssl.SSLEngine;
27
28 import org.eclipse.jetty.io.ByteBufferPool;
29 import org.eclipse.jetty.io.Connection;
30 import org.eclipse.jetty.io.EndPoint;
31 import org.eclipse.jetty.io.SelectChannelEndPoint;
32 import org.eclipse.jetty.io.SelectorManager;
33 import org.eclipse.jetty.io.ssl.SslConnection;
34 import org.eclipse.jetty.util.log.Log;
35 import org.eclipse.jetty.util.log.Logger;
36 import org.eclipse.jetty.util.ssl.SslContextFactory;
37 import org.eclipse.jetty.websocket.api.WebSocketPolicy;
38 import org.eclipse.jetty.websocket.client.WebSocketClient;
39
40 public class WebSocketClientSelectorManager extends SelectorManager
41 {
42 private static final Logger LOG = Log.getLogger(WebSocketClientSelectorManager.class);
43 private final WebSocketPolicy policy;
44 private final ByteBufferPool bufferPool;
45 private SslContextFactory sslContextFactory;
46
47 public WebSocketClientSelectorManager(WebSocketClient client)
48 {
49 super(client.getExecutor(),client.getScheduler());
50 this.bufferPool = client.getBufferPool();
51 this.policy = client.getPolicy();
52 }
53
54 @Override
55 protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
56 {
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 LOG.debug("newConnection({},{},{})",channel,endPoint,attachment);
71 ConnectPromise connectPromise = (ConnectPromise)attachment;
72
73 try
74 {
75 String scheme = connectPromise.getRequest().getRequestURI().getScheme();
76
77 if ("wss".equalsIgnoreCase(scheme))
78 {
79
80 SslContextFactory sslContextFactory = getSslContextFactory();
81 if (sslContextFactory != null)
82 {
83 SSLEngine engine = newSSLEngine(sslContextFactory,channel);
84 SslConnection sslConnection = new SslConnection(bufferPool,getExecutor(),endPoint,engine);
85 sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
86 EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
87
88 Connection connection = newUpgradeConnection(channel,sslEndPoint,connectPromise);
89 sslEndPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
90 sslEndPoint.setConnection(connection);
91 return sslConnection;
92 }
93 else
94 {
95 throw new IOException("Cannot init SSL");
96 }
97 }
98 else
99 {
100
101 endPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
102 return newUpgradeConnection(channel,endPoint,connectPromise);
103 }
104 }
105 catch (IOException e)
106 {
107 LOG.ignore(e);
108 connectPromise.failed(e);
109
110 throw e;
111 }
112 }
113
114 @Override
115 protected EndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException
116 {
117 LOG.debug("newEndPoint({}, {}, {})",channel,selectSet,selectionKey);
118 return new SelectChannelEndPoint(channel,selectSet,selectionKey,getScheduler(),policy.getIdleTimeout());
119 }
120
121 public SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel)
122 {
123 String peerHost = channel.socket().getInetAddress().getHostName();
124 int peerPort = channel.socket().getPort();
125 SSLEngine engine = sslContextFactory.newSSLEngine(peerHost,peerPort);
126 engine.setUseClientMode(true);
127 return engine;
128 }
129
130 public UpgradeConnection newUpgradeConnection(SocketChannel channel, EndPoint endPoint, ConnectPromise connectPromise)
131 {
132 WebSocketClient client = connectPromise.getClient();
133 Executor executor = client.getExecutor();
134 UpgradeConnection connection = new UpgradeConnection(endPoint,executor,connectPromise);
135 return connection;
136 }
137
138 public void setSslContextFactory(SslContextFactory sslContextFactory)
139 {
140 this.sslContextFactory = sslContextFactory;
141 }
142 }