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 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 @Override
113 public IoSessionConfig getSessionConfig() {
114 return connector.getSessionConfig();
115 }
116
117 public ProxyIoSession getProxyIoSession() {
118 return proxyIoSession;
119 }
120
121 public void setProxyIoSession(ProxyIoSession proxyIoSession) {
122 if (proxyIoSession == null) {
123 throw new NullPointerException("proxySession cannot be null");
124 }
125
126 if (proxyIoSession.getProxyAddress() == null) {
127 throw new NullPointerException(
128 "proxySession.proxyAddress cannot be null");
129 }
130
131 proxyIoSession.setConnector(this);
132 setDefaultRemoteAddress(proxyIoSession.getProxyAddress());
133 this.proxyIoSession = proxyIoSession;
134 }
135
136
137
138
139
140
141
142
143 @SuppressWarnings("unchecked")
144 @Override
145 protected ConnectFuture connect0(
146 final SocketAddress remoteAddress,
147 final SocketAddress localAddress,
148 final IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
149 if (!proxyIoSession.isReconnectionNeeded()) {
150
151 IoHandler handler = getHandler();
152 if (!(handler instanceof AbstractProxyIoHandler)) {
153 throw new IllegalArgumentException(
154 "IoHandler must be an instance of AbstractProxyIoHandler");
155 }
156
157 connector.setHandler(handler);
158 future = new DefaultConnectFuture();
159 }
160
161 ConnectFuture conFuture = connector.connect(proxyIoSession
162 .getProxyAddress(), new ProxyIoSessionInitializer(
163 sessionInitializer, proxyIoSession));
164
165 if (proxyIoSession.getRequest() instanceof SocksProxyRequest
166 || proxyIoSession.isReconnectionNeeded()) {
167 return conFuture;
168 } else {
169 return future;
170 }
171 }
172
173 public void cancelConnectFuture() {
174 future.cancel();
175 }
176
177 protected ConnectFuture fireConnected(final IoSession session) {
178 future.setSession(session);
179 return future;
180 }
181
182
183
184
185
186 public final SocketConnector getConnector() {
187 return connector;
188 }
189
190
191
192
193
194 public final void setConnector(final SocketConnector newConnector) {
195 if (newConnector == null) {
196 throw new NullPointerException("connector cannot be null");
197 }
198
199 SocketConnector oldConnector = this.connector;
200
201
202 if (oldConnector != null) {
203 oldConnector.getFilterChain().remove(ProxyFilter.class.getName());
204 }
205
206 this.connector = newConnector;
207
208
209 if (newConnector.getFilterChain().contains(ProxyFilter.class.getName())) {
210 newConnector.getFilterChain().remove(ProxyFilter.class.getName());
211 }
212
213 newConnector.getFilterChain().addFirst(ProxyFilter.class.getName(),
214 proxyFilter);
215 }
216
217
218
219
220 @Override
221 protected IoFuture dispose0() throws Exception {
222 if (connector != null) {
223 connector.dispose();
224 }
225 return null;
226 }
227
228
229
230
231 public TransportMetadata getTransportMetadata() {
232 return METADATA;
233 }
234 }