328199 ensure SSL closes connections when shutdownoutput is attempted
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2388 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
e5df5d82ee
commit
72e6f5ee40
|
@ -2,6 +2,7 @@
|
|||
+ 328199 Ensure blocking connectors always close socket
|
||||
+ 328205 Improved SelectManager stopping
|
||||
+ 328306 Serialization of FormAuthentication
|
||||
+ 328332 Response.getContentType works with setHeader
|
||||
|
||||
jetty-7.2.0.v20101020 20 October 2010
|
||||
+ 289540 added javadoc into distribution
|
||||
|
|
|
@ -260,7 +260,7 @@ public abstract class AbstractGenerator implements Generator
|
|||
?_persistent.booleanValue()
|
||||
:(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setPersistent(boolean persistent)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.net.Socket;
|
|||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* To change the template for this generated type comment go to
|
||||
* Window - Preferences - Java - Code Generation - Code and Comments
|
||||
|
|
|
@ -658,6 +658,9 @@ public class HttpConnection implements Connection
|
|||
// send the body anyway, or close. So we no longer need to
|
||||
// do anything special here.
|
||||
_expect100Continue = false;
|
||||
|
||||
if (!_response.isCommitted())
|
||||
_generator.setPersistent(false);
|
||||
}
|
||||
|
||||
if(_endp.isOpen())
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.io.IOException;
|
|||
import java.io.PrintWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
|
@ -39,7 +38,6 @@ import org.eclipse.jetty.io.BufferCache.CachedBuffer;
|
|||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
@ -64,15 +62,6 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include.";
|
||||
|
||||
private static final PrintWriter __nullPrintWriter;
|
||||
private static final ServletOutputStream __nullServletOut;
|
||||
|
||||
static
|
||||
{
|
||||
__nullPrintWriter = new PrintWriter(IO.getNullWriter());
|
||||
__nullServletOut = new NullOutput();
|
||||
}
|
||||
|
||||
private final HttpConnection _connection;
|
||||
private int _status=SC_OK;
|
||||
private String _reason;
|
||||
|
@ -472,20 +461,25 @@ public class Response implements HttpServletResponse
|
|||
*/
|
||||
public void setHeader(String name, String value)
|
||||
{
|
||||
if (_connection.isIncluding())
|
||||
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name))
|
||||
setContentType(value);
|
||||
else
|
||||
{
|
||||
if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
|
||||
name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
|
||||
else
|
||||
return;
|
||||
}
|
||||
_connection.getResponseFields().put(name, value);
|
||||
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
|
||||
{
|
||||
if (value==null)
|
||||
_connection._generator.setContentLength(-1);
|
||||
else
|
||||
_connection._generator.setContentLength(Long.parseLong(value));
|
||||
if (_connection.isIncluding())
|
||||
{
|
||||
if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
|
||||
name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
|
||||
else
|
||||
return;
|
||||
}
|
||||
_connection.getResponseFields().put(name, value);
|
||||
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
|
||||
{
|
||||
if (value==null)
|
||||
_connection._generator.setContentLength(-1);
|
||||
else
|
||||
_connection._generator.setContentLength(Long.parseLong(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -267,10 +267,24 @@ public class SocketConnector extends AbstractConnector
|
|||
_connections.remove(this);
|
||||
}
|
||||
|
||||
// ensure it really is closed and not just shutdown.
|
||||
// wait for client to close, but if not, close ourselves.
|
||||
try
|
||||
{
|
||||
_socket.close();
|
||||
if (!_socket.isClosed())
|
||||
{
|
||||
long timestamp=System.currentTimeMillis();
|
||||
int max_idle=getMaxIdleTime();
|
||||
|
||||
_socket.setSoTimeout(getMaxIdleTime());
|
||||
int c=0;
|
||||
do
|
||||
{
|
||||
c = _socket.getInputStream().read();
|
||||
}
|
||||
while (c>=0 && (System.currentTimeMillis()-timestamp)<max_idle);
|
||||
if (!_socket.isClosed())
|
||||
_socket.close();
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
|
|
|
@ -290,6 +290,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
|
|||
}
|
||||
|
||||
_connection = _connection.handle();
|
||||
|
||||
}
|
||||
}
|
||||
catch (EofException e)
|
||||
|
@ -315,10 +316,24 @@ public class BlockingChannelConnector extends AbstractNIOConnector
|
|||
connectionClosed(_connection);
|
||||
_endpoints.remove(this);
|
||||
|
||||
// ensure it really is closed and not just shutdown.
|
||||
// wait for client to close, but if not, close ourselves.
|
||||
try
|
||||
{
|
||||
_socket.close();
|
||||
if (!_socket.isClosed())
|
||||
{
|
||||
long timestamp=System.currentTimeMillis();
|
||||
int max_idle=getMaxIdleTime();
|
||||
|
||||
_socket.setSoTimeout(getMaxIdleTime());
|
||||
int c=0;
|
||||
do
|
||||
{
|
||||
c = _socket.getInputStream().read();
|
||||
}
|
||||
while (c>=0 && (System.currentTimeMillis()-timestamp)<max_idle);
|
||||
if (!_socket.isClosed())
|
||||
_socket.close();
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
|
|
|
@ -607,6 +607,7 @@ public class SslSocketConnector extends SocketConnector implements SslConnector
|
|||
@Override
|
||||
public void shutdownOutput() throws IOException
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -691,6 +691,48 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockedClient() throws Exception
|
||||
{
|
||||
configureServer(new HelloWorldHandler());
|
||||
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
try
|
||||
{
|
||||
OutputStream os=client.getOutputStream();
|
||||
InputStream is=client.getInputStream();
|
||||
|
||||
// Send a request with chunked input and expect 100
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n"+
|
||||
"Host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"Transfer-Encoding: chunked\r\n"+
|
||||
"Expect: 100-continue\r\n"+
|
||||
"Connection: Keep-Alive\r\n"+
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
|
||||
// Never send a body.
|
||||
// HelloWorldHandler does not read content, so 100 is not sent.
|
||||
// So close will have to happen anyway, without reset!
|
||||
|
||||
os.flush();
|
||||
|
||||
client.setSoTimeout(2000);
|
||||
long start=System.currentTimeMillis();
|
||||
String in = IO.toString(is);
|
||||
assertTrue(System.currentTimeMillis()-start<1000);
|
||||
assertTrue(in.indexOf("Connection: close")>0);
|
||||
assertTrue(in.indexOf("Hello world")>0);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read entire response from the client. Close the output.
|
||||
*
|
||||
|
|
|
@ -78,6 +78,9 @@ public class ResponseTest
|
|||
|
||||
assertEquals(null,response.getContentType());
|
||||
|
||||
response.setHeader("Content-Type","text/something");
|
||||
assertEquals("text/something",response.getContentType());
|
||||
|
||||
response.setContentType("foo/bar");
|
||||
assertEquals("foo/bar",response.getContentType());
|
||||
response.getWriter();
|
||||
|
|
|
@ -67,5 +67,11 @@ public class SslSelectChannelServerTest extends HttpServerTestBase
|
|||
{
|
||||
// TODO this test uses URL, so noop for now
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testBlockedClient() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,5 +66,5 @@ public class SslSocketServerTest extends HttpServerTestBase
|
|||
{
|
||||
// TODO this test uses URL, so noop for now
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.jetty.server.handler.DefaultHandler;
|
|||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.handler.RequestLogHandler;
|
||||
import org.eclipse.jetty.server.nio.BlockingChannelConnector;
|
||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||
import org.eclipse.jetty.server.session.HashSessionManager;
|
||||
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
|
||||
|
@ -87,6 +88,13 @@ public class TestServer
|
|||
connector2.setMaxIdleTime(30000);
|
||||
connector2.setConfidentialPort(8443);
|
||||
server.addConnector(connector2);
|
||||
|
||||
// Setup Connectors
|
||||
BlockingChannelConnector connector3 = new BlockingChannelConnector();
|
||||
connector3.setPort(8083);
|
||||
connector3.setMaxIdleTime(30000);
|
||||
connector3.setConfidentialPort(8443);
|
||||
server.addConnector(connector3);
|
||||
|
||||
SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector();
|
||||
ssl_connector.setPort(8443);
|
||||
|
|
|
@ -721,8 +721,11 @@ public abstract class RFC2616BaseTest
|
|||
|
||||
response.assertStatusOK("8.2.3 expect 100");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test Message Transmission Requirements -- Acceptable bad client behavior, Expect 100 with body content.
|
||||
* @throws Exception failure
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2616#section-8.2">RFC 2616 (section 8.2)</a>
|
||||
*/
|
||||
|
@ -749,10 +752,15 @@ public abstract class RFC2616BaseTest
|
|||
|
||||
List<HttpResponseTester> responses = http.requests(req3);
|
||||
|
||||
System.err.println(responses);
|
||||
|
||||
response=responses.get(0);
|
||||
System.err.println(response.getRawResponse());
|
||||
|
||||
response.assertStatus("8.2.3 ignored no 100",302);
|
||||
|
||||
response=responses.get(1);
|
||||
System.err.println(response.getRawResponse());
|
||||
response.assertStatus("8.2.3 ignored no 100",200);
|
||||
response.assertBody("87654321\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue