jetty 9: Improved NPN client connection to perform the connection replacement from onFillable() rather than from NPN callback methods.

This commit is contained in:
Greg Wilkins 2012-10-02 15:47:57 -07:00
parent 97d08c399a
commit 604f4985d3
2 changed files with 35 additions and 37 deletions

View File

@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger;
public class NextProtoNegoClientConnection extends AbstractConnection implements NextProtoNego.ClientProvider
{
private final Logger logger = Log.getLogger(getClass());
private final Logger LOG = Log.getLogger(getClass());
private final SocketChannel channel;
private final Object attachment;
private final SPDYClient client;
@ -49,7 +49,7 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
this.channel = channel;
this.attachment = attachment;
this.client = client;
this.engine=endPoint.getSslConnection().getSSLEngine();
this.engine = endPoint.getSslConnection().getSSLEngine();
NextProtoNego.put(engine, this);
}
@ -60,12 +60,12 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
try
{
getEndPoint().flush(BufferUtil.EMPTY_BUFFER);
fillInterested();
}
catch(IOException e)
{
throw new RuntimeIOException(e);
}
fillInterested();
}
@Override
@ -76,9 +76,11 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
int filled = fill();
if (filled == 0 && !completed)
fillInterested();
if (filled <= 0)
if (filled <= 0 || completed)
break;
}
if (completed)
replaceConnection();
}
private int fill()
@ -89,7 +91,7 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
}
catch (IOException x)
{
logger.debug(x);
LOG.debug(x);
getEndPoint().close();
return -1;
}
@ -105,10 +107,6 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
public void unsupported()
{
NextProtoNego.remove(engine);
// Server does not support NPN, but this is a SPDY client, so hardcode SPDY
EndPoint endPoint = getEndPoint();
Connection connection = client.getConnectionFactory().newConnection(channel, endPoint, attachment);
client.replaceConnection(endPoint, connection);
completed = true;
}
@ -116,14 +114,18 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
public String selectProtocol(List<String> protocols)
{
NextProtoNego.remove(engine);
String protocol = client.selectProtocol(protocols);
if (protocol == null)
return null;
EndPoint endPoint = getEndPoint();
Connection connection = client.getConnectionFactory().newConnection(channel, endPoint, attachment);
client.replaceConnection(endPoint, connection);
completed = true;
return protocol;
String protocol = client.selectProtocol(protocols);
return protocol == null ? null : protocol;
}
private void replaceConnection()
{
EndPoint endPoint = getEndPoint();
Connection connection = client.getConnectionFactory().newConnection(channel, endPoint, attachment);
endPoint.getConnection().onClose();
endPoint.setConnection(connection);
connection.onOpen();
completed = true;
}
}

View File

@ -40,18 +40,16 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements
private final SSLEngine engine;
private final List<String> protocols;
private final String defaultProtocol;
private boolean completed; // No need to be volatile: it is modified and read by the same thread
private String nextProtocol; // No need to be volatile: it is modified and read by the same thread
public NextProtoNegoServerConnection(DecryptedEndPoint endPoint, Connector connector, List<String>protocols, String defaultProtocol)
{
super(endPoint, connector.getExecutor());
this.connector = connector;
this.protocols = protocols;
this.defaultProtocol=defaultProtocol;
this.defaultProtocol = defaultProtocol;
engine = endPoint.getSslConnection().getSSLEngine();
NextProtoNego.put(engine,this);
NextProtoNego.put(engine, this);
}
@Override
@ -61,26 +59,29 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements
fillInterested();
}
@Override
public void onClose()
{
super.onClose();
}
@Override
public void onFillable()
{
while (true)
{
int filled = fill();
if (filled == 0 && !completed)
if (filled == 0 && nextProtocol == null)
fillInterested();
if (filled <= 0 || completed)
if (filled <= 0 || nextProtocol != null)
break;
}
if (completed)
if (nextProtocol != null)
{
ConnectionFactory connectionFactory = connector.getConnectionFactory(nextProtocol);
EndPoint endPoint = getEndPoint();
Connection oldConnection = endPoint.getConnection();
oldConnection.onClose();
Connection connection = connectionFactory.newConnection(connector, endPoint);
LOG.debug("{} switching from {} to {}", this, oldConnection, connection);
endPoint.setConnection(connection);
getEndPoint().getConnection().onOpen();
}
}
private int fill()
@ -112,13 +113,8 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements
@Override
public void protocolSelected(String protocol)
{
LOG.debug("{} protocolSelected {}",this,protocol);
LOG.debug("{} protocol selected {}", this, protocol);
nextProtocol = protocol;
NextProtoNego.remove(engine);
ConnectionFactory connectionFactory = connector.getConnectionFactory(protocol);
EndPoint endPoint = getEndPoint();
endPoint.getConnection().onClose();
Connection connection = connectionFactory.newConnection(connector, endPoint);
endPoint.setConnection(connection);
completed = true;
}
}