-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.go
130 lines (121 loc) · 3.08 KB
/
parser.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"errors"
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"strings"
)
var storedFilePath = "/var/lib/udpproxy/records"
func init() {
// try to read records path from environment
storedFilePathEnv := os.Getenv("RECORDS_PATH")
if storedFilePathEnv != "" {
storedFilePath = storedFilePathEnv
}
// create directory if not exists
directory := filepath.Dir(storedFilePath)
// create directory if not exists
err := os.MkdirAll(directory, 0755)
if err != nil {
log.Println("failed to create directory")
log.Println(err)
os.Exit(1)
}
}
func StoreRecordsInFile(proxyRequestList []ProxyRecord) error {
// prepare string to write in file
var data string
for _, proxyRequest := range proxyRequestList {
data += fmt.Sprintf("%d %s:%d\n", proxyRequest.Port, proxyRequest.Service, proxyRequest.TargetPort)
}
// write in file
err := writeToFile(storedFilePath, data)
if err != nil {
return err
}
return nil
}
func ReadRecordsFromFile() ([]ProxyRecord, error) {
// read from file
data, err := readFromFile(storedFilePath)
if err != nil {
return nil, err
}
// parse data
splitDataInLines := strings.Split(data, "\n")
var proxyRequestList []ProxyRecord = make([]ProxyRecord, 0)
for _, line := range splitDataInLines {
proxyRequest, err := parseLine(line)
if err != nil {
log.Println("failed to parse line")
log.Println(err)
} else {
proxyRequestList = append(proxyRequestList, proxyRequest)
}
}
if err != nil {
return nil, err
}
return proxyRequestList, nil
}
func writeToFile(path string, data string) error {
// write in file
err := os.WriteFile(path, []byte(data), 0644)
if err != nil {
log.Println("failed to write in file")
log.Println(err)
return errors.New("failed to write in file")
}
return nil
}
func readFromFile(path string) (string, error) {
data, err := os.ReadFile(path)
if err != nil {
// check if path does not exist
if os.IsNotExist(err) {
return "", nil
}
log.Println("failed to read from file")
log.Println(err)
return "", errors.New("failed to read from file")
}
d := string(data)
d = strings.TrimSpace(d)
return d, nil
}
func parseLine(line string) (ProxyRecord, error) {
var proxyRequest ProxyRecord = ProxyRecord{}
line = strings.TrimSpace(line)
// skip empty lines
if line == "" {
return proxyRequest, errors.New("empty line")
}
// split line
splitLine := strings.Split(line, " ")
if len(splitLine) != 2 {
return proxyRequest, errors.New("invalid line")
}
// parse port
port, err := strconv.Atoi(splitLine[0])
if err != nil {
return proxyRequest, errors.New("invalid port")
}
// parse service and target port
splitServiceAndTargetPort := strings.Split(splitLine[1], ":")
if len(splitServiceAndTargetPort) != 2 {
return proxyRequest, errors.New("invalid service and target port")
}
service := splitServiceAndTargetPort[0]
targetPort, err := strconv.Atoi(splitServiceAndTargetPort[1])
if err != nil {
return proxyRequest, errors.New("invalid target port")
}
// set values
proxyRequest.Port = port
proxyRequest.Service = service
proxyRequest.TargetPort = targetPort
return proxyRequest, nil
}