com.firefly.codec.http2.encode.PushPromiseGenerator Maven / Gradle / Ivy
package com.firefly.codec.http2.encode;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import com.firefly.codec.http2.frame.Flags;
import com.firefly.codec.http2.frame.Frame;
import com.firefly.codec.http2.frame.FrameType;
import com.firefly.codec.http2.frame.PushPromiseFrame;
import com.firefly.codec.http2.hpack.HpackEncoder;
import com.firefly.codec.http2.model.MetaData;
import com.firefly.utils.io.BufferUtils;
public class PushPromiseGenerator extends FrameGenerator {
private final HpackEncoder encoder;
public PushPromiseGenerator(HeaderGenerator headerGenerator, HpackEncoder encoder) {
super(headerGenerator);
this.encoder = encoder;
}
@Override
public List generate(Frame frame) {
PushPromiseFrame pushPromiseFrame = (PushPromiseFrame) frame;
return generatePushPromise(pushPromiseFrame.getStreamId(), pushPromiseFrame.getPromisedStreamId(),
pushPromiseFrame.getMetaData());
}
public List generatePushPromise(int streamId, int promisedStreamId, MetaData metaData) {
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
if (promisedStreamId < 0)
throw new IllegalArgumentException("Invalid promised stream id: " + promisedStreamId);
List list = new LinkedList<>();
int maxFrameSize = getMaxFrameSize();
// The promised streamId space.
int extraSpace = 4;
maxFrameSize -= extraSpace;
ByteBuffer hpacked = ByteBuffer.allocate(maxFrameSize);
BufferUtils.clearToFill(hpacked);
encoder.encode(hpacked, metaData);
int hpackedLength = hpacked.position();
BufferUtils.flipToFlush(hpacked, 0);
int length = hpackedLength + extraSpace;
int flags = Flags.END_HEADERS;
ByteBuffer header = generateHeader(FrameType.PUSH_PROMISE, length, flags, streamId);
header.putInt(promisedStreamId);
BufferUtils.flipToFlush(header, 0);
list.add(header);
list.add(hpacked);
return list;
}
}