Author: trustin
Date: Wed Jul 11 01:35:57 2007
New Revision: 555205

URL: http://svn.apache.org/viewvc?view=rev&rev=555205
Log:
Fixed issue: DIRMINA-390 (IoHandler.messageSent is not called when FilterChain 
contains SSLFilter)
* Removed ugly workaround for empty marker buffers generated in 
ProtocolCodecFilter
* Made sure CompressionFilter is not affected by the empty marker buffer
* Added Maarten's SSLFilterTest


Added:
    
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/
    
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
   (with props)
    mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/
    
mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
   (with props)
Modified:
    
mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
    
mina/branches/1.1/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
    
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
    
mina/trunk/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
    mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java

Modified: 
mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java?view=diff&rev=555205&r1=555204&r2=555205
==============================================================================
--- 
mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
 (original)
+++ 
mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
 Wed Jul 11 01:35:57 2007
@@ -25,7 +25,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IdleStatus;
 import org.apache.mina.common.IoFilter;
@@ -809,18 +808,6 @@
                 public void filterWrite( IoSession session, WriteRequest 
writeRequest )
                 {
                     Entry nextEntry = EntryImpl.this.prevEntry;
-                    if( nextEntry != head && writeRequest.getMessage() 
instanceof ByteBuffer )
-                    {
-                        // A special message is a buffer with zero length.
-                        // A special message will bypass all next filters.
-                        // TODO: Provide a nicer way to take care of special 
messages.
-                        ByteBuffer message = ( ByteBuffer ) 
writeRequest.getMessage();
-                        if( message.remaining() == 0 )
-                        {
-                            callPreviousFilterWrite( head, session, 
writeRequest );
-                            return;
-                        }
-                    }
                     callPreviousFilterWrite( nextEntry, session, writeRequest 
);
                 }
 

Added: 
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java?view=auto&rev=555205
==============================================================================
--- 
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
 (added)
+++ 
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
 Wed Jul 11 01:35:57 2007
@@ -0,0 +1,146 @@
+package org.apache.mina.example.echoserver.ssl;
+
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.charset.Charset;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import junit.framework.TestCase;
+
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.SSLFilter;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+
+public class SSLFilterTest extends TestCase {
+
+    private static final int PORT = 17887;
+
+    private IoAcceptor acceptor;
+
+    SocketAddress socketAddress = new InetSocketAddress(PORT);
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        acceptor = new SocketAcceptor();
+    }
+
+    protected void tearDown() throws Exception {
+        acceptor.unbindAll();
+        super.tearDown();
+    }
+
+    public void testMessageSentIsCalled() throws Exception {
+        testMessageSentIsCalled(false);
+    }
+
+    public void testMessageSentIsCalled_With_SSL() throws Exception {
+        testMessageSentIsCalled(true);
+    }
+
+    private void testMessageSentIsCalled(boolean useSSL) throws Exception {
+
+        if (useSSL) {
+            SSLFilter sslFilter = new SSLFilter(BogusSSLContextFactory
+                    .getInstance(true));
+            acceptor.getFilterChain().addLast("sslFilter", sslFilter);
+        }
+        acceptor.getFilterChain().addLast(
+                "codec",
+                new ProtocolCodecFilter(new TextLineCodecFactory(Charset
+                        .forName("UTF-8"))));
+
+        EchoHandler handler = new EchoHandler();
+        acceptor.bind(socketAddress, handler);
+        System.out.println("MINA server started.");
+
+        Socket socket = getClientSocket(useSSL);
+        int bytesSent = 0;
+        bytesSent += writeMessage(socket, "test-1\n");
+        bytesSent += writeMessage(socket, "test-2\n");
+        byte[] response = new byte[bytesSent];
+        for (int i = 0; i < response.length; i++) {
+            response[i] = (byte) socket.getInputStream().read();
+        }
+        long millis = System.currentTimeMillis();
+        while (handler.sentMessages.size() < 2
+                && System.currentTimeMillis() < millis + 5000) {
+            Thread.sleep(200);
+        }
+        assertEquals("received what we sent", "test-1\ntest-2\n", new String(
+                response, "UTF-8"));
+
+        System.out.println("handler: " + handler.sentMessages);
+        assertEquals("handler should have sent 2 messages:", 2,
+                handler.sentMessages.size());
+        assertTrue(handler.sentMessages.contains("test-1"));
+        assertTrue(handler.sentMessages.contains("test-2"));
+    }
+
+    private int writeMessage(Socket socket, String message) throws Exception {
+        byte request[] = message.getBytes("UTF-8");
+        socket.getOutputStream().write(request);
+        return request.length;
+    }
+
+    private Socket getClientSocket(boolean ssl) throws Exception {
+        if (ssl) {
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            ctx.init(null, trustManagers, null);
+            return ctx.getSocketFactory().createSocket("localhost", PORT);
+        }
+        return new Socket("localhost", PORT);
+    }
+
+    private static class EchoHandler extends IoHandlerAdapter {
+
+        List<String> sentMessages = new ArrayList<String>();
+
+        public void exceptionCaught(IoSession session, Throwable cause)
+                throws Exception {
+        }
+
+        public void messageReceived(IoSession session, Object message)
+                throws Exception {
+            session.write(message);
+        }
+
+        public void messageSent(IoSession session, Object message)
+                throws Exception {
+            sentMessages.add(message.toString());
+            if (sentMessages.size() >= 2) {
+                session.close();
+            }
+        }
+
+    }
+
+    TrustManager[] trustManagers = new TrustManager[] { new TrustAnyone() };
+
+    private static class TrustAnyone implements X509TrustManager {
+        public void checkClientTrusted(
+                java.security.cert.X509Certificate[] x509Certificates, String 
s)
+                throws CertificateException {
+        }
+
+        public void checkServerTrusted(
+                java.security.cert.X509Certificate[] x509Certificates, String 
s)
+                throws CertificateException {
+        }
+
+        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+            return new java.security.cert.X509Certificate[0];
+        }
+    }
+
+}

