From d2070c9d5b519fb1c061b7bcef2694f94faab2fd Mon Sep 17 00:00:00 2001 From: Zhan Ziyang Date: Sat, 22 Aug 2026 15:53:31 +0800 Subject: [PATCH] refactor: simplify Node SSR parsing and validation --- internal/hostnginx/nodessr.go | 60 +++++++++++-------- .../node_ssr_container_deployment.go | 14 ++++- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/internal/hostnginx/nodessr.go b/internal/hostnginx/nodessr.go index 675ae78..884a455 100644 --- a/internal/hostnginx/nodessr.go +++ b/internal/hostnginx/nodessr.go @@ -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 +} diff --git a/internal/transaction/node_ssr_container_deployment.go b/internal/transaction/node_ssr_container_deployment.go index eac1a0b..4bd50cb 100644 --- a/internal/transaction/node_ssr_container_deployment.go +++ b/internal/transaction/node_ssr_container_deployment.go @@ -88,9 +88,17 @@ func validateNodeSsrContainerDeployment(deployment NodeSsrContainerDeployment) e if deployment.ActivePort != 18910 && deployment.ActivePort != 28910 { return fmt.Errorf("Node SSR container deployment port must be 18910 or 28910: %d", deployment.ActivePort) } - for name, value := range map[string]string{"container name": deployment.ContainerName, "image digest": deployment.ImageDigest, "container ID": deployment.ContainerID} { - if value == "" || strings.TrimSpace(value) != value { - return fmt.Errorf("exact Node SSR container %s is required", name) + fields := []struct { + name string + value string + }{ + {name: "container name", value: deployment.ContainerName}, + {name: "image digest", value: deployment.ImageDigest}, + {name: "container ID", value: deployment.ContainerID}, + } + for _, field := range fields { + if field.value == "" || strings.TrimSpace(field.value) != field.value { + return fmt.Errorf("exact Node SSR container %s is required", field.name) } } return nil