Repository: nats-io/nats.go (go)

Issue:
Assume port 80/443 for ws:// and wss:// connection URIs if not specified instead of 4222.
## Feature request

#### Use Case:

Currently, you must specify the port in websocket URIs, as the client assumes 4222 if the port is not specified.

#### Proposed Change:

Assume port 80/443 for ws:// and wss:// connection URIs if not specified instead of 4222.

#### Who Benefits From The Change(s)?

For any nats server with websocket ports on standard 80/443 ports, the user does not have to specify port in the in the URL. For NATS servers that are used by web frontends, this will probably be fairly standard behavior. 

If a user currently enters a URI like: wss://myserver.com, it does not connect as it tries to make a websocket connection to port 4222 -- these kinds of issues are difficult to debug.

Smart defaults make SW easier to use :-)

#### Alternative Approaches

Continue to require port to be specified in ws* URIs -- perhaps document if not already.



Pull request:
[IMPROVED] Websocket: use 80/443 as default ports
If no port is specified in the URL, port 80 will be used if scheme
is "ws://" and port 443 will be used if scheme is "wss://".

Resolves #876

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>

Patch:
diff --git a/nats.go b/nats.go
index 8b963c5..840a1ff 100644
--- a/nats.go
+++ b/nats.go
@@ -1,4 +1,4 @@
-// Copyright 2012-2021 The NATS Authors
+// Copyright 2012-2022 The NATS Authors
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
@@ -480,8 +480,10 @@ const (
 	// NUID size
 	nuidSize = 22
 
-	// Default port used if none is specified in given URL(s)
-	defaultPortString = "4222"
+	// Default ports used if none is specified in given URL(s)
+	defaultWSPortString  = "80"
+	defaultWSSPortString = "443"
+	defaultPortString    = "4222"
 )
 
 // A Conn represents a bare connection to a nats-server.
@@ -1485,7 +1487,14 @@ func (nc *Conn) addURLToPool(sURL string, implicit, saveTLSName bool) error {
 		if sURL[len(sURL)-1] != ':' {
 			sURL += ":"
 		}
-		sURL += defaultPortString
+		switch u.Scheme {
+		case wsScheme:
+			sURL += defaultWSPortString
+		case wsSchemeTLS:
+			sURL += defaultWSSPortString
+		default:
+			sURL += defaultPortString
+		}
 	}
 
 	isWS := isWebsocketScheme(u)


Test patch:
diff --git a/nats_test.go b/nats_test.go
index fd965b2..7197e34 100644
--- a/nats_test.go
+++ b/nats_test.go
@@ -1,4 +1,4 @@
-// Copyright 2012-2020 The NATS Authors
+// Copyright 2012-2022 The NATS Authors
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
@@ -278,46 +278,95 @@ var testServers = []string{
 }
 
 func TestSimplifiedURLs(t *testing.T) {
-	opts := GetDefaultOptions()
-	opts.NoRandomize = true
-	opts.Servers = []string{
-		"nats://host1:1234",
-		"nats://host2:",
-		"nats://host3",
-		"host4:1234",
-		"host5:",
-		"host6",
-		"nats://[1:2:3:4]:1234",
-		"nats://[5:6:7:8]:",
-		"nats://[9:10:11:12]",
-		"[13:14:15:16]:",
-		"[17:18:19:20]:1234",
-	}
-
-	// We expect the result in the server pool to be:
-	expected := []string{
-		"nats://host1:1234",
-		"nats://host2:4222",
-		"nats://host3:4222",
-		"nats://host4:1234",
-		"nats://host5:4222",
-		"nats://host6:4222",
-		"nats://[1:2:3:4]:1234",
-		"nats://[5:6:7:8]:4222",
-		"nats://[9:10:11:12]:4222",
-		"nats://[13:14:15:16]:4222",
-		"nats://[17:18:19:20]:1234",
-	}
+	for _, test := range []struct {
+		name     string
+		servers  []string
+		expected []string
+	}{
+		{
+			"nats",
+			[]string{
+				"nats://host1:1234",
+				"nats://host2:",
+				"nats://host3",
+				"host4:1234",
+				"host5:",
+				"host6",
+				"nats://[1:2:3:4]:1234",
+				"nats://[5:6:7:8]:",
+				"nats://[9:10:11:12]",
+				"[13:14:15:16]:",
+				"[17:18:19:20]:1234",
+			},
+			[]string{
+				"nats://host1:1234",
+				"nats://host2:4222",
+				"nats://host3:4222",
+				"nats://host4:1234",
+				"nats://host5:4222",
+				"nats://host6:4222",
+				"nats://[1:2:3:4]:1234",
+				"nats://[5:6:7:8]:4222",
+				"nats://[9:10:11:12]:4222",
+				"nats://[13:14:15:16]:4222",
+				"nats://[17:18:19:20]:1234",
+			},
+		},
+		{
+			"ws",
+			[]string{
+				"ws://host1:1234",
+				"ws://host2:",
+				"ws://host3",
+				"ws://[1:2:3:4]:1234",
+				"ws://[5:6:7:8]:",
+				"ws://[9:10:11:12]",
+			},
+			[]string{
+				"ws://host1:1234",
+				"ws://host2:80",
+				"ws://host3:80",
+				"ws://[1:2:3:4]:1234",
+				"ws://[5:6:7:8]:80",
+				"ws://[9:10:11:12]:80",
+			},
+		},
+		{
+			"wss",
+			[]string{
+				"wss://host1:1234",
+				"wss://host2:",
+				"wss://host3",
+				"wss://[1:2:3:4]:1234",
+				"wss://[5:6:7:8]:",
+				"wss://[9:10:11:12]",
+			},
+			[]string{
+				"wss://host1:1234",
+				"wss://host2:443",
+				"wss://host3:443",
+				"wss://[1:2:3:4]:1234",
+				"wss://[5:6:7:8]:443",
+				"wss://[9:10:11:12]:443",
+			},
+		},
+	} {
+		t.Run(test.name, func(t *testing.T) {
+			opts := GetDefaultOptions()
+			opts.NoRandomize = true
+			opts.Servers = test.servers
 
-	nc := &Conn{Opts: opts}
-	if err := nc.setupServerPool(); err != nil {
-		t.Fatalf("Problem setting up Server Pool: %v\n", err)
-	}
-	// Check server pool directly
-	for i, u := range nc.srvPool {
-		if u.url.String() != expected[i] {
-			t.Fatalf("Expected url %q, got %q", expected[i], u.url.String())
-		}
+			nc := &Conn{Opts: opts}
+			if err := nc.setupServerPool(); err != nil {
+				t.Fatalf("Problem setting up Server Pool: %v\n", err)
+			}
+			// Check server pool directly
+			for i, u := range nc.srvPool {
+				if u.url.String() != test.expected[i] {
+					t.Fatalf("Expected url %q, got %q", test.expected[i], u.url.String())
+				}
+			}
+		})
 	}
 }