diff --git a/client.go b/client.go index d24dffe..440ca94 100644 --- a/client.go +++ b/client.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net" - "strings" "time" ) @@ -83,27 +82,23 @@ Setting up the client / Checking the parameters // NewClient generates a new XMPP client, based on Config passed as parameters. // If host is not specified, the DNS SRV should be used to find the host from the domainpart of the JID. // Default the port to 5222. -// TODO: better config checks func NewClient(config Config, r *Router) (c *Client, err error) { // Parse JID if config.parsedJid, err = NewJid(config.Jid); err != nil { err = errors.New("missing jid") return nil, NewConnError(err, true) } - + if config.Password == "" { err = errors.New("missing password") return nil, NewConnError(err, true) } - + // fallback to jid domain if config.Address == "" { config.Address = config.parsedJid.Domain } - // if address has no port (behind his ipv6 address) - add default port - if strings.LastIndex(config.Address, ":") <= strings.LastIndex(config.Address, "]") { - config.Address += ":5222" - } + config.Address = ensurePort(config.Address, 5222) c = new(Client) c.config = config diff --git a/network.go b/network.go new file mode 100644 index 0000000..75a0a60 --- /dev/null +++ b/network.go @@ -0,0 +1,32 @@ +package xmpp + +import ( + "strconv" + "strings" +) + +// ensurePort adds a port to an address if none are provided. +// It handles both IPV4 and IPV6 addresses. +func ensurePort(addr string, port int) string { + // This is an IPV6 address literal + if strings.HasPrefix(addr, "[") { + // if address has no port (behind his ipv6 address) - add default port + if strings.LastIndex(addr, ":") <= strings.LastIndex(addr, "]") { + return addr + ":" + strconv.Itoa(port) + } + return addr + } + + // This is either an IPV6 address without bracket or an IPV4 address + switch strings.Count(addr, ":") { + case 0: + // This is IPV4 without port + return addr + ":" + strconv.Itoa(port) + case 1: + // This is IPV$ with port + return addr + default: + // This is IPV6 without port, as you need to use bracket with port in IPV6 + return "[" + addr + "]:" + strconv.Itoa(port) + } +} diff --git a/network_test.go b/network_test.go new file mode 100644 index 0000000..840a6f1 --- /dev/null +++ b/network_test.go @@ -0,0 +1,35 @@ +package xmpp + +import ( + "testing" +) + +type params struct { +} + +func TestParseAddr(t *testing.T) { + tests := []struct { + name string + input string + want string + }{ + {name: "ipv4-no-port-1", input: "localhost", want: "localhost:5222"}, + {name: "ipv4-with-port-1", input: "localhost:5555", want: "localhost:5555"}, + {name: "ipv4-no-port-2", input: "127.0.0.1", want: "127.0.0.1:5222"}, + {name: "ipv4-with-port-2", input: "127.0.0.1:5555", want: "127.0.0.1:5555"}, + {name: "ipv6-no-port-1", input: "1::", want: "[1::]:5222"}, + {name: "ipv6-no-port-2", input: "[1::]", want: "[1::]:5222"}, + {name: "ipv6-no-port-3", input: "1::2008", want: "[1::2008]:5222"}, + {name: "ipv6-no-port-4", input: "1::2008:1", want: "[1::2008:1]:5222"}, + {name: "ipv6-with-port-1", input: "[1::]:5555", want: "[1::]:5555"}, + } + for _, tc := range tests { + t.Run(tc.name, func(st *testing.T) { + addr := ensurePort(tc.input, 5222) + + if addr != tc.want { + st.Errorf("incorrect Result: %v (!= %v)", addr, tc.want) + } + }) + } +}