1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy;
21
22 import java.net.InetSocketAddress;
23 import java.net.SocketAddress;
24 import java.util.concurrent.Executor;
25
26 import org.apache.mina.core.buffer.IoBuffer;
27 import org.apache.mina.core.file.FileRegion;
28 import org.apache.mina.core.filterchain.IoFilter;
29 import org.apache.mina.core.future.ConnectFuture;
30 import org.apache.mina.core.future.DefaultConnectFuture;
31 import org.apache.mina.core.future.IoFuture;
32 import org.apache.mina.core.service.AbstractIoConnector;
33 import org.apache.mina.core.service.DefaultTransportMetadata;
34 import org.apache.mina.core.service.IoHandler;
35 import org.apache.mina.core.service.TransportMetadata;
36 import org.apache.mina.core.session.IoSession;
37 import org.apache.mina.core.session.IoSessionConfig;
38 import org.apache.mina.core.session.IoSessionInitializer;
39 import org.apache.mina.proxy.filter.ProxyFilter;
40 import org.apache.mina.proxy.handlers.socks.SocksProxyRequest;
41 import org.apache.mina.proxy.session.ProxyIoSession;
42 import org.apache.mina.proxy.session.ProxyIoSessionInitializer;
43 import org.apache.mina.transport.socket.DefaultSocketSessionConfig;
44 import org.apache.mina.transport.socket.SocketConnector;
45 import org.apache.mina.transport.socket.SocketSessionConfig;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public class ProxyConnector extends AbstractIoConnector {
63 private static final TransportMetadata METADATA = new DefaultTransportMetadata(
64 "proxy", "proxyconnector", false, true, InetSocketAddress.class,
65 SocketSessionConfig.class, IoBuffer.class, FileRegion.class);
66
67
68
69
70 private SocketConnector connector = null;
71
72
73
74
75 private final ProxyFilter proxyFilter = new ProxyFilter();
76
77
78
79
80 private ProxyIoSession proxyIoSession;
81
82
83
84
85 private DefaultConnectFuture future;
86
87
88
89
90 public ProxyConnector() {
91 super(new DefaultSocketSessionConfig(), null);
92 }
93
94
95
96
97
98
99 public ProxyConnector(final SocketConnector connector) {
100 this(connector, new DefaultSocketSessionConfig(), null);
101 }
102
103
104
105
106
107 public ProxyConnector(final SocketConnector connector, IoSessionConfig config, Executor executor) {
108 super(config, executor);
109 setConnector(connector);
110 }
111
112
113
114
115 @Override
116 public IoSessionConfig getSessionConfig() {
117 return connector.getSessionConfig();
118 }
119
120
121
122
123 public ProxyIoSession getProxyIoSession() {
124 return proxyIoSession;
125 }
126
127
128
129
130
131 public void setProxyIoSession(ProxyIoSession proxyIoSession) {
132 if (proxyIoSession == null) {
133 throw new NullPointerException("proxySession object cannot be null");
134 }
135
136 if (proxyIoSession.getProxyAddress() == null) {
137 throw new NullPointerException(
138 "proxySession.proxyAddress cannot be null");
139 }
140
141 proxyIoSession.setConnector(this);
142 setDefaultRemoteAddress(proxyIoSession.getProxyAddress());
143 this.proxyIoSession = proxyIoSession;
144 }
145
146
147
148
149
150
151
152
153
154
155 @SuppressWarnings("unchecked")
156 @Override
157 protected ConnectFuture connect0(
158 final SocketAddress remoteAddress,
159 final SocketAddress localAddress,
160 final IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
161 if (!proxyIoSession.isReconnectionNeeded()) {
162
163 IoHandler handler = getHandler();
164 if (!(handler instanceof AbstractProxyIoHandler)) {
165 throw new IllegalArgumentException(
166 "IoHandler must be an instance of AbstractProxyIoHandler");
167 }
168
169 connector.setHandler(handler);
170 future = new DefaultConnectFuture();
171 }
172
173 ConnectFuture conFuture = connector.connect(proxyIoSession
174 .getProxyAddress(), new ProxyIoSessionInitializer(
175 sessionInitializer, proxyIoSession));
176
177
178
179
180
181
182 if (proxyIoSession.getRequest() instanceof SocksProxyRequest
183 || proxyIoSession.isReconnectionNeeded()) {
184 return conFuture;
185 }
186
187 return future;
188 }
189
190
191
192
193 public void cancelConnectFuture() {
194 future.cancel();
195 }
196
197
198
199
200
201
202
203 protected ConnectFuture fireConnected(final IoSession session) {
204 future.setSession(session);
205 return future;
206 }
207
208
209
210
211
212 public final SocketConnector getConnector() {
213 return connector;
214 }
215
216
217
218
219
220
221
222 private final void setConnector(final SocketConnector connector) {
223 if (connector == null) {
224 throw new NullPointerException("connector cannot be null");
225 }
226
227 this.connector = connector;
228 String className = ProxyFilter.class.getName();
229
230
231 if (connector.getFilterChain().contains(className)) {
232 connector.getFilterChain().remove(className);
233 }
234
235
236 connector.getFilterChain().addFirst(className, proxyFilter);
237 }
238
239
240
241
242 @Override
243 protected IoFuture dispose0() throws Exception {
244 if (connector != null) {
245 connector.dispose();
246 }
247 return null;
248 }
249
250
251
252
253 public TransportMetadata getTransportMetadata() {
254 return METADATA;
255 }
256 }