Skip to content

Commit e1f4ba9

Browse files
committed
SslFilter pass message to next filter
1 parent fc71b38 commit e1f4ba9

3 files changed

Lines changed: 246 additions & 12 deletions

File tree

mina-core/src/main/java/org/apache/mina/filter/ssl/SslFilter.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,14 +454,11 @@ public void messageSent(NextFilter next, IoSession session, WriteRequest request
454454
LOGGER.debug("CLIENT: Session {} ack {}", session, request);
455455
}
456456
}
457-
458-
EncryptedWriteRequest encryptedWriteRequest = EncryptedWriteRequest.class.cast(request);
457+
459458
SslHandler sslHandler = getSslHandler(session);
460459
sslHandler.ack(next, request);
461-
462-
if (encryptedWriteRequest.getOriginalRequest() != encryptedWriteRequest) {
463-
next.messageSent(session, encryptedWriteRequest.getOriginalRequest());
464-
}
460+
461+
super.messageSent(next, session, request.getOriginalRequest());
465462
} else {
466463
super.messageSent(next, session, request);
467464
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
*/
20+
package org.apache.mina.filter.ssl;
21+
22+
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
23+
import org.apache.mina.core.future.WriteFuture;
24+
import org.apache.mina.core.service.IoHandler;
25+
import org.apache.mina.core.service.IoHandlerAdapter;
26+
import org.apache.mina.core.service.IoService;
27+
import org.apache.mina.core.session.IoSession;
28+
import org.apache.mina.filter.FilterEvent;
29+
import org.apache.mina.filter.codec.ProtocolCodecFilter;
30+
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
31+
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
32+
import org.apache.mina.transport.socket.nio.NioSocketConnector;
33+
import org.apache.mina.util.AvailablePortFinder;
34+
import org.junit.Before;
35+
import org.junit.Test;
36+
37+
import javax.net.ssl.KeyManagerFactory;
38+
import javax.net.ssl.SSLContext;
39+
import javax.net.ssl.TrustManagerFactory;
40+
import java.net.InetSocketAddress;
41+
import java.security.KeyStore;
42+
import java.security.Security;
43+
import java.util.concurrent.CountDownLatch;
44+
import java.util.concurrent.TimeUnit;
45+
46+
import static org.junit.Assert.assertEquals;
47+
import static org.junit.Assert.assertTrue;
48+
49+
public class SslFilterScheduledWriteMessagesTest {
50+
51+
private static final String KEY_STORE_PATH = "keystore.jks";
52+
private static final String TRUST_STORE_PATH = "truststore.jks";
53+
private static final String[] ENABLED_PROTOCOLS = new String[] { "TLSv1.2" };
54+
private static final String KEY_MANAGER_FACTORY_ALGORITHM;
55+
56+
static {
57+
String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
58+
59+
if (algorithm == null) {
60+
algorithm = KeyManagerFactory.getDefaultAlgorithm();
61+
}
62+
63+
KEY_MANAGER_FACTORY_ALGORITHM = algorithm;
64+
}
65+
66+
private CountDownLatch handshakeDone = new CountDownLatch(2);
67+
private int port;
68+
69+
@Before
70+
public void setUp() {
71+
port = AvailablePortFinder.getNextAvailable(5555);
72+
}
73+
74+
@Test
75+
public void shouldDecrementScheduledWriteMessages() throws Exception {
76+
SSLContext sslContext = createSSLContext();
77+
78+
AcceptorIoHandler acceptorIoHandler = new AcceptorIoHandler(handshakeDone);
79+
ConnectionIoHandler connectionIoHandler = new ConnectionIoHandler(handshakeDone);
80+
81+
IoService acceptorService = startAcceptor(sslContext, acceptorIoHandler);
82+
83+
try {
84+
IoService connectorService = startConnector(sslContext, connectionIoHandler);
85+
86+
try {
87+
assertTrue(handshakeDone.await(10L, TimeUnit.SECONDS));
88+
89+
IoSession acceptorSession = acceptorIoHandler.session;
90+
IoSession connectorSession = connectionIoHandler.session;
91+
92+
assertEquals(acceptorSession.getWrittenMessages(), 2);
93+
assertEquals(connectorSession.getWrittenMessages(), 2);
94+
assertEquals(acceptorSession.getScheduledWriteMessages(), 0);
95+
assertEquals(connectorSession.getScheduledWriteMessages(), 0);
96+
assertEquals(acceptorIoHandler.sentMessageCount, 2);
97+
assertEquals(connectionIoHandler.sentMessageCount, 2);
98+
99+
WriteFuture connectorWriteFuture = connectorSession.write("connector message");
100+
assertTrue(connectorWriteFuture.await(2L, TimeUnit.SECONDS));
101+
102+
Thread.sleep(1000L);
103+
104+
assertEquals(acceptorSession.getWrittenMessages(), 2);
105+
assertEquals(connectorSession.getWrittenMessages(), 3);
106+
assertEquals(acceptorSession.getScheduledWriteMessages(), 0);
107+
assertEquals(connectorSession.getScheduledWriteMessages(), 0);
108+
assertEquals(acceptorIoHandler.sentMessageCount, 2);
109+
assertEquals(connectionIoHandler.sentMessageCount, 3);
110+
111+
WriteFuture acceptorWriteFuture = acceptorSession.write("acceptor message");
112+
assertTrue(acceptorWriteFuture.await(2L, TimeUnit.SECONDS));
113+
114+
Thread.sleep(1000L);
115+
116+
assertEquals(acceptorSession.getWrittenMessages(), 3);
117+
assertEquals(connectorSession.getWrittenMessages(), 3);
118+
assertEquals(acceptorSession.getScheduledWriteMessages(), 0);
119+
assertEquals(connectorSession.getScheduledWriteMessages(), 0);
120+
assertEquals(acceptorIoHandler.sentMessageCount, 3);
121+
assertEquals(connectionIoHandler.sentMessageCount, 3);
122+
} finally {
123+
connectorService.dispose();
124+
}
125+
} finally {
126+
acceptorService.dispose();
127+
}
128+
}
129+
130+
private IoService startAcceptor(SSLContext sslContext, IoHandler handler) throws Exception {
131+
NioSocketAcceptor acceptor = new NioSocketAcceptor();
132+
acceptor.setReuseAddress(true);
133+
134+
SslFilter sslFilter = new SslFilter(sslContext);
135+
sslFilter.setEnabledProtocols(ENABLED_PROTOCOLS);
136+
137+
DefaultIoFilterChainBuilder filters = acceptor.getFilterChain();
138+
filters.addLast("ssl", sslFilter);
139+
filters.addLast("text", new ProtocolCodecFilter(new TextLineCodecFactory()));
140+
141+
acceptor.setHandler(handler);
142+
acceptor.bind(new InetSocketAddress(port));
143+
144+
return acceptor;
145+
}
146+
147+
private IoService startConnector(SSLContext sslContext, IoHandler handler) {
148+
NioSocketConnector connector = new NioSocketConnector();
149+
150+
SslFilter sslFilter = new SslFilter(sslContext);
151+
sslFilter.setEnabledProtocols(ENABLED_PROTOCOLS);
152+
153+
DefaultIoFilterChainBuilder filters = connector.getFilterChain();
154+
filters.addLast("ssl", sslFilter);
155+
filters.addLast("text", new ProtocolCodecFilter(new TextLineCodecFactory()));
156+
157+
connector.setHandler(handler);
158+
connector.connect(new InetSocketAddress("localhost", port));
159+
160+
return connector;
161+
}
162+
163+
private static SSLContext createSSLContext() throws Exception {
164+
char[] password = "password".toCharArray();
165+
166+
KeyStore keyStore = KeyStore.getInstance("JKS");
167+
keyStore.load(SslIdentificationAlgorithmTest.class.getResourceAsStream(KEY_STORE_PATH), password);
168+
169+
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
170+
kmf.init(keyStore, password);
171+
172+
KeyStore trustStore = KeyStore.getInstance("JKS");
173+
trustStore.load(SslIdentificationAlgorithmTest.class.getResourceAsStream(TRUST_STORE_PATH), password);
174+
175+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
176+
tmf.init(trustStore);
177+
178+
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
179+
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
180+
181+
return sslContext;
182+
}
183+
184+
private static final class AcceptorIoHandler extends IoHandlerAdapter {
185+
186+
private final CountDownLatch handshakeDone;
187+
private IoSession session;
188+
private int sentMessageCount;
189+
190+
public AcceptorIoHandler(CountDownLatch handshakeDone) {
191+
this.handshakeDone = handshakeDone;
192+
}
193+
194+
@Override
195+
public void sessionOpened(IoSession session) {
196+
this.session = session;
197+
}
198+
199+
@Override
200+
public void messageSent(IoSession session, Object message) {
201+
sentMessageCount++;
202+
}
203+
204+
@Override
205+
public void event(IoSession session, FilterEvent event) {
206+
if (event == SslEvent.SECURED) {
207+
handshakeDone.countDown();
208+
}
209+
}
210+
}
211+
212+
private static final class ConnectionIoHandler extends IoHandlerAdapter {
213+
214+
private final CountDownLatch handshakeDone;
215+
private IoSession session;
216+
private int sentMessageCount;
217+
218+
public ConnectionIoHandler(CountDownLatch handshakeDone) {
219+
this.handshakeDone = handshakeDone;
220+
}
221+
222+
@Override
223+
public void sessionOpened(IoSession session) {
224+
this.session = session;
225+
}
226+
227+
@Override
228+
public void messageSent(IoSession session, Object message) {
229+
sentMessageCount++;
230+
}
231+
232+
@Override
233+
public void event(IoSession session, FilterEvent event) {
234+
if (event == SslEvent.SECURED) {
235+
handshakeDone.countDown();
236+
}
237+
}
238+
}
239+
}

mina-example/src/test/java/org/apache/mina/example/echoserver/ssl/SslFilterTest.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,13 @@ private void testMessageSentIsCalled(boolean useSSL) throws Exception {
130130
*/
131131

132132
socket.close();
133+
133134
while (acceptor.getManagedSessions().size() != 0) {
134135
Thread.sleep(100);
135136
}
136137

137-
// System.out.println("handler: " + handler.sentMessages);
138138
assertEquals("handler should have sent 1 messages:", 1, handler.sentMessages.size());
139139
assertTrue(handler.sentMessages.contains("test-1"));
140-
//assertTrue(handler.sentMessages.contains("test-2"));
141140
}
142141

143142
private int writeMessage(Socket socket, String message) throws Exception {
@@ -171,10 +170,9 @@ public void messageReceived(IoSession session, Object message) throws Exception
171170

172171
@Override
173172
public void messageSent(IoSession session, Object message) throws Exception {
174-
sentMessages.add(message.toString());
175-
176-
if (sentMessages.size() >= 2) {
177-
session.closeNow();
173+
// ignore ssl related messages
174+
if (message instanceof String) {
175+
sentMessages.add(message.toString());
178176
}
179177
}
180178
}

0 commit comments

Comments
 (0)