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