367716: maxIdleTime fixes

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Thomas Becker 2012-01-05 13:18:41 +01:00 committed by Simone Bordet
parent d6e841beae
commit 07afebafe5
4 changed files with 178 additions and 39 deletions

View File

@ -56,8 +56,7 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
setCurrentConnection(this); setCurrentConnection(this);
// don't check for idle while dispatched (unless blocking IO is done). // don't check for idle while dispatched (unless blocking IO is done).
if(!_request.isAsyncCompleted()) _asyncEndp.setCheckForIdle(false);
_asyncEndp.setCheckForIdle(false);
// While progress and the connection has not changed // While progress and the connection has not changed
@ -140,14 +139,14 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
setCurrentConnection(null); setCurrentConnection(null);
// If we are not suspended // If we are not suspended
if (!_request.isAsyncStarted()) if (!_request.getAsyncContinuation().isAsyncStarted())
{ {
// return buffers // return buffers
_parser.returnBuffers(); _parser.returnBuffers();
_generator.returnBuffers(); _generator.returnBuffers();
} }
if (_request.isAsyncCompleted() || _request.isAsyncInitial()) if (_request.getAsyncContinuation().isComplete() || _request.getAsyncContinuation().isInitial())
{ {
_asyncEndp.setCheckForIdle(true); _asyncEndp.setCheckForIdle(true);
} }

View File

@ -308,10 +308,11 @@ public class Request implements HttpServletRequest
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public AsyncContext getAsyncContext() public AsyncContext getAsyncContext()
{ {
if (_async.isInitial() && !isAsyncStarted()) if (_async.isInitial() && !_async.isAsyncStarted())
throw new IllegalStateException(_async.getStatusString()); throw new IllegalStateException(_async.getStatusString());
return _async; return _async;
} }
@ -1260,34 +1261,16 @@ public class Request implements HttpServletRequest
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean isAsyncStarted() public boolean isHandled()
{ {
return _async.isAsyncStarted(); return _handled;
} }
/* ------------------------------------------------------------ */
public boolean isAsyncInitial()
{
return _async.isInitial();
}
/* ------------------------------------------------------------ */
public boolean isAsyncCompleted()
{
return _async.isComplete();
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean isAsyncSupported() public boolean isAsyncSupported()
{ {
return _asyncSupported; return _asyncSupported;
} }
/* ------------------------------------------------------------ */
public boolean isHandled()
{
return _handled;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*

View File

@ -13,9 +13,13 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException;
import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.server.session.SessionHandler;
@ -34,7 +38,7 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
startServer(connector); startServer(connector);
} }
@Test(expected=SocketException.class) @Test
public void testIdleTimeoutAfterSuspend() throws Exception public void testIdleTimeoutAfterSuspend() throws Exception
{ {
SuspendHandler _handler = new SuspendHandler(); SuspendHandler _handler = new SuspendHandler();
@ -46,10 +50,10 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
_handler.setSuspendFor(100); _handler.setSuspendFor(100);
_handler.setResumeAfter(25); _handler.setResumeAfter(25);
process(null); assertTrue(process(null).toUpperCase().contains("RESUMED"));
} }
@Test(expected=SocketException.class) @Test
public void testIdleTimeoutAfterTimeout() throws Exception public void testIdleTimeoutAfterTimeout() throws Exception
{ {
SuspendHandler _handler = new SuspendHandler(); SuspendHandler _handler = new SuspendHandler();
@ -60,11 +64,11 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
_server.start(); _server.start();
_handler.setSuspendFor(50); _handler.setSuspendFor(50);
System.out.println(process(null)); assertTrue(process(null).toUpperCase().contains("TIMEOUT"));
} }
@Test(expected=SocketException.class) @Test
public void testIdleTimeoutAfterComplete() throws Exception public void testIdleTimeoutAfterComplete() throws Exception
{ {
SuspendHandler _handler = new SuspendHandler(); SuspendHandler _handler = new SuspendHandler();
_server.stop(); _server.stop();
@ -75,11 +79,10 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
_handler.setSuspendFor(100); _handler.setSuspendFor(100);
_handler.setCompleteAfter(25); _handler.setCompleteAfter(25);
System.out.println(process(null)); assertTrue(process(null).toUpperCase().contains("COMPLETED"));
} }
// TODO: remove code duplication to LocalAsyncContextTest.java private synchronized String process(String content) throws UnsupportedEncodingException, IOException, InterruptedException
private synchronized String process(String content) throws Exception
{ {
String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: close\r\n"; String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: close\r\n";
@ -90,15 +93,16 @@ public class SelectChannelTimeoutTest extends ConnectorTimeoutTest
return getResponse(request); return getResponse(request);
} }
protected String getResponse(String request) throws Exception private String getResponse(String request) throws UnsupportedEncodingException, IOException, InterruptedException
{ {
SelectChannelConnector connector = (SelectChannelConnector)_connector; SelectChannelConnector connector = (SelectChannelConnector)_connector;
Socket socket = new Socket((String)null,connector.getLocalPort()); Socket socket = new Socket((String)null,connector.getLocalPort());
socket.getOutputStream().write(request.getBytes("UTF-8")); socket.getOutputStream().write(request.getBytes("UTF-8"));
InputStream inputStream = socket.getInputStream(); InputStream inputStream = socket.getInputStream();
String response = IO.toString(inputStream);
Thread.sleep(500); Thread.sleep(500);
socket.getOutputStream().write(10); assertEquals("Socket should be closed and return -1 on reading",-1,socket.getInputStream().read());
return IO.toString(inputStream); return response;
} }
} }

