if err != nil {
                        return err
                }
-               if src == filepath.Join(runtime.GOROOT(), ".git") {
+               if info.IsDir() && src == filepath.Join(runtime.GOROOT(), ".git") {
                        return filepath.SkipDir
                }
 
                }
                dst := filepath.Join(gorootCopyDir, rel)
 
-               switch src {
-               case filepath.Join(runtime.GOROOT(), "bin"),
-                       filepath.Join(runtime.GOROOT(), "pkg"):
+               if info.IsDir() && (src == filepath.Join(runtime.GOROOT(), "bin") ||
+                       src == filepath.Join(runtime.GOROOT(), "pkg")) {
                        // If the OS supports symlinks, use them instead
                        // of copying the bin and pkg directories.
                        if err := os.Symlink(src, dst); err == nil {
                        if info.IsDir() && (info.Name() == "vendor" || info.Name() == "testdata") {
                                return filepath.SkipDir
                        }
-                       if path == filepath.Join(runtime.GOROOT(), "pkg") {
+                       if info.IsDir() && path == filepath.Join(runtime.GOROOT(), "pkg") {
                                // GOROOT/pkg contains generated artifacts, not source code.
                                //
                                // In https://golang.org/issue/37929 it was observed to somehow contain
                                // running time of this test anyway.)
                                return filepath.SkipDir
                        }
-                       if strings.HasPrefix(info.Name(), "_") || strings.HasPrefix(info.Name(), ".") {
+                       if info.IsDir() && (strings.HasPrefix(info.Name(), "_") || strings.HasPrefix(info.Name(), ".")) {
                                // _ and . prefixed directories can be used for internal modules
                                // without a vendor directory that don't contribute to the build
                                // but might be used for example as code generators.
                        goroot.modules = append(goroot.modules, m)
                        return nil
                })
-       })
+               if goroot.err != nil {
+                       return
+               }
 
+               // knownGOROOTModules is a hard-coded list of modules that are known to exist in GOROOT.
+               // If findGorootModules doesn't find a module, it won't be covered by tests at all,
+               // so make sure at least these modules are found. See issue 46254. If this list
+               // becomes a nuisance to update, can be replaced with len(goroot.modules) check.
+               knownGOROOTModules := [...]string{
+                       "std",
+                       "cmd",
+                       "misc",
+                       "test/bench/go1",
+               }
+               var seen = make(map[string]bool) // Key is module path.
+               for _, m := range goroot.modules {
+                       seen[m.Path] = true
+               }
+               for _, m := range knownGOROOTModules {
+                       if !seen[m] {
+                               goroot.err = fmt.Errorf("findGorootModules didn't find the well-known module %q", m)
+                               break
+                       }
+               }
+       })
        if goroot.err != nil {
                t.Fatal(goroot.err)
        }
 
        "golang.org/x/net/idna"
 )
 
+// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
+// are equal, ASCII-case-insensitively.
+func http2asciiEqualFold(s, t string) bool {
+       if len(s) != len(t) {
+               return false
+       }
+       for i := 0; i < len(s); i++ {
+               if http2lower(s[i]) != http2lower(t[i]) {
+                       return false
+               }
+       }
+       return true
+}
+
+// lower returns the ASCII lowercase version of b.
+func http2lower(b byte) byte {
+       if 'A' <= b && b <= 'Z' {
+               return b + ('a' - 'A')
+       }
+       return b
+}
+
+// isASCIIPrint returns whether s is ASCII and printable according to
+// https://tools.ietf.org/html/rfc20#section-4.2.
+func http2isASCIIPrint(s string) bool {
+       for i := 0; i < len(s); i++ {
+               if s[i] < ' ' || s[i] > '~' {
+                       return false
+               }
+       }
+       return true
+}
+
+// asciiToLower returns the lowercase version of s if s is ASCII and printable,
+// and whether or not it was.
+func http2asciiToLower(s string) (lower string, ok bool) {
+       if !http2isASCIIPrint(s) {
+               return "", false
+       }
+       return strings.ToLower(s), true
+}
+
 // A list of the possible cipher suite ids. Taken from
 // https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
 
        return nil
 }
 
+// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
+// connection.
+func (t *http2Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
+       dialer := &tls.Dialer{
+               Config: cfg,
+       }
+       cn, err := dialer.DialContext(ctx, network, addr)
+       if err != nil {
+               return nil, err
+       }
+       tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
+       return tlsCn, nil
+}
+
 var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
 
 type http2goroutineLock uint64
        }
 }
 
-func http2lowerHeader(v string) string {
+func http2lowerHeader(v string) (lower string, ascii bool) {
        http2buildCommonHeaderMapsOnce()
        if s, ok := http2commonLowerHeader[v]; ok {
-               return s
+               return s, true
        }
-       return strings.ToLower(v)
+       return http2asciiToLower(v)
 }
 
 var (
 
        if s.TLSConfig == nil {
                s.TLSConfig = new(tls.Config)
-       } else if s.TLSConfig.CipherSuites != nil {
-               // If they already provided a CipherSuite list, return
-               // an error if it has a bad order or is missing
-               // ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
+       } else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
+               // If they already provided a TLS 1.0–1.2 CipherSuite list, return an
+               // error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or
+               // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
                haveRequired := false
-               sawBad := false
-               for i, cs := range s.TLSConfig.CipherSuites {
+               for _, cs := range s.TLSConfig.CipherSuites {
                        switch cs {
                        case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                                // Alternative MTI cipher to not discourage ECDSA-only servers.
                                tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
                                haveRequired = true
                        }
-                       if http2isBadCipher(cs) {
-                               sawBad = true
-                       } else if sawBad {
-                               return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
-                       }
                }
                if !haveRequired {
-                       return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).")
+                       return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)")
                }
        }
 
                // but PUSH_PROMISE requests cannot have a body.
                // http://tools.ietf.org/html/rfc7540#section-8.2
                // Also disallow Host, since the promised URL must be absolute.
