Skip to content
This repository has been archived by the owner on Jun 9, 2019. It is now read-only.

Commit

Permalink
Merge pull request #381 from nats-io/improve_url_parsing
Browse files Browse the repository at this point in the history
[IMPROVED] URL parsing allowing to skip scheme and default port
  • Loading branch information
derekcollison committed Aug 14, 2018
2 parents 097d796 + ea8e897 commit 17bcb82
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 10 deletions.
30 changes: 26 additions & 4 deletions nats.go
Expand Up @@ -297,6 +297,9 @@ const (

// NUID size
nuidSize = 22

// Default port used if none is specified in given URL(s)
defaultPortString = "4222"
)

// A Conn represents a bare connection to a nats-server.
Expand Down Expand Up @@ -942,9 +945,27 @@ func (nc *Conn) setupServerPool() error {

// addURLToPool adds an entry to the server pool
func (nc *Conn) addURLToPool(sURL string, implicit bool) error {
u, err := url.Parse(sURL)
if err != nil {
return err
if !strings.Contains(sURL, "://") {
sURL = "nats://" + sURL
}
var (
u *url.URL
err error
)
for i := 0; i < 2; i++ {
u, err = url.Parse(sURL)
if err != nil {
return err
}
if u.Port() != "" {
break
}
// In case given URL is of the form "localhost:", just add
// the port number at the end, otherwise, add ":4222".
if sURL[len(sURL)-1] != ':' {
sURL += ":"
}
sURL += defaultPortString
}
s := &srv{url: u, isImplicit: implicit}
nc.srvPool = append(nc.srvPool, s)
Expand Down Expand Up @@ -1179,7 +1200,8 @@ func (nc *Conn) checkForSecure() error {
if o.Secure && !nc.info.TLSRequired {
return ErrSecureConnWanted
} else if nc.info.TLSRequired && !o.Secure {
return ErrSecureConnRequired
// Switch to Secure since server needs TLS.
o.Secure = true
}

// Need to rewrap with bufio
Expand Down
44 changes: 44 additions & 0 deletions nats_test.go
Expand Up @@ -223,6 +223,50 @@ var testServers = []string{
"nats://localhost:1228",
}

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",
}

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())
}
}
}

func TestServersRandomize(t *testing.T) {
opts := GetDefaultOptions()
opts.Servers = testServers
Expand Down
57 changes: 51 additions & 6 deletions test/conn_test.go
Expand Up @@ -165,14 +165,12 @@ func TestServerSecureConnections(t *testing.T) {

nc.Close()

// Server required, but not requested.
// Server required, but not specified in Connect(), should switch automatically
nc, err = nats.Connect(secureURL)
if err == nil || nc != nil || err != nats.ErrSecureConnRequired {
if nc != nil {
nc.Close()
}
t.Fatal("Should have failed to create secure (TLS) connection")
if err != nil {
t.Fatalf("Failed to create secure (TLS) connection: %v", err)
}
nc.Close()

// Test flag mismatch
// Wanted but not available..
Expand Down Expand Up @@ -1983,3 +1981,50 @@ func TestReceiveInfoWithEmptyConnectURLs(t *testing.T) {
nc.Close()
wg.Wait()
}

func TestConnectWithSimplifiedURLs(t *testing.T) {
urls := []string{
"nats://127.0.0.1:4222",
"nats://127.0.0.1:",
"nats://127.0.0.1",
"127.0.0.1:",
"127.0.0.1",
}

connect := func(t *testing.T, url string) {
t.Helper()
nc, err := nats.Connect(url)
if err != nil {
t.Fatalf("URL %q expected to connect, got %v", url, err)
}
nc.Close()
}

// Start a server that listens on default port 4222.
s := RunDefaultServer()
defer s.Shutdown()

// Try for every connection in the urls array.
for _, u := range urls {
connect(t, u)
}

s.Shutdown()

// Use this to build the options for us...
s, opts := RunServerWithConfig("configs/tls.conf")
s.Shutdown()
// Now change listen port to 4222 and remove auth
opts.Port = 4222
opts.Username = ""
opts.Password = ""
// and restart the server
s = RunServerWithOptions(*opts)
defer s.Shutdown()

// Test again against a server that wants TLS and check
// that we automatically switch to Secure.
for _, u := range urls {
connect(t, u)
}
}

0 comments on commit 17bcb82

Please sign in to comment.