1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.io.ssl;
20
21 import java.io.IOException;
22 import java.util.Map;
23 import java.util.concurrent.Executor;
24
25 import javax.net.ssl.SSLEngine;
26
27 import org.eclipse.jetty.io.ByteBufferPool;
28 import org.eclipse.jetty.io.ClientConnectionFactory;
29 import org.eclipse.jetty.io.Connection;
30 import org.eclipse.jetty.io.EndPoint;
31 import org.eclipse.jetty.util.component.ContainerLifeCycle;
32 import org.eclipse.jetty.util.ssl.SslContextFactory;
33
34 public class SslClientConnectionFactory implements ClientConnectionFactory
35 {
36 public static final String SSL_CONTEXT_FACTORY_CONTEXT_KEY = "ssl.context.factory";
37 public static final String SSL_PEER_HOST_CONTEXT_KEY = "ssl.peer.host";
38 public static final String SSL_PEER_PORT_CONTEXT_KEY = "ssl.peer.port";
39 public static final String SSL_ENGINE_CONTEXT_KEY = "ssl.engine";
40
41 private final SslContextFactory sslContextFactory;
42 private final ByteBufferPool byteBufferPool;
43 private final Executor executor;
44 private final ClientConnectionFactory connectionFactory;
45
46 public SslClientConnectionFactory(SslContextFactory sslContextFactory, ByteBufferPool byteBufferPool, Executor executor, ClientConnectionFactory connectionFactory)
47 {
48 this.sslContextFactory = sslContextFactory;
49 this.byteBufferPool = byteBufferPool;
50 this.executor = executor;
51 this.connectionFactory = connectionFactory;
52 }
53
54 @Override
55 public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
56 {
57 String host = (String)context.get(SSL_PEER_HOST_CONTEXT_KEY);
58 int port = (Integer)context.get(SSL_PEER_PORT_CONTEXT_KEY);
59 SSLEngine engine = sslContextFactory.newSSLEngine(host, port);
60 engine.setUseClientMode(true);
61 context.put(SSL_ENGINE_CONTEXT_KEY, engine);
62
63 SslConnection sslConnection = newSslConnection(byteBufferPool, executor, endPoint, engine);
64 endPoint.setConnection(sslConnection);
65
66 customize(sslConnection, context);
67
68 EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
69 appEndPoint.setConnection(connectionFactory.newConnection(appEndPoint, context));
70
71 return sslConnection;
72 }
73
74 protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
75 {
76 return new SslConnection(byteBufferPool, executor, endPoint, engine);
77 }
78
79 @Override
80 public Connection customize(Connection connection, Map<String, Object> context)
81 {
82 if (connection instanceof SslConnection)
83 {
84 SslConnection sslConnection = (SslConnection)connection;
85 sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
86 ContainerLifeCycle connector = (ContainerLifeCycle)context.get(ClientConnectionFactory.CONNECTOR_CONTEXT_KEY);
87 connector.getBeans(SslHandshakeListener.class).forEach(sslConnection::addHandshakeListener);
88 }
89 return ClientConnectionFactory.super.customize(connection, context);
90 }
91 }