-               switch strings.ToLower(k) {
-               case "content-length", "content-encoding", "trailer", "te", "expect", "host":
+               if http2asciiEqualFold(k, "content-length") ||
+                       http2asciiEqualFold(k, "content-encoding") ||
+                       http2asciiEqualFold(k, "trailer") ||
+                       http2asciiEqualFold(k, "te") ||
+                       http2asciiEqualFold(k, "expect") ||
+                       http2asciiEqualFold(k, "host") {
                        return fmt.Errorf("promised request headers cannot include %q", k)
                }
        }
                return t.DialTLS
        }
        return func(network, addr string, cfg *tls.Config) (net.Conn, error) {
-               dialer := &tls.Dialer{
-                       Config: cfg,
-               }
-               cn, err := dialer.DialContext(ctx, network, addr)
+               tlsCn, err := t.dialTLSWithContext(ctx, network, addr, cfg)
                if err != nil {
                        return nil, err
                }
-               tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
                state := tlsCn.ConnectionState()
                if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
                        return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
                if !state.NegotiatedProtocolIsMutual {
                        return nil, errors.New("http2: could not negotiate protocol mutually")
                }
-               return cn, nil
+               return tlsCn, nil
        }
 }
 
        if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
                return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
        }
-       if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !strings.EqualFold(vv[0], "close") && !strings.EqualFold(vv[0], "keep-alive")) {
+       if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !http2asciiEqualFold(vv[0], "close") && !http2asciiEqualFold(vv[0], "keep-alive")) {
                return fmt.Errorf("http2: invalid Connection request header: %q", vv)
        }
        return nil
 
                var didUA bool
                for k, vv := range req.Header {
-                       if strings.EqualFold(k, "host") || strings.EqualFold(k, "content-length") {
+                       if http2asciiEqualFold(k, "host") || http2asciiEqualFold(k, "content-length") {
                                // Host is :authority, already sent.
                                // Content-Length is automatic, set below.
                                continue
-                       } else if strings.EqualFold(k, "connection") || strings.EqualFold(k, "proxy-connection") ||
-                               strings.EqualFold(k, "transfer-encoding") || strings.EqualFold(k, "upgrade") ||
-                               strings.EqualFold(k, "keep-alive") {
+                       } else if http2asciiEqualFold(k, "connection") ||
+                               http2asciiEqualFold(k, "proxy-connection") ||
+                               http2asciiEqualFold(k, "transfer-encoding") ||
+                               http2asciiEqualFold(k, "upgrade") ||
+                               http2asciiEqualFold(k, "keep-alive") {
                                // Per 8.1.2.2 Connection-Specific Header
                                // Fields, don't send connection-specific
                                // fields. We have already checked if any
                                // are error-worthy so just ignore the rest.
                                continue
-                       } else if strings.EqualFold(k, "user-agent") {
+                       } else if http2asciiEqualFold(k, "user-agent") {
                                // Match Go's http1 behavior: at most one
                                // User-Agent. If set to nil or empty string,
                                // then omit it. Otherwise if not mentioned,
                                if vv[0] == "" {
                                        continue
                                }
-                       } else if strings.EqualFold(k, "cookie") {
+                       } else if http2asciiEqualFold(k, "cookie") {
                                // Per 8.1.2.5 To allow for better compression efficiency, the
                                // Cookie header field MAY be split into separate header fields,
                                // each with one or more cookie-pairs.
 
        // Header list size is ok. Write the headers.
        enumerateHeaders(func(name, value string) {
-               name = strings.ToLower(name)
+               name, ascii := http2asciiToLower(name)
+               if !ascii {
+                       // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+                       // field names have to be ASCII characters (just as in HTTP/1.x).
+                       return
+               }
                cc.writeHeader(name, value)
                if traceHeaders {
                        http2traceWroteHeaderField(trace, name, value)
        }
 
        for k, vv := range req.Trailer {
+               lowKey, ascii := http2asciiToLower(k)
+               if !ascii {
+                       // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+                       // field names have to be ASCII characters (just as in HTTP/1.x).
+                       continue
+               }
                // Transfer-Encoding, etc.. have already been filtered at the
                // start of RoundTrip
-               lowKey := strings.ToLower(k)
                for _, v := range vv {
                        cc.writeHeader(lowKey, v)
                }
        }
        for _, k := range keys {
                vv := h[k]
-               k = http2lowerHeader(k)
+               k, ascii := http2lowerHeader(k)
+               if !ascii {
+                       // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+                       // field names have to be ASCII characters (just as in HTTP/1.x).
+                       continue
+               }
                if !http2validWireHeaderFieldName(k) {
                        // Skip it as backup paranoia. Per
                        // golang.org/issue/14048, these should