-
-
Notifications
You must be signed in to change notification settings - Fork 239
/
Copy pathgrpc.go
95 lines (84 loc) · 1.85 KB
/
grpc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package protocol
import (
"encoding/binary"
"fmt"
"strings"
"google.golang.org/protobuf/encoding/protowire"
)
type grpcExplainer struct{}
func (g *grpcExplainer) explain(b []byte) string {
if len(b) < grpcHeaderLen {
return ""
}
if int(b[0]) == 1 {
return ""
}
b = b[1:]
// 4 bytes as the pb message length
size := binary.BigEndian.Uint32(b)
b = b[4:]
if len(b) < int(size) {
return ""
}
var builder strings.Builder
g.explainFields(b[:size], &builder, 0)
return builder.String()
}
func (g *grpcExplainer) explainFields(b []byte, builder *strings.Builder, depth int) bool {
for len(b) > 0 {
num, tp, n := protowire.ConsumeTag(b)
if n < 0 {
return false
}
b = b[n:]
switch tp {
case protowire.VarintType:
_, n = protowire.ConsumeVarint(b)
if n < 0 {
return false
}
b = b[n:]
write(builder, fmt.Sprintf("#%d: (varint)\n", num), depth)
case protowire.Fixed32Type:
_, n = protowire.ConsumeFixed32(b)
if n < 0 {
return false
}
b = b[n:]
write(builder, fmt.Sprintf("#%d: (fixed32)\n", num), depth)
case protowire.Fixed64Type:
_, n = protowire.ConsumeFixed64(b)
if n < 0 {
return false
}
b = b[n:]
write(builder, fmt.Sprintf("#%d: (fixed64)\n", num), depth)
case protowire.BytesType:
v, n := protowire.ConsumeBytes(b)
if n < 0 {
return false
}
var buf strings.Builder
if g.explainFields(b[1:n], &buf, depth+1) {
write(builder, fmt.Sprintf("#%d:\n", num), depth)
builder.WriteString(buf.String())
} else {
write(builder, fmt.Sprintf("#%d: %s\n", num, v), depth)
}
b = b[n:]
default:
_, _, n = protowire.ConsumeField(b)
if n < 0 {
return false
}
b = b[n:]
}
}
return true
}
func write(builder *strings.Builder, val string, depth int) {
for i := 0; i < depth; i++ {
builder.WriteString(" ")
}
builder.WriteString(val)
}