Last active
December 1, 2023 19:21
-
-
Save chmike/d4126a3247a6d9a70922fc0e8b4f4013 to your computer and use it in GitHub Desktop.
Check domain name validity in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Please use the package https://github.com/chmike/domain as is it maintained up to date with tests. | |
// checkDomain returns an error if the domain name is not valid. | |
// See https://tools.ietf.org/html/rfc1034#section-3.5 and | |
// https://tools.ietf.org/html/rfc1123#section-2. | |
func checkDomain(name string) error { | |
switch { | |
case len(name) == 0: | |
return nil // an empty domain name will result in a cookie without a domain restriction | |
case len(name) > 255: | |
return fmt.Errorf("domain name length is %d, can't exceed 255", len(name)) | |
} | |
var l int | |
for i := 0; i < len(name); i++ { | |
b := name[i] | |
if b == '.' { | |
// check domain labels validity | |
switch { | |
case i == l: | |
return fmt.Errorf("domain has invalid character '.' at offset %d, label can't begin with a period", i) | |
case i-l > 63: | |
return fmt.Errorf("domain byte length of label '%s' is %d, can't exceed 63", name[l:i], i-l) | |
case name[l] == '-': | |
return fmt.Errorf("domain label '%s' at offset %d begins with a hyphen", name[l:i], l) | |
case name[i-1] == '-': | |
return fmt.Errorf("domain label '%s' at offset %d ends with a hyphen", name[l:i], l) | |
} | |
l = i + 1 | |
continue | |
} | |
// test label character validity, note: tests are ordered by decreasing validity frequency | |
if !(b >= 'a' && b <= 'z' || b >= '0' && b <= '9' || b == '-' || b >= 'A' && b <= 'Z') { | |
// show the printable unicode character starting at byte offset i | |
c, _ := utf8.DecodeRuneInString(name[i:]) | |
if c == utf8.RuneError { | |
return fmt.Errorf("domain has invalid rune at offset %d", i) | |
} | |
return fmt.Errorf("domain has invalid character '%c' at offset %d", c, i) | |
} | |
} | |
// check top level domain validity | |
switch { | |
case l == len(name): | |
return fmt.Errorf("domain has missing top level domain, domain can't end with a period") | |
case len(name)-l > 63: | |
return fmt.Errorf("domain's top level domain '%s' has byte length %d, can't exceed 63", name[l:], len(name)-l) | |
case name[l] == '-': | |
return fmt.Errorf("domain's top level domain '%s' at offset %d begin with a hyphen", name[l:], l) | |
case name[len(name)-1] == '-': | |
return fmt.Errorf("domain's top level domain '%s' at offset %d ends with a hyphen", name[l:], l) | |
case name[l] >= '0' && name[l] <= '9': | |
return fmt.Errorf("domain's top level domain '%s' at offset %d begins with a digit", name[l:], l) | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
oh I missed that - apologies. thank you!