NewOutboundHttpClient returns an [http.Client] that validates every outbound request URL via the same logic as [FilterOutboundURL] and pins the resulting dial to the resolved IPs. The client re-validates redirect targets automatically because the underlying [http.Client] invokes the wrapping [http.
(timeout time.Duration, allowList, denyList []*regexp2.Regexp, opts ...DecideOption)
| 390 | // The default posture is permissive; callers pass [WithDenyPrivateIPs] |
| 391 | // or [WithDenyPublicIPs] to opt into IP-class rejection. |
| 392 | func NewOutboundHttpClient(timeout time.Duration, allowList, denyList []*regexp2.Regexp, opts ...DecideOption) *http.Client { |
| 393 | base := http.DefaultTransport.(*http.Transport).Clone() |
| 394 | base.DialContext = secureDialContext |
| 395 | return &http.Client{ |
| 396 | Timeout: timeout, |
| 397 | Transport: &outboundRoundTripper{ |
| 398 | base: base, |
| 399 | allowList: allowList, |
| 400 | denyList: denyList, |
| 401 | opts: opts, |
| 402 | }, |
| 403 | } |
| 404 | } |
| 405 | |
| 406 | // secureDialContext consumes the [OutboundDecision] stashed in ctx by |
| 407 | // [outboundRoundTripper]. When the decision is to bypass (allow-list |
no outgoing calls
no test coverage detected