mirror of
https://github.com/qdm12/ddns-updater.git
synced 2026-04-05 08:54:09 -04:00
chore(deps): drop dependency on github.com/chmike/domain
This commit is contained in:
1
go.mod
1
go.mod
@@ -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
2
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
133
internal/provider/utils/domain_test.go
Normal file
133
internal/provider/utils/domain_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user