diff --git a/vendor/cmd/go/internal/webtest/test.go b/vendor/cmd/go/internal/webtest/test.go
new file mode 100644
index 0000000..94b20a3
--- /dev/null
+++ b/vendor/cmd/go/internal/webtest/test.go
@@ -0,0 +1,314 @@
+// Copyright 2018 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 webtest
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/hex"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"os"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode/utf8"
+
+	web "cmd/go/internal/web2"
+)
+
+var mode = flag.String("webtest", "replay", "set webtest `mode` - record, replay, bypass")
+
+func Hook() {
+	if *mode == "bypass" {
+		return
+	}
+	web.SetHTTPDoForTesting(Do)
+}
+
+func Unhook() {
+	web.SetHTTPDoForTesting(nil)
+}
+
+func Print() {
+	web.SetHTTPDoForTesting(DoPrint)
+}
+
+var responses struct {
+	mu    sync.Mutex
+	byURL map[string]*respEntry
+}
+
+type respEntry struct {
+	status string
+	code   int
+	hdr    http.Header
+	body   []byte
+}
+
+func Serve(url string, status string, hdr http.Header, body []byte) {
+	if status == "" {
+		status = "200 OK"
+	}
+	code, err := strconv.Atoi(strings.Fields(status)[0])
+	if err != nil {
+		panic("bad Serve status - " + status + " - " + err.Error())
+	}
+
+	responses.mu.Lock()
+	defer responses.mu.Unlock()
+
+	if responses.byURL == nil {
+		responses.byURL = make(map[string]*respEntry)
+	}
+	responses.byURL[url] = &respEntry{status: status, code: code, hdr: web.CopyHeader(hdr), body: body}
+}
+
+func Do(req *http.Request) (*http.Response, error) {
+	if req.Method != "GET" {
+		return nil, fmt.Errorf("bad method - must be GET")
+	}
+
+	responses.mu.Lock()
+	e := responses.byURL[req.URL.String()]
+	responses.mu.Unlock()
+
+	if e == nil {
+		if *mode == "record" {
+			loaded.mu.Lock()
+			if len(loaded.did) != 1 {
+				loaded.mu.Unlock()
+				return nil, fmt.Errorf("cannot use -webtest=record with multiple loaded response files")
+			}
+			var file string
+			for file = range loaded.did {
+				break
+			}
+			loaded.mu.Unlock()
+			return doSave(file, req)
+		}
+		e = &respEntry{code: 599, status: "599 unexpected request (no canned response)"}
+	}
+	resp := &http.Response{
+		Status:     e.status,
+		StatusCode: e.code,
+		Header:     web.CopyHeader(e.hdr),
+		Body:       ioutil.NopCloser(bytes.NewReader(e.body)),
+	}
+	return resp, nil
+}
+
+func DoPrint(req *http.Request) (*http.Response, error) {
+	return doSave("", req)
+}
+
+func doSave(file string, req *http.Request) (*http.Response, error) {
+	resp, err := http.DefaultClient.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	data, err := ioutil.ReadAll(resp.Body)
+	resp.Body.Close()
+	if err != nil {
+		return nil, err
+	}
+	resp.Body = ioutil.NopCloser(bytes.NewReader(data))
+
+	var f *os.File
+	if file == "" {
+		f = os.Stderr
+	} else {
+		f, err = os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer f.Close()
+	}
+
+	fmt.Fprintf(f, "GET %s\n", req.URL.String())
+	fmt.Fprintf(f, "%s\n", resp.Status)
+	var keys []string
+	for k := range resp.Header {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		if k == "Set-Cookie" {
+			continue
+		}
+		for _, v := range resp.Header[k] {
+			fmt.Fprintf(f, "%s: %s\n", k, v)
+		}
+	}
+	fmt.Fprintf(f, "\n")
+	if utf8.Valid(data) && !bytes.Contains(data, []byte("\nGET")) && !isHexDump(data) {
+		fmt.Fprintf(f, "%s\n\n", data)
+	} else {
+		fmt.Fprintf(f, "%s\n", hex.Dump(data))
+	}
+	return resp, err
+}
+
+var loaded struct {
+	mu  sync.Mutex
+	did map[string]bool
+}
+
+func LoadOnce(file string) {
+	loaded.mu.Lock()
+	if loaded.did[file] {
+		loaded.mu.Unlock()
+		return
+	}
+	if loaded.did == nil {
+		loaded.did = make(map[string]bool)
+	}
+	loaded.did[file] = true
+	loaded.mu.Unlock()
+
+	f, err := os.Open(file)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f.Close()
+
+	b := bufio.NewReader(f)
+	var ungetLine string
+	nextLine := func() string {
+		if ungetLine != "" {
+			l := ungetLine
+			ungetLine = ""
+			return l
+		}
+		line, err := b.ReadString('\n')
+		if err != nil {
+			if err == io.EOF {
+				return ""
+			}
+			log.Fatalf("%s: unexpected read error: %v", file, err)
+		}
+		return line
+	}
+
+	for {
+		line := nextLine()
+		if line == "" { // EOF
+			break
+		}
+		line = strings.TrimSpace(line)
+		if strings.HasPrefix(line, "#") || line == "" {
+			continue
+		}
+		if !strings.HasPrefix(line, "GET ") {
+			log.Fatalf("%s: malformed GET line: %s", file, line)
+		}
+		url := line[len("GET "):]
+		status := nextLine()
+		if _, err := strconv.Atoi(strings.Fields(status)[0]); err != nil {
+			log.Fatalf("%s: malformed status line (after GET %s): %s", file, url, status)
+		}
+		hdr := make(http.Header)
+		for {
+			kv := strings.TrimSpace(nextLine())
+			if kv == "" {
+				break
+			}
+			i := strings.Index(kv, ":")
+			if i < 0 {
+				log.Fatalf("%s: malformed header line (after GET %s): %s", file, url, kv)
+			}
+			k, v := kv[:i], strings.TrimSpace(kv[i+1:])
+			hdr[k] = append(hdr[k], v)
+		}
+
+		var body []byte
+	Body:
+		for n := 0; ; n++ {
+			line := nextLine()
+			if n == 0 && isHexDump([]byte(line)) {
+				ungetLine = line
+				b, err := parseHexDump(nextLine)
+				if err != nil {
+					log.Fatalf("%s: malformed hex dump (after GET %s): %v", file, url, err)
+				}
+				body = b
+				break
+			}
+			if line == "" { // EOF
+				for i := 0; i < 2; i++ {
+					if len(body) > 0 && body[len(body)-1] == '\n' {
+						body = body[:len(body)-1]
+					}
+				}
+				break
+			}
+			body = append(body, line...)
+			for line == "\n" {
+				line = nextLine()
+				if strings.HasPrefix(line, "GET ") {
+					ungetLine = line
+					body = body[:len(body)-1]
+					if len(body) > 0 {
+						body = body[:len(body)-1]
+					}
+					break Body
+				}
+				body = append(body, line...)
+			}
+		}
+
+		Serve(url, status, hdr, body)
+	}
+}
+
+func isHexDump(data []byte) bool {
+	return bytes.HasPrefix(data, []byte("00000000  ")) || bytes.HasPrefix(data, []byte("0000000 "))
+}
+
+// parseHexDump parses the hex dump in text, which should be the
+// output of "hexdump -C" or Plan 9's "xd -b" or Go's hex.Dump
+// and returns the original data used to produce the dump.
+// It is meant to enable storing golden binary files as text, so that
+// changes to the golden files can be seen during code reviews.
+func parseHexDump(nextLine func() string) ([]byte, error) {
+	var out []byte
+	for {
+		line := nextLine()
+		if line == "" || line == "\n" {
+			break
+		}
+		if i := strings.Index(line, "|"); i >= 0 { // remove text dump
+			line = line[:i]
+		}
+		f := strings.Fields(line)
+		if len(f) > 1+16 {
+			return nil, fmt.Errorf("parsing hex dump: too many fields on line %q", line)
+		}
+		if len(f) == 0 || len(f) == 1 && f[0] == "*" { // all zeros block omitted
+			continue
+		}
+		addr64, err := strconv.ParseUint(f[0], 16, 0)
+		if err != nil {
+			return nil, fmt.Errorf("parsing hex dump: invalid address %q", f[0])
+		}
+		addr := int(addr64)
+		if len(out) < addr {
+			out = append(out, make([]byte, addr-len(out))...)
+		}
+		for _, x := range f[1:] {
+			val, err := strconv.ParseUint(x, 16, 8)
+			if err != nil {
+				return nil, fmt.Errorf("parsing hexdump: invalid hex byte %q", x)
+			}
+			out = append(out, byte(val))
+		}
+	}
+	return out, nil
+}
