From 97d75321edfb3f6ff2450097fb85c34ebca8476f Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Fri, 18 Feb 2022 14:05:53 -0700 Subject: [PATCH] [FIXED] Websocket: discovered urls would not have "wss://" scheme If the user originally connects with "wss://" but has not configured any secure related option (Options.Secure/TLSConfig), then when adding implicit URLs (from the server INFO) the library would add the "ws://" prefix to the received URL. When trying to connect to those URLs, the library would not try to make a TLS handshake and would get an error back that would result in a "websocket invalid connection". Resolves #914 Signed-off-by: Ivan Kozlovic --- nats.go | 2 +- ws_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/nats.go b/nats.go index 3bf5b4d57..2dbd4e840 100644 --- a/nats.go +++ b/nats.go @@ -1435,7 +1435,7 @@ func (nc *Conn) setupServerPool() error { // Check for Scheme hint to move to TLS mode. for _, srv := range nc.srvPool { - if srv.url.Scheme == tlsScheme { + if srv.url.Scheme == tlsScheme || srv.url.Scheme == wsSchemeTLS { // FIXME(dlc), this is for all in the pool, should be case by case. nc.Opts.Secure = true if nc.Opts.TLSConfig == nil { diff --git a/ws_test.go b/ws_test.go index 0462cc7db..551ce3f05 100644 --- a/ws_test.go +++ b/ws_test.go @@ -860,6 +860,36 @@ func TestWSWithTLS(t *testing.T) { } } +func TestWSTlsNoConfig(t *testing.T) { + opts := GetDefaultOptions() + opts.Servers = []string{"wss://localhost:443"} + + nc := &Conn{Opts: opts} + if err := nc.setupServerPool(); err != nil { + t.Fatalf("Error setting up pool: %v", err) + } + // Verify that this has set Secure/TLSConfig + nc.mu.Lock() + ok := nc.Opts.Secure && nc.Opts.TLSConfig != nil + nc.mu.Unlock() + if !ok { + t.Fatal("Secure and TLSConfig were not set") + } + // Now try to add a bare host:ip to the pool and verify + // that the wss:// scheme is added. + if err := nc.addURLToPool("1.2.3.4:443", true, false); err != nil { + t.Fatalf("Error adding to pool: %v", err) + } + nc.mu.Lock() + for _, srv := range nc.srvPool { + if srv.url.Scheme != wsSchemeTLS { + nc.mu.Unlock() + t.Fatalf("Expected scheme to be %q, got url: %s", wsSchemeTLS, srv.url) + } + } + nc.mu.Unlock() +} + func TestWSGossipAndReconnect(t *testing.T) { o1 := testWSGetDefaultOptions(t, false) o1.ServerName = "A"