in pkg/accesslog/collector/protocols/http2.go [166:219]
func (r *HTTP2Protocol) HandleHeader(connection *PartitionConnection, header *http2.FrameHeader, startPos *buffer.Position,
metrics *HTTP2Metrics, buf *buffer.Buffer) (enums.ParseResult, bool, error) {
bytes := make([]byte, header.Length)
if err := buf.ReadUntilBufferFull(bytes); err != nil {
return enums.ParseResultSkipPackage, true, err
}
headerData, err := metrics.HpackDecoder.DecodeFull(bytes)
if err != nil {
// reading the header failure, maybe not tracing the connection from beginning
return enums.ParseResultSkipPackage, true, err
}
// saving stream
streaming := metrics.Streams[header.StreamID]
headers := r.parseHeaders(headerData)
if streaming == nil {
streaming = &HTTP2Streaming{
ReqHeader: headers,
RespHeader: make(map[string]string),
ReqHeaderBuffer: buf.Slice(true, startPos, buf.Position()),
Connection: connection,
}
metrics.Streams[header.StreamID] = streaming
return enums.ParseResultSuccess, false, nil
}
status, contains := headers[":status"]
if contains {
streaming.IsInResponse = true
code, err := strconv.ParseInt(status, 10, 64)
if err != nil {
log.Warnf("cannot parse status code: %s", status)
code = 200
}
streaming.Status = int(code)
}
if !streaming.IsInResponse {
r.AppendHeaders(streaming.ReqHeader, headers)
streaming.ReqHeaderBuffer = buffer.CombineSlices(true, buf, streaming.ReqHeaderBuffer, buf.Slice(true, startPos, buf.Position()))
return enums.ParseResultSuccess, false, nil
}
r.AppendHeaders(streaming.RespHeader, headers)
streaming.RespHeaderBuffer = buffer.CombineSlices(true, buf, streaming.RespHeaderBuffer, buf.Slice(true, startPos, buf.Position()))
// is end of stream and in the response
if header.Flags.Has(http2.FlagHeadersEndStream) {
// should be end of the stream and send to the protocol
_ = r.analyzer.HandleWholeStream(connection, streaming)
// delete streaming
delete(metrics.Streams, header.StreamID)
}
return enums.ParseResultSuccess, false, nil
}