Skip to content

Commit

Permalink
client.go fix addMissingPort() (#1444)
Browse files Browse the repository at this point in the history
* client.go Make addMissingPort() public

It's needed for those who creates the instance of the HostClient manually.

* client.go fix AddMissingPort()

Previously for IPv6 addresses the default port wasn't added.
The fix adding a test and optimization that should avoid itoa() call and reduce a memory usage
  • Loading branch information
stokito committed Nov 28, 2022
1 parent 4995135 commit c50de95
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 9 deletions.
34 changes: 25 additions & 9 deletions client.go
Expand Up @@ -9,7 +9,6 @@ import (
"fmt"
"io"
"net"
"strconv"
"strings"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -495,7 +494,7 @@ func (c *Client) Do(req *Request, resp *Response) error {
hc := m[string(host)]
if hc == nil {
hc = &HostClient{
Addr: addMissingPort(string(host), isTLS),
Addr: AddMissingPort(string(host), isTLS),
Name: c.Name,
NoDefaultUserAgentHeader: c.NoDefaultUserAgentHeader,
Dial: c.Dial,
Expand Down Expand Up @@ -1968,7 +1967,7 @@ func dialAddr(addr string, dial DialFunc, dialDualStack, isTLS bool, tlsConfig *
} else {
dial = Dial
}
addr = addMissingPort(addr, isTLS)
addr = AddMissingPort(addr, isTLS)
}
conn, err := dial(addr)
if err != nil {
Expand Down Expand Up @@ -2006,16 +2005,33 @@ func (c *HostClient) getClientName() []byte {
return clientName
}

func addMissingPort(addr string, isTLS bool) string {
n := strings.Index(addr, ":")
if n >= 0 {
// AddMissingPort adds a port to a host if it is missing.
// A literal IPv6 address in hostport must be enclosed in square
// brackets, as in "[::1]:80", "[::1%lo0]:80".
func AddMissingPort(addr string, isTLS bool) string {
addrLen := len(addr)
if addrLen == 0 {
return addr
}
port := 80

isIp6 := addr[0] == '['
if isIp6 {
// if the IPv6 has opening bracket but closing bracket is the last char then it doesn't have a port
isIp6WithoutPort := addr[addrLen-1] == ']'
if !isIp6WithoutPort {
return addr
}
} else { // IPv4
columnPos := strings.LastIndexByte(addr, ':')
if columnPos > 0 {
return addr
}
}
port := ":80"
if isTLS {
port = 443
port = ":443"
}
return net.JoinHostPort(addr, strconv.Itoa(port))
return addr + port
}

// A wantConn records state about a wanted connection
Expand Down
60 changes: 60 additions & 0 deletions client_test.go
Expand Up @@ -2971,3 +2971,63 @@ func TestHttpsRequestWithoutParsedURL(t *testing.T) {
t.Fatal("https requests with IsTLS client must succeed")
}
}

func Test_AddMissingPort(t *testing.T) {
type args struct {
addr string
isTLS bool
}
tests := []struct {
name string
args args
want string
}{
{
args: args{"127.1", false}, // 127.1 is a short form of 127.0.0.1
want: "127.1:80",
},
{
args: args{"127.0.0.1", false},
want: "127.0.0.1:80",
},
{
args: args{"127.0.0.1", true},
want: "127.0.0.1:443",
},
{
args: args{"[::1]", false},
want: "[::1]:80",
},
{
args: args{"::1", false},
want: "::1", // keep as is
},
{
args: args{"[::1]", true},
want: "[::1]:443",
},
{
args: args{"127.0.0.1:8080", false},
want: "127.0.0.1:8080",
},
{
args: args{"127.0.0.1:8443", true},
want: "127.0.0.1:8443",
},
{
args: args{"[::1]:8080", false},
want: "[::1]:8080",
},
{
args: args{"[::1]:8443", true},
want: "[::1]:8443",
},
}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
if got := AddMissingPort(tt.args.addr, tt.args.isTLS); got != tt.want {
t.Errorf("AddMissingPort() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit c50de95

Please sign in to comment.