@@ -4,146 +4,174 @@ Used internally for the RPC protocol.
4
4
package bridge
5
5
6
6
import (
7
+ "encoding/binary"
7
8
"errors"
9
+ "io"
10
+ "log"
11
+ "net"
12
+
13
+ "github.com/Kong/go-pdk/server/kong_plugin_protocol"
14
+ "github.com/golang/protobuf/proto"
15
+ "google.golang.org/protobuf/types/known/structpb"
8
16
)
9
17
10
18
type PdkBridge struct {
11
- ch chan interface {}
19
+ conn net. Conn
12
20
}
13
21
14
22
type StepData struct {
15
23
Method string
16
24
Args []interface {}
17
25
}
18
26
19
- func New (ch chan interface {}) PdkBridge {
20
- return PdkBridge {ch : ch }
27
+ func New (conn net.Conn ) PdkBridge {
28
+ return PdkBridge {
29
+ conn : conn ,
30
+ }
21
31
}
22
32
23
- func (b PdkBridge ) Ask (method string , args ... interface {}) (interface {}, error ) {
24
- b .ch <- StepData {method , args }
33
+ func readPbFrame (conn net.Conn ) (data []byte , err error ) {
34
+ var len uint32
35
+ err = binary .Read (conn , binary .LittleEndian , & len )
36
+ if err != nil {
37
+ return
38
+ }
25
39
26
- reply := <- b .ch
40
+ data = make ([]byte , len )
41
+ if data == nil {
42
+ return nil , errors .New ("no memory" )
43
+ }
27
44
28
- err , ok := reply .( error )
29
- if ok {
45
+ _ , err = io . ReadFull ( conn , data )
46
+ if err != nil {
30
47
return nil , err
31
48
}
32
49
33
- return reply , nil
34
- }
35
-
36
- func (b PdkBridge ) AskClose (method string , args ... interface {}) {
37
- b .ch <- StepData { method , args }
38
- close (b .ch )
50
+ return
39
51
}
40
52
41
- func (b PdkBridge ) AskInt (method string , args ... interface {}) (i int , err error ) {
42
- val , err := b .Ask (method , args ... )
53
+ func writePbFrame (conn net.Conn , data []byte ) (err error ) {
54
+ var len uint32 = uint32 (len (data ))
55
+ err = binary .Write (conn , binary .LittleEndian , len )
43
56
if err != nil {
44
57
return
45
58
}
46
- if val == nil {
47
- err = errors .New ("null response" )
48
- return
49
- }
50
59
51
- switch val := val .(type ) {
52
- case int :
53
- i = int (val )
54
- case int8 :
55
- i = int (val )
56
- case int16 :
57
- i = int (val )
58
- case int32 :
59
- i = int (val )
60
- case int64 :
61
- i = int (val )
62
- case uint :
63
- i = int (val )
64
- case uint8 :
65
- i = int (val )
66
- case uint16 :
67
- i = int (val )
68
- case uint32 :
69
- i = int (val )
70
- case uint64 :
71
- i = int (val )
72
- default :
73
- err = ReturnTypeError ("integer" )
60
+ if len > 0 {
61
+ _ , err = conn .Write (data )
74
62
}
63
+
75
64
return
76
65
}
77
66
78
- func (b PdkBridge ) AskFloat (method string , args ... interface {}) (f float64 , err error ) {
79
- val , err := b .Ask (method , args ... )
80
- if err != nil {
81
- return
67
+ func WrapString (s string ) * kong_plugin_protocol.String {
68
+ return & kong_plugin_protocol.String {V : s }
69
+ }
70
+
71
+ func WrapHeaders (h map [string ][]string ) (* structpb.Struct , error ) {
72
+ h2 := make (map [string ]interface {}, len (h ))
73
+ for k , v := range h {
74
+ l := make ([]interface {}, len (v ))
75
+ for i , v2 := range v {
76
+ l [i ] = v2
77
+ }
78
+ h2 [k ] = l
82
79
}
83
- if val == nil {
84
- err = errors .New ("null response" )
85
- return
80
+
81
+ st , err := structpb .NewStruct (h2 )
82
+ if err != nil {
83
+ return nil , err
86
84
}
87
85
88
- switch val := val .(type ) {
89
- case int :
90
- f = float64 (val )
91
- case int8 :
92
- f = float64 (val )
93
- case int16 :
94
- f = float64 (val )
95
- case int32 :
96
- f = float64 (val )
97
- case int64 :
98
- f = float64 (val )
99
- case uint :
100
- f = float64 (val )
101
- case uint8 :
102
- f = float64 (val )
103
- case uint16 :
104
- f = float64 (val )
105
- case uint32 :
106
- f = float64 (val )
107
- case uint64 :
108
- f = float64 (val )
109
- case float32 :
110
- f = float64 (val )
111
- case float64 :
112
- f = float64 (val )
113
- default :
114
- err = ReturnTypeError ("float" )
86
+ return st , nil
87
+ }
88
+
89
+ func UnwrapHeaders (st * structpb.Struct ) map [string ][]string {
90
+ m := st .AsMap ()
91
+ m2 := make (map [string ][]string )
92
+ for k , v := range m {
93
+ switch v2 := v .(type ) {
94
+ case string :
95
+ m2 [k ] = []string {v2 }
96
+ case []string :
97
+ m2 [k ] = v2
98
+ case []interface {}:
99
+ m2 [k ] = make ([]string , len (v2 ))
100
+ for i , v3 := range v2 {
101
+ if s , ok := v3 .(string ); ok {
102
+ m2 [k ][i ] = s
103
+ }
104
+ }
105
+ default :
106
+ log .Printf ("unexpected type %T on header %s:%v" , v2 , k , v2 )
107
+ }
115
108
}
116
- return
109
+
110
+ return m2
117
111
}
118
112
119
- func (b PdkBridge ) AskString (method string , args ... interface {}) ( s string , err error ) {
120
- val , err := b . Ask ( method , args ... )
113
+ func (b PdkBridge ) Ask (method string , args proto. Message , out proto. Message ) error {
114
+ err := writePbFrame ( b . conn , [] byte ( method ) )
121
115
if err != nil {
122
- return
116
+ return err
123
117
}
124
- if val == nil {
125
- err = errors .New ("null response" )
126
- return
118
+
119
+ var args_d []byte
120
+
121
+ if args != nil {
122
+ args_d , err = proto .Marshal (args )
123
+ if err != nil {
124
+ return err
125
+ }
127
126
}
128
127
129
- var ok bool
130
- if s , ok = val .( string ); ! ok {
131
- err = ReturnTypeError ( "string" )
128
+ err = writePbFrame ( b . conn , args_d )
129
+ if err != nil {
130
+ return err
132
131
}
133
- return
134
- }
135
132
136
- func (b PdkBridge ) AskMap (method string , args ... interface {}) (m map [string ][]string , err error ) {
137
- val , err := b .Ask (method , args ... )
133
+ out_d , err := readPbFrame (b .conn )
138
134
if err != nil {
139
- return
135
+ return err
140
136
}
141
137
142
- var ok bool
143
- if m , ok = val .(map [string ][]string ); ! ok {
144
- err = ReturnTypeError ("map[string][]string" )
138
+ if out != nil {
139
+ err = proto .Unmarshal (out_d , out )
145
140
}
146
- return
141
+
142
+ return err
143
+ }
144
+
145
+ func (b PdkBridge ) AskString (method string , args proto.Message ) (string , error ) {
146
+ out := new (kong_plugin_protocol.String )
147
+ err := b .Ask (method , args , out )
148
+ return out .V , err
149
+ }
150
+
151
+ func (b PdkBridge ) AskInt (method string , args proto.Message ) (int , error ) {
152
+ out := new (kong_plugin_protocol.Int )
153
+ err := b .Ask (method , args , out )
154
+ return int (out .V ), err
155
+ }
156
+
157
+ func (b PdkBridge ) AskNumber (method string , args proto.Message ) (float64 , error ) {
158
+ out := new (kong_plugin_protocol.Number )
159
+ err := b .Ask (method , args , out )
160
+ return out .V , err
161
+ }
162
+
163
+ func (b PdkBridge ) AskValue (method string , args proto.Message ) (interface {}, error ) {
164
+ out := new (structpb.Value )
165
+ err := b .Ask (method , args , out )
166
+ if err != nil {
167
+ return nil , err
168
+ }
169
+
170
+ return out .AsInterface (), nil
171
+ }
172
+
173
+ func (b PdkBridge ) Close () error {
174
+ return b .conn .Close ()
147
175
}
148
176
149
177
func ReturnTypeError (expected string ) error {
0 commit comments