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
42 SelectorManager _selectorManager=new Manager();
43
44
45
46
47 SelectConnector(HttpClient httpClient)
48 {
49 _httpClient = httpClient;
50 }
51
52 protected void doStart() throws Exception
53 {
54 _selectorManager.start();
55 _httpClient._threadPool.dispatch(this);
56 }
57
58 protected void doStop() throws Exception
59 {
60 _selectorManager.stop();
61 }
62
63 public void startConnection( HttpDestination destination )
64 throws IOException
65 {
66 SocketChannel channel = SocketChannel.open();
67 Address address = destination.isProxied() ? destination.getProxy() : destination.getAddress();
68 channel.connect(address.toSocketAddress());
69 channel.configureBlocking( false );
70 channel.socket().setSoTimeout( _httpClient._soTimeout );
71 _selectorManager.register( channel, destination );
72 }
73
74 public void run()
75 {
76 while (_httpClient.isRunning())
77 {
78 try
79 {
80 _selectorManager.doSelect(0);
81 }
82 catch (Exception e)
83 {
84 e.printStackTrace();
85 }
86 }
87 }
88
89 class Manager extends SelectorManager
90 {
91 protected SocketChannel acceptChannel(SelectionKey key) throws IOException
92 {
93 throw new IllegalStateException();
94 }
95
96 public boolean dispatch(Runnable task)
97 {
98 return SelectConnector.this._httpClient._threadPool.dispatch(task);
99 }
100
101 protected void endPointOpened(SelectChannelEndPoint endpoint)
102 {
103 }
104
105 protected void endPointClosed(SelectChannelEndPoint endpoint)
106 {
107 }
108
109 protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
110 {
111 return new HttpConnection(_httpClient,endpoint,SelectConnector.this._httpClient.getHeaderBufferSize(),SelectConnector.this._httpClient.getRequestBufferSize());
112 }
113
114 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
115 {
116
117 HttpDestination dest=(HttpDestination)key.attachment();
118
119
120 SelectChannelEndPoint ep=null;
121
122 if (dest.isSecure())
123 {
124 if (dest.isProxied())
125 {
126 String connect = HttpMethods.CONNECT+" "+dest.getAddress()+HttpVersions.HTTP_1_0+"\r\n\r\n";
127
128
129 throw new IllegalStateException("Not Implemented");
130 }
131
132 SSLEngine engine=newSslEngine();
133 ep = new SslSelectChannelEndPoint(_sslBuffers,channel,selectSet,key,engine);
134 }
135 else
136 {
137 ep=new SelectChannelEndPoint(channel,selectSet,key);
138 }
139
140 HttpConnection connection=(HttpConnection)ep.getConnection();
141 connection.setDestination(dest);
142 dest.onNewConnection(connection);
143 return ep;
144 }
145
146 private synchronized SSLEngine newSslEngine() throws IOException
147 {
148 if (_sslContext==null)
149 {
150 _sslContext = SelectConnector.this._httpClient.getSSLContext();
151 }
152
153 SSLEngine sslEngine = _sslContext.createSSLEngine();
154 sslEngine.setUseClientMode(true);
155 sslEngine.beginHandshake();
156
157 if (_sslBuffers==null)
158 {
159 AbstractBuffers buffers = new AbstractBuffers()
160 {
161 public Buffer newBuffer( int size )
162 {
163 return new IndirectNIOBuffer( size);
164 }
165 };
166
167 buffers.setRequestBufferSize( sslEngine.getSession().getPacketBufferSize());
168 buffers.setResponseBufferSize(sslEngine.getSession().getApplicationBufferSize());
169
170 try
171 {
172 buffers.start();
173 }
174 catch(Exception e)
175 {
176 throw new IllegalStateException(e);
177 }
178 _sslBuffers=buffers;
179 }
180
181 return sslEngine;
182 }
183
184
185
186
187
188 protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
189 {
190 if (attachment instanceof HttpDestination)
191 ((HttpDestination)attachment).onConnectionFailed(ex);
192 else
193 Log.warn(ex);
194 }
195
196 }
197
198 }