in src/main/java/com/twitter/http2/HttpFrameEncoder.java [60:113]
public ByteBuf encodeHeadersFrame(
int streamId,
boolean endStream,
boolean exclusive,
int dependency,
int weight,
ByteBuf headerBlock
) {
byte flags = endStream ? HTTP_FLAG_END_STREAM : 0;
boolean hasPriority = exclusive
|| dependency != HTTP_DEFAULT_DEPENDENCY || weight != HTTP_DEFAULT_WEIGHT;
if (hasPriority) {
flags |= HTTP_FLAG_PRIORITY;
}
int maxLength = hasPriority ? HTTP_MAX_LENGTH - 5 : HTTP_MAX_LENGTH;
boolean needsContinuations = headerBlock.readableBytes() > maxLength;
if (!needsContinuations) {
flags |= HTTP_FLAG_END_HEADERS;
}
int length = needsContinuations ? maxLength : headerBlock.readableBytes();
if (hasPriority) {
length += 5;
}
int frameLength = hasPriority ? HTTP_FRAME_HEADER_SIZE + 5 : HTTP_FRAME_HEADER_SIZE;
ByteBuf header = Unpooled.buffer(frameLength);
writeFrameHeader(header, length, HTTP_HEADERS_FRAME, flags, streamId);
if (hasPriority) {
if (exclusive) {
header.writeInt(dependency | 0x80000000);
} else {
header.writeInt(dependency);
}
header.writeByte(weight - 1);
length -= 5;
}
ByteBuf frame = Unpooled.wrappedBuffer(header, headerBlock.readSlice(length));
if (needsContinuations) {
while (headerBlock.readableBytes() > HTTP_MAX_LENGTH) {
header = Unpooled.buffer(HTTP_FRAME_HEADER_SIZE);
writeFrameHeader(header, HTTP_MAX_LENGTH, HTTP_CONTINUATION_FRAME, (byte) 0, streamId);
frame = Unpooled.wrappedBuffer(frame, header, headerBlock.readSlice(HTTP_MAX_LENGTH));
}
header = Unpooled.buffer(HTTP_FRAME_HEADER_SIZE);
writeFrameHeader(
header,
headerBlock.readableBytes(),
HTTP_CONTINUATION_FRAME,
HTTP_FLAG_END_HEADERS,
streamId
);
frame = Unpooled.wrappedBuffer(frame, header, headerBlock);
}
return frame;
}