459845 - Support upgrade from http1 to http2.

Simplified upgrade mechanism, and made it available through clearer
internal APIs.
This commit is contained in:
Simone Bordet 2015-03-20 15:02:40 +01:00
parent 2a21f8cb2f
commit e255bda694
6 changed files with 50 additions and 34 deletions

View File

@ -125,6 +125,8 @@ public class HTTP2Connection extends AbstractConnection
tasks.offer(task);
if (dispatch)
executionStrategy.dispatch();
else
executionStrategy.execute();
}
protected class HTTP2Producer implements ExecutionStrategy.Producer

View File

@ -843,6 +843,12 @@ public abstract class HTTP2Session implements ISession, Parser.Listener
}
}
@Override
public void onFrame(Frame frame)
{
onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "upgrade");
}
public void disconnect()
{
if (LOG.isDebugEnabled())

View File

@ -93,7 +93,7 @@ public interface ISession extends Session
public int updateRecvWindow(int delta);
/**
* <p>Callback method invoked when the a WINDOW_UPDATE frame has been received.</p>
* <p>Callback method invoked when a WINDOW_UPDATE frame has been received.</p>
*
* @param stream the stream the window update belongs to, or null if the window update belongs to the session
* @param frame the WINDOW_UPDATE frame received
@ -120,4 +120,12 @@ public interface ISession extends Session
* @see #close(int, String, Callback)
*/
public void onIdleTimeout();
/**
* <p>Callback method invoked during an HTTP/1.1 to HTTP/2 upgrade requests
* to process the given synthetic frame.</p>
*
* @param frame the synthetic frame to process
*/
public void onFrame(Frame frame);
}

View File

@ -65,17 +65,14 @@ public class HTTP2CServerConnectionFactory extends HTTP2ServerConnectionFactory
public Connection upgradeConnection(Connector connector, EndPoint endPoint, Request request, HttpFields response101) throws BadMessageException
{
if (LOG.isDebugEnabled())
LOG.debug("{} upgraded {}",this,request.toString()+request.getFields());
LOG.debug("{} upgraded {}{}", this, request.toString(), request.getFields());
if (request.getContentLength()>0)
if (request.getContentLength() > 0)
return null;
HTTP2ServerConnection connection = (HTTP2ServerConnection)newConnection(connector,endPoint);
if (connection.upgrade(request,response101))
HTTP2ServerConnection connection = (HTTP2ServerConnection)newConnection(connector, endPoint);
if (connection.upgrade(request, response101))
return connection;
return null;
}
}

View File

@ -26,11 +26,9 @@ import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.MetaData.Request;
import org.eclipse.jetty.http2.HTTP2Connection;
import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.ISession;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
@ -54,7 +52,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
private final Queue<HttpChannelOverHTTP2> channels = new ConcurrentArrayQueue<>();
private final ServerSessionListener listener;
private final HttpConfiguration httpConfig;
private MetaData.Request upgrade;
private HeadersFrame upgradeRequest;
public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, Parser parser, ISession session, int inputBufferSize, ServerSessionListener listener)
{
@ -70,23 +68,14 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
LOG.debug("HTTP2 onUpgradeTo {} {}", this, BufferUtil.toDetailString(prefilled));
prefill(prefilled);
}
@Override
public void onOpen()
{
super.onOpen();
notifyAccept(getSession());
if (upgrade!=null)
{
MetaData.Request request=upgrade;
upgrade=null;
// TODO get rid of the downcasts below
IStream stream = ((HTTP2Session)getSession()).createUpgradeStream();
Connector connector = ((HTTP2ServerConnectionFactory.HTTPServerSessionListener)listener).getConnector();
push(connector,stream,request);
}
if (upgradeRequest != null)
getSession().onFrame(upgradeRequest);
}
private void notifyAccept(ISession session)
@ -154,24 +143,21 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
if (LOG.isDebugEnabled())
LOG.debug("{} settings {}",this,TypeUtil.toHexString(settings));
SettingsFrame frame = SettingsBodyParser.parseBody(BufferUtil.toBuffer(settings));
if (frame == null)
SettingsFrame settingsFrame = SettingsBodyParser.parseBody(BufferUtil.toBuffer(settings));
if (settingsFrame == null)
{
LOG.warn("Invalid {} header value: {}", HttpHeader.HTTP2_SETTINGS, value);
throw new BadMessageException();
}
HTTP2Session session = (HTTP2Session)getSession();
// SPEC: the required reply to this SETTINGS frame is the 101 response.
session.onSettings(frame, false);
// TODO why is the metadata recycled???? it should me immutable!!! Oh well guess we have to create a new copy
upgrade=new MetaData.Request(request);
getSession().onFrame(settingsFrame);
// Remember the request to send a response from onOpen().
upgradeRequest = new HeadersFrame(1, request, null, true);
}
return true;
}
private class ServerHttpChannelOverHTTP2 extends HttpChannelOverHTTP2
{
public ServerHttpChannelOverHTTP2(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransportOverHTTP2 transport)
@ -187,5 +173,4 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
channels.offer(this);
}
}
}

View File

@ -103,4 +103,22 @@ public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Lis
return null;
}
}
@Override
public void onFrame(Frame frame)
{
switch (frame.getType())
{
case SETTINGS:
// SPEC: the required reply to this SETTINGS frame is the 101 response.
onSettings((SettingsFrame)frame, false);
break;
case HEADERS:
onHeaders((HeadersFrame)frame);
break;
default:
super.onFrame(frame);
break;
}
}
}