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.filter;
21
22 import org.apache.mina.core.buffer.IoBuffer;
23 import org.apache.mina.core.filterchain.IoFilter;
24 import org.apache.mina.core.filterchain.IoFilterAdapter;
25 import org.apache.mina.core.filterchain.IoFilterChain;
26 import org.apache.mina.core.session.IdleStatus;
27 import org.apache.mina.core.session.IoSession;
28 import org.apache.mina.core.write.WriteRequest;
29 import org.apache.mina.proxy.ProxyAuthException;
30 import org.apache.mina.proxy.ProxyConnector;
31 import org.apache.mina.proxy.ProxyLogicHandler;
32 import org.apache.mina.proxy.event.IoSessionEvent;
33 import org.apache.mina.proxy.event.IoSessionEventQueue;
34 import org.apache.mina.proxy.event.IoSessionEventType;
35 import org.apache.mina.proxy.handlers.ProxyRequest;
36 import org.apache.mina.proxy.handlers.http.HttpSmartProxyHandler;
37 import org.apache.mina.proxy.handlers.socks.Socks4LogicHandler;
38 import org.apache.mina.proxy.handlers.socks.Socks5LogicHandler;
39 import org.apache.mina.proxy.handlers.socks.SocksProxyConstants;
40 import org.apache.mina.proxy.handlers.socks.SocksProxyRequest;
41 import org.apache.mina.proxy.session.ProxyIoSession;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class ProxyFilter extends IoFilterAdapter {
58 private static final Logger LOGGER = LoggerFactory.getLogger(ProxyFilter.class);
59
60
61
62
63 public ProxyFilter() {
64
65 }
66
67
68
69
70
71
72
73
74
75
76
77 @Override
78 public void onPreAdd(final IoFilterChain chain, final String name, final NextFilter nextFilter) {
79 if (chain.contains(ProxyFilter.class)) {
80 throw new IllegalStateException("A filter chain cannot contain more than one ProxyFilter.");
81 }
82 }
83
84
85
86
87
88
89
90
91
92 @Override
93 public void onPreRemove(final IoFilterChain chain, final String name, final NextFilter nextFilter) {
94 IoSession session = chain.getSession();
95 session.removeAttribute(ProxyIoSession.PROXY_SESSION);
96 }
97
98
99
100
101
102
103
104
105
106
107 @Override
108 public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception {
109 ProxyIoSessionrg/apache/mina/proxy/session/ProxyIoSession.html#ProxyIoSession">ProxyIoSession proxyIoSession = (ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION);
110 proxyIoSession.setAuthenticationFailed(true);
111 super.exceptionCaught(nextFilter, session, cause);
112 }
113
114
115
116
117
118
119
120 private ProxyLogicHandler getProxyHandler(final IoSession session) {
121 ProxyLogicHandler handler = ((ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION)).getHandler();
122
123 if (handler == null) {
124 throw new IllegalStateException();
125 }
126
127
128 if (handler.getProxyIoSession().getProxyFilter() != this) {
129 throw new IllegalArgumentException("Not managed by this filter.");
130 }
131
132 return handler;
133 }
134
135
136
137
138
139
140
141
142
143 @Override
144 public void messageReceived(final NextFilter nextFilter, final IoSession session, final Object message)
145 throws ProxyAuthException {
146 ProxyLogicHandler handler = getProxyHandler(session);
147
148 synchronized (handler) {
149 IoBuffer"../../../../../org/apache/mina/core/buffer/IoBuffer.html#IoBuffer">IoBuffer buf = (IoBuffer) message;
150
151 if (handler.isHandshakeComplete()) {
152
153 nextFilter.messageReceived(session, buf);
154
155 } else {
156 if (LOGGER.isDebugEnabled()) {
157 LOGGER.debug(" Data Read: {} ({})", handler, buf);
158 }
159
160
161
162 while (buf.hasRemaining() && !handler.isHandshakeComplete()) {
163 if (LOGGER.isDebugEnabled()) {
164 LOGGER.debug(" Pre-handshake - passing to handler");
165 }
166
167 int pos = buf.position();
168 handler.messageReceived(nextFilter, buf);
169
170
171 if (buf.position() == pos || session.isClosing()) {
172 return;
173 }
174 }
175
176
177 if (buf.hasRemaining()) {
178 if (LOGGER.isDebugEnabled()) {
179 LOGGER.debug(" Passing remaining data to next filter");
180 }
181
182 nextFilter.messageReceived(session, buf);
183 }
184 }
185 }
186 }
187
188
189
190
191
192
193
194
195
196 @Override
197 public void filterWrite(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest) {
198 writeData(nextFilter, session, writeRequest, false);
199 }
200
201
202
203
204
205
206
207
208
209
210 public void writeData(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest,
211 final boolean isHandshakeData) {
212 ProxyLogicHandler handler = getProxyHandler(session);
213
214 synchronized (handler) {
215 if (handler.isHandshakeComplete()) {
216
217 nextFilter.filterWrite(session, writeRequest);
218 } else if (isHandshakeData) {
219 if (LOGGER.isDebugEnabled()) {
220 LOGGER.debug(" handshake data: {}", writeRequest.getMessage());
221 }
222
223
224 nextFilter.filterWrite(session, writeRequest);
225 } else {
226
227 if (!session.isConnected()) {
228
229 if (LOGGER.isDebugEnabled()) {
230 LOGGER.debug(" Write request on closed session. Request ignored.");
231 }
232 } else {
233
234 if (LOGGER.isDebugEnabled()) {
235 LOGGER.debug(" Handshaking is not complete yet. Buffering write request.");
236 }
237
238 handler.enqueueWriteRequest(nextFilter, writeRequest);
239 }
240 }
241 }
242 }
243
244
245
246
247
248
249
250
251
252 @Override
253 public void messageSent(final NextFilter nextFilter, final IoSession session, final WriteRequest writeRequest)
254 throws Exception {
255 if (writeRequest.getMessage() != null && writeRequest.getMessage() instanceof ProxyHandshakeIoBuffer) {
256
257 return;
258 }
259
260 nextFilter.messageSent(session, writeRequest);
261 }
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 @Override
278 public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
279 if (LOGGER.isDebugEnabled()) {
280 LOGGER.debug("Session created: " + session);
281 }
282
283 ProxyIoSessionrg/apache/mina/proxy/session/ProxyIoSession.html#ProxyIoSession">ProxyIoSession proxyIoSession = (ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION);
284
285 if (LOGGER.isDebugEnabled()) {
286 LOGGER.debug(" get proxyIoSession: " + proxyIoSession);
287 }
288
289 proxyIoSession.setProxyFilter(this);
290
291
292 ProxyLogicHandler handler = proxyIoSession.getHandler();
293
294
295
296 if (handler == null) {
297 ProxyRequest request = proxyIoSession.getRequest();
298
299 if (request instanceof SocksProxyRequest) {
300 SocksProxyRequest/../../org/apache/mina/proxy/handlers/socks/SocksProxyRequest.html#SocksProxyRequest">SocksProxyRequest req = (SocksProxyRequest) request;
301 if (req.getProtocolVersion() == SocksProxyConstants.SOCKS_VERSION_4) {
302 handler = new Socks4LogicHandler(proxyIoSession);
303 } else {
304 handler = new Socks5LogicHandler(proxyIoSession);
305 }
306 } else {
307 handler = new HttpSmartProxyHandler(proxyIoSession);
308 }
309
310 proxyIoSession.setHandler(handler);
311 handler.doHandshake(nextFilter);
312 }
313
314 proxyIoSession.getEventQueue().enqueueEventIfNecessary(
315 new IoSessionEvent(nextFilter, session, IoSessionEventType.CREATED));
316 }
317
318
319
320
321
322
323
324
325
326 @Override
327 public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
328 ProxyIoSessionrg/apache/mina/proxy/session/ProxyIoSession.html#ProxyIoSession">ProxyIoSession proxyIoSession = (ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION);
329 proxyIoSession.getEventQueue().enqueueEventIfNecessary(
330 new IoSessionEvent(nextFilter, session, IoSessionEventType.OPENED));
331 }
332
333
334
335
336
337
338
339
340
341 @Override
342 public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
343 ProxyIoSessionrg/apache/mina/proxy/session/ProxyIoSession.html#ProxyIoSession">ProxyIoSession proxyIoSession = (ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION);
344 proxyIoSession.getEventQueue().enqueueEventIfNecessary(new IoSessionEvent(nextFilter, session, status));
345 }
346
347
348
349
350
351
352
353
354
355 @Override
356 public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
357 ProxyIoSessionrg/apache/mina/proxy/session/ProxyIoSession.html#ProxyIoSession">ProxyIoSession proxyIoSession = (ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION);
358 proxyIoSession.getEventQueue().enqueueEventIfNecessary(
359 new IoSessionEvent(nextFilter, session, IoSessionEventType.CLOSED));
360 }
361 }