Skip to content

Commit fd3b030

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 fd05106 commit fd3b030

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
@@ -15,6 +15,8 @@ import (
1515
"errors"
1616
"fmt"
1717
"math/rand"
18+
"net"
19+
"net/url"
1820
"strings"
1921
"sync"
2022
"sync/atomic"
@@ -231,7 +233,21 @@ func (t *Topology) Connect() error {
231233

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

@@ -553,7 +569,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology,
553569
return suitable, nil
554570
}
555571

556-
func (t *Topology) pollSRVRecords() {
572+
func (t *Topology) pollSRVRecords(hosts string) {
557573
defer t.pollingwg.Done()
558574

559575
serverConfig := newServerConfig(t.cfg.serverOpts...)
@@ -570,13 +586,6 @@ func (t *Topology) pollSRVRecords() {
570586
}
571587
}()
572588

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

0 commit comments

Comments
 (0)