diff --git a/protocol/dump.go b/protocol/dump.go index 921cfb6..17bf6b2 100644 --- a/protocol/dump.go +++ b/protocol/dump.go @@ -52,13 +52,14 @@ func (d Dumper) Dump() { n, err := d.r.Read(data) if n > 0 && !d.quiet { prot := d.interop.Protocol() - frameType, ok := d.interop.Interop(data) + frameInfo, ok := d.interop.Interop(data) if ok { display.PrintfWithTime("from %s [%d] %s%s%s:\n", d.source, d.id, color.HiBlueString("%s:(", prot), - frameType, color.HiBlueString(")")) + color.HiYellowString(frameInfo), + color.HiBlueString(")")) } else { display.PrintfWithTime("from %s [%d]:\n", d.source, d.id) } diff --git a/protocol/grpc.go b/protocol/grpc.go index bc58c3d..9da23d1 100644 --- a/protocol/grpc.go +++ b/protocol/grpc.go @@ -1,32 +1,41 @@ package protocol import ( + "encoding/binary" + "fmt" "strings" - "github.com/fatih/color" "github.com/grpc/grpc/tools/http2_interop" ) -const grpcHeaderLen = 9 +const ( + http2HeaderLen = 9 + priFrameType = 32 +) type GrpcInterop struct{} func (i *GrpcInterop) Interop(b []byte) (string, bool) { - if len(b) < grpcHeaderLen { + if len(b) < http2HeaderLen { return "", false } var frame http2interop.FrameHeader // ignore errors - if err := frame.UnmarshalBinary(b[:9]); err == nil { - if frame.Type == http2interop.FrameType(32) { - return color.HiYellowString("http2:PRI"), true - } - - return color.HiYellowString(strings.ToLower(frame.Type.String())), true + if err := frame.UnmarshalBinary(b[:http2HeaderLen]); err != nil { + return "", false } - return "", false + if frame.Type == http2interop.FrameType(priFrameType) { + return "http2:pri", true + } + + id := binary.BigEndian.Uint32(b[5:http2HeaderLen]) & 0x7fffffff + if id > 0 { + return fmt.Sprintf("http2:%s stream:%d", strings.ToLower(frame.Type.String()), id), true + } + + return "http2:" + strings.ToLower(frame.Type.String()), true } func (i *GrpcInterop) Protocol() string {