host.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package protocol
  2. import (
  3. "strings"
  4. "github.com/aws/aws-sdk-go/aws/request"
  5. )
  6. // ValidateEndpointHostHandler is a request handler that will validate the
  7. // request endpoint's hosts is a valid RFC 3986 host.
  8. var ValidateEndpointHostHandler = request.NamedHandler{
  9. Name: "awssdk.protocol.ValidateEndpointHostHandler",
  10. Fn: func(r *request.Request) {
  11. err := ValidateEndpointHost(r.Operation.Name, r.HTTPRequest.URL.Host)
  12. if err != nil {
  13. r.Error = err
  14. }
  15. },
  16. }
  17. // ValidateEndpointHost validates that the host string passed in is a valid RFC
  18. // 3986 host. Returns error if the host is not valid.
  19. func ValidateEndpointHost(opName, host string) error {
  20. paramErrs := request.ErrInvalidParams{Context: opName}
  21. labels := strings.Split(host, ".")
  22. for i, label := range labels {
  23. if i == len(labels)-1 && len(label) == 0 {
  24. // Allow trailing dot for FQDN hosts.
  25. continue
  26. }
  27. if !ValidHostLabel(label) {
  28. paramErrs.Add(request.NewErrParamFormat(
  29. "endpoint host label", "[a-zA-Z0-9-]{1,63}", label))
  30. }
  31. }
  32. if len(host) > 255 {
  33. paramErrs.Add(request.NewErrParamMaxLen(
  34. "endpoint host", 255, host,
  35. ))
  36. }
  37. if paramErrs.Len() > 0 {
  38. return paramErrs
  39. }
  40. return nil
  41. }
  42. // ValidHostLabel returns if the label is a valid RFC 3986 host label.
  43. func ValidHostLabel(label string) bool {
  44. if l := len(label); l == 0 || l > 63 {
  45. return false
  46. }
  47. for _, r := range label {
  48. switch {
  49. case r >= '0' && r <= '9':
  50. case r >= 'A' && r <= 'Z':
  51. case r >= 'a' && r <= 'z':
  52. case r == '-':
  53. default:
  54. return false
  55. }
  56. }
  57. return true
  58. }