Getting started¶
This tutorial builds a hardened HTTP client, makes a request through it, and adds
automatic retry — enough to see what the factory gives you for free and how the
go/transit middleware layers on.
Install¶
A hardened client¶
NewClient returns an ordinary *http.Client — you use it exactly as you would the
standard library's, but it arrives secured:
package main
import (
"fmt"
"gitlab.com/phpboyscout/go/httpclient"
)
func main() {
client := httpclient.NewClient()
resp, err := client.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}
Out of the box that client enforces a TLS 1.2 floor with curated cipher suites, bounded connection pools and timeouts, and a redirect policy that caps redirects and refuses an HTTPS→HTTP downgrade. You did not opt in to any of it — see hardened defaults for the full list.
Add retry¶
Transient failures (429/502/503/504 and transient network errors) are common against
real services. WithRetry installs the go/transit retry transport — exponential
backoff with full jitter, honouring Retry-After:
import transithttp "gitlab.com/phpboyscout/go/transit/http"
client := httpclient.NewClient(
httpclient.WithRetry(transithttp.DefaultRetryConfig()),
)
DefaultRetryConfig() is three retries with a 500ms→30s backoff. The retry config is a
go/transit type because the retry behaviour lives in that module; this factory just
wires it into the client's transport.
Trust a private CA¶
For a service behind a private certificate authority, add its pool without giving up the hardened TLS defaults:
pool, _ := gtls.CertPool("/etc/pki/internal-ca.pem") // gitlab.com/phpboyscout/go/tls
client := httpclient.NewClient(httpclient.WithCertPool(pool))
Where next¶
- Compose client middleware — stack retry, the circuit breaker, credentials and logging in the correct order.
- Hardened defaults & the factory model — the reasoning behind the split between this factory and the transit middleware.