-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
107 lines (85 loc) · 2.64 KB
/
server.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
96
97
98
99
100
101
102
103
104
105
106
107
package socket
import (
"context"
"encoding/json"
"net"
"os"
"github.com/PumpkinSeed/heimdall/internal/api/socket/services"
"github.com/PumpkinSeed/heimdall/internal/errors"
"github.com/PumpkinSeed/heimdall/internal/structs"
"github.com/PumpkinSeed/heimdall/pkg/crypto/unseal"
log "github.com/sirupsen/logrus"
)
var servers = map[structs.SocketType]Server{}
type Server interface {
Handler(ctx context.Context, req structs.SocketRequest) (structs.SocketResponse, error)
}
func initServers(u *unseal.Unseal) {
servers[structs.SocketUnseal] = services.NewUnseal(u)
servers[structs.SocketInit] = services.NewInit(u)
servers[structs.TokenCreate] = services.NewTokenCreate(u)
}
func Serve(addr string) error {
if err := os.RemoveAll(addr); err != nil {
return errors.Wrap(err, "socket remove error", errors.CodeApiSocket)
}
ln, err := net.Listen("unix", addr)
if err != nil {
return errors.Wrap(err, "socket listen error", errors.CodeApiSocket)
}
log.Infof("Socket listening on %s", addr)
initServers(unseal.Get())
for {
fd, err := ln.Accept()
if err != nil {
log.Debugf("Accept error: %v", err)
return errors.Wrap(err, "socket listener accept error", errors.CodeApiSocket)
}
serve(fd)
}
}
func serve(c net.Conn) {
req, err := bindInput(c)
if err != nil {
log.Debugf("error at input binding: %v", err)
log.Error(errors.Wrap(err, "socket bind error", errors.CodeApiSocketBind))
writeError(c, err)
return
}
res, err := servers[req.Type].Handler(context.Background(), req)
if err != nil {
log.Debugf("error request handling: %v", err)
log.Error(errors.Wrap(err, "socket request handler error", errors.CodeApiSocketHandler))
writeError(c, err)
write(c, res.Data)
return
}
write(c, res.Data)
}
func bindInput(c net.Conn) (structs.SocketRequest, error) {
buf := make([]byte, 512)
nr, err := c.Read(buf)
if err != nil {
return structs.SocketRequest{}, errors.Wrap(err, "socket read error", errors.CodeApiSocketBindRead)
}
var req structs.SocketRequest
if err := json.Unmarshal(buf[0:nr], &req); err != nil {
return structs.SocketRequest{}, errors.Wrap(err, "socket unmarshal error", errors.CodeApiSocketBindUnmarshal)
}
if req.Type == structs.SocketUnknown {
return structs.SocketRequest{}, errors.Wrap(structs.ErrUnknownRequest, "socket unknown response type error", errors.CodeApiSocketBindUnknown)
}
return req, nil
}
func writeError(c net.Conn, err error) {
writeStr(c, "\nError:\n")
writeStr(c, err.Error())
}
func writeStr(c net.Conn, s string) {
write(c, []byte(s))
}
func write(c net.Conn, v []byte) {
if _, err := c.Write(v); err != nil {
log.Error(errors.NewErr(err, errors.CodeApiSocketWrite))
}
}