From 11b7b7247f7e794fd0d0070d7fe52abfe853aafb Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 23 Jun 2026 11:32:43 +0800 Subject: [PATCH] util: support IPv6 host port parsing (#10046) * util: support IPv6 host port parsing * Update weed/util/parse.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: Chris Lu Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- weed/util/parse.go | 11 ++++---- weed/util/parse_test.go | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 weed/util/parse_test.go diff --git a/weed/util/parse.go b/weed/util/parse.go index 180e8e61e..b46b18da1 100644 --- a/weed/util/parse.go +++ b/weed/util/parse.go @@ -2,6 +2,7 @@ package util import ( "fmt" + "net" "net/url" "strconv" "strings" @@ -60,15 +61,15 @@ func ParseFilerUrl(entryPath string) (filerServer string, filerPort int64, path } func ParseHostPort(hostPort string) (filerServer string, filerPort int64, err error) { - parts := strings.Split(hostPort, ":") - if len(parts) != 2 { - err = fmt.Errorf("failed to parse %s\n", hostPort) + host, port, err := net.SplitHostPort(hostPort) + if err != nil { + err = fmt.Errorf("failed to parse %s", hostPort) return } - filerPort, err = strconv.ParseInt(parts[1], 10, 64) + filerPort, err = strconv.ParseInt(port, 10, 64) if err == nil { - filerServer = parts[0] + filerServer = host } return diff --git a/weed/util/parse_test.go b/weed/util/parse_test.go new file mode 100644 index 000000000..ba2708c33 --- /dev/null +++ b/weed/util/parse_test.go @@ -0,0 +1,57 @@ +package util + +import "testing" + +func TestParseHostPort(t *testing.T) { + tests := []struct { + name string + hostPort string + wantHost string + wantPort int64 + wantErr bool + }{ + { + name: "hostname", + hostPort: "localhost:8888", + wantHost: "localhost", + wantPort: 8888, + }, + { + name: "ipv4", + hostPort: "127.0.0.1:8888", + wantHost: "127.0.0.1", + wantPort: 8888, + }, + { + name: "bracketed ipv6", + hostPort: "[::1]:8888", + wantHost: "::1", + wantPort: 8888, + }, + { + name: "missing port", + hostPort: "localhost", + wantErr: true, + }, + { + name: "invalid port", + hostPort: "localhost:bad", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotHost, gotPort, err := ParseHostPort(tt.hostPort) + if gotErr := err != nil; gotErr != tt.wantErr { + t.Fatalf("ParseHostPort(%q) error = %v, wantErr %v", tt.hostPort, err, tt.wantErr) + } + if tt.wantErr { + return + } + if gotHost != tt.wantHost || gotPort != tt.wantPort { + t.Fatalf("ParseHostPort(%q) = (%q, %d), want (%q, %d)", tt.hostPort, gotHost, gotPort, tt.wantHost, tt.wantPort) + } + }) + } +}