Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMPROVED] URL parsing allowing to skip scheme and default port #381

Merged
merged 1 commit into from
Aug 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions nats.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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)
}
}