View File

@ -0,0 +1,153 @@
package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.HandlerWrapper;
class SuspendHandler extends HandlerWrapper
{
private int _read;
private long _suspendFor=-1;
private long _resumeAfter=-1;
private long _completeAfter=-1;
public SuspendHandler()
{
}
public int getRead()
{
return _read;
}
public void setRead(int read)
{
_read = read;
}
public long getSuspendFor()
{
return _suspendFor;
}
public void setSuspendFor(long suspendFor)
{
_suspendFor = suspendFor;
}
public long getResumeAfter()
{
return _resumeAfter;
}
public void setResumeAfter(long resumeAfter)
{
_resumeAfter = resumeAfter;
}
public long getCompleteAfter()
{
return _completeAfter;
}
public void setCompleteAfter(long completeAfter)
{
_completeAfter = completeAfter;
}
@Override
public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
{
if (_read>0)
{
byte[] buf=new byte[_read];
request.getInputStream().read(buf);
}
else if (_read<0)
{
InputStream in = request.getInputStream();
int b=in.read();
while(b!=-1)
b=in.read();
}
final AsyncContext asyncContext = baseRequest.startAsync();
asyncContext.addContinuationListener(LocalAsyncContextTest.__asyncListener);
if (_suspendFor>0)
asyncContext.setTimeout(_suspendFor);
if (_completeAfter>0)
{
new Thread() {
@Override
public void run()
{
try
{
Thread.sleep(_completeAfter);
response.getOutputStream().print("COMPLETED");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_completeAfter==0)
{
response.getOutputStream().print("COMPLETED");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
if (_resumeAfter>0)
{
new Thread() {
@Override
public void run()
{
try
{
Thread.sleep(_resumeAfter);
if(((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId()!=null)
asyncContext.dispatch();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_resumeAfter==0)
{
asyncContext.dispatch();
}
}
else if (request.getAttribute("TIMEOUT")!=null)
{
response.setStatus(200);
response.getOutputStream().print("TIMEOUT");
baseRequest.setHandled(true);
}
else
{
response.setStatus(200);
response.getOutputStream().print("RESUMED");
baseRequest.setHandled(true);
}
}
}