Skip to content

Commit 2517798

Browse files
regedajohnweldon
authored andcommitted
DialURL supports options to configure net.Dialer and tls.Config (#249)
1 parent 34eb223 commit 2517798

File tree

7 files changed

+270
-262
lines changed

7 files changed

+270
-262
lines changed

conn.go

+73-30
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,63 @@ var _ Client = &Conn{}
112112
// multiple places will probably result in undesired behaviour.
113113
var DefaultTimeout = 60 * time.Second
114114

115+
// DialOpt configures DialContext.
116+
type DialOpt func(*DialContext)
117+
118+
// DialWithDialer updates net.Dialer in DialContext.
119+
func DialWithDialer(d *net.Dialer) DialOpt {
120+
return func(dc *DialContext) {
121+
dc.d = d
122+
}
123+
}
124+
125+
// DialWithTLSConfig updates tls.Config in DialContext.
126+
func DialWithTLSConfig(tc *tls.Config) DialOpt {
127+
return func(dc *DialContext) {
128+
dc.tc = tc
129+
}
130+
}
131+
132+
// DialContext contains necessary parameters to dial the given ldap URL.
133+
type DialContext struct {
134+
d *net.Dialer
135+
tc *tls.Config
136+
}
137+
138+
func (dc *DialContext) dial(u *url.URL) (net.Conn, error) {
139+
if u.Scheme == "ldapi" {
140+
if u.Path == "" || u.Path == "/" {
141+
u.Path = "/var/run/slapd/ldapi"
142+
}
143+
return dc.d.Dial("unix", u.Path)
144+
}
145+
146+
host, port, err := net.SplitHostPort(u.Host)
147+
if err != nil {
148+
// we asume that error is due to missing port
149+
host = u.Host
150+
port = ""
151+
}
152+
153+
switch u.Scheme {
154+
case "ldap":
155+
if port == "" {
156+
port = DefaultLdapPort
157+
}
158+
return dc.d.Dial("tcp", net.JoinHostPort(host, port))
159+
case "ldaps":
160+
if port == "" {
161+
port = DefaultLdapsPort
162+
}
163+
return tls.DialWithDialer(dc.d, "tcp", net.JoinHostPort(host, port), dc.tc)
164+
}
165+
166+
return nil, fmt.Errorf("Unknown scheme '%s'", u.Scheme)
167+
}
168+
115169
// Dial connects to the given address on the given network using net.Dial
116170
// and then returns a new Conn for the connection.
171+
// @deprecated Use DialURL instead.
117172
func Dial(network, addr string) (*Conn, error) {
118173
c, err := net.DialTimeout(network, addr, DefaultTimeout)
119174
if err != nil {
@@ -126,6 +181,7 @@ func Dial(network, addr string) (*Conn, error) {
126181

127182
// DialTLS connects to the given address on the given network using tls.Dial
128183
// and then returns a new Conn for the connection.
184+
// @deprecated Use DialURL instead.
129185
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
130186
c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config)
131187
if err != nil {
@@ -136,44 +192,31 @@ func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
136192
return conn, nil
137193
}
138194

139-
// DialURL connects to the given ldap URL vie TCP using tls.Dial or net.Dial if ldaps://
140-
// or ldap:// specified as protocol. On success a new Conn for the connection
141-
// is returned.
142-
func DialURL(addr string) (*Conn, error) {
143-
lurl, err := url.Parse(addr)
195+
// DialURL connects to the given ldap URL.
196+
// The following schemas are supported: ldap://, ldaps://, ldapi://.
197+
// On success a new Conn for the connection is returned.
198+
func DialURL(addr string, opts ...DialOpt) (*Conn, error) {
199+
u, err := url.Parse(addr)
144200
if err != nil {
145201
return nil, NewError(ErrorNetwork, err)
146202
}
147203

148-
host, port, err := net.SplitHostPort(lurl.Host)
149-
if err != nil {
150-
// we asume that error is due to missing port
151-
host = lurl.Host
152-
port = ""
204+
var dc DialContext
205+
for _, opt := range opts {
206+
opt(&dc)
207+
}
208+
if dc.d == nil {
209+
dc.d = &net.Dialer{Timeout: DefaultTimeout}
153210
}
154211

155-
switch lurl.Scheme {
156-
case "ldapi":
157-
if lurl.Path == "" || lurl.Path == "/" {
158-
lurl.Path = "/var/run/slapd/ldapi"
159-
}
160-
return Dial("unix", lurl.Path)
161-
case "ldap":
162-
if port == "" {
163-
port = DefaultLdapPort
164-
}
165-
return Dial("tcp", net.JoinHostPort(host, port))
166-
case "ldaps":
167-
if port == "" {
168-
port = DefaultLdapsPort
169-
}
170-
tlsConf := &tls.Config{
171-
ServerName: host,
172-
}
173-
return DialTLS("tcp", net.JoinHostPort(host, port), tlsConf)
212+
c, err := dc.dial(u)
213+
if err != nil {
214+
return nil, NewError(ErrorNetwork, err)
174215
}
175216

176-
return nil, NewError(ErrorNetwork, fmt.Errorf("Unknown scheme '%s'", lurl.Scheme))
217+
conn := NewConn(c, u.Scheme == "ldaps")
218+
conn.Start()
219+
return conn, nil
177220
}
178221

179222
// NewConn returns a new Conn using conn for network I/O.

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module github.com/go-ldap/ldap
22

3-
require github.com/go-asn1-ber/asn1-ber v1.3.1
4-
53
go 1.13
4+
5+
require github.com/go-asn1-ber/asn1-ber v1.3.1

0 commit comments

Comments
 (0)