refactor: simplify Node SSR parsing and validation

This commit is contained in:
2026-08-22 15:53:31 +08:00
parent 56e104ccf0
commit d2070c9d5b
2 changed files with 47 additions and 27 deletions
+36 -24
View File
@@ -99,36 +99,48 @@ func parseNodeSsrBlock(content []byte) (nodeSsrBlock, error) {
servers := make([]nodeSsrServer, 0, 2)
seen := make(map[int]struct{}, 2)
for index := begin + 1; index < end; index++ {
trimmed := strings.TrimSpace(lines[index])
commented := strings.HasPrefix(trimmed, "# server ")
active := strings.HasPrefix(trimmed, "server ")
if !commented && !active {
if trimmed != "" {
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains an unexpected line: %q", trimmed)
}
server, found, err := parseNodeSsrServer(lines[index], index)
if err != nil {
return nodeSsrBlock{}, err
}
if !found {
continue
}
serverText := strings.TrimPrefix(trimmed, "# ")
fields := strings.Fields(serverText)
if len(fields) != 4 || fields[0] != "server" || fields[2] != "max_fails=1" || fields[3] != "fail_timeout=2s;" {
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream server line has an unsupported format: %q", trimmed)
if _, exists := seen[server.port]; exists {
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains duplicate port %d", server.port)
}
_, portText, err := net.SplitHostPort(fields[1])
if err != nil {
return nodeSsrBlock{}, fmt.Errorf("parse managed Node SSR upstream address %q: %w", fields[1], err)
}
port, err := strconv.Atoi(portText)
if err != nil || (port != nodeSsrPort18910 && port != nodeSsrPort28910) {
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains unsupported port %q", portText)
}
if _, exists := seen[port]; exists {
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains duplicate port %d", port)
}
seen[port] = struct{}{}
servers = append(servers, nodeSsrServer{line: index, port: port, commented: commented})
seen[server.port] = struct{}{}
servers = append(servers, server)
}
if len(servers) != 2 {
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream must contain exactly two servers, got %d", len(servers))
}
return nodeSsrBlock{lines: lines, servers: servers}, nil
}
// parseNodeSsrServer parses one server line inside the managed Node SSR block.
func parseNodeSsrServer(line string, lineIndex int) (nodeSsrServer, bool, error) {
trimmed := strings.TrimSpace(line)
commented := strings.HasPrefix(trimmed, "# server ")
active := strings.HasPrefix(trimmed, "server ")
if !commented && !active {
if trimmed != "" {
return nodeSsrServer{}, false, fmt.Errorf("managed Node SSR upstream contains an unexpected line: %q", trimmed)
}
return nodeSsrServer{}, false, nil
}
serverText := strings.TrimPrefix(trimmed, "# ")
fields := strings.Fields(serverText)
if len(fields) != 4 || fields[0] != "server" || fields[2] != "max_fails=1" || fields[3] != "fail_timeout=2s;" {
return nodeSsrServer{}, false, fmt.Errorf("managed Node SSR upstream server line has an unsupported format: %q", trimmed)
}
_, portText, err := net.SplitHostPort(fields[1])
if err != nil {
return nodeSsrServer{}, false, fmt.Errorf("parse managed Node SSR upstream address %q: %w", fields[1], err)
}
port, err := strconv.Atoi(portText)
if err != nil || (port != nodeSsrPort18910 && port != nodeSsrPort28910) {
return nodeSsrServer{}, false, fmt.Errorf("managed Node SSR upstream contains unsupported port %q", portText)
}
return nodeSsrServer{line: lineIndex, port: port, commented: commented}, true, nil
}