398872 - SslConnection should not be notified of idle timeouts. First solution.
This commit is contained in:
parent
b5df3a6b76
commit
b2f3852fb3
|
@ -871,6 +871,16 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return encodingField;
|
||||
}
|
||||
|
||||
protected HttpConnection newHttpConnection(HttpClient httpClient, EndPoint endPoint, HttpDestination destination)
|
||||
{
|
||||
return new HttpConnection(httpClient, endPoint, destination);
|
||||
}
|
||||
|
||||
protected SslConnection newSslConnection(HttpClient httpClient, EndPoint endPoint, SSLEngine engine)
|
||||
{
|
||||
return new SslConnection(httpClient.getByteBufferPool(), httpClient.getExecutor(), endPoint, engine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
|
@ -916,12 +926,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
SSLEngine engine = sslContextFactory.newSSLEngine(endPoint.getRemoteAddress());
|
||||
engine.setUseClientMode(true);
|
||||
|
||||
SslConnection sslConnection = new SslConnection(getByteBufferPool(), getExecutor(), endPoint, engine);
|
||||
// TODO: configureConnection => implies we should use SslConnectionFactory to do it
|
||||
|
||||
SslConnection sslConnection = newSslConnection(HttpClient.this, endPoint, engine);
|
||||
EndPoint appEndPoint = sslConnection.getDecryptedEndPoint();
|
||||
HttpConnection connection = newHttpConnection(HttpClient.this, appEndPoint, destination);
|
||||
// TODO: configureConnection, see above
|
||||
|
||||
appEndPoint.setConnection(connection);
|
||||
callback.promise.succeeded(connection);
|
||||
|
@ -932,7 +939,6 @@ public class HttpClient extends ContainerLifeCycle
|
|||
else
|
||||
{
|
||||
HttpConnection connection = newHttpConnection(HttpClient.this, endPoint, destination);
|
||||
// TODO: configureConnection, see above
|
||||
callback.promise.succeeded(connection);
|
||||
return connection;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import java.io.IOException;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -34,10 +36,13 @@ import org.eclipse.jetty.client.api.Response;
|
|||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.util.InputStreamContentProvider;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.ssl.SslConnection;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -223,6 +228,46 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdleTimeout() throws Throwable
|
||||
{
|
||||
long timeout = 1000;
|
||||
start(new TimeoutHandler(2 * timeout));
|
||||
client.stop();
|
||||
final AtomicBoolean sslIdle = new AtomicBoolean();
|
||||
client = new HttpClient(sslContextFactory)
|
||||
{
|
||||
@Override
|
||||
protected SslConnection newSslConnection(HttpClient httpClient, EndPoint endPoint, SSLEngine engine)
|
||||
{
|
||||
return new SslConnection(httpClient.getByteBufferPool(), httpClient.getExecutor(), endPoint, engine)
|
||||
{
|
||||
@Override
|
||||
protected boolean onReadTimeout()
|
||||
{
|
||||
sslIdle.set(true);
|
||||
return super.onReadTimeout();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
client.setIdleTimeout(timeout);
|
||||
client.start();
|
||||
|
||||
try
|
||||
{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.send();
|
||||
Assert.fail();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
Assert.assertFalse(sslIdle.get());
|
||||
Assert.assertThat(x.getCause(), Matchers.instanceOf(TimeoutException.class));
|
||||
}
|
||||
}
|
||||
|
||||
private class TimeoutHandler extends AbstractHandler
|
||||
{
|
||||
private final long timeout;
|
||||
|
|
|
@ -83,7 +83,7 @@ public abstract class IdleTimeout
|
|||
if (old>0)
|
||||
{
|
||||
// if the old was less than or equal to the new timeout, then nothing more to do
|
||||
if (old<=_idleTimeout)
|
||||
if (old<=idleTimeout)
|
||||
return;
|
||||
|
||||
// old timeout is too long, so cancel it.
|
||||
|
@ -93,7 +93,7 @@ public abstract class IdleTimeout
|
|||
}
|
||||
|
||||
// If we have a new timeout, then check and reschedule
|
||||
if (_idleTimeout>0 && isOpen())
|
||||
if (idleTimeout>0 && isOpen())
|
||||
_idleTask.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -220,9 +220,6 @@ public class SslConnection extends AbstractConnection
|
|||
// the decrypted readInterest and/or writeFlusher so that they will attempt
|
||||
// to do the fill and/or flush again and these calls will do the actually
|
||||
// handle the cause.
|
||||
|
||||
super.onFillInterestedFailed(cause);
|
||||
|
||||
synchronized(_decryptedEndPoint)
|
||||
{
|
||||
_decryptedEndPoint.getFillInterest().onFail(cause);
|
||||
|
|
|
@ -20,11 +20,9 @@ package org.eclipse.jetty.io;
|
|||
|
||||
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;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLEngineResult;
|
||||
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
||||
|
@ -42,9 +40,7 @@ import org.junit.Test;
|
|||
|
||||
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;
|
||||
|
||||
|
||||
public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||
|
@ -226,51 +222,6 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
|||
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);
|
||||
}
|
||||
|
||||
assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS));
|
||||
_lastEndPoint.setIdleTimeout(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(_lastEndPoint.isOpen());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
@Stress("Requires a relatively idle (network wise) environment")
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.io;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -52,6 +46,12 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class SelectChannelEndPointTest
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class);
|
||||
|
@ -425,6 +425,7 @@ public class SelectChannelEndPointTest
|
|||
public void testBlockedReadIdle() throws Exception
|
||||
{
|
||||
Socket client = newClient();
|
||||
InputStream clientInputStream = client.getInputStream();
|
||||
OutputStream clientOutputStream = client.getOutputStream();
|
||||
|
||||
client.setSoTimeout(5000);
|
||||
|
@ -440,7 +441,7 @@ public class SelectChannelEndPointTest
|
|||
// Verify echo server to client
|
||||
for (char c : "HelloWorld".toCharArray())
|
||||
{
|
||||
int b = client.getInputStream().read();
|
||||
int b = clientInputStream.read();
|
||||
assertTrue(b > 0);
|
||||
assertEquals(c, (char)b);
|
||||
}
|
||||
|
@ -456,7 +457,7 @@ public class SelectChannelEndPointTest
|
|||
|
||||
// read until idle shutdown received
|
||||
long start = System.currentTimeMillis();
|
||||
int b = client.getInputStream().read();
|
||||
int b = clientInputStream.read();
|
||||
assertEquals('E', b);
|
||||
long idle = System.currentTimeMillis() - start;
|
||||
assertTrue(idle > idleTimeout / 2);
|
||||
|
@ -464,10 +465,12 @@ public class SelectChannelEndPointTest
|
|||
|
||||
for (char c : "E: 12345678".toCharArray())
|
||||
{
|
||||
b = client.getInputStream().read();
|
||||
b = clientInputStream.read();
|
||||
assertTrue(b > 0);
|
||||
assertEquals(c, (char)b);
|
||||
}
|
||||
b = clientInputStream.read();
|
||||
assertEquals(-1,b);
|
||||
|
||||
// But endpoint is still open.
|
||||
if(_lastEndPoint.isOpen())
|
||||
|
|
Loading…
Reference in New Issue