73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptrace"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
type RequestTrace struct {
|
|
Started time.Time
|
|
DNSStart time.Time
|
|
DNSDone time.Time
|
|
ConnectStart time.Time
|
|
ConnectDone time.Time
|
|
TLSStart time.Time
|
|
TLSDone time.Time
|
|
WroteHeaders time.Time
|
|
FirstByte time.Time
|
|
AllDone time.Time
|
|
}
|
|
|
|
func (t RequestTrace) ConnectionReady() time.Time {
|
|
if t.TLSDone.After(t.ConnectDone) {
|
|
return t.TLSDone
|
|
}
|
|
return t.ConnectDone
|
|
}
|
|
|
|
func TraceRequest(uri *url.URL) (RequestTrace, error) {
|
|
var trace RequestTrace
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
|
|
ctx = httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
|
|
GotConn: func(info httptrace.GotConnInfo) { trace.Started = time.Now() },
|
|
DNSStart: func(info httptrace.DNSStartInfo) { trace.DNSStart = time.Now() },
|
|
DNSDone: func(info httptrace.DNSDoneInfo) { trace.DNSDone = time.Now() },
|
|
ConnectStart: func(network, addr string) { trace.ConnectStart = time.Now() },
|
|
ConnectDone: func(network, addr string, err error) { trace.ConnectDone = time.Now() },
|
|
TLSHandshakeStart: func() { trace.TLSStart = time.Now() },
|
|
TLSHandshakeDone: func(tls.ConnectionState, error) { trace.TLSDone = time.Now() },
|
|
WroteHeaders: func() { trace.WroteHeaders = time.Now() },
|
|
GotFirstResponseByte: func() { trace.FirstByte = time.Now() },
|
|
})
|
|
|
|
req, err := http.NewRequest("GET", uri.String(), nil)
|
|
req = req.WithContext(ctx)
|
|
|
|
if err != nil {
|
|
return trace, err
|
|
}
|
|
|
|
t := http.DefaultTransport.(*http.Transport).Clone()
|
|
t.DisableKeepAlives = true
|
|
c := &http.Client{Transport: t}
|
|
|
|
resp, err := c.Do(req)
|
|
if err != nil {
|
|
return trace, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
io.Copy(io.Discard, resp.Body)
|
|
trace.AllDone = time.Now()
|
|
|
|
return trace, nil
|
|
}
|