Skip to content

Commit 861364b

Browse files
qingyang-huprestonvasquezkevinAlbs
committed
GODRIVER-2620 Fix hostname parsing for SRV polling. (#1112)
* GODRIVER-2620 Fix hostname parsing for SRV polling. Co-authored-by: Preston Vasquez <[email protected]> Co-authored-by: Kevin Albertson <[email protected]>
1 parent 5762c6a commit 861364b

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

x/mongo/driver/topology/polling_srv_records_test.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,22 @@ func compareHosts(t *testing.T, received []description.Server, expected []string
125125
}
126126

127127
func TestPollingSRVRecordsSpec(t *testing.T) {
128+
for _, uri := range []string{
129+
"mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100",
130+
// Test with user:pass as a regression test for GODRIVER-2620
131+
"mongodb+srv://user:[email protected]/?heartbeatFrequencyMS=100",
132+
} {
133+
t.Run(uri, func(t *testing.T) {
134+
testPollingSRVRecordsSpec(t, uri)
135+
})
136+
}
137+
}
138+
139+
func testPollingSRVRecordsSpec(t *testing.T, uri string) {
140+
t.Helper()
128141
for _, tt := range srvPollingTests {
129142
t.Run(tt.name, func(t *testing.T) {
130-
cs, err := connstring.ParseAndValidate("mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100")
143+
cs, err := connstring.ParseAndValidate(uri)
131144
require.NoError(t, err, "Problem parsing the uri: %v", err)
132145
topo, err := New(
133146
WithConnString(func(connstring.ConnString) connstring.ConnString { return cs }),

x/mongo/driver/topology/topology.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"context"
1515
"errors"
1616
"fmt"
17+
"net"
18+
"net/url"
1719
"strings"
1820
"sync"
1921
"sync/atomic"
@@ -230,7 +232,21 @@ func (t *Topology) Connect() error {
230232

231233
t.serversLock.Unlock()
232234
if t.pollingRequired {
233-
go t.pollSRVRecords()
235+
uri, err := url.Parse(t.cfg.uri)
236+
if err != nil {
237+
return err
238+
}
239+
// sanity check before passing the hostname to resolver
240+
if parsedHosts := strings.Split(uri.Host, ","); len(parsedHosts) != 1 {
241+
return fmt.Errorf("URI with SRV must include one and only one hostname")
242+
}
243+
_, _, err = net.SplitHostPort(uri.Host)
244+
if err == nil {
245+
// we were able to successfully extract a port from the host,
246+
// but should not be able to when using SRV
247+
return fmt.Errorf("URI with srv must not include a port number")
248+
}
249+
go t.pollSRVRecords(uri.Host)
234250
t.pollingwg.Add(1)
235251
}
236252

@@ -552,7 +568,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
552568
return suitable, nil
553569
}
554570

555-
func (t *Topology) pollSRVRecords() {
571+
func (t *Topology) pollSRVRecords(hosts string) {
556572
defer t.pollingwg.Done()
557573

558574
serverConfig := newServerConfig(t.cfg.serverOpts...)
@@ -569,13 +585,6 @@ func (t *Topology) pollSRVRecords() {
569585
}
570586
}()
571587

572-
// remove the scheme
573-
uri := t.cfg.uri[14:]
574-
hosts := uri
575-
if idx := strings.IndexAny(uri, "/?@"); idx != -1 {
576-
hosts = uri[:idx]
577-
}
578-
579588
for {
580589
select {
581590
case <-pollTicker.C:

0 commit comments

Comments
 (0)