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