// TINYGO: The following is copied and modified from Go 1.26.2 official implementation. // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package net import ( "internal/bytealg" ) // SplitHostPort splits a network address of the form "host:port", // "host%zone:port", "[host]:port" or "[host%zone]:port" into host or // host%zone and port. // // A literal IPv6 address in hostport must be enclosed in square // brackets, as in "[::1]:80", "[::1%lo0]:80". // // See func Dial for a description of the hostport parameter, and host // and port results. func SplitHostPort(hostport string) (host, port string, err error) { const ( missingPort = "missing port in address" tooManyColons = "too many colons in address" ) addrErr := func(addr, why string) (host, port string, err error) { return "", "", &AddrError{Err: why, Addr: addr} } j, k := 0, 0 // The port starts after the last colon. i := bytealg.LastIndexByteString(hostport, ':') if i < 0 { return addrErr(hostport, missingPort) } if hostport[0] == '[' { // Expect the first ']' just before the last ':'. end := bytealg.IndexByteString(hostport, ']') if end < 0 { return addrErr(hostport, "missing ']' in address") } switch end + 1 { case len(hostport): // There can't be a ':' behind the ']' now. return addrErr(hostport, missingPort) case i: // The expected result. default: // Either ']' isn't followed by a colon, or it is // followed by a colon that is not the last one. if hostport[end+1] == ':' { return addrErr(hostport, tooManyColons) } return addrErr(hostport, missingPort) } host = hostport[1:end] j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions } else { host = hostport[:i] if bytealg.IndexByteString(host, ':') >= 0 { return addrErr(hostport, tooManyColons) } } if bytealg.IndexByteString(hostport[j:], '[') >= 0 { return addrErr(hostport, "unexpected '[' in address") } if bytealg.IndexByteString(hostport[k:], ']') >= 0 { return addrErr(hostport, "unexpected ']' in address") } port = hostport[i+1:] return host, port, nil } func splitHostZone(s string) (host, zone string) { // The IPv6 scoped addressing zone identifier starts after the // last percent sign. if i := bytealg.LastIndexByteString(s, '%'); i > 0 { host, zone = s[:i], s[i+1:] } else { host = s } return } // JoinHostPort combines host and port into a network address of the // form "host:port". If host contains a colon, as found in literal // IPv6 addresses, then JoinHostPort returns "[host]:port". // // See func Dial for a description of the host and port parameters. func JoinHostPort(host, port string) string { // We assume that host is a literal IPv6 address if host has // colons. if bytealg.IndexByteString(host, ':') >= 0 { return "[" + host + "]:" + port } return host + ":" + port }