...
1 package http
2
3 import (
4 "fmt"
5 "net"
6 "strconv"
7 "strings"
8 )
9
10
11
12 func ValidateEndpointHost(host string) error {
13 var errors strings.Builder
14 var hostname string
15 var port string
16 var err error
17
18 if strings.Contains(host, ":") {
19 hostname, port, err = net.SplitHostPort(host)
20 if err != nil {
21 errors.WriteString(fmt.Sprintf("\n endpoint %v, failed to parse, got ", host))
22 errors.WriteString(err.Error())
23 }
24
25 if !ValidPortNumber(port) {
26 errors.WriteString(fmt.Sprintf("port number should be in range [0-65535], got %v", port))
27 }
28 } else {
29 hostname = host
30 }
31
32 labels := strings.Split(hostname, ".")
33 for i, label := range labels {
34 if i == len(labels)-1 && len(label) == 0 {
35
36 continue
37 }
38
39 if !ValidHostLabel(label) {
40 errors.WriteString("\nendpoint host domain labels must match \"[a-zA-Z0-9-]{1,63}\", but found: ")
41 errors.WriteString(label)
42 }
43 }
44
45 if len(hostname) == 0 && len(port) != 0 {
46 errors.WriteString("\nendpoint host with port must not be empty")
47 }
48
49 if len(hostname) > 255 {
50 errors.WriteString(fmt.Sprintf("\nendpoint host must be less than 255 characters, but was %d", len(hostname)))
51 }
52
53 if len(errors.String()) > 0 {
54 return fmt.Errorf("invalid endpoint host%s", errors.String())
55 }
56 return nil
57 }
58
59
60 func ValidPortNumber(port string) bool {
61 i, err := strconv.Atoi(port)
62 if err != nil {
63 return false
64 }
65
66 if i < 0 || i > 65535 {
67 return false
68 }
69 return true
70 }
71
72
73 func ValidHostLabel(label string) bool {
74 if l := len(label); l == 0 || l > 63 {
75 return false
76 }
77 for _, r := range label {
78 switch {
79 case r >= '0' && r <= '9':
80 case r >= 'A' && r <= 'Z':
81 case r >= 'a' && r <= 'z':
82 case r == '-':
83 default:
84 return false
85 }
86 }
87
88 return true
89 }
90
View as plain text