1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.io;
20
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23 import java.util.Map;
24 import java.util.concurrent.Executor;
25
26 import javax.net.ssl.SSLEngine;
27
28 import org.eclipse.jetty.util.BufferUtil;
29 import org.eclipse.jetty.util.log.Log;
30 import org.eclipse.jetty.util.log.Logger;
31
32 public abstract class NegotiatingClientConnection extends AbstractConnection
33 {
34 private static final Logger LOG = Log.getLogger(NegotiatingClientConnection.class);
35
36 private final SSLEngine engine;
37 private final ClientConnectionFactory connectionFactory;
38 private final Map<String, Object> context;
39 private volatile boolean completed;
40
41 protected NegotiatingClientConnection(EndPoint endp, Executor executor, SSLEngine sslEngine, ClientConnectionFactory connectionFactory, Map<String, Object> context)
42 {
43 super(endp, executor);
44 this.engine = sslEngine;
45 this.connectionFactory = connectionFactory;
46 this.context = context;
47 }
48
49 protected SSLEngine getSSLEngine()
50 {
51 return engine;
52 }
53
54 protected void completed()
55 {
56 completed = true;
57 }
58
59 @Override
60 public void onOpen()
61 {
62 super.onOpen();
63 try
64 {
65 getEndPoint().flush(BufferUtil.EMPTY_BUFFER);
66 if (completed)
67 replaceConnection();
68 else
69 fillInterested();
70 }
71 catch (IOException x)
72 {
73 close();
74 throw new RuntimeIOException(x);
75 }
76 }
77
78 @Override
79 public void onFillable()
80 {
81 while (true)
82 {
83 int filled = fill();
84 if (filled == 0 && !completed)
85 fillInterested();
86 if (filled <= 0 || completed)
87 break;
88 }
89 if (completed)
90 replaceConnection();
91 }
92
93 private int fill()
94 {
95 try
96 {
97 return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
98 }
99 catch (IOException x)
100 {
101 LOG.debug(x);
102 close();
103 return -1;
104 }
105 }
106
107 private void replaceConnection()
108 {
109 EndPoint endPoint = getEndPoint();
110 try
111 {
112 Connection oldConnection = endPoint.getConnection();
113 Connection newConnection = connectionFactory.newConnection(endPoint, context);
114 ClientConnectionFactory.Helper.replaceConnection(oldConnection, newConnection);
115 }
116 catch (Throwable x)
117 {
118 LOG.debug(x);
119 close();
120 }
121 }
122
123 @Override
124 public void close()
125 {
126
127 getEndPoint().shutdownOutput();
128 super.close();
129 }
130 }