Propchange: 
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
mina/branches/1.1/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.1/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java?view=diff&rev=555205&r1=555204&r2=555205
==============================================================================
--- 
mina/branches/1.1/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
 (original)
+++ 
mina/branches/1.1/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
 Wed Jul 11 01:35:57 2007
@@ -195,10 +195,15 @@
         }
 
         ByteBuffer inBuffer = ( ByteBuffer ) writeRequest.getMessage();
-        ByteBuffer outBuf = deflater.deflate( inBuffer );
-        inBuffer.release();
-        nextFilter.filterWrite( session, new WriteRequest( outBuf, writeRequest
-                .getFuture() ) );
+        if (!inBuffer.hasRemaining()) {
+            // Ignore empty buffers
+            nextFilter.filterWrite(session, writeRequest);
+        } else {
+            ByteBuffer outBuf = deflater.deflate( inBuffer );
+            inBuffer.release();
+            nextFilter.filterWrite( session, new WriteRequest( outBuf, 
writeRequest
+                    .getFuture() ) );
+        }
     }
 
     public void onPreAdd( IoFilterChain parent, String name, NextFilter 
nextFilter ) throws Exception

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java?view=diff&rev=555205&r1=555204&r2=555205
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
 (original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
 Wed Jul 11 01:35:57 2007
@@ -25,7 +25,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IdleStatus;
 import org.apache.mina.common.IoFilter;
@@ -836,18 +835,6 @@
                 public void filterWrite( IoSession session, WriteRequest 
writeRequest )
                 {
                     Entry nextEntry = EntryImpl.this.prevEntry;
-                    if( nextEntry != head && writeRequest.getMessage() 
instanceof ByteBuffer )
-                    {
-                        // A special message is a buffer with zero length.
-                        // A special message will bypass all next filters.
-                        // TODO: Provide a nicer way to take care of special 
messages.
-                        ByteBuffer message = ( ByteBuffer ) 
writeRequest.getMessage();
-                        if( message.remaining() == 0 )
-                        {
-                            callPreviousFilterWrite( head, session, 
writeRequest );
-                            return;
-                        }
-                    }
                     callPreviousFilterWrite( nextEntry, session, writeRequest 
);
                 }
 

Added: 
mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java?view=auto&rev=555205
==============================================================================
--- 
mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
 (added)
+++ 
mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
 Wed Jul 11 01:35:57 2007
@@ -0,0 +1,143 @@
+package org.apache.mina.example.echoserver.ssl;
+
+import junit.framework.TestCase;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.example.echoserver.ssl.BogusSSLContextFactory;
+import org.apache.mina.filter.SSLFilter;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.charset.Charset;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SSLFilterTest extends TestCase {
+
+    private static final int PORT = 17887;
+
+    private IoAcceptor acceptor;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        acceptor = new SocketAcceptor();
+    }
+
+    protected void tearDown() throws Exception {
+        acceptor.setDisconnectOnUnbind(true);
+        acceptor.unbind();
+        super.tearDown();
+    }
+
+    public void testMessageSentIsCalled() throws Exception {
+        testMessageSentIsCalled(false);
+    }
+
+    public void testMessageSentIsCalled_With_SSL() throws Exception {
+        testMessageSentIsCalled(true);
+    }
+
+    private void testMessageSentIsCalled(boolean useSSL) throws Exception {
+
+        if (useSSL) {
+            SSLFilter sslFilter = new SSLFilter(BogusSSLContextFactory
+                    .getInstance(true));
+            acceptor.getFilterChain().addLast("sslFilter", sslFilter);
+        }
+        acceptor.getFilterChain().addLast(
+                "codec",
+                new ProtocolCodecFilter(new TextLineCodecFactory(Charset
+                        .forName("UTF-8"))));
+
+        acceptor.setLocalAddress(new InetSocketAddress(PORT));
+
+        EchoHandler handler = new EchoHandler();
+        acceptor.setHandler(handler);
+        acceptor.bind();
+        System.out.println("MINA server started.");
+
+        Socket socket = getClientSocket(useSSL);
+        int bytesSent = 0;
+        bytesSent += writeMessage(socket, "test-1\n");
+        Thread.sleep(2000);
+        bytesSent += writeMessage(socket, "test-2\n");
+        int[] response = new int[bytesSent];
+        for (int i = 0; i < response.length; i++) {
+            response[i] = socket.getInputStream().read();
+        }
+        socket.close();
+        while (acceptor.getManagedSessions().size() != 0) {
+            Thread.sleep(100);
+        }
+
+        System.out.println("handler: " + handler.sentMessages);
+        assertEquals("handler should have sent 2 messages:", 2,
+                handler.sentMessages.size());
+        assertTrue(handler.sentMessages.contains("test-1"));
+        assertTrue(handler.sentMessages.contains("test-2"));
+    }
+
+    private int writeMessage(Socket socket, String message) throws Exception {
+        byte request[] = message.getBytes("UTF-8");
+        socket.getOutputStream().write(request);
+        return request.length;
+    }
+
+    private Socket getClientSocket(boolean ssl) throws Exception {
+        if (ssl) {
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            ctx.init(null, trustManagers, null);
+            return ctx.getSocketFactory().createSocket("localhost", PORT);
+        }
+        return new Socket("localhost", PORT);
+    }
+
+    private static class EchoHandler extends IoHandlerAdapter {
+
+        List<String> sentMessages = new ArrayList<String>();
+
+        public void exceptionCaught(IoSession session, Throwable cause)
+                throws Exception {
+        }
+
+        public void messageReceived(IoSession session, Object message)
+                throws Exception {
+            session.write(message);
+        }
+
+        public void messageSent(IoSession session, Object message)
+                throws Exception {
+            sentMessages.add(message.toString());
+            if (sentMessages.size() >= 2) {
+                session.close();
+            }
+        }
+    }
+
+    TrustManager[] trustManagers = new TrustManager[] { new TrustAnyone() };
+
+    private static class TrustAnyone implements X509TrustManager {
+        public void checkClientTrusted(
+                java.security.cert.X509Certificate[] x509Certificates, String 
s)
+                throws CertificateException {
+        }
+
+        public void checkServerTrusted(
+                java.security.cert.X509Certificate[] x509Certificates, String 
s)
+                throws CertificateException {
+        }
+
+        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+            return new java.security.cert.X509Certificate[0];
+        }
+    }
+
+}

