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