chore(deps): drop dependency on github.com/chmike/domain

This commit is contained in:
Quentin McGaw
2024-06-27 09:18:28 +00:00
parent dbd2f79760
commit db07ed3759
4 changed files with 207 additions and 5 deletions

1
go.mod
View File

@@ -4,7 +4,6 @@ go 1.22
require (
github.com/breml/rootcerts v0.2.17
github.com/chmike/domain v1.0.1
github.com/containrrr/shoutrrr v0.8.0
github.com/go-chi/chi/v5 v5.0.12
github.com/golang/mock v1.6.0

2
go.sum
View File

@@ -2,8 +2,6 @@ cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2Qx
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
github.com/breml/rootcerts v0.2.17 h1:0/M2BE2Apw0qEJCXDOkaiu7d5Sx5ObNfe1BkImJ4u1I=
github.com/breml/rootcerts v0.2.17/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
github.com/chmike/domain v1.0.1 h1:ug6h3a7LLAfAecBAysbCXWxP1Jo8iBKWNVDxcs1BNzA=
github.com/chmike/domain v1.0.1/go.mod h1:h558M2qGKpYRUxHHNyey6puvXkZBjvjmseOla/d1VGQ=
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@@ -1,9 +1,12 @@
package utils
import (
"errors"
"fmt"
"strings"
"unicode/utf8"
"github.com/chmike/domain"
ddnserrors "github.com/qdm12/ddns-updater/internal/provider/errors"
)
func BuildDomainName(owner, domain string) string {
@@ -21,6 +24,75 @@ func BuildURLQueryHostname(owner, domain string) string {
return owner + "." + domain
}
var (
ErrDomainTooLong = errors.New("domain name is too long")
ErrDomainLabelTooLong = errors.New("domain label is too long")
ErrDomainInvalidCharacter = errors.New("domain name has invalid character")
ErrDomainTLDMissing = errors.New("domain has missing top level domain")
)
// CheckDomain returns an non-nil error if the domain name is not valid.
// https://tools.ietf.org/html/rfc1034#section-3.5
// https://tools.ietf.org/html/rfc1123#section-2.
func CheckDomain(domainString string) (err error) {
return domain.Check(domainString)
const maxDomainLength = 255
switch {
case len(domainString) == 0:
return fmt.Errorf("%w", ddnserrors.ErrDomainNotSet)
case len(domainString) > maxDomainLength:
return fmt.Errorf("%w: %q has a length of %d characters exceeding the maximum of %d",
ErrDomainTooLong, domainString, len(domainString), maxDomainLength)
}
labelStartIndex := 0
for i, character := range domainString {
if character == '.' {
const maxLabelLength = 63
switch {
case i == labelStartIndex:
return fmt.Errorf("%w: label starts with '.' for domain %q", ErrDomainInvalidCharacter, domainString)
case i-labelStartIndex > maxLabelLength:
return fmt.Errorf("%w: for domain %q", ErrDomainLabelTooLong, domainString)
case domainString[labelStartIndex] == '-':
return fmt.Errorf("%w: label starts with '-' for domain %q", ErrDomainInvalidCharacter, domainString)
case domainString[i-1] == '-':
return fmt.Errorf("%w: label ends with '-' for domain %q", ErrDomainInvalidCharacter, domainString)
}
labelStartIndex = i + 1
continue
}
if (character < 'a' || character > 'z') &&
(character < '0' || character > '9') &&
character != '-' &&
(character < 'A' || character > 'Z') {
r, _ := utf8.DecodeRuneInString(domainString[i:])
if r == utf8.RuneError {
return fmt.Errorf("%w: invalid rune at offset %d for domain %q",
ErrDomainInvalidCharacter, i, domainString)
}
return fmt.Errorf("%w: '%c' for domain %q",
ErrDomainInvalidCharacter, r, domainString)
}
}
// check top level domain validity
const maxLabelLength = 63
switch {
case labelStartIndex == len(domainString):
return fmt.Errorf("%w: %q", ErrDomainTLDMissing, domainString)
case len(domainString)-labelStartIndex > maxLabelLength:
return fmt.Errorf("%w: TLD label in domain %q",
ErrDomainLabelTooLong, domainString)
case domainString[labelStartIndex] == '-':
return fmt.Errorf("%w: TLD label starts with '-' in domain %q",
ErrDomainInvalidCharacter, domainString)
case domainString[len(domainString)-1] == '-':
return fmt.Errorf("%w: TLD label ends with '-' in domain %q",
ErrDomainInvalidCharacter, domainString)
case domainString[labelStartIndex] >= '0' && domainString[labelStartIndex] <= '9':
return fmt.Errorf("%w: TLD label begins with a digit in domain %q",
ErrDomainInvalidCharacter, domainString)
}
return nil
}

View File

@@ -0,0 +1,133 @@
package utils
import (
"fmt"
"strings"
"testing"
"github.com/qdm12/ddns-updater/internal/provider/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_CheckDomain(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
domain string
errWrapped error
errMessage string
}{
"empty_domain": {
domain: "",
errWrapped: errors.ErrDomainNotSet,
errMessage: "domain is not set",
},
"lowercase_valid": {
domain: "example.com",
},
"uppercase_valid": {
domain: "EXAMPLE.com",
},
"hyphen_valid": {
domain: "foo-bar.com",
},
"subdomain_valid": {
domain: "www1.foo-bar.com",
},
"digits_valid": {
domain: "192.168.1.1.example.com",
},
"domain_too_long": {
domain: strings.Repeat("a", 300),
errWrapped: ErrDomainTooLong,
errMessage: fmt.Sprintf(`domain name is too long: "%s" has a length of 300 characters `+
`exceeding the maximum of 255`, strings.Repeat("a", 300)),
},
"label_too_long": {
domain: strings.Repeat("a", 70) + ".com",
errWrapped: ErrDomainLabelTooLong,
errMessage: "domain label is too long: for domain " +
"\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com\"",
},
"tld_too_long": {
domain: "example." + strings.Repeat("b", 70),
errWrapped: ErrDomainLabelTooLong,
errMessage: "domain label is too long: TLD label in domain " +
"\"example.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"",
},
"invalid_character_?": {
domain: "?",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: '?' for domain \"?\"",
},
"invalid_character_tab": {
domain: "\t",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: '\t' for domain \"\\t\"",
},
"invalid_character_à": {
domain: "exàmple.com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: 'à' for domain \"exàmple.com\"",
},
"invalid_rune": {
domain: "www.\xbd\xb2.com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: invalid rune at offset 4 for domain \"www.\\xbd\\xb2.com\"",
},
"invalid_starts_hyphen": {
domain: "-example.com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: label starts with '-' for domain \"-example.com\"",
},
"invalid_ends_hyphen": {
domain: "example-.com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: label ends with '-' for domain \"example-.com\"",
},
"invalid_tld_starts_hyphen": {
domain: "example.-com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: TLD label starts with '-' in domain \"example.-com\"",
},
"invalid_tld_ends_hyphen": {
domain: "example.com-",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: TLD label ends with '-' in domain \"example.com-\"",
},
"invalid_tld_starts_digit": {
domain: "example.1com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: TLD label begins with a digit in domain \"example.1com\"",
},
"invalid_empty_first_label": {
domain: ".example.com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: label starts with '.' for domain \".example.com\"",
},
"invalid_empty_middle_label": {
domain: "example..com",
errWrapped: ErrDomainInvalidCharacter,
errMessage: "domain name has invalid character: label starts with '.' for domain \"example..com\"",
},
"invalid_trailing_dot": {
domain: "example.com.",
errWrapped: ErrDomainTLDMissing,
errMessage: "domain has missing top level domain: \"example.com.\"",
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
err := CheckDomain(testCase.domain)
require.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {
assert.EqualError(t, err, testCase.errMessage)
}
})
}
}