All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.firefly.codec.http2.encode.HeadersGenerator 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.HeadersFrame;
import com.firefly.codec.http2.frame.PriorityFrame;
import com.firefly.codec.http2.hpack.HpackEncoder;
import com.firefly.codec.http2.model.MetaData;
import com.firefly.utils.io.BufferUtils;
public class HeadersGenerator extends FrameGenerator {
private final HpackEncoder encoder;
private final int maxHeaderBlockFragment;
private final PriorityGenerator priorityGenerator;
public HeadersGenerator(HeaderGenerator headerGenerator, HpackEncoder encoder) {
this(headerGenerator, encoder, 0);
}
public HeadersGenerator(HeaderGenerator headerGenerator, HpackEncoder encoder, int maxHeaderBlockFragment) {
super(headerGenerator);
this.encoder = encoder;
this.maxHeaderBlockFragment = maxHeaderBlockFragment;
this.priorityGenerator = new PriorityGenerator(headerGenerator);
}
@Override
public List generate(Frame frame) {
HeadersFrame headersFrame = (HeadersFrame) frame;
return generateHeaders(headersFrame.getStreamId(), headersFrame.getMetaData(), headersFrame.getPriority(),
headersFrame.isEndStream());
}
public List generateHeaders(int streamId, MetaData metaData, PriorityFrame priority,
boolean endStream) {
List list = new LinkedList<>();
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
int flags = Flags.NONE;
if (priority != null)
flags = Flags.PRIORITY;
int maxFrameSize = getMaxFrameSize();
ByteBuffer hpacked = ByteBuffer.allocate(maxFrameSize);
BufferUtils.clearToFill(hpacked);
encoder.encode(hpacked, metaData);
int hpackedLength = hpacked.position();
BufferUtils.flipToFlush(hpacked, 0);
// Split into CONTINUATION frames if necessary.
if (maxHeaderBlockFragment > 0 && hpackedLength > maxHeaderBlockFragment) {
if (endStream)
flags |= Flags.END_STREAM;
int length = maxHeaderBlockFragment;
if (priority != null)
length += PriorityFrame.PRIORITY_LENGTH;
ByteBuffer header = generateHeader(FrameType.HEADERS, length, flags, streamId);
generatePriority(header, priority);
BufferUtils.flipToFlush(header, 0);
list.add(header);
hpacked.limit(maxHeaderBlockFragment);
list.add(hpacked.slice());
int position = maxHeaderBlockFragment;
int limit = position + maxHeaderBlockFragment;
while (limit < hpackedLength) {
hpacked.position(position).limit(limit);
header = generateHeader(FrameType.CONTINUATION, maxHeaderBlockFragment, Flags.NONE, streamId);
BufferUtils.flipToFlush(header, 0);
list.add(header);
list.add(hpacked.slice());
position += maxHeaderBlockFragment;
limit += maxHeaderBlockFragment;
}
hpacked.position(position).limit(hpackedLength);
header = generateHeader(FrameType.CONTINUATION, hpacked.remaining(), Flags.END_HEADERS, streamId);
BufferUtils.flipToFlush(header, 0);
list.add(header);
list.add(hpacked);
} else {
flags |= Flags.END_HEADERS;
if (endStream)
flags |= Flags.END_STREAM;
int length = hpackedLength;
if (priority != null)
length += PriorityFrame.PRIORITY_LENGTH;
ByteBuffer header = generateHeader(FrameType.HEADERS, length, flags, streamId);
generatePriority(header, priority);
BufferUtils.flipToFlush(header, 0);
list.add(header);
list.add(hpacked);
}
return list;
}
private void generatePriority(ByteBuffer header, PriorityFrame priority) {
if (priority != null) {
priorityGenerator.generatePriorityBody(header, priority.getStreamId(), priority.getParentStreamId(),
priority.getWeight(), priority.isExclusive());
}
}
}