diff --git a/request.go b/request.go index ed475e52..ad578a9b 100644 --- a/request.go +++ b/request.go @@ -1242,15 +1242,30 @@ func (r *Request) TraceInfo() TraceInfo { } ti := TraceInfo{ - DNSLookup: ct.dnsDone.Sub(ct.dnsStart), - TLSHandshake: ct.tlsHandshakeDone.Sub(ct.tlsHandshakeStart), - ServerTime: ct.gotFirstResponseByte.Sub(ct.gotConn), IsConnReused: ct.gotConnInfo.Reused, IsConnWasIdle: ct.gotConnInfo.WasIdle, ConnIdleTime: ct.gotConnInfo.IdleTime, RequestAttempt: r.Attempt, } + if !ct.dnsStart.IsZero() && !ct.dnsDone.IsZero() { + ti.DNSLookup = ct.dnsDone.Sub(ct.dnsStart) + } else { + ti.DNSLookup = 0 + } + + if !ct.tlsHandshakeDone.IsZero() && !ct.tlsHandshakeStart.IsZero() { + ti.TLSHandshake = ct.tlsHandshakeDone.Sub(ct.tlsHandshakeStart) + } else { + ti.TLSHandshake = 0 + } + + if !ct.gotFirstResponseByte.IsZero() && !ct.gotConn.IsZero() { + ti.ServerTime = ct.gotFirstResponseByte.Sub(ct.gotConn) + } else { + ti.ServerTime = 0 + } + // Calculate the total time accordingly when connection is reused, // and DNS start and get conn time may be zero if the request is invalid. // See issue #1016. diff --git a/request_test.go b/request_test.go index 215e04f1..ef013ddb 100644 --- a/request_test.go +++ b/request_test.go @@ -1927,6 +1927,28 @@ func TestTraceInfoOnTimeout(t *testing.T) { assertEqual(t, true, tr.TotalTime == resp.Duration()) } +func TestTraceInfoOnTimeoutWithSetTimeout(t *testing.T) { + client := New(). + SetTimeout(1 * time.Millisecond). + SetBaseURL("http://resty-nowhere.local"). + EnableTrace() + + resp, err := client.R().Get("/") + assertNotNil(t, err) + assertNotNil(t, resp) + + tr := resp.Request.TraceInfo() + + assertEqual(t, true, tr.DNSLookup == 0) + assertEqual(t, true, tr.ConnTime == 0) + assertEqual(t, true, tr.TLSHandshake == 0) + assertEqual(t, true, tr.TCPConnTime == 0) + assertEqual(t, true, tr.ServerTime == 0) + assertEqual(t, true, tr.ResponseTime == 0) + assertEqual(t, true, tr.TotalTime > 0) + assertEqual(t, true, tr.TotalTime == resp.Duration()) +} + func TestDebugLoggerRequestBodyTooLarge(t *testing.T) { formTs := createFormPostServer(t) defer formTs.Close()