Black Lives Matter. Support the Equal Justice Initiative.

Source file src/net/external_test.go

Documentation: net

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !js
     6  // +build !js
     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