Copyright 2016 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package httptrace provides mechanisms to trace the events within HTTP client requests.
package httptrace

import (
	
	
	
	
	
	
	
)
unique type to prevent assignment.
type clientEventContextKey struct{}
ContextClientTrace returns the ClientTrace associated with the provided context. If none, it returns nil.
func ( context.Context) *ClientTrace {
	,  := .Value(clientEventContextKey{}).(*ClientTrace)
	return 
}
WithClientTrace returns a new context based on the provided parent ctx. HTTP client requests made with the returned context will use the provided trace hooks, in addition to any previous hooks registered with ctx. Any hooks defined in the provided trace will be called first.
func ( context.Context,  *ClientTrace) context.Context {
	if  == nil {
		panic("nil trace")
	}
	 := ContextClientTrace()
	.compose()

	 = context.WithValue(, clientEventContextKey{}, )
	if .hasNetHooks() {
		 := &nettrace.Trace{
			ConnectStart: .ConnectStart,
			ConnectDone:  .ConnectDone,
		}
		if .DNSStart != nil {
			.DNSStart = func( string) {
				.DNSStart(DNSStartInfo{Host: })
			}
		}
		if .DNSDone != nil {
			.DNSDone = func( []interface{},  bool,  error) {
				 := make([]net.IPAddr, len())
				for ,  := range  {
					[] = .(net.IPAddr)
				}
				.DNSDone(DNSDoneInfo{
					Addrs:     ,
					Coalesced: ,
					Err:       ,
				})
			}
		}
		 = context.WithValue(, nettrace.TraceKey{}, )
	}
	return 
}
ClientTrace is a set of hooks to run at various stages of an outgoing HTTP request. Any particular hook may be nil. Functions may be called concurrently from different goroutines and some may be called after the request has completed or failed. ClientTrace currently traces a single HTTP request & response during a single round trip and has no hooks that span a series of redirected requests. See https://blog.golang.org/http-tracing for more.
GetConn is called before a connection is created or retrieved from an idle pool. The hostPort is the "host:port" of the target or proxy. GetConn is called even if there's already an idle cached connection available.
	GetConn func(hostPort string)
GotConn is called after a successful connection is obtained. There is no hook for failure to obtain a connection; instead, use the error from Transport.RoundTrip.
PutIdleConn is called when the connection is returned to the idle pool. If err is nil, the connection was successfully returned to the idle pool. If err is non-nil, it describes why not. PutIdleConn is not called if connection reuse is disabled via Transport.DisableKeepAlives. PutIdleConn is called before the caller's Response.Body.Close call returns. For HTTP/2, this hook is not currently used.
	PutIdleConn func(err error)
GotFirstResponseByte is called when the first byte of the response headers is available.
Got100Continue is called if the server replies with a "100 Continue" response.
Got1xxResponse is called for each 1xx informational response header returned before the final non-1xx response. Got1xxResponse is called for "100 Continue" responses, even if Got100Continue is also defined. If it returns an error, the client request is aborted with that error value.
DNSStart is called when a DNS lookup begins.
DNSDone is called when a DNS lookup ends.
ConnectStart is called when a new connection's Dial begins. If net.Dialer.DualStack (IPv6 "Happy Eyeballs") support is enabled, this may be called multiple times.
	ConnectStart func(network, addr string)
ConnectDone is called when a new connection's Dial completes. The provided err indicates whether the connection completedly successfully. If net.Dialer.DualStack ("Happy Eyeballs") support is enabled, this may be called multiple times.
	ConnectDone func(network, addr string, err error)
TLSHandshakeStart is called when the TLS handshake is started. When connecting to an HTTPS site via an HTTP proxy, the handshake happens after the CONNECT request is processed by the proxy.
TLSHandshakeDone is called after the TLS handshake with either the successful handshake's connection state, or a non-nil error on handshake failure.
WroteHeaderField is called after the Transport has written each request header. At the time of this call the values might be buffered and not yet written to the network.
	WroteHeaderField func(key string, value []string)
WroteHeaders is called after the Transport has written all request headers.
	WroteHeaders func()
Wait100Continue is called if the Request specified "Expect: 100-continue" and the Transport has written the request headers but is waiting for "100 Continue" from the server before writing the request body.
WroteRequest is called with the result of writing the request and any body. It may be called multiple times in the case of retried requests.
WroteRequestInfo contains information provided to the WroteRequest hook.
Err is any error encountered while writing the Request.
compose modifies t such that it respects the previously-registered hooks in old, subject to the composition policy requested in t.Compose.
func ( *ClientTrace) ( *ClientTrace) {
	if  == nil {
		return
	}
	 := reflect.ValueOf().Elem()
	 := reflect.ValueOf().Elem()
	 := .Type()
	for  := 0;  < .NumField(); ++ {
		 := .Field()
		 := .Type()
		if .Kind() != reflect.Func {
			continue
		}
		 := .Field()
		if .IsNil() {
			continue
		}
		if .IsNil() {
			.Set()
			continue
		}
Make a copy of tf for tf to call. (Otherwise it creates a recursive call cycle and stack overflows)
		 := reflect.ValueOf(.Interface())
We need to call both tf and of in some order.
		 := reflect.MakeFunc(, func( []reflect.Value) []reflect.Value {
			.Call()
			return .Call()
		})
		.Field().Set()
	}
}
DNSStartInfo contains information about a DNS request.
type DNSStartInfo struct {
	Host string
}
DNSDoneInfo contains information about the results of a DNS lookup.
Addrs are the IPv4 and/or IPv6 addresses found in the DNS lookup. The contents of the slice should not be mutated.
Err is any error that occurred during the DNS lookup.
Coalesced is whether the Addrs were shared with another caller who was doing the same DNS lookup concurrently.
	Coalesced bool
}

func ( *ClientTrace) () bool {
	if  == nil {
		return false
	}
	return .DNSStart != nil || .DNSDone != nil || .ConnectStart != nil || .ConnectDone != nil
}
GotConnInfo is the argument to the ClientTrace.GotConn function and contains information about the obtained connection.
Conn is the connection that was obtained. It is owned by the http.Transport and should not be read, written or closed by users of ClientTrace.
Reused is whether this connection has been previously used for another HTTP request.
WasIdle is whether this connection was obtained from an idle pool.
IdleTime reports how long the connection was previously idle, if WasIdle is true.