JETTY-547 delay close after shutdown

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1948 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Greg Wilkins 2010-06-09 06:11:12 +00:00
parent 3a1758ce6f
commit 21f0c161d2
12 changed files with 93 additions and 69 deletions

View File

@ -18,6 +18,7 @@ jetty-7.1.4-SNAPSHOT
+ 315925 Improved context xml configuration handling
+ 315995 Incorrect package name in system classes list
+ 316119 Fixed maxIdleTime for SocketEndPoint
+ JETTY-547 Delay close after shutdown until request read
+ JETTY-1231 Support context request log handler
jetty-7.1.3.v20100526

View File

@ -434,24 +434,30 @@ public abstract class AbstractGenerator implements Generator
/* ------------------------------------------------------------ */
/**
* Utility method to send an error response. If the builder is not committed, this call is
* equivalent to a setResponse, addcontent and complete call.
* equivalent to a setResponse, addContent and complete call.
*
* @param code
* @param reason
* @param content
* @param close
* @throws IOException
* @param code The error code
* @param reason The error reason
* @param content Contents of the error page
* @param close True if the connection should be closed
* @throws IOException if there is a problem flushing the response
*/
public void sendError(int code, String reason, String content, boolean close) throws IOException
{
if (close)
_persistent=false;
if (!isCommitted())
{
setResponse(code, reason);
if (close)
_persistent=false;
completeHeader(null, false);
if (content != null)
{
completeHeader(null, false);
addContent(new View(new ByteArrayBuffer(content)), Generator.LAST);
}
else
{
completeHeader(null, true);
}
complete();
}
}

View File

@ -885,8 +885,8 @@ public class HttpGenerator extends AbstractGenerator
{
if (_state == STATE_FLUSHING)
_state = STATE_END;
if (_state==STATE_END && !_persistent && _status!=100)
_endp.close();
if (_state==STATE_END && !_persistent && _status!=100 && _method==null)
_endp.shutdownOutput();
}
else
// Try to prepare more to write.

View File

@ -151,6 +151,14 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
return true;
}
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.io.EndPoint#shutdownOutput()
*/
public void shutdownOutput() throws IOException
{
}
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.io.EndPoint#close()

View File

@ -23,7 +23,12 @@ import java.io.IOException;
public interface EndPoint
{
/**
* Close any backing stream associated with the buffer
* Shutdown any backing output stream associated with the endpoint
*/
void shutdownOutput() throws IOException;
/**
* Close any backing stream associated with the endpoint
*/
void close() throws IOException;

View File

@ -65,27 +65,25 @@ public class SocketEndPoint extends StreamEndPoint
return super.isOpen() && _socket!=null && !_socket.isClosed() && !_socket.isInputShutdown() && !_socket.isOutputShutdown();
}
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.io.bio.StreamEndPoint#shutdownOutput()
*/
@Override
public void shutdownOutput() throws IOException
{
if (!_socket.isClosed() && !_socket.isOutputShutdown())
_socket.shutdownOutput();
}
/* (non-Javadoc)
* @see org.eclipse.io.BufferIO#close()
*/
@Override
public void close() throws IOException
{
if (!_socket.isClosed() && !_socket.isOutputShutdown())
{
try
{
_socket.shutdownOutput();
}
catch(IOException e)
{
Log.ignore(e);
}
catch(UnsupportedOperationException e)
{
Log.ignore(e);
}
}
_socket.close();
_in=null;
_out=null;

View File

@ -73,6 +73,10 @@ public class StreamEndPoint implements EndPoint
return !isOpen();
}
public void shutdownOutput() throws IOException
{
}
/*
* @see org.eclipse.io.BufferIO#close()
*/

View File

