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