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