@ -90,36 +90,25 @@ public class ChannelEndPoint implements EndPoint
return _channel.isOpen();
}
/* (non-Javadoc)
* @see org.eclipse.io.EndPoint#close()
*/
public void shutdownOutput() throws IOException
{
if (_channel.isOpen() && _channel instanceof SocketChannel)
{
Socket socket= ((SocketChannel)_channel).socket();
if (!socket.isClosed()&&!socket.isOutputShutdown())
socket.shutdownOutput();
}
}
/* (non-Javadoc)
* @see org.eclipse.io.EndPoint#close()
*/
public void close() throws IOException
{
if (_channel.isOpen())
{
try
{
if (_channel instanceof SocketChannel)
{
// TODO - is this really required?
Socket socket= ((SocketChannel)_channel).socket();
if (!socket.isClosed()&&!socket.isOutputShutdown())
socket.shutdownOutput();
}
}
catch(IOException e)
{
Log.ignore(e);
}
catch(UnsupportedOperationException e)
{
Log.ignore(e);
}
finally
{
_channel.close();
}
}
_channel.close();
}
/* (non-Javadoc)

View File

@ -143,14 +143,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
{
Log.info(""+_result);
}
/* ------------------------------------------------------------ */
@Override
public void close() throws IOException
public void shutdownOutput() throws IOException
{
// TODO - this really should not be done in a loop here - but with async callbacks.
_closing=true;
long end=System.currentTimeMillis()+((SocketChannel)_channel).socket().getSoTimeout();
try
{
@ -241,11 +238,23 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
}
}
}
catch(IOException e)
catch (InterruptedException e)
{
Log.ignore(e);
}
catch (InterruptedException e)
}
/* ------------------------------------------------------------ */
@Override
public void close() throws IOException
{
try
{
_closing=true;
shutdownOutput();
}
catch(IOException e)
{
Log.ignore(e);
}

View File

@ -489,6 +489,7 @@ public class HttpConnection implements Connection
{
_parser.reset(true);
more_in_buffer=false;
_endp.close();
}
if (more_in_buffer)
@ -632,7 +633,6 @@ public class HttpConnection implements Connection
Log.debug(e);
_request.setHandled(true);
_generator.sendError(info==null?400:500, null, null, true);
}
finally
{
@ -1019,7 +1019,10 @@ public class HttpConnection implements Connection
if (_expect)
{
_generator.sendError(HttpStatus.EXPECTATION_FAILED_417, null, null, true);
_generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
_responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
_generator.completeHeader(_responseFields, true);
_generator.complete();
return;
}

View File

@ -137,7 +137,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
Socket socket = _serverSocket.accept();
configure(socket);
ConnectorEndPoint connection=new SslConnection(socket);
ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
connection.dispatch();
}
@ -606,13 +606,18 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
}
/* ------------------------------------------------------------ */
public class SslConnection extends ConnectorEndPoint
public class SslConnectorEndPoint extends ConnectorEndPoint
{
public SslConnection(Socket socket) throws IOException
public SslConnectorEndPoint(Socket socket) throws IOException
{
super(socket);
}
@Override
public void shutdownOutput() throws IOException
{
}
@Override
public void run()
{

View File

@ -661,7 +661,8 @@ public abstract class RFC2616BaseTest
req2.append("Expect: unknown\n"); // Invalid Expect header.
req2.append("Content-Type: text/plain\n");
req2.append("Content-Length: 8\n");
req2.append("\n"); // No body
req2.append("\n");
req2.append("12345678\n");
response = http.request(req2);
@ -976,7 +977,6 @@ public abstract class RFC2616BaseTest
req2.append("Range: bytes=1-3\n"); // request first 3 bytes
req2.append("\n");
http.enableDebug();
response = http.request(req2);
response.assertStatus("10.2.7 Partial Content",HttpStatus.PARTIAL_CONTENT_206);
@ -1260,7 +1260,6 @@ public abstract class RFC2616BaseTest
req1.append("\n");
http.setTimeoutMillis(60000);
http.enableDebug();
response = http.request(req1);
String msg = "Partial Range (Mixed): 'bytes=a-b,5-8'";
@ -1449,7 +1448,6 @@ public abstract class RFC2616BaseTest
req1.append("Connection: close\n");
req1.append("\n");
http.enableDebug();
response = http.request(req1);
String msg = "Partial (Byte) Range: '" + rangedef + "'";
@ -1567,7 +1565,6 @@ public abstract class RFC2616BaseTest
req1.append("Connection: close\n");
req1.append("\n");
http.enableDebug();
response = http.request(req1);
String msg = "Partial (Byte) Range: '" + rangedef + "'";
@ -1689,7 +1686,6 @@ public abstract class RFC2616BaseTest
req1.append("Connection: close\n");
req1.append("\n");
http.enableDebug();
response = http.request(req1);
specId = "14.39 TE Header";
response.assertStatusOK(specId);