Propchange: 
mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
mina/trunk/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java?view=diff&rev=555205&r1=555204&r2=555205
==============================================================================
--- 
mina/trunk/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
 (original)
+++ 
mina/trunk/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
 Wed Jul 11 01:35:57 2007
@@ -198,10 +198,15 @@
         }
 
         ByteBuffer inBuffer = ( ByteBuffer ) writeRequest.getMessage();
-        ByteBuffer outBuf = deflater.deflate( inBuffer );
-        nextFilter.filterWrite(
-                session,
-                new DefaultWriteRequest(outBuf, writeRequest.getFuture(), 
writeRequest.getDestination()));
+        if (!inBuffer.hasRemaining()) {
+            // Ignore empty buffers
+            nextFilter.filterWrite(session, writeRequest);
+        } else {
+            ByteBuffer outBuf = deflater.deflate( inBuffer );
+            nextFilter.filterWrite(
+                    session,
+                    new DefaultWriteRequest(outBuf, writeRequest.getFuture(), 
writeRequest.getDestination()));
+        }
     }
 
     @Override

Modified: 
mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java?view=diff&rev=555205&r1=555204&r2=555205
==============================================================================
--- mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java 
(original)
+++ mina/trunk/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java 
Wed Jul 11 01:35:57 2007
@@ -28,6 +28,7 @@
 import javax.net.ssl.SSLSession;
 
 import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.DefaultWriteRequest;
 import org.apache.mina.common.IoFilterAdapter;
 import org.apache.mina.common.IoFilterChain;
 import org.apache.mina.common.IoFuture;


Reply via email to