459845 - Support upgrade from http1 to http2
Parse setting frame.
This commit is contained in:
parent
e9658c0aef
commit
b7d719be5f
|
@ -43,7 +43,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
super(headerParser, listener);
|
||||
}
|
||||
|
||||
private void reset()
|
||||
protected void reset()
|
||||
{
|
||||
state = State.PREPARE;
|
||||
cursor = 0;
|
||||
|
@ -157,7 +157,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean onSettings(Map<Integer, Integer> settings)
|
||||
protected boolean onSettings(Map<Integer, Integer> settings)
|
||||
{
|
||||
SettingsFrame frame = new SettingsFrame(settings, hasFlag(Flags.ACK));
|
||||
reset();
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Map;
|
|||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.http2.ErrorCode;
|
||||
import org.eclipse.jetty.http2.Flags;
|
||||
import org.eclipse.jetty.http2.HTTP2Cipher;
|
||||
import org.eclipse.jetty.http2.IStream;
|
||||
import org.eclipse.jetty.http2.api.Session;
|
||||
|
@ -34,12 +35,14 @@ import org.eclipse.jetty.http2.frames.HeadersFrame;
|
|||
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
|
||||
import org.eclipse.jetty.http2.frames.ResetFrame;
|
||||
import org.eclipse.jetty.http2.frames.SettingsFrame;
|
||||
import org.eclipse.jetty.http2.parser.SettingsBodyParser;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.NegotiatingServerConnection.CipherDiscriminator;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
|
@ -76,26 +79,52 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF
|
|||
@Override
|
||||
public Connection newConnection(Connector connector, EndPoint endPoint, Object attachment)
|
||||
{
|
||||
Connection connection = super.newConnection(connector,endPoint,attachment);
|
||||
|
||||
HTTP2ServerConnection connection = (HTTP2ServerConnection)super.newConnection(connector,endPoint,attachment);
|
||||
|
||||
if (attachment instanceof MetaData.Request)
|
||||
{
|
||||
MetaData.Request request = (MetaData.Request) attachment;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} upgraded {}",this,request.toString()+request.getFields());
|
||||
|
||||
// TODO work out why _ needs replacing?
|
||||
byte[] settings = B64Code.decode(request.getFields().getField(HttpHeader.HTTP2_SETTINGS).getValue().replace('_', '='));
|
||||
|
||||
final byte[] settings = B64Code.decodeRFC4648URL(request.getFields().getField(HttpHeader.HTTP2_SETTINGS).getValue());
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} settings {}",this, TypeUtil.toHexString(settings));
|
||||
|
||||
// TODO process the settings frame
|
||||
LOG.debug("{} settings {}",this,TypeUtil.toHexString(settings));
|
||||
|
||||
SettingsBodyParser parser = new SettingsBodyParser(null,null)
|
||||
{
|
||||
@Override
|
||||
protected int getStreamId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getBodyLength()
|
||||
{
|
||||
return settings.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSettings(Map<Integer, Integer> settings)
|
||||
{
|
||||
SettingsFrame frame = new SettingsFrame(settings, false);
|
||||
// TODO something with this frame?
|
||||
|
||||
reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
parser.parse(BufferUtil.toBuffer(settings));
|
||||
|
||||
// TODO use the metadata to push a response
|
||||
}
|
||||
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
private class HTTPServerSessionListener extends ServerSessionListener.Adapter implements Stream.Listener
|
||||
{
|
||||
|
@ -170,4 +199,5 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF
|
|||
session.close(ErrorCode.PROTOCOL_ERROR.code, reason, Callback.Adapter.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ public class B64Code
|
|||
{
|
||||
private static final char __pad='=';
|
||||
private static final char[] __rfc1421alphabet=
|
||||
{
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
||||
};
|
||||
{
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
||||
};
|
||||
|
||||
private static final byte[] __rfc1421nibbles;
|
||||
static
|
||||
|
@ -52,6 +52,25 @@ public class B64Code
|
|||
__rfc1421nibbles[(byte)__rfc1421alphabet[b]]=b;
|
||||
__rfc1421nibbles[(byte)__pad]=0;
|
||||
}
|
||||
|
||||
private static final char[] __rfc4648urlAlphabet=
|
||||
{
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','-','_'
|
||||
};
|
||||
|
||||
private static final byte[] __rfc4648urlNibbles;
|
||||
static
|
||||
{
|
||||
__rfc4648urlNibbles=new byte[256];
|
||||
for (int i=0;i<256;i++)
|
||||
__rfc4648urlNibbles[i]=-1;
|
||||
for (byte b=0;b<64;b++)
|
||||
__rfc4648urlNibbles[(byte)__rfc4648urlAlphabet[b]]=b;
|
||||
__rfc4648urlNibbles[(byte)__pad]=0;
|
||||
}
|
||||
|
||||
private B64Code()
|
||||
{
|
||||
|
@ -430,6 +449,75 @@ public class B64Code
|
|||
return;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static byte[] decodeRFC4648URL(String encoded)
|
||||
{
|
||||
if (encoded==null)
|
||||
return null;
|
||||
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream(4*encoded.length()/3);
|
||||
decodeRFC4648URL(encoded, bout);
|
||||
return bout.toByteArray();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Base 64 decode as described in RFC 4648 URL.
|
||||
* <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
|
||||
* @param encoded String to decode.
|
||||
* @param bout stream for decoded bytes
|
||||
* @throws IllegalArgumentException if the input is not a valid
|
||||
* B64 encoding.
|
||||
*/
|
||||
static public void decodeRFC4648URL (String encoded, ByteArrayOutputStream bout)
|
||||
{
|
||||
if (encoded==null)
|
||||
return;
|
||||
|
||||
if (bout == null)
|
||||
throw new IllegalArgumentException("No outputstream for decoded bytes");
|
||||
|
||||
int ci=0;
|
||||
byte nibbles[] = new byte[4];
|
||||
int s=0;
|
||||
|
||||
while (ci<encoded.length())
|
||||
{
|
||||
char c=encoded.charAt(ci++);
|
||||
|
||||
if (c==__pad)
|
||||
break;
|
||||
|
||||
if (Character.isWhitespace(c))
|
||||
continue;
|
||||
|
||||
byte nibble=__rfc4648urlNibbles[c];
|
||||
if (nibble<0)
|
||||
throw new IllegalArgumentException("Not B64 encoded");
|
||||
|
||||
nibbles[s++]=__rfc4648urlNibbles[c];
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
bout.write(nibbles[0]<<2|nibbles[1]>>>4);
|
||||
break;
|
||||
case 3:
|
||||
bout.write(nibbles[1]<<4|nibbles[2]>>>2);
|
||||
break;
|
||||
case 4:
|
||||
bout.write(nibbles[2]<<6|nibbles[3]);
|
||||
s=0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public static void encode(int value,Appendable buf) throws IOException
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue