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.NIOBuffer;
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 Buffers _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 channel.connect( destination.isProxied() ? destination.getProxy() : destination.getAddress() );
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 SslHttpChannelEndPoint(_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 protected Buffer newBuffer( int size )
162 {
163 return new NIOBuffer( size, NIOBuffer.INDIRECT );
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 }