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 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 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 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.setRequestBufferSize( sslEngine.getSession().getPacketBufferSize());
169 buffers.setResponseBufferSize(sslEngine.getSession().getApplicationBufferSize());
170
171 try
172 {
173 buffers.start();
174 }
175 catch(Exception e)
176 {
177 throw new IllegalStateException(e);
178 }
179 _sslBuffers=buffers;
180 }
181
182 return sslEngine;
183 }
184
185
186
187
188
189 protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
190 {
191 if (attachment instanceof HttpDestination)
192 ((HttpDestination)attachment).onConnectionFailed(ex);
193 else
194 Log.warn(ex);
195 }
196
197 }
198
199 }