package com.webpieces.http2parser.impl.marshallers; import java.nio.ByteBuffer; import org.webpieces.data.api.BufferPool; import org.webpieces.data.api.DataWrapper; import org.webpieces.data.api.DataWrapperGenerator; import com.webpieces.http2parser.api.ConnectionException; import com.webpieces.http2parser.api.ParseFailReason; import com.webpieces.http2parser.api.dto.PingFrame; import com.webpieces.http2parser.api.dto.lib.AbstractHttp2Frame; import com.webpieces.http2parser.api.dto.lib.Http2Frame; import com.webpieces.http2parser.impl.FrameHeaderData; import com.webpieces.http2parser.impl.Http2MementoImpl; public class PingMarshaller extends AbstractFrameMarshaller implements FrameMarshaller { public PingMarshaller(BufferPool bufferPool, DataWrapperGenerator dataGen) { super(bufferPool); } @Override public DataWrapper marshal(Http2Frame frame) { if(frame.getStreamId() != 0) throw new IllegalArgumentException("PingFrame can never be any other stream id except 0 which is already set"); PingFrame ping = (PingFrame) frame; ByteBuffer payload = bufferPool.nextBuffer(8); payload.putLong(ping.getOpaqueData()); payload.flip(); DataWrapper dataPayload = dataGen.wrapByteBuffer(payload); byte value = 0x0; if (ping.isPingResponse()) value |= 0x1; return marshalFrame(frame, value, dataPayload); } @Override public AbstractHttp2Frame unmarshal(Http2MementoImpl state, DataWrapper framePayloadData) { FrameHeaderData frameHeaderData = state.getFrameHeaderData(); int streamId = frameHeaderData.getStreamId(); if(state.getFrameHeaderData().getPayloadLength() != 8) throw new ConnectionException(ParseFailReason.FRAME_SIZE_INCORRECT, streamId, "ping size not 8 and instead is="+state.getFrameHeaderData().getPayloadLength()); else if(streamId != 0) throw new ConnectionException(ParseFailReason.INVALID_STREAM_ID, streamId, "streamId on ping needs to be 0 but was="+streamId); //TODO: Verify this, previous code looks like connectionlevel = false but shouldn't this be true PingFrame frame = new PingFrame(); super.unmarshalFrame(state, frame); byte flags = state.getFrameHeaderData().getFlagsByte(); frame.setIsPingResponse((flags & 0x1) == 0x1); ByteBuffer payloadByteBuffer = bufferPool.createWithDataWrapper(framePayloadData); frame.setOpaqueData(payloadByteBuffer.getLong()); bufferPool.releaseBuffer(payloadByteBuffer); if(frame.getStreamId() != 0) throw new IllegalArgumentException("PingFrame can never be any other stream id except 0 which is already set"); return frame; } }