NewDirect returns a new Direct client.
(opts Options)
| 299 | |
| 300 | // NewDirect returns a new Direct client. |
| 301 | func NewDirect(opts Options) (*Direct, error) { |
| 302 | if opts.ServerURL == "" { |
| 303 | return nil, errors.New("controlclient.New: no server URL specified") |
| 304 | } |
| 305 | if opts.GetMachinePrivateKey == nil { |
| 306 | return nil, errors.New("controlclient.New: no GetMachinePrivateKey specified") |
| 307 | } |
| 308 | if opts.Dialer == nil { |
| 309 | if testenv.InTest() { |
| 310 | panic("no Dialer") |
| 311 | } |
| 312 | return nil, errors.New("controlclient.New: no Dialer specified") |
| 313 | } |
| 314 | netMon := opts.Dialer.NetMon() |
| 315 | if netMon == nil { |
| 316 | if testenv.InTest() { |
| 317 | panic("no NetMon in Dialer") |
| 318 | } |
| 319 | return nil, errors.New("controlclient.New: Dialer has nil NetMon") |
| 320 | } |
| 321 | if opts.ControlKnobs == nil { |
| 322 | opts.ControlKnobs = &controlknobs.Knobs{} |
| 323 | } |
| 324 | opts.ServerURL = strings.TrimRight(opts.ServerURL, "/") |
| 325 | if opts.Clock == nil { |
| 326 | opts.Clock = tstime.StdClock{} |
| 327 | } |
| 328 | if opts.Logf == nil { |
| 329 | // TODO(apenwarr): remove this default and fail instead. |
| 330 | // TODO(bradfitz): ... but then it shouldn't be in Options. |
| 331 | opts.Logf = log.Printf |
| 332 | } |
| 333 | |
| 334 | dnsCache := &dnscache.Resolver{ |
| 335 | Forward: dnscache.Get().Forward, // use default cache's forwarder |
| 336 | UseLastGood: true, |
| 337 | LookupIPFallback: dnsfallback.MakeLookupFunc(opts.Logf, netMon), |
| 338 | Logf: opts.Logf, |
| 339 | } |
| 340 | |
| 341 | httpc := opts.HTTPTestClient |
| 342 | if httpc == nil && runtime.GOOS == "js" { |
| 343 | // In js/wasm, net/http.Transport (as of Go 1.18) will |
| 344 | // only use the browser's Fetch API if you're using |
| 345 | // the DefaultClient (or a client without dial hooks |
| 346 | // etc set). |
| 347 | httpc = http.DefaultClient |
| 348 | } |
| 349 | var interceptedDial *atomic.Bool |
| 350 | if httpc == nil { |
| 351 | tr := netutil.NewDefaultTransport() |
| 352 | if buildfeatures.HasUseProxy { |
| 353 | tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil() |
| 354 | if f, ok := feature.HookProxySetTransportGetProxyConnectHeader.GetOk(); ok { |
| 355 | f(tr) |
| 356 | } |
| 357 | } |
| 358 | if opts.ExtraRootCAs != nil { |
searching dependent graphs…