func()

in pkg/accesslog/collector/protocols/http2.go [95:160]


func (r *HTTP2Protocol) Analyze(connection *PartitionConnection, helper *AnalyzeHelper) error {
	http2Metrics := connection.Metrics(enums.ConnectionProtocolHTTP2).(*HTTP2Metrics)
	buf := connection.Buffer(enums.ConnectionProtocolHTTP2)
	http2Log.Debugf("ready to analyze HTTP/2 protocol data, connection ID: %d, random ID: %d",
		http2Metrics.ConnectionID, http2Metrics.RandomID)
	buf.ResetForLoopReading()
	for {
		if !buf.PrepareForReading() {
			return nil
		}

		startPosition := buf.Position()
		header, err := http2.ReadFrameHeader(buf)
		if err != nil {
			http2Log.Debugf("failed to read frame header, %v", err)
			if buf.SkipCurrentElement() {
				break
			}
			continue
		}
		http2Log.Debugf("current reading buffer data id: %d, seq: %d", startPosition.DataID(), startPosition.Seq())

		var protocolBreak bool
		var result enums.ParseResult
		switch header.Type {
		case http2.FrameHeaders:
			result, protocolBreak, _ = r.HandleHeader(connection, &header, startPosition, http2Metrics, buf)
		case http2.FrameData:
			result, protocolBreak, _ = r.HandleData(connection, &header, startPosition, http2Metrics, buf)
		default:
			tmp := make([]byte, header.Length)
			if err := buf.ReadUntilBufferFull(tmp); err != nil {
				if errors.Is(err, buffer.ErrNotComplete) {
					result = enums.ParseResultSkipPackage
				} else {
					protocolBreak = true
				}
			} else {
				result = enums.ParseResultSuccess
			}
		}

		// if the protocol break, then stop the loop and notify the caller to skip analyze all data(just sending the detail)
		if protocolBreak {
			http2Log.Debugf("the HTTP/2 protocol break, maybe not tracing the connection from beginning, skip all data analyze in this connection, "+
				"connection ID: %d", http2Metrics.ConnectionID)
			helper.ProtocolBreak = true
			r.analyzer.OnProtocolBreak(connection, http2Metrics)
			break
		}

		finishReading := false
		switch result {
		case enums.ParseResultSuccess:
			finishReading = buf.RemoveReadElements(false)
		case enums.ParseResultSkipPackage:
			finishReading = buf.SkipCurrentElement()
		}

		if finishReading {
			break
		}
	}

	return nil
}