diff options
author | Greg Wilkins | 2012-05-31 11:39:57 +0000 |
---|---|---|
committer | Greg Wilkins | 2012-05-31 11:39:57 +0000 |
commit | b9e28ba51ec1152b7655d006fd6a18c765125065 (patch) | |
tree | cc909b56029c479147580b49c1d11dfbae860bae | |
parent | b8e2c65fa8672b72014420f4beb5d5401bfebbb1 (diff) | |
download | org.eclipse.jetty.project-b9e28ba51ec1152b7655d006fd6a18c765125065.tar.gz org.eclipse.jetty.project-b9e28ba51ec1152b7655d006fd6a18c765125065.tar.xz org.eclipse.jetty.project-b9e28ba51ec1152b7655d006fd6a18c765125065.zip |
jetty-9 new simple SslConnection - passing tests
3 files changed, 112 insertions, 17 deletions
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java index e8e485fdb7..349d74aa76 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java @@ -136,6 +136,14 @@ public class SslConnection extends AbstractAsyncConnection /* ------------------------------------------------------------ */ @Override + public void onReadFail(Throwable cause) + { + System.err.println("SSL onReadFail "+cause); + super.onReadFail(cause); + } + + /* ------------------------------------------------------------ */ + @Override public String toString() { return String.format("SslConnection@%x{%s,%s%s}", @@ -151,6 +159,7 @@ public class SslConnection extends AbstractAsyncConnection private AsyncConnection _connection; private boolean _fillWrap; private boolean _writing; + private boolean _underflown; private boolean _ishut=false; private final Callback<Void> _writeCallback = new Callback<Void>(){ @@ -207,21 +216,36 @@ public class SslConnection extends AbstractAsyncConnection { synchronized (SslEndPoint.this) { - if (BufferUtil.hasContent(_appIn)||BufferUtil.hasContent(_netIn)) + // Do we already have some app data + if (BufferUtil.hasContent(_appIn)) return true; + // If we are not underflown and have net data + if (!_underflown && BufferUtil.hasContent(_netIn)) + return true; + + + // So we are not read ready + // Are we actually write blocked? - if (_sslEngine.getHandshakeStatus()==HandshakeStatus.NEED_WRAP && BufferUtil.hasContent(_netOut) ) + if (_sslEngine.getHandshakeStatus()==HandshakeStatus.NEED_WRAP ) { - // we must be blocked trying to write before we can read, so - // let's write the netdata + // we must be blocked trying to write before we can read + + // Do we don't have some netdata to write + if (BufferUtil.isEmpty(_netOut)) + // pretend we are readable so the wrap is done by next fill call + return true; + + // otherwise write the net data _fillWrap=true; + _writing=true; getEndPoint().write(null,_writeCallback,_netOut); } else // Normal readable callback scheduleOnReadable(); - + return false; } } @@ -236,7 +260,8 @@ public class SslConnection extends AbstractAsyncConnection { // If we have pending output data, if (BufferUtil.hasContent(_netOut)) - { // write it + { + // write it _writing=true; getEndPoint().write(null,_writeCallback,_netOut); } @@ -294,6 +319,8 @@ public class SslConnection extends AbstractAsyncConnection { // Let's try reading some encrypted data... even if we have some already. int net_filled=getEndPoint().fill(_netIn); + if (net_filled>0) + _underflown=false; // Let's try the SSL thang even if we have no net data because in that // case we want to fall through to the handshake handling @@ -331,7 +358,12 @@ public class SslConnection extends AbstractAsyncConnection default: throw new IllegalStateException(); } + + case BUFFER_UNDERFLOW: + _underflown=true; + //$FALL-THROUGH$ to deal with handshaking stuff + default: // if we produced bytes, we don't care about the handshake state if (result.bytesProduced()>0) diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java index b41e459096..1f9628c582 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java @@ -2,10 +2,13 @@ package org.eclipse.jetty.io; import static org.hamcrest.Matchers.greaterThan; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; @@ -193,6 +196,63 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest super.testWriteBlock(); } + @Override + public void testBlockRead() throws Exception + { + super.testBlockRead(); + } + + @Override + public void testIdle() throws Exception + { + super.testIdle(); + } + + @Override + public void testBlockedReadIdle() throws Exception + { + Socket client = newClient(); + OutputStream clientOutputStream = client.getOutputStream(); + + client.setSoTimeout(5000); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + + // Write client to server + clientOutputStream.write("HelloWorld".getBytes("UTF-8")); + + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b>0); + assertEquals(c,(char)b); + } + + // Set Max idle + _lastEndp.setMaxIdleTime(500); + + // Write 8 and cause block waiting for 10 + _blockAt=10; + clientOutputStream.write("12345678".getBytes("UTF-8")); + clientOutputStream.flush(); + + // read until idle shutdown received + long start=System.currentTimeMillis(); + int b=client.getInputStream().read(); + assertEquals(-1,b); + long idle=System.currentTimeMillis()-start; + assertTrue(idle>400); + assertTrue(idle<2000); + + Thread.sleep(1000); + + assertFalse(_lastEndp.isOpen()); + } + @Test @Override public void testStress() throws Exception diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java index 45668b3b4c..7361fb6b6f 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java @@ -83,7 +83,7 @@ public class SelectChannelEndPointTest }; // Must be volatile or the test may fail spuriously - private volatile int _blockAt=0; + protected volatile int _blockAt=0; private volatile int _writeCount=1; @Before @@ -349,20 +349,19 @@ public class SelectChannelEndPointTest OutputStream clientOutputStream = client.getOutputStream(); InputStream clientInputStream = client.getInputStream(); - int specifiedTimeout = 2000; + int specifiedTimeout = 1000; client.setSoTimeout(specifiedTimeout); // Write 8 and cause block waiting for 10 _blockAt=10; clientOutputStream.write("12345678".getBytes("UTF-8")); clientOutputStream.flush(); - + while(_lastEndp==null); _lastEndp.setMaxIdleTime(10*specifiedTimeout); - Thread.sleep(2 * specifiedTimeout); - - // No echo as blocking for 10 + Thread.sleep((11*specifiedTimeout)/10); + long start=System.currentTimeMillis(); try { @@ -374,7 +373,7 @@ public class SelectChannelEndPointTest int elapsed = Long.valueOf(System.currentTimeMillis() - start).intValue(); Assert.assertThat("Expected timeout", elapsed, greaterThanOrEqualTo(3*specifiedTimeout/4)); } - + // write remaining characters clientOutputStream.write("90ABCDEF".getBytes("UTF-8")); clientOutputStream.flush(); @@ -503,7 +502,7 @@ public class SelectChannelEndPointTest server.configureBlocking(false); _manager.accept(server); - int writes = 1000000; + int writes = 100000; final byte[] bytes="HelloWorld-".getBytes(StringUtil.__UTF8_CHARSET); byte[] count="0\n".getBytes(StringUtil.__UTF8_CHARSET); @@ -595,21 +594,25 @@ public class SelectChannelEndPointTest _writeCount=10000; String data="Now is the time for all good men to come to the aid of the party"; client.getOutputStream().write(data.getBytes("UTF-8")); + BufferedInputStream in = new BufferedInputStream(client.getInputStream()); for (int i=0;i<_writeCount;i++) { + if (i%1000==0) + { + //System.out.println(i); + TimeUnit.MILLISECONDS.sleep(200); + } // Verify echo server to client for (int j=0;j<data.length();j++) { char c=data.charAt(j); - int b = client.getInputStream().read(); + int b = in.read(); assertTrue(b>0); assertEquals("test-"+i+"/"+j,c,(char)b); } if (i==0) _lastEndp.setMaxIdleTime(60000); - if (i%100==0) - TimeUnit.MILLISECONDS.sleep(10); } |