Tip
Use context.WithTimeout
when you need to enforce timeouts on internal operations like database queries or HTTP calls, especially when you want to propagate cancellation signals through the call stack to prevent resource leaks or manage goroutines. It's ideal for fine-grained control within a handler. In contrast, use http.TimeoutHandler
when you want a simple way to enforce a timeout on the entire HTTP handler response, particularly when you don’t control the handler logic or don’t need to cancel ongoing work—it only cuts off the response after the timeout but doesn’t stop the underlying processing.
Warning
Be careful when using http.TimeoutHander
. If automatically applied to all handlers (as part of a middleware pipeline) then it will not work when it comes to a streaming endpoint (see the relevant Cloudflare article linked in the NOTE below).
Note
Read the following articles:
Resilient HTTP servers using timeouts
Guide to net/http
timeouts
Also, here are some Transport settings you might want.
Although not explicitly stated, DNS resolution appears to be taken into consideration as part of the overall http.Client.Timeout
setting. If you need to set your own DNS timeout, then it seems https://github.com/miekg/dns is a popular solution.
Additionally, it's important to realise how golang resolves hostnames to IPs (i.e. DNS resolution):
https://golang.org/pkg/net/#hdr-Name_Resolution
When cross-compiling binaries you'll find that CGO is typically disabled in favour of the native Go resolver. You can enforce CGO or native like so:
env GODEBUG=netdns=cgo+2 go run main.go
env GODEBUG=netdns=go+2 go run main.go
@thepabloaguilar I think you might want to append errors to your
var err error
rather than reset it on each loop iteration...Otherwise, multiple servers might fail to resolve and you'd only know about the last one.
Also, one thing I discovered recently was the issue of truncation. See https://pkg.go.dev/github.com/miekg/dns#Client.Exchange
Check the implementation in this PR for an example:
domainr/dnsr#118