-
Notifications
You must be signed in to change notification settings - Fork 53
/
rpc.go
79 lines (69 loc) · 1.65 KB
/
rpc.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
package znet
import (
"io"
"net/http"
"net/rpc"
"net/rpc/jsonrpc"
"reflect"
)
type JSONRPCOption struct {
DisabledHTTP bool
Debug bool
}
func JSONRPC(rcvr map[string]interface{}, opts ...func(o *JSONRPCOption)) func(c *Context) {
o := JSONRPCOption{}
if len(opts) > 0 {
opts[0](&o)
}
s := rpc.NewServer()
methods := make(map[string][]string, 0)
for name, v := range rcvr {
err := s.RegisterName(name, v)
if err == nil && o.Debug {
typ := reflect.TypeOf(v)
for m := 0; m < typ.NumMethod(); m++ {
method := typ.Method(m)
mtype := method.Type
mname := method.Name
argType := mtype.In(1).String()
replyType := mtype.In(2).String()
methods[name+"."+mname] = []string{argType, replyType}
}
}
}
return func(c *Context) {
req := c.Request
method := req.Method
if o.Debug && method == "GET" {
c.JSON(200, methods)
return
}
if c.stopHandle.Load() {
return
}
var codec rpc.ServerCodec
if method == "CONNECT" || (method == "POST" && !o.DisabledHTTP) {
c.stopHandle.Store(true)
c.write()
if method == "CONNECT" {
conn, _, _ := c.Writer.(http.Hijacker).Hijack()
codec = jsonrpc.NewServerCodec(conn)
_, _ = io.WriteString(conn, "HTTP/1.0 200 Connected to JSON RPC\n\n")
s.ServeCodec(codec)
return
}
c.Writer.Header().Set("Content-Type", ContentTypeJSON)
var conn io.ReadWriteCloser = struct {
io.Writer
io.ReadCloser
}{
ReadCloser: c.Request.Body,
Writer: c.Writer,
}
_ = s.ServeRequest(jsonrpc.NewServerCodec(conn))
return
}
c.SetContentType(ContentTypePlain)
c.String(http.StatusMethodNotAllowed, "405 must CONNECT\n")
}
}