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.util.thread.Scheduler;
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(ByteBufferPool bufferPool, Executor executor, Scheduler scheduler, WebSocketPolicy policy)
49 {
50 super(executor,scheduler);
51 this.bufferPool = bufferPool;
52 this.policy = policy;
53 }
54
55 @Override
56 protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
57 {
58 LOG.info("Connection Failed",ex);
59 ConnectPromise connect = (ConnectPromise)attachment;
60 connect.failed(ex);
61 }
62
63 public SslContextFactory getSslContextFactory()
64 {
65 return sslContextFactory;
66 }
67
68 @Override
69 public Connection newConnection(final SocketChannel channel, EndPoint endPoint, final Object attachment) throws IOException
70 {
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 EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
87
88 Connection connection = newUpgradeConnection(channel,sslEndPoint,connectPromise);
89 sslEndPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
90 sslEndPoint.setConnection(connection);
91 connectionOpened(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.getClient().getMaxIdleTimeout());
103 return newUpgradeConnection(channel,endPoint,connectPromise);
104 }
105 }
106 catch (IOException e)
107 {
108 LOG.debug(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 LOG.debug("newEndPoint({}, {}, {})",channel,selectSet,selectionKey);
119 return new SelectChannelEndPoint(channel,selectSet,selectionKey,getScheduler(),policy.getIdleTimeout());
120 }
121
122 public SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel)
123 {
124 String peerHost = channel.socket().getInetAddress().getHostAddress();
125 int peerPort = channel.socket().getPort();
126 SSLEngine engine = sslContextFactory.newSSLEngine(peerHost,peerPort);
127 engine.setUseClientMode(true);
128 return engine;
129 }
130
131 public UpgradeConnection newUpgradeConnection(SocketChannel channel, EndPoint endPoint, ConnectPromise connectPromise)
132 {
133 WebSocketClient client = connectPromise.getClient();
134 Executor executor = client.getExecutor();
135 UpgradeConnection connection = new UpgradeConnection(endPoint,executor,connectPromise);
136 return connection;
137 }
138
139 public void setSslContextFactory(SslContextFactory sslContextFactory)
140 {
141 this.sslContextFactory = sslContextFactory;
142 }
143 }