Changes in preparation for #340040 (Support for a total timeout).
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@3044 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
9be79e1750
commit
26751210e4
|
@ -130,22 +130,36 @@ public class HttpConnection extends AbstractConnection
|
|||
scep.scheduleWrite();
|
||||
}
|
||||
|
||||
long exchTimeout = _exchange.getTimeout();
|
||||
if (exchTimeout > 0)
|
||||
{
|
||||
if (exchTimeout!=_destination.getHttpClient().getTimeout())
|
||||
_endp.setMaxIdleTime((int)exchTimeout);
|
||||
_destination.getHttpClient().schedule(_timeout, exchTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
_destination.getHttpClient().schedule(_timeout);
|
||||
}
|
||||
scheduleTimeout();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void scheduleTimeout() throws IOException
|
||||
{
|
||||
HttpClient httpClient = _destination.getHttpClient();
|
||||
|
||||
long exchangeTimeout = _exchange.getTimeout();
|
||||
long timeout = exchangeTimeout;
|
||||
if (timeout <= 0)
|
||||
timeout = httpClient.getTimeout();
|
||||
|
||||
long endPointTimeout = _endp.getMaxIdleTime();
|
||||
|
||||
if (timeout > 0 && timeout > endPointTimeout)
|
||||
{
|
||||
// Make it larger than the exchange timeout so that there are
|
||||
// no races in trying to close the endpoint between the 2 timeouts
|
||||
_endp.setMaxIdleTime(2 * (int)timeout);
|
||||
}
|
||||
|
||||
if (exchangeTimeout > 0)
|
||||
httpClient.schedule(_timeout, exchangeTimeout);
|
||||
else
|
||||
httpClient.schedule(_timeout);
|
||||
}
|
||||
|
||||
public Connection handle() throws IOException
|
||||
{
|
||||
if (_exchange != null)
|
||||
|
@ -369,12 +383,13 @@ public class HttpConnection extends AbstractConnection
|
|||
if (_exchange != null)
|
||||
{
|
||||
HttpExchange exchange=_exchange;
|
||||
_exchange.disassociate();
|
||||
|
||||
if (_exchange.getTimeout()>0 && _exchange.getTimeout()!=getDestination().getHttpClient().getTimeout())
|
||||
_endp.setMaxIdleTime((int)getDestination().getHttpClient().getTimeout());
|
||||
exchange.disassociate();
|
||||
_exchange = null;
|
||||
|
||||
// Reset the maxIdleTime because it may have been changed
|
||||
if (!close)
|
||||
_endp.setMaxIdleTime((int)_destination.getHttpClient().getIdleTimeout());
|
||||
|
||||
if (_status==HttpStatus.SWITCHING_PROTOCOLS_101)
|
||||
{
|
||||
Connection switched=exchange.onSwitchProtocol(_endp);
|
||||
|
@ -714,7 +729,7 @@ public class HttpConnection extends AbstractConnection
|
|||
{
|
||||
if (ex != null && ex.getStatus() < HttpExchange.STATUS_COMPLETED)
|
||||
ex.setStatus(HttpExchange.STATUS_EXPIRED);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
close();
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.nio.channels.SelectionKey;
|
|||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
@ -72,7 +71,7 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
_sslBuffers = BuffersFactory.newBuffers(
|
||||
direct?Type.DIRECT:Type.INDIRECT,ssl_session.getApplicationBufferSize(),
|
||||
direct?Type.DIRECT:Type.INDIRECT,ssl_session.getApplicationBufferSize(),
|
||||
direct?Type.DIRECT:Type.INDIRECT,_maxBuffers);
|
||||
direct?Type.DIRECT:Type.INDIRECT,_maxBuffers);
|
||||
|
||||
_httpClient._threadPool.dispatch(this);
|
||||
}
|
||||
|
@ -105,12 +104,8 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
}
|
||||
else
|
||||
{
|
||||
channel.configureBlocking( true );
|
||||
channel.socket().setSoTimeout(_httpClient.getConnectTimeout());
|
||||
channel.socket().connect(address.toSocketAddress(),_httpClient.getConnectTimeout());
|
||||
channel.configureBlocking(false);
|
||||
channel.socket().setSoTimeout((int)_httpClient.getTimeout());
|
||||
|
||||
channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
|
||||
_selectorManager.register( channel, destination );
|
||||
}
|
||||
|
||||
|
@ -192,17 +187,17 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
if (dest.isProxied())
|
||||
{
|
||||
SSLEngine engine=newSslEngine();
|
||||
ep = new ProxySelectChannelEndPoint(channel,selectSet,key,_sslBuffers,engine);
|
||||
ep = new ProxySelectChannelEndPoint(channel, selectSet, key, _sslBuffers, engine, (int)_httpClient.getIdleTimeout());
|
||||
}
|
||||
else
|
||||
{
|
||||
SSLEngine engine=newSslEngine();
|
||||
ep = new SslSelectChannelEndPoint(_sslBuffers,channel,selectSet,key,engine);
|
||||
ep = new SslSelectChannelEndPoint(_sslBuffers, channel, selectSet, key, engine, (int)_httpClient.getIdleTimeout());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ep=new SelectChannelEndPoint(channel,selectSet,key);
|
||||
ep = new SelectChannelEndPoint(channel, selectSet, key, (int)_httpClient.getIdleTimeout());
|
||||
}
|
||||
|
||||
HttpConnection connection=(HttpConnection)ep.getConnection();
|
||||
|
@ -281,10 +276,10 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
|||
private final SelectChannelEndPoint plainEndPoint;
|
||||
private volatile boolean upgraded = false;
|
||||
|
||||
public ProxySelectChannelEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key, Buffers sslBuffers, SSLEngine engine) throws IOException
|
||||
public ProxySelectChannelEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key, Buffers sslBuffers, SSLEngine engine, int maxIdleTimeout) throws IOException
|
||||
{
|
||||
super(sslBuffers, channel, selectSet, key, engine);
|
||||
this.plainEndPoint = new SelectChannelEndPoint(channel, selectSet, key);
|
||||
super(sslBuffers, channel, selectSet, key, engine, maxIdleTimeout);
|
||||
this.plainEndPoint = new SelectChannelEndPoint(channel, selectSet, key, maxIdleTimeout);
|
||||
}
|
||||
|
||||
public void upgrade()
|
||||
|
|
|
@ -16,13 +16,11 @@ package org.eclipse.jetty.client;
|
|||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.http.HttpMethods;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
|
@ -94,11 +92,17 @@ public class TimeoutExchangeTest
|
|||
}
|
||||
|
||||
private void startClient(long clientTimeout) throws Exception
|
||||
{
|
||||
startClient(clientTimeout, 20000);
|
||||
}
|
||||
|
||||
private void startClient(long clientTimeout, long maxIdleTimeout) throws Exception
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
|
||||
_httpClient.setMaxConnectionsPerAddress(2);
|
||||
_httpClient.setTimeout(clientTimeout);
|
||||
_httpClient.setIdleTimeout(maxIdleTimeout);
|
||||
_httpClient.start();
|
||||
}
|
||||
|
||||
|
@ -184,6 +188,50 @@ public class TimeoutExchangeTest
|
|||
Assert.assertFalse(httpExchange.isErrorOccurred());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultTimeoutWithSmallerIdleTimeoutNotExpiring() throws Exception
|
||||
{
|
||||
startClient(3000, 1000);
|
||||
long serverSleep = 2000;
|
||||
|
||||
// The idle timeout is shorter than the default timeout, but will be
|
||||
// temporarily increased on the endpoint in order for the exchange to complete.
|
||||
|
||||
CustomContentExchange httpExchange = new CustomContentExchange();
|
||||
httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep);
|
||||
httpExchange.setMethod(HttpMethods.POST);
|
||||
httpExchange.setRequestContent(new ByteArrayBuffer("<h1>??</h1>"));
|
||||
_httpClient.send(httpExchange);
|
||||
|
||||
Assert.assertTrue(httpExchange.getDoneLatch().await(2 * serverSleep, TimeUnit.MILLISECONDS));
|
||||
Assert.assertFalse(httpExchange.isTimeoutOccurred());
|
||||
Assert.assertTrue(httpExchange.isResponseReceived());
|
||||
Assert.assertFalse(httpExchange.isErrorOccurred());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExchangeTimeoutWithSmallerIdleTimeoutNotExpiring() throws Exception
|
||||
{
|
||||
startClient(4000, 3000);
|
||||
long serverSleep = 1000;
|
||||
long exchangeTimeout = 2000;
|
||||
|
||||
// The idle timeout is shorter than the default timeout, but will be
|
||||
// temporarily increased on the endpoint in order for the exchange to complete.
|
||||
|
||||
CustomContentExchange httpExchange = new CustomContentExchange();
|
||||
httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep);
|
||||
httpExchange.setMethod(HttpMethods.POST);
|
||||
httpExchange.setRequestContent(new ByteArrayBuffer("<h1>??</h1>"));
|
||||
httpExchange.setTimeout(exchangeTimeout);
|
||||
_httpClient.send(httpExchange);
|
||||
|
||||
Assert.assertTrue(httpExchange.getDoneLatch().await(2 * serverSleep, TimeUnit.MILLISECONDS));
|
||||
Assert.assertFalse(httpExchange.isTimeoutOccurred());
|
||||
Assert.assertTrue(httpExchange.isResponseReceived());
|
||||
Assert.assertFalse(httpExchange.isErrorOccurred());
|
||||
}
|
||||
|
||||
private class CustomContentExchange extends ContentExchange
|
||||
{
|
||||
private final CountDownLatch _doneLatch = new CountDownLatch(1);
|
||||
|
|
Loading…
Reference in New Issue