// Package probe measures per-phase HTTP request latency. package probe import ( "io" "net/http" "time" ) // Phase holds the measured duration of a single request phase. type Phase struct { Duration time.Duration // Present is false when the phase was skipped (e.g. no TLS for http://). Present bool } // Result holds all timing phases for a single HTTP request. type Result struct { URL string DNS Phase Connect Phase TLS Phase TTFB Phase // server processing: WroteRequest → GotFirstResponseByte Transfer Phase // body read: GotFirstResponseByte → body closed Total Phase // StatusCode is the HTTP response status code (0 on error). StatusCode int // Err is non-nil if the request failed. Err error } // Measure performs an HTTP GET to url and returns a Result. // In Step 1 only the Total phase is populated. func Measure(url string) Result { r := Result{URL: url} start := time.Now() resp, err := http.Get(url) //nolint:noctx if err != nil { r.Err = err r.Total = Phase{Duration: time.Since(start), Present: true} return r } defer resp.Body.Close() _, err = io.Copy(io.Discard, resp.Body) r.Total = Phase{Duration: time.Since(start), Present: true} r.StatusCode = resp.StatusCode if err != nil { r.Err = err } return r }