An IPv6 address is full of colons, so RFC 3986 wraps it in square brackets to keep those colons from being read as a port separator. Today you handle the bracketed host and only look for a port after the closing bracket.
Parse a bracketed IPv6 host and find the port only after the closing bracket.
An IPv6 address like 2001:db8::1 uses colons as its own separators, which collides head-on with the host:port colon. RFC 3986 resolves the ambiguity with an IP-literal form: the address goes inside square brackets, [2001:db8::1], and the brackets are part of the host as the parser sees it. Because the whole address is bracketed, none of its internal colons can be confused with the port delimiter.
So when the host portion begins with [, scan to the closing ] and take everything up to and including it as the host. Only a colon after that bracket introduces a port. This is why last lesson’s “split on the last colon” was not the final rule: for [2001:db8::1]:443 the last colon is inside the address, and splitting there would be wrong. Checking for the bracket first, and searching for the port colon only in the tail after ], is what makes both the plain-host and IPv6 cases come out right. The keeps-the-brackets choice also means recomposing the URI later just writes the host back verbatim.
// if the host starts with '[', the host runs THROUGH the ']';// only a ':' AFTER the bracket is a portif strings.HasPrefix(a, "[") {j := strings.IndexByte(a, ']')u.Host = a[:j+1]rest := a[j+1:]if strings.HasPrefix(rest, ":") { u.Port = rest[1:]; u.HasPort = true }return}