...
1 package detector
2
3 import (
4 "encoding/json"
5 "fmt"
6 "net"
7 "os"
8 "time"
9 )
10
11 const (
12 SocketReadTimeout time.Duration = 30 * time.Second
13 SocketWriteTimeout time.Duration = 300 * time.Second
14 )
15
16 type SocketResponse struct {
17 Message string `json:"message,omitempty"`
18 Error string `json:"error,omitempty"`
19 }
20
21 type SocketHandler struct {
22 listener net.Listener
23 path string
24 }
25
26
27 func NewSocketHandler(path string) (*SocketHandler, error) {
28 sh := &SocketHandler{
29 path: path,
30 }
31
32 if err := sh.Clear(); err != nil {
33 return nil, fmt.Errorf("failed to clear stale sockets: %w", err)
34 }
35
36 listener, err := net.Listen("unix", sh.path)
37 if err != nil {
38 return nil, fmt.Errorf("failed to connect to socket at %v: %w", sh.path, err)
39 }
40
41 sh.listener = listener
42
43 return sh, nil
44 }
45
46
47 func (s *SocketHandler) Clear() error {
48 return os.RemoveAll(s.path)
49 }
50
51
52 func (s *SocketHandler) ReceiveConnection() (*Conn, error) {
53 conn, err := s.listener.Accept()
54 if err != nil {
55 return nil, err
56 }
57
58 if err := conn.SetReadDeadline(time.Now().Add(SocketReadTimeout)); err != nil {
59 return nil, fmt.Errorf("failed to set read deadline on connection: %w", err)
60 }
61
62 if err := conn.SetWriteDeadline(time.Now().Add(SocketWriteTimeout)); err != nil {
63 return nil, fmt.Errorf("failed to set write deadline on connection: %w", err)
64 }
65
66 return &Conn{
67 conn: conn,
68 }, nil
69 }
70
71 type Conn struct {
72 conn net.Conn
73 }
74
75
76 func (c *Conn) Receive() (string, error) {
77 buf := make([]byte, 512)
78 size, err := c.conn.Read(buf)
79 if err != nil {
80 return "", fmt.Errorf("failed to read from buffer: %w", err)
81 }
82 data := buf[0:size]
83
84 return string(data), nil
85 }
86
87
88 func (c *Conn) Respond(response string, errMessage string) error {
89 sr := &SocketResponse{
90 Message: response,
91 Error: errMessage,
92 }
93
94 data, err := json.Marshal(sr)
95 if err != nil {
96 return fmt.Errorf("failed to marshal response: %w", err)
97 }
98
99 _, err = c.conn.Write(data)
100 return err
101 }
102
View as plain text