Skip to content

Instantly share code, notes, and snippets.

@bananaumai
Created September 9, 2025 02:45
Show Gist options
  • Save bananaumai/c93af8686b6d4c1edde4f9a0800bf475 to your computer and use it in GitHub Desktop.
Save bananaumai/c93af8686b6d4c1edde4f9a0800bf475 to your computer and use it in GitHub Desktop.
Go program to examine net.SplitHostPort function behavior

Go net.SplitHostPort Test Program

This program demonstrates the behavior of Go's net.SplitHostPort function with various input cases.

What it does

The net.SplitHostPort function splits a network address into host and port components. This program tests the function with:

  1. Standard cases: Regular hostnames and IP addresses with ports
  2. IPv6 cases: IPv6 addresses properly bracketed
  3. Edge cases: Boundary port numbers, empty values
  4. Error cases: Invalid formats that should fail
  5. JoinHostPort demonstration: Shows the reverse operation and round-trip testing

Key Observations

From running the program, you can see that:

  • IPv4 addresses: 127.0.0.1:80 → Host: 127.0.0.1, Port: 80
  • Hostnames: localhost:8080 → Host: localhost, Port: 8080
  • IPv6 addresses: Must be bracketed like [::1]:8080 → Host: ::1, Port: 8080
  • Missing ports: Addresses without ports fail with "missing port in address"
  • IPv6 without brackets: Fail with "too many colons in address"
  • Port validation: The function doesn't validate port number ranges - it accepts invalid ports like 99999999 or -1
  • Empty components: Both host and port can be empty strings

Usage

go run main.go

Files

  • main.go: The main test program
  • go.mod: Go module definition
  • README.md: This documentation

Important Notes

  • net.SplitHostPort is purely a string parsing function - it doesn't validate that ports are in valid ranges (0-65535)
  • IPv6 addresses must be enclosed in square brackets when combined with ports
  • The function is commonly used in network programming when parsing address strings from configuration files or user input
module go-split-hostport
go 1.21
package main
import (
"fmt"
"net"
)
func testSplitHostPort(address string) {
fmt.Printf("Input: %q\n", address)
host, port, err := net.SplitHostPort(address)
if err != nil {
fmt.Printf(" Error: %v\n", err)
} else {
fmt.Printf(" Host: %q, Port: %q\n", host, port)
}
fmt.Println()
}
func main() {
fmt.Println("Testing net.SplitHostPort function with various inputs:")
fmt.Println("============================================================")
fmt.Println()
// Test cases covering different scenarios
testCases := []string{
// Standard cases
"localhost:8080",
"127.0.0.1:80",
"example.com:443",
// IPv6 cases
"[::1]:8080",
"[2001:db8::1]:443",
"[fe80::1%lo0]:22",
// Edge cases with ports
"localhost:0",
"example.com:65535",
// Cases without ports (should fail)
"localhost",
"127.0.0.1",
"example.com",
// IPv6 without brackets (should fail)
"::1:8080",
"2001:db8::1:443",
// Empty and special cases
"",
":",
":8080",
"localhost:",
// Cases with brackets but no port
"[::1]",
"[2001:db8::1]",
// Invalid port numbers
"localhost:abc",
"localhost:99999999",
"localhost:-1",
// Special characters in hostname
"my-host.example.com:8080",
"host_name:3000",
"192.168.1.1:22",
// Unix socket path (should fail)
"/var/run/docker.sock",
// Multiple colons without brackets
"host:port:extra",
}
for i, testCase := range testCases {
fmt.Printf("Test %d:\n", i+1)
testSplitHostPort(testCase)
}
// Additional demonstration: JoinHostPort
fmt.Println("Demonstrating net.JoinHostPort (reverse operation):")
fmt.Println("============================================================")
fmt.Println()
joinCases := []struct {
host string
port string
}{
{"localhost", "8080"},
{"127.0.0.1", "80"},
{"::1", "8080"},
{"2001:db8::1", "443"},
{"example.com", "22"},
{"", "8080"}, // empty host
{"localhost", ""}, // empty port
}
for _, jc := range joinCases {
result := net.JoinHostPort(jc.host, jc.port)
fmt.Printf("JoinHostPort(%q, %q) = %q\n", jc.host, jc.port, result)
// Test round-trip
host, port, err := net.SplitHostPort(result)
if err != nil {
fmt.Printf(" Round-trip failed: %v\n", err)
} else if host != jc.host || port != jc.port {
fmt.Printf(" Round-trip mismatch: got (%q, %q), want (%q, %q)\n",
host, port, jc.host, jc.port)
} else {
fmt.Printf(" Round-trip successful ✓\n")
}
fmt.Println()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment