357240 ensure half closed is not schedule with no progress
This commit is contained in:
parent
be8edbd785
commit
f778867f32
|
@ -483,8 +483,13 @@ public abstract class AbstractGenerator implements Generator
|
|||
{
|
||||
if (close)
|
||||
_persistent=false;
|
||||
if (!isCommitted())
|
||||
if (isCommitted())
|
||||
{
|
||||
LOG.debug("sendError on committed: {} {}",code,reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("sendError: {} {}",code,reason);
|
||||
setResponse(code, reason);
|
||||
if (content != null)
|
||||
{
|
||||
|
|
|
@ -27,7 +27,6 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
|
||||
public Connection handle() throws IOException
|
||||
{
|
||||
LOG.debug("handle {}",this);
|
||||
Connection connection = this;
|
||||
boolean some_progress=false;
|
||||
boolean progress=true;
|
||||
|
@ -60,6 +59,11 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
// Flush output from buffering endpoint
|
||||
if (_endp.isBufferingOutput())
|
||||
_endp.flush();
|
||||
|
||||
// Special case close handling.
|
||||
// If we were dispatched and have made no progress, but io is shutdown, then close
|
||||
if (!progress && !some_progress && (_endp.isInputShutdown()||_endp.isOutputShutdown()))
|
||||
_endp.close();
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
|
@ -123,13 +127,12 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
{
|
||||
setCurrentConnection(null);
|
||||
_parser.returnBuffers();
|
||||
_generator.returnBuffers();
|
||||
|
||||
// Are we write blocked
|
||||
if (_generator.isCommitted() && !_generator.isComplete() && _endp.isOpen())
|
||||
((AsyncEndPoint)_endp).scheduleWrite();
|
||||
else
|
||||
_generator.returnBuffers();
|
||||
|
||||
// Check if we are write blocked
|
||||
if (_generator.isCommitted() && !_generator.isComplete() && _endp.isOpen() && !_endp.isOutputShutdown())
|
||||
((AsyncEndPoint)_endp).scheduleWrite(); // TODO. This should not be required
|
||||
|
||||
if (!some_progress)
|
||||
{
|
||||
_total_no_progress++;
|
||||
|
@ -137,11 +140,6 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
if (NO_PROGRESS_INFO>0 && _total_no_progress%NO_PROGRESS_INFO==0 && (NO_PROGRESS_CLOSE<=0 || _total_no_progress< NO_PROGRESS_CLOSE))
|
||||
{
|
||||
LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp);
|
||||
|
||||
LOG.setDebugEnabled(true);
|
||||
Log.getLogger("org.eclipse.jetty.io.nio").getLogger("ssl").setDebugEnabled(true);
|
||||
Log.getLogger(ChannelEndPoint.class).setDebugEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
if (NO_PROGRESS_CLOSE>0 && _total_no_progress>NO_PROGRESS_CLOSE)
|
||||
|
@ -154,7 +152,6 @@ public class AsyncHttpConnection extends HttpConnection
|
|||
}
|
||||
}
|
||||
}
|
||||
LOG.debug("unhandle {}",this);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
|
|
@ -453,29 +453,29 @@ public abstract class HttpConnection extends AbstractConnection
|
|||
catch (EofException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
_request.setHandled(true);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
}
|
||||
catch (RuntimeIOException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
_request.setHandled(true);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
_response.sendError(e.getStatus(), e.getReason());
|
||||
error=true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof ThreadDeath)
|
||||
throw (ThreadDeath)e;
|
||||
|
||||
error=true;
|
||||
LOG.warn(String.valueOf(_uri),e);
|
||||
error=true;
|
||||
_request.setHandled(true);
|
||||
_generator.sendError(info==null?400:500, null, null, true);
|
||||
}
|
||||
|
@ -509,7 +509,12 @@ public abstract class HttpConnection extends AbstractConnection
|
|||
if(_endp.isOpen())
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
_endp.shutdownOutput();
|
||||
_generator.setPersistent(false);
|
||||
if (!_generator.isComplete())
|
||||
_response.complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_response.isCommitted() && !_request.isHandled())
|
||||
|
|
|
@ -37,8 +37,11 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.StdErrLog;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -108,7 +111,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRequest1() throws Exception
|
||||
{
|
||||
System.err.println("testRequest1");
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -134,7 +136,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testFragmentedChunk() throws Exception
|
||||
{
|
||||
System.err.println("testFragmentedChunk");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -168,7 +169,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRequest1Fragments() throws Exception, InterruptedException
|
||||
{
|
||||
System.err.println("testRequest1Fragments");
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -202,7 +202,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRequest2() throws Exception
|
||||
{
|
||||
System.err.println("testRequest2");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
byte[] bytes=REQUEST2.getBytes();
|
||||
|
@ -232,7 +231,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRequest2Fragments() throws Exception
|
||||
{
|
||||
System.err.println("testRequest2Fragments");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
byte[] bytes=REQUEST2.getBytes();
|
||||
|
@ -277,7 +275,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRequest2Iterate() throws Exception
|
||||
{
|
||||
System.err.println("testRequest2Iterate");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
byte[] bytes=REQUEST2.getBytes();
|
||||
|
@ -317,7 +314,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRequest2KnownBad() throws Exception
|
||||
{
|
||||
System.err.println("testRequest2KnownBad");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
byte[] bytes=REQUEST2.getBytes();
|
||||
|
@ -356,7 +352,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testFlush() throws Exception
|
||||
{
|
||||
System.err.println("testFlush");
|
||||
configureServer(new DataHandler());
|
||||
|
||||
String[] encoding = {"NONE","UTF-8","ISO-8859-1","ISO-8859-2"};
|
||||
|
@ -393,7 +388,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testBlockingWhileReadingRequestContent() throws Exception
|
||||
{
|
||||
System.err.println("testBlockingWhileReadingRequestContent");
|
||||
configureServer(new DataHandler());
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
|
@ -452,7 +446,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testBlockingWhileWritingResponseContent() throws Exception
|
||||
{
|
||||
System.err.println("testBlockingWhileWritingResponseContent");
|
||||
configureServer(new DataHandler());
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
|
@ -498,7 +491,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testBigBlocks() throws Exception
|
||||
{
|
||||
System.err.println("testBigBlocks");
|
||||
configureServer(new BigBlockHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -632,7 +624,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testPipeline() throws Exception
|
||||
{
|
||||
System.err.println("testPipeline");
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
//for (int pipeline=1;pipeline<32;pipeline++)
|
||||
|
@ -689,7 +680,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRecycledWriters() throws Exception
|
||||
{
|
||||
System.err.println("testRecycledWriters");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -778,7 +768,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testHead() throws Exception
|
||||
{
|
||||
System.err.println("testHead");
|
||||
configureServer(new EchoHandler(false));
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -831,7 +820,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testRecycledReaders() throws Exception
|
||||
{
|
||||
System.err.println("testRecycledReaders");
|
||||
configureServer(new EchoHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -891,7 +879,6 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testBlockedClient() throws Exception
|
||||
{
|
||||
System.err.println("testBlockedClient");
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
|
@ -933,12 +920,13 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
@Test
|
||||
public void testCommittedError() throws Exception
|
||||
{
|
||||
System.err.println("testCommittedError");
|
||||
configureServer(new CommittedErrorHandler());
|
||||
CommittedErrorHandler handler =new CommittedErrorHandler();
|
||||
configureServer(handler);
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
try
|
||||
{
|
||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
|
||||
OutputStream os=client.getOutputStream();
|
||||
InputStream is=client.getInputStream();
|
||||
|
||||
|
@ -946,37 +934,45 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
os.write((
|
||||
"GET / HTTP/1.1\r\n"+
|
||||
"Host: "+HOST+":"+_connector.getLocalPort()+"\r\n" +
|
||||
"Connection: close\r\n"+
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
os.flush();
|
||||
|
||||
client.setSoTimeout(2000);
|
||||
String in = IO.toString(is);
|
||||
System.err.println("in="+in);
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
assertEquals(-1,is.read()); // Closed by error!
|
||||
|
||||
assertTrue(in.indexOf("HTTP/1.1 200 OK")>=0);
|
||||
assertTrue(in.indexOf("Transfer-Encoding: chunked")>0);
|
||||
assertTrue(in.indexOf("Now is the time for all good men to come to the aid of the party")>0);
|
||||
assertTrue(in.indexOf("\r\n0\r\n")==-1); // chunking is interrupted by error close
|
||||
|
||||
assertTrue(!handler._endp.isBlocking() || handler._endp.isOutputShutdown()); // oshut
|
||||
client.close();
|
||||
Thread.sleep(100);
|
||||
assertTrue(!handler._endp.isOpen());
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.err.println("closing");
|
||||
client.close();
|
||||
Thread.sleep(2000);
|
||||
((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
|
||||
|
||||
System.err.println("FINALLY");
|
||||
Thread.sleep(2000);
|
||||
if (!client.isClosed())
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class CommittedErrorHandler extends AbstractHandler
|
||||
{
|
||||
public EndPoint _endp;
|
||||
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
_endp=baseRequest.getConnection().getEndPoint();
|
||||
response.setHeader("test","value");
|
||||
response.setStatus(200);
|
||||
response.setContentType("text/plain");
|
||||
response.getWriter().println("Now is the time for all good ment to come to the aid of the party");
|
||||
response.getWriter().println("Now is the time for all good men to come to the aid of the party");
|
||||
response.getWriter().flush();
|
||||
response.flushBuffer();
|
||||
|
||||
|
|
|
@ -25,10 +25,12 @@ public class SelectChannelServerTest extends HttpServerTestBase
|
|||
{
|
||||
startServer(new SelectChannelConnector());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void testBigBlocks() throws Exception
|
||||
public void testCommittedError() throws Exception
|
||||
{
|
||||
super.testBigBlocks();
|
||||
super.testCommittedError();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue