Repository: gojue/ecapture
File: pkg/event_processor/http2_response.go (Go)

Code before:
				log.Println("[http2 response] Dump HTTP2 Frame error:", err)
			}
			break
		}
		switch f := f.(type) {
		case *http2.MetaHeadersFrame:
			streamID := f.StreamID
			dataBufMap[streamID] = bytes.NewBuffer(nil)
			frameBuf.WriteString(fmt.Sprintf("\nFrame Type\t=>\tHEADERS\nFrame StreamID\t=>\t%d\n", streamID))
			for _, header := range f.Fields {
				frameBuf.WriteString(fmt.Sprintf("%s\n", header.String()))
				if header.Name == "content-encoding" {
					encodingMap[streamID] = header.Value
				}
			}
		case *http2.DataFrame:
			streamID := f.StreamID
			frameBuf.WriteString(fmt.Sprintf("\nFrame Type\t=>\tDATA\nFrame StreamID\t=>\t%d\n", streamID))
			payload := f.Data()
			switch encodingMap[streamID] {
			case "gzip":
				h2r.packerType = PacketTypeGzip
				frameBuf.WriteString("Partial entity body with gzip encoding ... \n")
				_, err := dataBufMap[streamID].Write(payload)
				if err != nil {
					log.Println("[http2 response] Write HTTP2 Data Frame buffuer error:", err)
				}
			default:
				h2r.packerType = PacketTypeNull
				frameBuf.Write(payload)
				frameBuf.WriteString("\n")
			}
		default:
			fh := f.Header()
			frameBuf.WriteString(fmt.Sprintf("\nFrame Type\t=>\t%s\nFrame StreamID\t=>\t%d\n", fh.Type.String(), fh.StreamID))
		}
	}
	// merge data frame with encoding
	for id, buf := range dataBufMap {
		if buf.Len() > 0 && encodingMap[id] == "gzip" {
			payload := buf.Bytes()
			reader, err := gzip.NewReader(bytes.NewReader(payload))
			if err != nil {
				log.Println("[http2 response] Create gzip reader error:", err)
				continue
			}
			defer reader.Close()
			payload, err = io.ReadAll(reader)
			if err != nil {
				log.Println("[http2 response] Uncompress gzip data error:", err)
				continue

Review comment (bug):
If `dataBufMap[streamID]` cannot be found, then a null pointer will appear

Code after:
				log.Println("[http2 response] Dump HTTP2 Frame error:", err)
			}
			break
		}
		switch f := f.(type) {
		case *http2.MetaHeadersFrame:
			streamID := f.StreamID
			frameBuf.WriteString(fmt.Sprintf("\nFrame Type\t=>\tHEADERS\nFrame StreamID\t=>\t%d\n", streamID))
			for _, header := range f.Fields {
				frameBuf.WriteString(fmt.Sprintf("%s\n", header.String()))
				if header.Name == "content-encoding" {
					encodingMap[streamID] = header.Value
				}
			}
		case *http2.DataFrame:
			streamID := f.StreamID
			frameBuf.WriteString(fmt.Sprintf("\nFrame Type\t=>\tDATA\nFrame StreamID\t=>\t%d\n", streamID))
			payload := f.Data()
			switch encodingMap[streamID] {
			case "gzip":
				h2r.packerType = PacketTypeGzip
				frameBuf.WriteString("Partial entity body with gzip encoding ... \n")
				if dataBufMap[streamID] == nil {
					dataBufMap[streamID] = bytes.NewBuffer(nil) 
				}
				_, err := dataBufMap[streamID].Write(payload)
				if err != nil {
					log.Println("[http2 response] Write HTTP2 Data Frame buffuer error:", err)
				}
			default:
				h2r.packerType = PacketTypeNull
				frameBuf.Write(payload)
				frameBuf.WriteString("\n")
			}
		default:
			fh := f.Header()
			frameBuf.WriteString(fmt.Sprintf("\nFrame Type\t=>\t%s\nFrame StreamID\t=>\t%d\n", fh.Type.String(), fh.StreamID))
		}
	}
	// merge data frame with encoding
	for id, buf := range dataBufMap {
		if buf.Len() > 0 && encodingMap[id] == "gzip" {
			payload := buf.Bytes()
			reader, err := gzip.NewReader(bytes.NewReader(payload))
			if err != nil {
				log.Println("[http2 response] Create gzip reader error:", err)
				continue
			}
			defer reader.Close()
			payload, err = io.ReadAll(reader)
			if err != nil {