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:
parent
3a1758ce6f
commit
21f0c161d2
|
@ -18,6 +18,7 @@ jetty-7.1.4-SNAPSHOT
|
||||||
+ 315925 Improved context xml configuration handling
|
+ 315925 Improved context xml configuration handling
|
||||||
+ 315995 Incorrect package name in system classes list
|
+ 315995 Incorrect package name in system classes list
|
||||||
+ 316119 Fixed maxIdleTime for SocketEndPoint
|
+ 316119 Fixed maxIdleTime for SocketEndPoint
|
||||||
|
+ JETTY-547 Delay close after shutdown until request read
|
||||||
+ JETTY-1231 Support context request log handler
|
+ JETTY-1231 Support context request log handler
|
||||||
|
|
||||||
jetty-7.1.3.v20100526
|
jetty-7.1.3.v20100526
|
||||||
|
|
|
@ -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
|
* 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 code The error code
|
||||||
* @param reason
|
* @param reason The error reason
|
||||||
* @param content
|
* @param content Contents of the error page
|
||||||
* @param close
|
* @param close True if the connection should be closed
|
||||||
* @throws IOException
|
* @throws IOException if there is a problem flushing the response
|
||||||
*/
|
*/
|
||||||
public void sendError(int code, String reason, String content, boolean close) throws IOException
|
public void sendError(int code, String reason, String content, boolean close) throws IOException
|
||||||
{
|
{
|
||||||
|
if (close)
|
||||||
|
_persistent=false;
|
||||||
if (!isCommitted())
|
if (!isCommitted())
|
||||||
{
|
{
|
||||||
setResponse(code, reason);
|
setResponse(code, reason);
|
||||||
if (close)
|
|
||||||
_persistent=false;
|
|
||||||
completeHeader(null, false);
|
|
||||||
if (content != null)
|
if (content != null)
|
||||||
|
{
|
||||||
|
completeHeader(null, false);
|
||||||
addContent(new View(new ByteArrayBuffer(content)), Generator.LAST);
|
addContent(new View(new ByteArrayBuffer(content)), Generator.LAST);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
completeHeader(null, true);
|
||||||
|
}
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -885,8 +885,8 @@ public class HttpGenerator extends AbstractGenerator
|
||||||
{
|
{
|
||||||
if (_state == STATE_FLUSHING)
|
if (_state == STATE_FLUSHING)
|
||||||
_state = STATE_END;
|
_state = STATE_END;
|
||||||
if (_state==STATE_END && !_persistent && _status!=100)
|
if (_state==STATE_END && !_persistent && _status!=100 && _method==null)
|
||||||
_endp.close();
|
_endp.shutdownOutput();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// Try to prepare more to write.
|
// Try to prepare more to write.
|
||||||
|
|
|
@ -151,6 +151,14 @@ public class ByteArrayEndPoint implements ConnectedEndPoint
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.io.EndPoint#shutdownOutput()
|
||||||
|
*/
|
||||||
|
public void shutdownOutput() throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.io.EndPoint#close()
|
* @see org.eclipse.io.EndPoint#close()
|
||||||
|
|
|
@ -23,7 +23,12 @@ import java.io.IOException;
|
||||||
public interface EndPoint
|
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;
|
void close() throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -65,27 +65,25 @@ public class SocketEndPoint extends StreamEndPoint
|
||||||
return super.isOpen() && _socket!=null && !_socket.isClosed() && !_socket.isInputShutdown() && !_socket.isOutputShutdown();
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.io.BufferIO#close()
|
* @see org.eclipse.io.BufferIO#close()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException
|
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();
|
_socket.close();
|
||||||
_in=null;
|
_in=null;
|
||||||
_out=null;
|
_out=null;
|
||||||
|
|
|
@ -73,6 +73,10 @@ public class StreamEndPoint implements EndPoint
|
||||||
return !isOpen();
|
return !isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void shutdownOutput() throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.io.BufferIO#close()
|
* @see org.eclipse.io.BufferIO#close()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -90,36 +90,25 @@ public class ChannelEndPoint implements EndPoint
|
||||||
return _channel.isOpen();
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.io.EndPoint#close()
|
* @see org.eclipse.io.EndPoint#close()
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
if (_channel.isOpen())
|
_channel.close();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -143,14 +143,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
||||||
{
|
{
|
||||||
Log.info(""+_result);
|
Log.info(""+_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@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.
|
// 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();
|
long end=System.currentTimeMillis()+((SocketChannel)_channel).socket().getSoTimeout();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -241,11 +238,23 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(IOException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
Log.ignore(e);
|
Log.ignore(e);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_closing=true;
|
||||||
|
shutdownOutput();
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
{
|
{
|
||||||
Log.ignore(e);
|
Log.ignore(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -489,6 +489,7 @@ public class HttpConnection implements Connection
|
||||||
{
|
{
|
||||||
_parser.reset(true);
|
_parser.reset(true);
|
||||||
more_in_buffer=false;
|
more_in_buffer=false;
|
||||||
|
_endp.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (more_in_buffer)
|
if (more_in_buffer)
|
||||||
|
@ -632,7 +633,6 @@ public class HttpConnection implements Connection
|
||||||
Log.debug(e);
|
Log.debug(e);
|
||||||
_request.setHandled(true);
|
_request.setHandled(true);
|
||||||
_generator.sendError(info==null?400:500, null, null, true);
|
_generator.sendError(info==null?400:500, null, null, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -1019,7 +1019,10 @@ public class HttpConnection implements Connection
|
||||||
|
|
||||||
if (_expect)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
||||||
Socket socket = _serverSocket.accept();
|
Socket socket = _serverSocket.accept();
|
||||||
configure(socket);
|
configure(socket);
|
||||||
|
|
||||||
ConnectorEndPoint connection=new SslConnection(socket);
|
ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
|
||||||
connection.dispatch();
|
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);
|
super(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdownOutput() throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
|
|
|
@ -661,7 +661,8 @@ public abstract class RFC2616BaseTest
|
||||||
req2.append("Expect: unknown\n"); // Invalid Expect header.
|
req2.append("Expect: unknown\n"); // Invalid Expect header.
|
||||||
req2.append("Content-Type: text/plain\n");
|
req2.append("Content-Type: text/plain\n");
|
||||||
req2.append("Content-Length: 8\n");
|
req2.append("Content-Length: 8\n");
|
||||||
req2.append("\n"); // No body
|
req2.append("\n");
|
||||||
|
req2.append("12345678\n");
|
||||||
|
|
||||||
response = http.request(req2);
|
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("Range: bytes=1-3\n"); // request first 3 bytes
|
||||||
req2.append("\n");
|
req2.append("\n");
|
||||||
|
|
||||||
http.enableDebug();
|
|
||||||
response = http.request(req2);
|
response = http.request(req2);
|
||||||
|
|
||||||
response.assertStatus("10.2.7 Partial Content",HttpStatus.PARTIAL_CONTENT_206);
|
response.assertStatus("10.2.7 Partial Content",HttpStatus.PARTIAL_CONTENT_206);
|
||||||
|
@ -1260,7 +1260,6 @@ public abstract class RFC2616BaseTest
|
||||||
req1.append("\n");
|
req1.append("\n");
|
||||||
|
|
||||||
http.setTimeoutMillis(60000);
|
http.setTimeoutMillis(60000);
|
||||||
http.enableDebug();
|
|
||||||
response = http.request(req1);
|
response = http.request(req1);
|
||||||
|
|
||||||
String msg = "Partial Range (Mixed): 'bytes=a-b,5-8'";
|
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("Connection: close\n");
|
||||||
req1.append("\n");
|
req1.append("\n");
|
||||||
|
|
||||||
http.enableDebug();
|
|
||||||
response = http.request(req1);
|
response = http.request(req1);
|
||||||
|
|
||||||
String msg = "Partial (Byte) Range: '" + rangedef + "'";
|
String msg = "Partial (Byte) Range: '" + rangedef + "'";
|
||||||
|
@ -1567,7 +1565,6 @@ public abstract class RFC2616BaseTest
|
||||||
req1.append("Connection: close\n");
|
req1.append("Connection: close\n");
|
||||||
req1.append("\n");
|
req1.append("\n");
|
||||||
|
|
||||||
http.enableDebug();
|
|
||||||
response = http.request(req1);
|
response = http.request(req1);
|
||||||
|
|
||||||
String msg = "Partial (Byte) Range: '" + rangedef + "'";
|
String msg = "Partial (Byte) Range: '" + rangedef + "'";
|
||||||
|
@ -1689,7 +1686,6 @@ public abstract class RFC2616BaseTest
|
||||||
req1.append("Connection: close\n");
|
req1.append("Connection: close\n");
|
||||||
req1.append("\n");
|
req1.append("\n");
|
||||||
|
|
||||||
http.enableDebug();
|
|
||||||
response = http.request(req1);
|
response = http.request(req1);
|
||||||
specId = "14.39 TE Header";
|
specId = "14.39 TE Header";
|
||||||
response.assertStatusOK(specId);
|
response.assertStatusOK(specId);
|
||||||
|
|
Loading…
Reference in New Issue