diff options
author | Greg Wilkins | 2015-02-13 00:41:18 +0000 |
---|---|---|
committer | Greg Wilkins | 2015-02-13 00:41:18 +0000 |
commit | 2b2a70a93a50fd20f17f38be82b8e15d1365dccd (patch) | |
tree | b9303c0612ed91737d99808c115284adfe4429ee /jetty-io | |
parent | d788df9a57172e378c10a4be7862cc73b856113b (diff) | |
download | org.eclipse.jetty.project-2b2a70a93a50fd20f17f38be82b8e15d1365dccd.tar.gz org.eclipse.jetty.project-2b2a70a93a50fd20f17f38be82b8e15d1365dccd.tar.xz org.eclipse.jetty.project-2b2a70a93a50fd20f17f38be82b8e15d1365dccd.zip |
459845 Support upgrade
Added the concept of UpgradeFrom and UpgradeTo connections that support
transferring a buffer with content before opening new connection.
Aded EndPoint.update method as utility
Diffstat (limited to 'jetty-io')
5 files changed, 63 insertions, 8 deletions
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java index d38949b470..19abf0b19f 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java @@ -23,6 +23,7 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.concurrent.TimeoutException; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -164,6 +165,27 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint } @Override + public void upgrade(Connection newConnection) + { + Connection old_connection = getConnection(); + + if (LOG.isDebugEnabled()) + LOG.debug("{} upgradeing from {} to {}", this, old_connection, newConnection); + + ByteBuffer prefilled = (old_connection instanceof Connection.UpgradeFrom) + ?((Connection.UpgradeFrom)old_connection).onUpgradeFrom():null; + old_connection.onClose(); + old_connection.getEndPoint().setConnection(newConnection); + + if (newConnection instanceof Connection.UpgradeTo) + ((Connection.UpgradeTo)newConnection).onUpgradeTo(prefilled); + else if (BufferUtil.hasContent(prefilled)) + throw new IllegalStateException(); + + newConnection.onOpen(); + } + + @Override public String toString() { return String.format("%s@%x{%s<->%d,%s,%s,%s,%s,%s,%d/%d,%s}", diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java index ecfd83633b..1d9615539f 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.io; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Map; import org.eclipse.jetty.util.log.Log; @@ -51,7 +52,7 @@ public interface ClientConnectionFactory * {@link EndPoint} associated with {@code oldConnection}, performing connection lifecycle management. * <p /> * The {@code oldConnection} will be closed by invoking {@link org.eclipse.jetty.io.Connection#onClose()} - * and the {@code newConnection} will be opened by invoking {@link org.eclipse.jetty.io.Connection#onOpen()}. + * and the {@code newConnection} will be opened by invoking {@link org.eclipse.jetty.io.Connection#onOpen(ByteBuffer)}. * @param oldConnection the old connection to replace * @param newConnection the new connection replacement */ diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java index 402310ed16..41336d5fc9 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java @@ -19,11 +19,12 @@ package org.eclipse.jetty.io; import java.io.Closeable; +import java.nio.ByteBuffer; /** * <p>A {@link Connection} is associated to an {@link EndPoint} so that I/O events * happening on the {@link EndPoint} can be processed by the {@link Connection}.</p> - * <p>A typical implementation of {@link Connection} overrides {@link #onOpen()} to + * <p>A typical implementation of {@link Connection} overrides {@link #onOpen(ByteBuffer)} to * {@link EndPoint#fillInterested(Callback) set read interest} on the {@link EndPoint}, * and when the {@link EndPoint} signals read readyness, this {@link Connection} can * read bytes from the network and interpret them.</p> @@ -32,10 +33,6 @@ public interface Connection extends Closeable { public void addListener(Listener listener); - /** - * <p>Callback method invoked when this {@link Connection} is opened.</p> - * <p>Creators of the connection implementation are responsible for calling this method.</p> - */ public void onOpen(); /** @@ -48,7 +45,7 @@ public interface Connection extends Closeable * @return the {@link EndPoint} associated with this {@link Connection} */ public EndPoint getEndPoint(); - + /** * <p>Performs a logical close of this connection.</p> * <p>For simple connections, this may just mean to delegate the close to the associated @@ -64,6 +61,30 @@ public interface Connection extends Closeable public long getBytesOut(); public long getCreatedTimeStamp(); + public interface UpgradeFrom extends Connection + { + /* ------------------------------------------------------------ */ + /** Take the input buffer from the connection on upgrade. + * <p>This method is used to take any unconsumed input from + * a connection during an upgrade. + * @return A buffer of unconsumed input. The caller must return the buffer + * to the bufferpool when consumed and this connection must not. + */ + ByteBuffer onUpgradeFrom(); + } + + public interface UpgradeTo extends Connection + { + /** + * <p>Callback method invoked when this {@link Connection} is upgraded.</p> + * <p>This must be called before {@link #onOpen()}.</p> + * @param prefilledBuffer An optional buffer that can contain prefilled data. Typically this + * results from an upgrade of one protocol to the other where the old connection has buffered + * data destined for the new connection. The new connection must take ownership of the buffer + * and is responsible for returning it to the buffer pool + */ + void onUpgradeTo(ByteBuffer prefilled); + } public interface Listener { diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java index 92997bea83..2eb75a5db2 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java @@ -222,6 +222,7 @@ public interface EndPoint extends Closeable /** * @param connection the {@link Connection} associated with this {@link EndPoint} * @see #getConnection() + * @see #upgrade(Connection) */ void setConnection(Connection connection); @@ -237,5 +238,13 @@ public interface EndPoint extends Closeable */ void onClose(); - + + /** Upgrade connections. + * Close the old connection, update the endpoint and open the new connection. + * If the oldConnection is an instance of {@link Connection.UpgradeFrom} then + * a prefilled buffer is requested and passed to the newConnection if it is an instance + * of {@link Connection.UpgradeTo} + * @param newConnection The connection to upgrade to + */ + public void upgrade(Connection newConnection); } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java index 44e22081bd..f72714f7e2 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java @@ -19,8 +19,10 @@ package org.eclipse.jetty.io; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Map; import java.util.concurrent.Executor; + import javax.net.ssl.SSLEngine; import org.eclipse.jetty.util.BufferUtil; |