aboutsummaryrefslogtreecommitdiff
path: root/src/net/lookup.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-04-16 11:57:06 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2016-04-28 20:56:38 +0000
commit1518d431321100cd9f0e18d740da7c835ba438dd (patch)
treedb1d8f1be8e5b3aeba6ef90c3f097f3c96676dce /src/net/lookup.go
parent1b591dfb1f071d978448966e979e40b1f265c1a5 (diff)
downloadgo-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.go44
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)
}
}