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