diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-04-09 16:43:22 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-04-09 16:43:22 +0000 |
commit | 9bafe5a81e42406b86a65ef14b011ed9acc96c5d (patch) | |
tree | 35478f4f4ff092374f748479debcda06b96dd6dd /libgo/go/net | |
parent | 10f47d3d1dc2e1267a32fa6459655b4645a9adad (diff) | |
parent | 3fa176b767e14e1d2491775978afac3e87892d1d (diff) | |
download | gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.zip gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.tar.gz gcc-9bafe5a81e42406b86a65ef14b011ed9acc96c5d.tar.bz2 |
Merge from trunk revision 270220.
From-SVN: r270233
Diffstat (limited to 'libgo/go/net')
-rw-r--r-- | libgo/go/net/http/httputil/reverseproxy.go | 5 | ||||
-rw-r--r-- | libgo/go/net/http/httputil/reverseproxy_test.go | 42 | ||||
-rw-r--r-- | libgo/go/net/interface_aix.go | 8 | ||||
-rw-r--r-- | libgo/go/net/interface_stub.go | 2 | ||||
-rw-r--r-- | libgo/go/net/lookup.go | 5 | ||||
-rw-r--r-- | libgo/go/net/lookup_test.go | 89 | ||||
-rw-r--r-- | libgo/go/net/sockoptip_aix.go | 15 |
7 files changed, 131 insertions, 35 deletions
diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go index 4e10bf3..4b165d6 100644 --- a/libgo/go/net/http/httputil/reverseproxy.go +++ b/libgo/go/net/http/httputil/reverseproxy.go @@ -389,6 +389,11 @@ func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval latency: flushInterval, } defer mlw.stop() + + // set up initial timer so headers get flushed even if body writes are delayed + mlw.flushPending = true + mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush) + dst = mlw } } diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go index 5edefa0..367ba73 100644 --- a/libgo/go/net/http/httputil/reverseproxy_test.go +++ b/libgo/go/net/http/httputil/reverseproxy_test.go @@ -9,6 +9,7 @@ package httputil import ( "bufio" "bytes" + "context" "errors" "fmt" "io" @@ -317,6 +318,47 @@ func TestReverseProxyFlushInterval(t *testing.T) { } } +func TestReverseProxyFlushIntervalHeaders(t *testing.T) { + const expected = "hi" + stopCh := make(chan struct{}) + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("MyHeader", expected) + w.WriteHeader(200) + w.(http.Flusher).Flush() + <-stopCh + })) + defer backend.Close() + defer close(stopCh) + + backendURL, err := url.Parse(backend.URL) + if err != nil { + t.Fatal(err) + } + + proxyHandler := NewSingleHostReverseProxy(backendURL) + proxyHandler.FlushInterval = time.Microsecond + + frontend := httptest.NewServer(proxyHandler) + defer frontend.Close() + + req, _ := http.NewRequest("GET", frontend.URL, nil) + req.Close = true + + ctx, cancel := context.WithTimeout(req.Context(), 10*time.Second) + defer cancel() + req = req.WithContext(ctx) + + res, err := frontend.Client().Do(req) + if err != nil { + t.Fatalf("Get: %v", err) + } + defer res.Body.Close() + + if res.Header.Get("MyHeader") != expected { + t.Errorf("got header %q; expected %q", res.Header.Get("MyHeader"), expected) + } +} + func TestReverseProxyCancelation(t *testing.T) { const backendResponse = "I am the backend" diff --git a/libgo/go/net/interface_aix.go b/libgo/go/net/interface_aix.go index 9a8b5bb..1fe9bba 100644 --- a/libgo/go/net/interface_aix.go +++ b/libgo/go/net/interface_aix.go @@ -32,6 +32,8 @@ const _RTAX_NETMASK = 2 const _RTAX_IFA = 5 const _RTAX_MAX = 8 +const _SIOCGIFMTU = -0x3fd796aa + func getIfList() ([]byte, error) { needed, err := syscall.Getkerninfo(_KINFO_RT_IFLIST, 0, 0, 0) if err != nil { @@ -62,7 +64,7 @@ func interfaceTable(ifindex int) ([]Interface, error) { } if ifm.Type == syscall.RTM_IFINFO { if ifindex == 0 || ifindex == int(ifm.Index) { - sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[syscall.SizeofIfMsghdr])) + sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[unsafe.Sizeof(syscall.IfMsgHdr)])) ifi := &Interface{Index: int(ifm.Index), Flags: linkFlags(ifm.Flags)} ifi.Name = string(sdl.Data[:sdl.Nlen]) @@ -75,7 +77,7 @@ func interfaceTable(ifindex int) ([]Interface, error) { if err != nil { return nil, err } - err = unix.Ioctl(sock, syscall.SIOCGIFMTU, uintptr(unsafe.Pointer(ifr))) + err = unix.Ioctl(sock, _SIOCGIFMTU, uintptr(unsafe.Pointer(ifr))) if err != nil { return nil, err } @@ -131,7 +133,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) { if ifm.Type == syscall.RTM_NEWADDR { if ifi == nil || ifi.Index == int(ifm.Index) { mask := ifm.Addrs - off := uint(syscall.SizeofIfMsghdr) + off := uint(unsafe.Sizeof(syscall.IfMsgHdr)) var iprsa, nmrsa *syscall.RawSockaddr for i := uint(0); i < _RTAX_MAX; i++ { diff --git a/libgo/go/net/interface_stub.go b/libgo/go/net/interface_stub.go index 0b3580e..d8afd5e 100644 --- a/libgo/go/net/interface_stub.go +++ b/libgo/go/net/interface_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix nacl hurd js,wasm +// +build nacl hurd js,wasm package net diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index e108893..08e8d01 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/net/lookup.go @@ -262,8 +262,9 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP // only the values in context. See Issue 28600. lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx)) + lookupKey := network + "\000" + host dnsWaitGroup.Add(1) - ch, called := r.getLookupGroup().DoChan(host, func() (interface{}, error) { + ch, called := r.getLookupGroup().DoChan(lookupKey, func() (interface{}, error) { defer dnsWaitGroup.Done() return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host) }) @@ -280,7 +281,7 @@ func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IP // let the lookup continue uncanceled, and let later // lookups with the same key share the result. // See issues 8602, 20703, 22724. - if r.getLookupGroup().ForgetUnshared(host) { + if r.getLookupGroup().ForgetUnshared(lookupKey) { lookupGroupCancel() } else { go func() { diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index 85bcb2b..28a895e 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -16,6 +16,7 @@ import ( "sort" "strings" "sync" + "sync/atomic" "testing" "time" ) @@ -253,14 +254,11 @@ func TestLookupGmailTXT(t *testing.T) { } } -var lookupGooglePublicDNSAddrTests = []struct { - addr, name string -}{ - {"8.8.8.8", ".google.com."}, - {"8.8.4.4", ".google.com."}, - - {"2001:4860:4860::8888", ".google.com."}, - {"2001:4860:4860::8844", ".google.com."}, +var lookupGooglePublicDNSAddrTests = []string{ + "8.8.8.8", + "8.8.4.4", + "2001:4860:4860::8888", + "2001:4860:4860::8844", } func TestLookupGooglePublicDNSAddr(t *testing.T) { @@ -272,8 +270,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) { defer dnsWaitGroup.Wait() - for _, tt := range lookupGooglePublicDNSAddrTests { - names, err := LookupAddr(tt.addr) + for _, ip := range lookupGooglePublicDNSAddrTests { + names, err := LookupAddr(ip) if err != nil { t.Fatal(err) } @@ -281,8 +279,8 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) { t.Error("got no record") } for _, name := range names { - if !strings.HasSuffix(name, tt.name) { - t.Errorf("got %s; want a record containing %s", name, tt.name) + if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") { + t.Errorf("got %q; want a record ending in .google.com. or .google.", name) } } } @@ -658,8 +656,8 @@ func testDots(t *testing.T, mode string) { t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode) } else { for _, name := range names { - if !strings.HasSuffix(name, ".google.com.") { - t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode) + if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") { + t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com or .google with trailing dot (mode=%v)", names, mode) break } } @@ -1096,6 +1094,69 @@ func TestLookupIPAddrPreservesContextValues(t *testing.T) { } } +// Issue 30521: The lookup group should call the resolver for each network. +func TestLookupIPAddrConcurrentCallsForNetworks(t *testing.T) { + origTestHookLookupIP := testHookLookupIP + defer func() { testHookLookupIP = origTestHookLookupIP }() + + queries := [][]string{ + {"udp", "golang.org"}, + {"udp4", "golang.org"}, + {"udp6", "golang.org"}, + {"udp", "golang.org"}, + {"udp", "golang.org"}, + } + results := map[[2]string][]IPAddr{ + {"udp", "golang.org"}: { + {IP: IPv4(127, 0, 0, 1)}, + {IP: IPv6loopback}, + }, + {"udp4", "golang.org"}: { + {IP: IPv4(127, 0, 0, 1)}, + }, + {"udp6", "golang.org"}: { + {IP: IPv6loopback}, + }, + } + calls := int32(0) + waitCh := make(chan struct{}) + testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) { + // We'll block until this is called one time for each different + // expected result. This will ensure that the lookup group would wait + // for the existing call if it was to be reused. + if atomic.AddInt32(&calls, 1) == int32(len(results)) { + close(waitCh) + } + select { + case <-waitCh: + case <-ctx.Done(): + return nil, ctx.Err() + } + return results[[2]string{network, host}], nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + wg := sync.WaitGroup{} + for _, q := range queries { + network := q[0] + host := q[1] + wg.Add(1) + go func() { + defer wg.Done() + gotIPs, err := DefaultResolver.lookupIPAddr(ctx, network, host) + if err != nil { + t.Errorf("lookupIPAddr(%v, %v): unexpected error: %v", network, host, err) + } + wantIPs := results[[2]string{network, host}] + if !reflect.DeepEqual(gotIPs, wantIPs) { + t.Errorf("lookupIPAddr(%v, %v): mismatched IPAddr results\n\tGot: %v\n\tWant: %v", network, host, gotIPs, wantIPs) + } + }() + } + wg.Wait() +} + func TestWithUnexpiredValuesPreserved(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/libgo/go/net/sockoptip_aix.go b/libgo/go/net/sockoptip_aix.go deleted file mode 100644 index 1e28fe6..0000000 --- a/libgo/go/net/sockoptip_aix.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 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 net - -import "syscall" - -func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { - return syscall.ENOPROTOOPT -} - -func setIPv4MulticastLoopback(fd *netFD, v bool) error { - return syscall.ENOPROTOOPT -} |