diff options
author | Brad Fitzpatrick <bradfitz@golang.org> | 2016-04-16 11:57:06 -0700 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2016-04-28 20:56:38 +0000 |
commit | 1518d431321100cd9f0e18d740da7c835ba438dd (patch) | |
tree | db1d8f1be8e5b3aeba6ef90c3f097f3c96676dce /src/net/lookup.go | |
parent | 1b591dfb1f071d978448966e979e40b1f265c1a5 (diff) | |
download | go-1518d431321100cd9f0e18d740da7c835ba438dd.tar.gz go-1518d431321100cd9f0e18d740da7c835ba438dd.zip |
net/http, net/http/httptrace: new package for tracing HTTP client requests
Updates #12580
Change-Id: I9f9578148ef2b48dffede1007317032d39f6af55
Reviewed-on: https://go-review.googlesource.com/22191
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Tom Bergan <tombergan@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/net/lookup.go')
-rw-r--r-- | src/net/lookup.go | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src/net/lookup.go b/src/net/lookup.go index 5e60011165..c169e9e902 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -6,6 +6,7 @@ package net import ( "context" + "internal/nettrace" "internal/singleflight" ) @@ -85,16 +86,37 @@ func lookupIPReturn(addrsi interface{}, err error, shared bool) ([]IPAddr, error return addrs, nil } +// ipAddrsEface returns an empty interface slice of addrs. +func ipAddrsEface(addrs []IPAddr) []interface{} { + s := make([]interface{}, len(addrs)) + for i, v := range addrs { + s[i] = v + } + return s +} + // lookupIPContext looks up a hostname with a context. +// +// TODO(bradfitz): rename this function. All the other +// build-tag-specific lookupIP funcs also take a context now, so this +// name is no longer great. Maybe make this lookupIPMerge and ditch +// the other one, making its callers call this instead with a +// context.Background(). func lookupIPContext(ctx context.Context, host string) (addrs []IPAddr, err error) { - // TODO(bradfitz): when adding trace hooks later here, make - // sure the tracing is done outside of the singleflight - // merging. Both callers should see the DNS lookup delay, even - // if it's only being done once. The r.Shared bit can be - // included in the trace for callers who need it. + trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace) + if trace != nil && trace.DNSStart != nil { + trace.DNSStart(host) + } + // The underlying resolver func is lookupIP by default but it + // can be overridden by tests. This is needed by net/http, so it + // uses a context key instead of unexported variables. + resolverFunc := lookupIP + if alt, _ := ctx.Value(nettrace.LookupIPAltResolverKey{}).(func(context.Context, string) ([]IPAddr, error)); alt != nil { + resolverFunc = alt + } ch := lookupGroup.DoChan(host, func() (interface{}, error) { - return testHookLookupIP(ctx, lookupIP, host) + return testHookLookupIP(ctx, resolverFunc, host) }) select { @@ -103,9 +125,17 @@ func lookupIPContext(ctx context.Context, host string) (addrs []IPAddr, err erro // future requests to start the DNS lookup again // rather than waiting for the current lookup to // complete. See issue 8602. + err := mapErr(ctx.Err()) lookupGroup.Forget(host) - return nil, mapErr(ctx.Err()) + if trace != nil && trace.DNSDone != nil { + trace.DNSDone(nil, false, err) + } + return nil, err case r := <-ch: + if trace != nil && trace.DNSDone != nil { + addrs, _ := r.Val.([]IPAddr) + trace.DNSDone(ipAddrsEface(addrs), r.Shared, r.Err) + } return lookupIPReturn(r.Val, r.Err, r.Shared) } } |