in src/main/java/com/twitter/http2/HttpConnectionHandler.java [310:363]
public void readHeadersFrame(
int streamId,
boolean endStream,
boolean endSegment,
boolean exclusive,
int dependency,
int weight
) {
// HTTP/2 HEADERS frame processing requirements:
//
// If an endpoint receives a HEADERS frame with a Stream-ID that is less than
// any previously received HEADERS, it must issue a connection error of type
// PROTOCOL_ERROR.
//
// If an endpoint receives multiple SYN_STREAM frames with the same active
// Stream-ID, it must issue a stream error with the status code PROTOCOL_ERROR.
//
// The recipient can reject a stream by sending a stream error with the
// status code REFUSED_STREAM.
if (isRemoteInitiatedId(streamId)) {
if (streamId <= lastStreamId) {
// Check if we received a HEADERS frame for a stream which is half-closed (remote) or closed
if (httpConnection.isRemoteSideClosed(streamId)) {
issueStreamError(streamId, HttpErrorCode.STREAM_CLOSED);
return;
}
} else {
// Try to accept the stream
if (!acceptStream(streamId, exclusive, dependency, weight)) {
issueStreamError(streamId, HttpErrorCode.REFUSED_STREAM);
return;
}
}
} else {
// Check if we received a HEADERS frame for a stream which is half-closed (remote) or closed
if (httpConnection.isRemoteSideClosed(streamId)) {
issueStreamError(streamId, HttpErrorCode.STREAM_CLOSED);
return;
}
}
// Close the remote side of the stream if this is the last frame
if (endStream) {
halfCloseStream(streamId, true, context.channel().newSucceededFuture());
}
HttpHeadersFrame httpHeadersFrame = new DefaultHttpHeadersFrame(streamId);
httpHeadersFrame.setLast(endStream);
httpHeadersFrame.setExclusive(exclusive);
httpHeadersFrame.setDependency(dependency);
httpHeadersFrame.setWeight(weight);
httpHeaderBlockFrame = httpHeadersFrame;
}