forked from skyformat99/rttys
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand.go
More file actions
126 lines (109 loc) · 3.47 KB
/
command.go
File metadata and controls
126 lines (109 loc) · 3.47 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
/*
* Copyright (C) 2017 Jianhui Zhao <jianhuizhao329@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package main
import (
"time"
"sync"
"net/http"
"io/ioutil"
"encoding/json"
"github.com/gorilla/websocket"
"github.com/zhaojh329/rttys/rtty"
)
type CommandReq struct {
Username string `json:"username"`
Password string `json:"password"`
Devid string `json:"devid"`
Cmd string `json:"cmd"`
Params []string `json:"params"`
Env map[string]string `json:"env"`
}
type CommandResult struct {
ID uint32 `json:"id,omitempty"`
Err int32 `json:err`
Msg string `json:"msg"`
Code int32 `json:"code"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
}
var commandID uint32 = 0
var cmdMutex sync.Mutex
var command = make(map[uint32]chan *rtty.RttyMessage)
func serveCmd(br *Broker, w http.ResponseWriter, r *http.Request) {
ticker := time.NewTicker(time.Second * 5)
defer func() {
ticker.Stop()
}()
err := rtty.RttyMessage_CommandErr_value["NONE"]
body, _ := ioutil.ReadAll(r.Body)
r.Body.Close()
req := CommandReq{}
json.Unmarshal(body, &req)
if req.Devid == "" {
err = rtty.RttyMessage_CommandErr_value["DEVID_REQUIRED"]
} else if req.Cmd == "" {
err = rtty.RttyMessage_CommandErr_value["CMD_REQUIRED"]
} else if dev, ok := br.devices[req.Devid]; !ok {
err = rtty.RttyMessage_CommandErr_value["DEV_OFFLINE"]
} else {
cmdMutex.Lock()
id := commandID
command[id] = make(chan *rtty.RttyMessage)
commandID = commandID + 1
if commandID == 1024 {
commandID = 0
}
cmd := command[id]
cmdMutex.Unlock()
msg := RttyMessageInit(&rtty.RttyMessage{
Version: RTTY_MESSAGE_VERSION,
Type: rtty.RttyMessage_COMMAND,
Id: id,
Name: req.Cmd,
Username: req.Username,
Password: req.Password,
Params: req.Params,
Env: req.Env,
})
dev.wsWrite(websocket.BinaryMessage, msg)
select {
case msg := <- cmd:
res := CommandResult{
Err: msg.Err,
Msg: rtty.RttyMessage_CommandErr_name[msg.Err],
Code: msg.Code,
Stdout: msg.StdOut,
Stderr: msg.StdErr,
}
cmdMutex.Lock()
delete(command, msg.Id)
cmdMutex.Unlock()
js, _ := json.Marshal(res)
w.Write(js)
return
case <- ticker.C:
err = rtty.RttyMessage_CommandErr_value["TIMEOUT"]
goto Err
}
}
Err:
res := CommandResult{Err: err, Msg: rtty.RttyMessage_CommandErr_name[err]}
js, _ := json.Marshal(res)
w.Write(js)
}