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.io.UnsupportedEncodingException;
23 import java.util.LinkedList;
24 import java.util.Queue;
25
26 import org.apache.mina.core.buffer.IoBuffer;
27 import org.apache.mina.core.filterchain.IoFilter.NextFilter;
28 import org.apache.mina.core.future.DefaultWriteFuture;
29 import org.apache.mina.core.future.WriteFuture;
30 import org.apache.mina.core.session.IoSession;
31 import org.apache.mina.core.write.DefaultWriteRequest;
32 import org.apache.mina.core.write.WriteRequest;
33 import org.apache.mina.proxy.filter.ProxyFilter;
34 import org.apache.mina.proxy.filter.ProxyHandshakeIoBuffer;
35 import org.apache.mina.proxy.session.ProxyIoSession;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43
44
45
46
47
48
49 public abstract class AbstractProxyLogicHandler implements ProxyLogicHandler {
50
51 private final static Logger logger = LoggerFactory
52 .getLogger(AbstractProxyLogicHandler.class);
53
54
55
56
57 private ProxyIoSession proxyIoSession;
58
59
60
61
62 private Queue<Event> writeRequestQueue = null;
63
64
65
66
67 private boolean handshakeComplete = false;
68
69
70
71
72
73
74 public AbstractProxyLogicHandler(ProxyIoSession proxyIoSession) {
75 this.proxyIoSession = proxyIoSession;
76 }
77
78
79
80
81 protected ProxyFilter getProxyFilter() {
82 return proxyIoSession.getProxyFilter();
83 }
84
85
86
87
88 protected IoSession getSession() {
89 return proxyIoSession.getSession();
90 }
91
92
93
94
95 public ProxyIoSession getProxyIoSession() {
96 return proxyIoSession;
97 }
98
99 public void setProxySession(ProxyIoSession proxyIoSession) {
100 this.proxyIoSession = proxyIoSession;
101 }
102
103
104
105
106
107
108
109 protected WriteFuture writeData(final NextFilter nextFilter,
110 final IoBuffer data) throws UnsupportedEncodingException {
111
112 ProxyHandshakeIoBuffer writeBuffer = new ProxyHandshakeIoBuffer(data);
113
114 logger.debug(" session write: {}", writeBuffer);
115
116 WriteFuture writeFuture = new DefaultWriteFuture(getSession());
117 getProxyFilter().writeData(nextFilter, getSession(),
118 new DefaultWriteRequest(writeBuffer, writeFuture), true);
119
120 return writeFuture;
121 }
122
123
124
125
126
127 public boolean isHandshakeComplete() {
128 synchronized (this) {
129 return handshakeComplete;
130 }
131 }
132
133
134
135
136 protected final void setHandshakeComplete() {
137 synchronized (this) {
138 handshakeComplete = true;
139 }
140
141 ProxyIoSession proxyIoSession = getProxyIoSession();
142 proxyIoSession.getConnector()
143 .fireConnected(proxyIoSession.getSession())
144 .awaitUninterruptibly();
145
146 logger.debug(" handshake completed");
147
148
149 try {
150 proxyIoSession.getEventQueue().flushPendingSessionEvents();
151 flushPendingWriteRequests();
152 } catch (Exception ex) {
153 logger.error("Unable to flush pending write requests", ex);
154 }
155 }
156
157
158
159
160 protected synchronized void flushPendingWriteRequests() throws Exception {
161 logger.debug(" flushPendingWriteRequests()");
162
163 if (writeRequestQueue == null) {
164 return;
165 }
166
167 Event scheduledWrite;
168 while ((scheduledWrite = writeRequestQueue.poll()) != null) {
169 logger.debug(" Flushing buffered write request: {}",
170 scheduledWrite.data);
171
172 getProxyFilter().filterWrite(scheduledWrite.nextFilter,
173 getSession(), (WriteRequest) scheduledWrite.data);
174 }
175
176
177 writeRequestQueue = null;
178 }
179
180
181
182
183 public synchronized void enqueueWriteRequest(final NextFilter nextFilter,
184 final WriteRequest writeRequest) {
185 if (writeRequestQueue == null) {
186 writeRequestQueue = new LinkedList<Event>();
187 }
188
189 writeRequestQueue.offer(new Event(nextFilter, writeRequest));
190 }
191
192
193
194
195 protected void closeSession(final String message, final Throwable t) {
196 if (t != null) {
197 logger.error(message, t);
198 proxyIoSession.setAuthenticationFailed(true);
199 } else {
200 logger.error(message);
201 }
202
203 getSession().close(true);
204 }
205
206 protected void closeSession(final String message) {
207 closeSession(message, null);
208 }
209
210
211
212
213 private final static class Event {
214 private final NextFilter nextFilter;
215
216 private final Object data;
217
218 Event(final NextFilter nextFilter, final Object data) {
219 this.nextFilter = nextFilter;
220 this.data = data;
221 }
222
223 public Object getData() {
224 return data;
225 }
226
227 public NextFilter getNextFilter() {
228 return nextFilter;
229 }
230 }
231 }