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 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 SocketChannel channel;
private final Object attachment; private final Object attachment;
private final SPDYClient client; private final SPDYClient client;
@ -49,7 +49,7 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
this.channel = channel; this.channel = channel;
this.attachment = attachment; this.attachment = attachment;
this.client = client; this.client = client;
this.engine=endPoint.getSslConnection().getSSLEngine(); this.engine = endPoint.getSslConnection().getSSLEngine();
NextProtoNego.put(engine, this); NextProtoNego.put(engine, this);
} }
@ -60,12 +60,12 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
try try
{ {
getEndPoint().flush(BufferUtil.EMPTY_BUFFER); getEndPoint().flush(BufferUtil.EMPTY_BUFFER);
fillInterested();
} }
catch(IOException e) catch(IOException e)
{ {
throw new RuntimeIOException(e); throw new RuntimeIOException(e);
} }
fillInterested();
} }
@Override @Override
@ -76,9 +76,11 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
int filled = fill(); int filled = fill();
if (filled == 0 && !completed) if (filled == 0 && !completed)
fillInterested(); fillInterested();
if (filled <= 0) if (filled <= 0 || completed)
break; break;
} }
if (completed)
replaceConnection();
} }
private int fill() private int fill()
@ -89,7 +91,7 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
} }
catch (IOException x) catch (IOException x)
{ {
logger.debug(x); LOG.debug(x);
getEndPoint().close(); getEndPoint().close();
return -1; return -1;
} }
@ -105,10 +107,6 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
public void unsupported() public void unsupported()
{ {
NextProtoNego.remove(engine); 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; completed = true;
} }
@ -116,14 +114,18 @@ public class NextProtoNegoClientConnection extends AbstractConnection implements
public String selectProtocol(List<String> protocols) public String selectProtocol(List<String> protocols)
{ {
NextProtoNego.remove(engine); 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; 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 SSLEngine engine;
private final List<String> protocols; private final List<String> protocols;
private final String defaultProtocol; 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) public NextProtoNegoServerConnection(DecryptedEndPoint endPoint, Connector connector, List<String>protocols, String defaultProtocol)
{ {
super(endPoint, connector.getExecutor()); super(endPoint, connector.getExecutor());
this.connector = connector; this.connector = connector;
this.protocols = protocols; this.protocols = protocols;
this.defaultProtocol=defaultProtocol; this.defaultProtocol = defaultProtocol;
engine = endPoint.getSslConnection().getSSLEngine(); engine = endPoint.getSslConnection().getSSLEngine();
NextProtoNego.put(engine, this);
NextProtoNego.put(engine,this);
} }
@Override @Override
@ -61,27 +59,30 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements
fillInterested(); fillInterested();
} }
@Override
public void onClose()
{
super.onClose();
}
@Override @Override
public void onFillable() public void onFillable()
{ {
while (true) while (true)
{ {
int filled = fill(); int filled = fill();
if (filled == 0 && !completed) if (filled == 0 && nextProtocol == null)
fillInterested(); fillInterested();
if (filled <= 0 || completed) if (filled <= 0 || nextProtocol != null)
break; 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(); getEndPoint().getConnection().onOpen();
} }
}
private int fill() private int fill()
{ {
@ -112,13 +113,8 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements
@Override @Override
public void protocolSelected(String protocol) public void protocolSelected(String protocol)
{ {
LOG.debug("{} protocolSelected {}",this,protocol); LOG.debug("{} protocol selected {}", this, protocol);
nextProtocol = protocol;
NextProtoNego.remove(engine); 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;
} }
} }