Skip to content

Commit

Permalink
private/protocol: Loosen endpoint validation to allow customer specif…
Browse files Browse the repository at this point in the history
…y port number (#3730)

Adds support for port numbers in endpoint host validation.
  • Loading branch information
macrovve committed Jan 13, 2021
1 parent a770b41 commit d64f6df
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
### SDK Features

### SDK Enhancements
* `private/protocol`: Loosen endpoint validation to allow customer specify port number ([#3730](https://github.com/aws/aws-sdk-go/pull/3730))
* Updates SDK's endpoint validation of the hostname to allow ports to be specified.
* `service/s3/s3manager`: Add ETag field to UploadOutput ([#3733](https://github.com/aws/aws-sdk-go/pull/3733))
* Adds the ETag field to the Uploader's UploadOutput return value.
* Fixes [#2764](https://github.com/aws/aws-sdk-go/issues/2764)
Expand Down
44 changes: 40 additions & 4 deletions private/protocol/host.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package protocol

import (
"strings"

"github.com/aws/aws-sdk-go/aws/request"
"net"
"strconv"
"strings"
)

// ValidateEndpointHostHandler is a request handler that will validate the
Expand All @@ -22,8 +23,26 @@ var ValidateEndpointHostHandler = request.NamedHandler{
// 3986 host. Returns error if the host is not valid.
func ValidateEndpointHost(opName, host string) error {
paramErrs := request.ErrInvalidParams{Context: opName}
labels := strings.Split(host, ".")

var hostname string
var port string
var err error

if strings.Contains(host, ":") {
hostname, port, err = net.SplitHostPort(host)

if err != nil {
paramErrs.Add(request.NewErrParamFormat("endpoint", err.Error(), host))
}

if !ValidPortNumber(port) {
paramErrs.Add(request.NewErrParamFormat("endpoint port number", "[0-65535]", port))
}
} else {
hostname = host
}

labels := strings.Split(hostname, ".")
for i, label := range labels {
if i == len(labels)-1 && len(label) == 0 {
// Allow trailing dot for FQDN hosts.
Expand All @@ -36,7 +55,11 @@ func ValidateEndpointHost(opName, host string) error {
}
}

if len(host) > 255 {
if len(hostname) == 0 {
paramErrs.Add(request.NewErrParamMinLen("endpoint host", 1))
}

if len(hostname) > 255 {
paramErrs.Add(request.NewErrParamMaxLen(
"endpoint host", 255, host,
))
Expand Down Expand Up @@ -66,3 +89,16 @@ func ValidHostLabel(label string) bool {

return true
}

// ValidPortNumber return if the port is valid RFC 3986 port
func ValidPortNumber(port string) bool {
i, err := strconv.Atoi(port)
if err != nil {
return false
}

if i < 0 || i > 65535 {
return false
}
return true
}
26 changes: 26 additions & 0 deletions private/protocol/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ import (
"testing"
)

func TestValidPortNumber(t *testing.T) {
cases := []struct {
Input string
Valid bool
}{
{Input: "123", Valid: true},
{Input: "123.0", Valid: false},
{Input: "-123", Valid: false},
{Input: "65536", Valid: false},
{Input: "0", Valid: true},
}
for i, c := range cases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
valid := ValidPortNumber(c.Input)
if e, a := c.Valid, valid; e != a {
t.Errorf("expect valid %v, got %v", e, a)
}
})
}

}

func TestValidHostLabel(t *testing.T) {
cases := []struct {
Input string
Expand Down Expand Up @@ -50,6 +72,10 @@ func TestValidateEndpointHostHandler(t *testing.T) {
Input: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456",
Valid: false,
},
"valid host with port number": {Input: "abd.123:1234", Valid: true},
"valid host with invalid port number": {Input: "abc.123:99999", Valid: false},
"empty host with port number": {Input: ":1234", Valid: false},
"valid host with empty port number": {Input: "abc.123:", Valid: false},
}

for name, c := range cases {
Expand Down

0 comments on commit d64f6df

Please sign in to comment.