func()

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
}