Source file
src/net/external_test.go
Documentation: net
1
2
3
4
5
6
7
8 package net
9
10 import (
11 "fmt"
12 "internal/testenv"
13 "io"
14 "strings"
15 "testing"
16 )
17
18 func TestResolveGoogle(t *testing.T) {
19 testenv.MustHaveExternalNetwork(t)
20
21 if !supportsIPv4() || !supportsIPv6() || !*testIPv4 || !*testIPv6 {
22 t.Skip("both IPv4 and IPv6 are required")
23 }
24
25 for _, network := range []string{"tcp", "tcp4", "tcp6"} {
26 addr, err := ResolveTCPAddr(network, "www.google.com:http")
27 if err != nil {
28 t.Error(err)
29 continue
30 }
31 switch {
32 case network == "tcp" && addr.IP.To4() == nil:
33 fallthrough
34 case network == "tcp4" && addr.IP.To4() == nil:
35 t.Errorf("got %v; want an IPv4 address on %s", addr, network)
36 case network == "tcp6" && (addr.IP.To16() == nil || addr.IP.To4() != nil):
37 t.Errorf("got %v; want an IPv6 address on %s", addr, network)
38 }
39 }
40 }
41
42 var dialGoogleTests = []struct {
43 dial func(string, string) (Conn, error)
44 unreachableNetwork string
45 networks []string
46 addrs []string
47 }{
48 {
49 dial: (&Dialer{DualStack: true}).Dial,
50 networks: []string{"tcp", "tcp4", "tcp6"},
51 addrs: []string{"www.google.com:http"},
52 },
53 {
54 dial: Dial,
55 unreachableNetwork: "tcp6",
56 networks: []string{"tcp", "tcp4"},
57 },
58 {
59 dial: Dial,
60 unreachableNetwork: "tcp4",
61 networks: []string{"tcp", "tcp6"},
62 },
63 }
64
65 func TestDialGoogle(t *testing.T) {
66 testenv.MustHaveExternalNetwork(t)
67
68 if !supportsIPv4() || !supportsIPv6() || !*testIPv4 || !*testIPv6 {
69 t.Skip("both IPv4 and IPv6 are required")
70 }
71
72 var err error
73 dialGoogleTests[1].addrs, dialGoogleTests[2].addrs, err = googleLiteralAddrs()
74 if err != nil {
75 t.Error(err)
76 }
77 for _, tt := range dialGoogleTests {
78 for _, network := range tt.networks {
79 disableSocketConnect(tt.unreachableNetwork)
80 for _, addr := range tt.addrs {
81 if err := fetchGoogle(tt.dial, network, addr); err != nil {
82 t.Error(err)
83 }
84 }
85 enableSocketConnect()
86 }
87 }
88 }
89
90 var (
91 literalAddrs4 = [...]string{
92 "%d.%d.%d.%d:80",
93 "www.google.com:80",
94 "%d.%d.%d.%d:http",
95 "www.google.com:http",
96 "%03d.%03d.%03d.%03d:0080",
97 "[::ffff:%d.%d.%d.%d]:80",
98 "[::ffff:%02x%02x:%02x%02x]:80",
99 "[0:0:0:0:0000:ffff:%d.%d.%d.%d]:80",
100 "[0:0:0:0:000000:ffff:%d.%d.%d.%d]:80",
101 "[0:0:0:0::ffff:%d.%d.%d.%d]:80",
102 }
103 literalAddrs6 = [...]string{
104 "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:80",
105 "ipv6.google.com:80",
106 "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:http",
107 "ipv6.google.com:http",
108 }
109 )
110
111 func googleLiteralAddrs() (lits4, lits6 []string, err error) {
112 ips, err := LookupIP("www.google.com")
113 if err != nil {
114 return nil, nil, err
115 }
116 if len(ips) == 0 {
117 return nil, nil, nil
118 }
119 var ip4, ip6 IP
120 for _, ip := range ips {
121 if ip4 == nil && ip.To4() != nil {
122 ip4 = ip.To4()
123 }
124 if ip6 == nil && ip.To16() != nil && ip.To4() == nil {
125 ip6 = ip.To16()
126 }
127 if ip4 != nil && ip6 != nil {
128 break
129 }
130 }
131 if ip4 != nil {
132 for i, lit4 := range literalAddrs4 {
133 if strings.Contains(lit4, "%") {
134 literalAddrs4[i] = fmt.Sprintf(lit4, ip4[0], ip4[1], ip4[2], ip4[3])
135 }
136 }
137 lits4 = literalAddrs4[:]
138 }
139 if ip6 != nil {
140 for i, lit6 := range literalAddrs6 {
141 if strings.Contains(lit6, "%") {
142 literalAddrs6[i] = fmt.Sprintf(lit6, ip6[0], ip6[1], ip6[2], ip6[3], ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15])
143 }
144 }
145 lits6 = literalAddrs6[:]
146 }
147 return
148 }
149
150 func fetchGoogle(dial func(string, string) (Conn, error), network, address string) error {
151 c, err := dial(network, address)
152 if err != nil {
153 return err
154 }
155 defer c.Close()
156 req := []byte("GET /robots.txt HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
157 if _, err := c.Write(req); err != nil {
158 return err
159 }
160 b := make([]byte, 1000)
161 n, err := io.ReadFull(c, b)
162 if err != nil {
163 return err
164 }
165 if n < 1000 {
166 return fmt.Errorf("short read from %s:%s->%s", network, c.RemoteAddr(), c.LocalAddr())
167 }
168 return nil
169 }
170
View as plain text