-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathjsonrpc.go
More file actions
132 lines (126 loc) · 3.89 KB
/
jsonrpc.go
File metadata and controls
132 lines (126 loc) · 3.89 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package main
import (
"encoding/json"
"io"
"log"
"math/rand"
"net"
"os"
"strconv"
"strings"
"time"
)
// {"jsonrpc": "2.0", "method": "command", "params": [p1, "p2"], "id": 1}
type GMJSONRPCMethod struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params []any `json:"Params,omitempty"`
Id int `json:"id"`
}
func GMJSONRPCExec(sCommand string) (string, bool) {
if len(GMConfigV.JSONRPC.Protocol) == 0 {
return "", false
}
sArr := strings.SplitN(sCommand, " ", 2)
sMethod := sArr[0]
sParams := ""
if len(sArr) > 1 {
sParams = sArr[1]
}
var jCmd = GMJSONRPCMethod{}
jCmd.JSONRPC = "2.0"
jCmd.Method = sMethod
jCmd.Id = 1 + rand.Intn(1000000)
if len(sParams) > 0 {
pTokens := strings.Split(sParams, " ")
if len(pTokens) > 0 {
for _, v := range pTokens {
if strings.HasPrefix(v, "i:") || strings.HasPrefix(v, "n:") {
if n, err := strconv.Atoi(v[2:]); err == nil {
jCmd.Params = append(jCmd.Params, n)
} else {
jCmd.Params = append(jCmd.Params, v)
}
} else if strings.HasPrefix(v, "s:") {
jCmd.Params = append(jCmd.Params, v[2:])
} else {
if n, err := strconv.Atoi(v); err == nil {
jCmd.Params = append(jCmd.Params, n)
} else {
jCmd.Params = append(jCmd.Params, v)
}
}
}
}
}
bCmd, err := json.Marshal(&jCmd)
if err != nil {
log.Printf("failed to generate jsonrpc command: '%s'\n", sMethod)
return "", false
}
if GMConfigV.JSONRPC.Protocol == "udp" {
log.Printf("udp - jsonrpc command: '%s'\n", sMethod)
LocalAddr, err := net.ResolveUDPAddr(GMConfigV.JSONRPC.Protocol, GMConfigV.JSONRPC.LAddress)
if err != nil {
log.Printf("failed to resolve udp local address: '%s'\n", GMConfigV.JSONRPC.LAddress)
return "", false
}
RemoteAddr, err := net.ResolveUDPAddr(GMConfigV.JSONRPC.Protocol, GMConfigV.JSONRPC.RAddress)
if err != nil {
log.Printf("failed to resolve udp remote address: '%s'\n", GMConfigV.JSONRPC.RAddress)
return "", false
}
conn, err := net.DialUDP(GMConfigV.JSONRPC.Protocol, LocalAddr, RemoteAddr)
if err != nil {
log.Printf("failed to connect to udp remote address: '%s'\n", GMConfigV.JSONRPC.RAddress)
return "", false
}
conn.Write(bCmd)
defer conn.Close()
bRes, err := io.ReadAll(conn)
if err != nil {
log.Printf("failed to read from udp remote address: '%s'\n", GMConfigV.JSONRPC.RAddress)
return "", false
}
return string(bRes), true
} else if GMConfigV.JSONRPC.Protocol == "unixgram" {
log.Printf("unixgram - jsonrpc command: '%s'\n", sMethod)
// remove any existing local socket
os.Remove(GMConfigV.JSONRPC.LAddress)
LocalAddr, err := net.ResolveUnixAddr(GMConfigV.JSONRPC.Protocol, GMConfigV.JSONRPC.LAddress)
if err != nil {
log.Printf("failed to resolve unixgram local address: '%s'\n", GMConfigV.JSONRPC.LAddress)
return "", false
}
RemoteAddr, err := net.ResolveUnixAddr(GMConfigV.JSONRPC.Protocol, GMConfigV.JSONRPC.RAddress)
if err != nil {
log.Printf("failed to resolve unixgram remote address: '%s'\n", GMConfigV.JSONRPC.RAddress)
return "", false
}
rConn, err := net.DialUnix(GMConfigV.JSONRPC.Protocol, LocalAddr, RemoteAddr)
if err != nil {
log.Printf("failed to connect to unixgram remote address: '%s' (%v)\n",
GMConfigV.JSONRPC.RAddress, err)
return "", false
}
defer rConn.Close()
defer os.Remove(GMConfigV.JSONRPC.LAddress)
rConn.SetWriteDeadline(time.Now().Add(5 * time.Second))
rConn.SetReadDeadline(time.Now().Add(5 * time.Second))
_, err = rConn.Write(bCmd)
if err != nil {
log.Printf("failed to write to unixgram remote address: '%s' (%v)\n",
GMConfigV.JSONRPC.RAddress, err)
return "", false
}
bRes := make([]byte, 8*1024)
_, err = rConn.Read(bRes)
if err != nil {
log.Printf("failed to read from unixgram remote address: '%s' (%v)\n",
GMConfigV.JSONRPC.RAddress, err)
return "", false
}
return string(bRes), true
}
return "", false
}