Skip to content

Commit 2952197

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 497afc9 commit 2952197

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,22 @@ func TestPollingSRVRecordsSpec(t *testing.T) {
128128
if testing.Short() {
129129
t.Skip("skipping integration test in short mode")
130130
}
131+
for _, uri := range []string{
132+
"mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100",
133+
// Test with user:pass as a regression test for GODRIVER-2620
134+
"mongodb+srv://user:[email protected]/?heartbeatFrequencyMS=100",
135+
} {
136+
t.Run(uri, func(t *testing.T) {
137+
testPollingSRVRecordsSpec(t, uri)
138+
})
139+
}
140+
}
141+
142+
func testPollingSRVRecordsSpec(t *testing.T, uri string) {
143+
t.Helper()
131144
for _, tt := range srvPollingTests {
132145
t.Run(tt.name, func(t *testing.T) {
133-
cs, err := connstring.ParseAndValidate("mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100")
146+
cs, err := connstring.ParseAndValidate(uri)
134147
require.NoError(t, err, "Problem parsing the uri: %v", err)
135148
topo, err := New(
136149
WithConnString(func(connstring.ConnString) connstring.ConnString { return cs }),

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
"math/rand"
17+
"net"
18+
"net/url"
1719
"strings"
1820
"sync"
1921
"sync/atomic"
@@ -224,7 +226,21 @@ func (t *Topology) Connect() error {
224226

225227
t.serversLock.Unlock()
226228
if t.pollingRequired {
227-
go t.pollSRVRecords()
229+
uri, err := url.Parse(t.cfg.uri)
230+
if err != nil {
231+
return err
232+
}
233+
// sanity check before passing the hostname to resolver
234+
if parsedHosts := strings.Split(uri.Host, ","); len(parsedHosts) != 1 {
235+
return fmt.Errorf("URI with SRV must include one and only one hostname")
236+
}
237+
_, _, err = net.SplitHostPort(uri.Host)
238+
if err == nil {
239+
// we were able to successfully extract a port from the host,
240+
// but should not be able to when using SRV
241+
return fmt.Errorf("URI with srv must not include a port number")
242+
}
243+
go t.pollSRVRecords(uri.Host)
228244
t.pollingwg.Add(1)
229245
}
230246

@@ -495,7 +511,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
495511
return suitable, nil
496512
}
497513

498-
func (t *Topology) pollSRVRecords() {
514+
func (t *Topology) pollSRVRecords(hosts string) {
499515
defer t.pollingwg.Done()
500516

501517
serverConfig, _ := newServerConfig(t.cfg.serverOpts...)
@@ -512,13 +528,6 @@ func (t *Topology) pollSRVRecords() {
512528
}
513529
}()
514530

515-
// remove the scheme
516-
uri := t.cfg.uri[14:]
517-
hosts := uri
518-
if idx := strings.IndexAny(uri, "/?@"); idx != -1 {
519-
hosts = uri[:idx]
520-
}
521-
522531
for {
523532
select {
524533
case <-pollTicker.C:

0 commit comments

Comments
 (0)