Skip to content

Commit e4853fb

Browse files
qingyang-huprestonvasquezkevinAlbs
authored
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 f5312df commit e4853fb

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

x/mongo/driver/topology/polling_srv_records_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,21 @@ 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-
uri := "mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100"
131143
cfg, err := NewConfig(options.Client().ApplyURI(uri), nil)
132144
require.NoError(t, err, "error constructing topology configs: %v", err)
133145

x/mongo/driver/topology/topology.go

Lines changed: 18 additions & 9 deletions
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"
@@ -234,7 +236,21 @@ func (t *Topology) Connect() error {
234236

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

@@ -556,7 +572,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
556572
return suitable, nil
557573
}
558574

559-
func (t *Topology) pollSRVRecords() {
575+
func (t *Topology) pollSRVRecords(hosts string) {
560576
defer t.pollingwg.Done()
561577

562578
serverConfig := newServerConfig(t.cfg.ServerOpts...)
@@ -573,13 +589,6 @@ func (t *Topology) pollSRVRecords() {
573589
}
574590
}()
575591

576-
// remove the scheme
577-
uri := t.cfg.URI[14:]
578-
hosts := uri
579-
if idx := strings.IndexAny(uri, "/?@"); idx != -1 {
580-
hosts = uri[:idx]
581-
}
582-
583592
for {
584593
select {
585594
case <-pollTicker.C:

0 commit comments

Comments
 (0)