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