Reworking Generator (with jesse on a hangout)
This commit is contained in:
parent
228565068f
commit
30901917eb
|
@ -3,29 +3,18 @@ package org.eclipse.jetty.websocket.generator;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.websocket.api.OpCode;
|
|
||||||
import org.eclipse.jetty.websocket.frames.CloseFrame;
|
import org.eclipse.jetty.websocket.frames.CloseFrame;
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrame;
|
|
||||||
|
|
||||||
public class CloseFrameGenerator extends ControlFrameGenerator
|
public class CloseFrameGenerator extends FrameGenerator<CloseFrame>
|
||||||
{
|
{
|
||||||
public CloseFrameGenerator(ByteBufferPool bufferPool)
|
public CloseFrameGenerator(ByteBufferPool bufferPool)
|
||||||
{
|
{
|
||||||
super(bufferPool);
|
super(bufferPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer generate(ControlFrame frame)
|
public void generatePayload(ByteBuffer buffer, CloseFrame close)
|
||||||
{
|
{
|
||||||
CloseFrame close = (CloseFrame)frame;
|
|
||||||
|
|
||||||
ByteBuffer buffer = super.generate(frame);
|
|
||||||
|
|
||||||
buffer.putInt(OpCode.CLOSE.getCode());
|
|
||||||
buffer.put(frame.getMask());
|
|
||||||
buffer.putLong(frame.getPayloadLength());
|
|
||||||
buffer.put(close.getReason().getBytes());
|
buffer.put(close.getReason().getBytes());
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package org.eclipse.jetty.websocket.generator;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrame;
|
|
||||||
|
|
||||||
public abstract class ControlFrameGenerator
|
|
||||||
{
|
|
||||||
private final ByteBufferPool bufferPool;
|
|
||||||
|
|
||||||
protected ControlFrameGenerator(ByteBufferPool bufferPool)
|
|
||||||
{
|
|
||||||
this.bufferPool = bufferPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ByteBuffer generate(ControlFrame frame)
|
|
||||||
{
|
|
||||||
// how to calculate the size since control frames may hold
|
|
||||||
// application data
|
|
||||||
// grabing 125 now since that is _max_ possible
|
|
||||||
ByteBuffer buffer = getByteBufferPool().acquire(125,true);
|
|
||||||
|
|
||||||
// all control frames are FIN as they can not be fragmented
|
|
||||||
buffer.putInt(0x80);
|
|
||||||
|
|
||||||
// revisit this on extensions since they can negotiate this
|
|
||||||
buffer.putInt(0);
|
|
||||||
buffer.putInt(0);
|
|
||||||
buffer.putInt(0);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ByteBufferPool getByteBufferPool()
|
|
||||||
{
|
|
||||||
return bufferPool;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package org.eclipse.jetty.websocket.generator;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
|
import org.eclipse.jetty.websocket.frames.BaseFrame;
|
||||||
|
|
||||||
|
public abstract class FrameGenerator<T extends BaseFrame>
|
||||||
|
{
|
||||||
|
private final ByteBufferPool bufferPool;
|
||||||
|
|
||||||
|
protected FrameGenerator(ByteBufferPool bufferPool)
|
||||||
|
{
|
||||||
|
this.bufferPool = bufferPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer generate(T frame)
|
||||||
|
{
|
||||||
|
ByteBuffer framing = ByteBuffer.allocate(16);
|
||||||
|
|
||||||
|
byte b;
|
||||||
|
|
||||||
|
// Setup fin thru opcode
|
||||||
|
b = 0x00;
|
||||||
|
b |= (frame.isFin()?0x80:0x00); // 1000_0000
|
||||||
|
b |= (frame.isRsv1()?0x40:0x00); // 0100_0000
|
||||||
|
b |= (frame.isRsv2()?0x20:0x00); // 0010_0000 TODO: validate?
|
||||||
|
b |= (frame.isRsv3()?0x10:0x00); // 0001_0000 TODO: validate?
|
||||||
|
b |= (frame.getOpCode().getCode() & 0x0F);
|
||||||
|
framing.put(b);
|
||||||
|
|
||||||
|
// is masked
|
||||||
|
b = 0x00;
|
||||||
|
b |= (frame.isMasked()?0x80:0x00);
|
||||||
|
|
||||||
|
// payload lengths
|
||||||
|
int payloadLength = frame.getPayloadLength();
|
||||||
|
if (payloadLength >= 0x7F)
|
||||||
|
{
|
||||||
|
// we have a 64 bit length
|
||||||
|
b |= 0x7F;
|
||||||
|
framing.put(b);
|
||||||
|
|
||||||
|
framing.putInt(payloadLength);
|
||||||
|
}
|
||||||
|
else if (payloadLength >= 0x7E)
|
||||||
|
{
|
||||||
|
// we have a 16 bit length
|
||||||
|
b |= 0x7E;
|
||||||
|
framing.put(b);
|
||||||
|
|
||||||
|
framing.putShort((short)(payloadLength & 0xFFFF));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we have a 7 bit length
|
||||||
|
b |= (payloadLength & 0x7F);
|
||||||
|
framing.put(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// masking key
|
||||||
|
if (frame.isMasked())
|
||||||
|
{
|
||||||
|
// TODO: figure out maskgen
|
||||||
|
framing.put(frame.getMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
framing.flip(); // to figure out how many bytes are used
|
||||||
|
|
||||||
|
// now the payload itself
|
||||||
|
int buflen = frame.getPayloadLength() + framing.remaining();
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(buflen);
|
||||||
|
// TODO: figure out how to get this from a bytebuffer pool
|
||||||
|
|
||||||
|
generatePayload(buffer, frame);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void generatePayload(ByteBuffer buffer, T frame);
|
||||||
|
|
||||||
|
protected ByteBufferPool getByteBufferPool()
|
||||||
|
{
|
||||||
|
return bufferPool;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import java.util.EnumMap;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.websocket.api.OpCode;
|
import org.eclipse.jetty.websocket.api.OpCode;
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrame;
|
import org.eclipse.jetty.websocket.frames.BaseFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generating a frame in WebSocket land.
|
* Generating a frame in WebSocket land.
|
||||||
|
@ -33,24 +33,21 @@ import org.eclipse.jetty.websocket.frames.ControlFrame;
|
||||||
*/
|
*/
|
||||||
public class Generator {
|
public class Generator {
|
||||||
|
|
||||||
private final EnumMap<OpCode, ControlFrameGenerator> generators = new EnumMap<>(OpCode.class);
|
private final EnumMap<OpCode, FrameGenerator<?>> generators = new EnumMap<>(OpCode.class);
|
||||||
|
|
||||||
|
|
||||||
public Generator(ByteBufferPool bufferPool) //, CompressionFactory.Compressor compressor)
|
public Generator(ByteBufferPool bufferPool) //, CompressionFactory.Compressor compressor)
|
||||||
{
|
{
|
||||||
HeadersBlockGenerator headerBlockGenerator = new HeadersBlockGenerator();
|
|
||||||
generators.put(OpCode.PING,new PingFrameGenerator(bufferPool));
|
generators.put(OpCode.PING,new PingFrameGenerator(bufferPool));
|
||||||
generators.put(OpCode.PONG,new PongFrameGenerator(bufferPool));
|
generators.put(OpCode.PONG,new PongFrameGenerator(bufferPool));
|
||||||
generators.put(OpCode.CLOSE,new CloseFrameGenerator(bufferPool));
|
generators.put(OpCode.CLOSE,new CloseFrameGenerator(bufferPool));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings(
|
||||||
public ByteBuffer control(ControlFrame frame)
|
{ "unchecked", "rawtypes" })
|
||||||
|
public ByteBuffer control(BaseFrame frame)
|
||||||
{
|
{
|
||||||
ControlFrameGenerator generator = generators.get(frame.getOpCode());
|
FrameGenerator generator = generators.get(frame.getOpCode());
|
||||||
return generator.generate(frame);
|
return generator.generate(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,9 @@ package org.eclipse.jetty.websocket.generator;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.websocket.api.OpCode;
|
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrame;
|
|
||||||
import org.eclipse.jetty.websocket.frames.PingFrame;
|
import org.eclipse.jetty.websocket.frames.PingFrame;
|
||||||
|
|
||||||
public class PingFrameGenerator extends ControlFrameGenerator
|
public class PingFrameGenerator extends FrameGenerator<PingFrame>
|
||||||
{
|
{
|
||||||
public PingFrameGenerator(ByteBufferPool bufferPool)
|
public PingFrameGenerator(ByteBufferPool bufferPool)
|
||||||
{
|
{
|
||||||
|
@ -15,18 +13,8 @@ public class PingFrameGenerator extends ControlFrameGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer generate(ControlFrame frame)
|
public void generatePayload(ByteBuffer buffer, PingFrame ping)
|
||||||
{
|
{
|
||||||
PingFrame ping = (PingFrame)frame;
|
|
||||||
|
|
||||||
ByteBuffer buffer = super.generate(frame);
|
|
||||||
|
|
||||||
buffer.putInt(OpCode.PING.getCode());
|
|
||||||
buffer.put(frame.getMask());
|
|
||||||
buffer.putLong(frame.getPayloadLength());
|
|
||||||
|
|
||||||
buffer.put(ping.getPayload().array());
|
buffer.put(ping.getPayload().array());
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,18 @@ package org.eclipse.jetty.websocket.generator;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrame;
|
import org.eclipse.jetty.websocket.frames.PongFrame;
|
||||||
|
|
||||||
public class PongFrameGenerator extends ControlFrameGenerator
|
public class PongFrameGenerator extends FrameGenerator<PongFrame>
|
||||||
{
|
{
|
||||||
public PongFrameGenerator(ByteBufferPool bufferPool)
|
public PongFrameGenerator(ByteBufferPool bufferPool)
|
||||||
{
|
{
|
||||||
super(bufferPool);
|
super(bufferPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer generate(ControlFrame frame)
|
public void generatePayload(ByteBuffer buffer, PongFrame frame)
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ public class PingParserTest
|
||||||
{
|
{
|
||||||
Debug.enableDebugLogging(Parser.class);
|
Debug.enableDebugLogging(Parser.class);
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.allocate(7);
|
ByteBuffer buf = ByteBuffer.allocate(16);
|
||||||
buf.put(new byte[]
|
buf.put(new byte[]
|
||||||
{ (byte)0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f });
|
{ (byte)0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f });
|
||||||
Debug.dumpState(buf);
|
Debug.dumpState(buf);
|
||||||
|
|
Loading…
Reference in New Issue