1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.client;
15
16 import java.io.IOException;
17 import java.nio.channels.SelectionKey;
18 import java.nio.channels.SocketChannel;
19
20 import javax.net.ssl.SSLContext;
21 import javax.net.ssl.SSLEngine;
22
23 import org.eclipse.jetty.http.HttpMethods;
24 import org.eclipse.jetty.http.HttpVersions;
25 import org.eclipse.jetty.http.ssl.SslSelectChannelEndPoint;
26 import org.eclipse.jetty.io.AbstractBuffers;
27 import org.eclipse.jetty.io.Buffer;
28 import org.eclipse.jetty.io.Buffers;
29 import org.eclipse.jetty.io.Connection;
30 import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
31 import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
32 import org.eclipse.jetty.io.nio.SelectorManager;
33 import org.eclipse.jetty.util.component.AbstractLifeCycle;
34 import org.eclipse.jetty.util.log.Log;
35
36 class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, Runnable
37 {
38 private final HttpClient _httpClient;
39 private SSLContext _sslContext;
40 private Buffers _sslBuffers;
41 private boolean _blockingConnect;
42
43 SelectorManager _selectorManager=new Manager();
44
45
46
47
48 SelectConnector(HttpClient httpClient)
49 {
50 _httpClient = httpClient;
51 }
52
53
54
55
56
57 public boolean isBlockingConnect()
58 {
59 return _blockingConnect;
60 }
61
62
63
64
65
66 public void setBlockingConnect(boolean blockingConnect)
67 {
68 _blockingConnect = blockingConnect;
69 }
70
71
72 protected void doStart() throws Exception
73 {
74 _selectorManager.start();
75 _httpClient._threadPool.dispatch(this);
76 }
77
78
79 protected void doStop() throws Exception
80 {
81 _selectorManager.stop();
82 }
83
84
85 public void startConnection( HttpDestination destination )
86 throws IOException
87 {
88 SocketChannel channel = SocketChannel.open();
89 Address address = destination.isProxied() ? destination.getProxy() : destination.getAddress();
90 channel.configureBlocking( false );
91 channel.connect(address.toSocketAddress());
92 channel.socket().setSoTimeout( _httpClient._soTimeout );
93 _selectorManager.register( channel, destination );
94 }
95
96
97 public void run()
98 {
99 while (_httpClient.isRunning())
100 {
101 try
102 {
103 _selectorManager.doSelect(0);
104 }
105 catch (Exception e)
106 {
107 e.printStackTrace();
108 }
109 }
110 }
111
112
113 class Manager extends SelectorManager
114 {
115 protected SocketChannel acceptChannel(SelectionKey key) throws IOException
116 {
117 throw new IllegalStateException();
118 }
119
120 public boolean dispatch(Runnable task)
121 {
122 return SelectConnector.this._httpClient._threadPool.dispatch(task);
123 }
124
125 protected void endPointOpened(SelectChannelEndPoint endpoint)
126 {
127 }
128
129 protected void endPointClosed(SelectChannelEndPoint endpoint)
130 {
131 }
132
133 protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
134 {
135 return new HttpConnection(_httpClient,endpoint,SelectConnector.this._httpClient.getHeaderBufferSize(),SelectConnector.this._httpClient.getRequestBufferSize());
136 }
137
138 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
139 {
140
141 HttpDestination dest=(HttpDestination)key.attachment();
142
143
144 SelectChannelEndPoint ep=null;
145
146 if (dest.isSecure())
147 {
148 if (dest.isProxied())
149 {
150 String connect = HttpMethods.CONNECT+" "+dest.getAddress()+HttpVersions.HTTP_1_0+"\r\n\r\n";
151
152
153 throw new IllegalStateException("Not Implemented");
154 }
155
156 SSLEngine engine=newSslEngine();
157 ep = new SslSelectChannelEndPoint(_sslBuffers,channel,selectSet,key,engine);
158 }
159 else
160 {
161 ep=new SelectChannelEndPoint(channel,selectSet,key);
162 }
163
164 HttpConnection connection=(HttpConnection)ep.getConnection();
165 connection.setDestination(dest);
166 dest.onNewConnection(connection);
167 return ep;
168 }
169
170 private synchronized SSLEngine newSslEngine() throws IOException
171 {
172 if (_sslContext==null)
173 {
174 _sslContext = SelectConnector.this._httpClient.getSSLContext();
175 }
176
177 SSLEngine sslEngine = _sslContext.createSSLEngine();
178 sslEngine.setUseClientMode(true);
179 sslEngine.beginHandshake();
180
181 if (_sslBuffers==null)
182 {
183 AbstractBuffers buffers = new AbstractBuffers()
184 {
185 public Buffer newBuffer( int size )
186 {
187 return new IndirectNIOBuffer( size);
188 }
189 };
190
191 buffers.setRequestBufferSize( sslEngine.getSession().getPacketBufferSize());
192 buffers.setResponseBufferSize(sslEngine.getSession().getApplicationBufferSize());
193
194 try
195 {
196 buffers.start();
197 }
198 catch(Exception e)
199 {
200 throw new IllegalStateException(e);
201 }
202 _sslBuffers=buffers;
203 }
204
205 return sslEngine;
206 }
207
208
209
210
211
212 protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
213 {
214 if (attachment instanceof HttpDestination)
215 ((HttpDestination)attachment).onConnectionFailed(ex);
216 else
217 Log.warn(ex);
218 }
219 }
220 }