package  httpimport  (	"bufio" 	"bytes" 	"compress/gzip" 	"context" 	"crypto/rand" 	"crypto/tls" 	"encoding/binary" 	"errors" 	"fmt" 	"io" 	"io/fs" 	"log" 	"math" 	"math/bits" 	mathrand  "math/rand" 	"net" 	"net/http/httptrace" 	"net/textproto" 	"net/url" 	"os" 	"reflect" 	"runtime" 	"sort" 	"strconv" 	"strings" 	"sync" 	"sync/atomic" 	"time" 	"golang.org/x/net/http/httpguts" 	"golang.org/x/net/http2/hpack" 	"golang.org/x/net/idna" )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 }func  http2lower b  byte ) byte  {	if  'A'  <= b  && b  <= 'Z'  {		return  b  + ('a'  - 'A' )	}	return  b }func  http2isASCIIPrint s  string ) bool  {	for  i  := 0 ; i  < len (s ); i ++ {		if  s [i ] < ' '  || s [i ] > '~'  {			return  false 		}	}	return  true }func  http2asciiToLower s  string ) (lower  string , ok  bool ) {	if  !http2isASCIIPrint (s ) {		return  "" , false 	}	return  strings .ToLower (s ), true }const  (	http2cipher_TLS_NULL_WITH_NULL_NULL                uint16  = 0x0000 	http2cipher_TLS_RSA_WITH_NULL_MD5                  uint16  = 0x0001 	http2cipher_TLS_RSA_WITH_NULL_SHA                  uint16  = 0x0002 	http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5         uint16  = 0x0003 	http2cipher_TLS_RSA_WITH_RC4_128_MD5               uint16  = 0x0004 	http2cipher_TLS_RSA_WITH_RC4_128_SHA               uint16  = 0x0005 	http2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5     uint16  = 0x0006 	http2cipher_TLS_RSA_WITH_IDEA_CBC_SHA              uint16  = 0x0007 	http2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA      uint16  = 0x0008 	http2cipher_TLS_RSA_WITH_DES_CBC_SHA               uint16  = 0x0009 	http2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA          uint16  = 0x000A 	http2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA   uint16  = 0x000B 	http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHA            uint16  = 0x000C 	http2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA       uint16  = 0x000D 	http2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA   uint16  = 0x000E 	http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHA            uint16  = 0x000F 	http2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA       uint16  = 0x0010 	http2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA  uint16  = 0x0011 	http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA           uint16  = 0x0012 	http2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA      uint16  = 0x0013 	http2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA  uint16  = 0x0014 	http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA           uint16  = 0x0015 	http2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA      uint16  = 0x0016 	http2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5     uint16  = 0x0017 	http2cipher_TLS_DH_anon_WITH_RC4_128_MD5           uint16  = 0x0018 	http2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA  uint16  = 0x0019 	http2cipher_TLS_DH_anon_WITH_DES_CBC_SHA           uint16  = 0x001A 	http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA      uint16  = 0x001B 		http2cipher_TLS_KRB5_WITH_DES_CBC_SHA              uint16  = 0x001E 	http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA         uint16  = 0x001F 	http2cipher_TLS_KRB5_WITH_RC4_128_SHA              uint16  = 0x0020 	http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHA             uint16  = 0x0021 	http2cipher_TLS_KRB5_WITH_DES_CBC_MD5              uint16  = 0x0022 	http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5         uint16  = 0x0023 	http2cipher_TLS_KRB5_WITH_RC4_128_MD5              uint16  = 0x0024 	http2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5             uint16  = 0x0025 	http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA    uint16  = 0x0026 	http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA    uint16  = 0x0027 	http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA        uint16  = 0x0028 	http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5    uint16  = 0x0029 	http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5    uint16  = 0x002A 	http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5        uint16  = 0x002B 	http2cipher_TLS_PSK_WITH_NULL_SHA                  uint16  = 0x002C 	http2cipher_TLS_DHE_PSK_WITH_NULL_SHA              uint16  = 0x002D 	http2cipher_TLS_RSA_PSK_WITH_NULL_SHA              uint16  = 0x002E 	http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA           uint16  = 0x002F 	http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA        uint16  = 0x0030 	http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA        uint16  = 0x0031 	http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA       uint16  = 0x0032 	http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA       uint16  = 0x0033 	http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA       uint16  = 0x0034 	http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA           uint16  = 0x0035 	http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA        uint16  = 0x0036 	http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA        uint16  = 0x0037 	http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA       uint16  = 0x0038 	http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA       uint16  = 0x0039 	http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA       uint16  = 0x003A 	http2cipher_TLS_RSA_WITH_NULL_SHA256               uint16  = 0x003B 	http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256        uint16  = 0x003C 	http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256        uint16  = 0x003D 	http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256     uint16  = 0x003E 	http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256     uint16  = 0x003F 	http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256    uint16  = 0x0040 	http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA      uint16  = 0x0041 	http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA   uint16  = 0x0042 	http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA   uint16  = 0x0043 	http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA  uint16  = 0x0044 	http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA  uint16  = 0x0045 	http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA  uint16  = 0x0046 		http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256  uint16  = 0x0067 	http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256   uint16  = 0x0068 	http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256   uint16  = 0x0069 	http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256  uint16  = 0x006A 	http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256  uint16  = 0x006B 	http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256  uint16  = 0x006C 	http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256  uint16  = 0x006D 		http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA         uint16  = 0x0084 	http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA      uint16  = 0x0085 	http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA      uint16  = 0x0086 	http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA     uint16  = 0x0087 	http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA     uint16  = 0x0088 	http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA     uint16  = 0x0089 	http2cipher_TLS_PSK_WITH_RC4_128_SHA                  uint16  = 0x008A 	http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA             uint16  = 0x008B 	http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA              uint16  = 0x008C 	http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA              uint16  = 0x008D 	http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHA              uint16  = 0x008E 	http2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA         uint16  = 0x008F 	http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA          uint16  = 0x0090 	http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA          uint16  = 0x0091 	http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHA              uint16  = 0x0092 	http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA         uint16  = 0x0093 	http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA          uint16  = 0x0094 	http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA          uint16  = 0x0095 	http2cipher_TLS_RSA_WITH_SEED_CBC_SHA                 uint16  = 0x0096 	http2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA              uint16  = 0x0097 	http2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA              uint16  = 0x0098 	http2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA             uint16  = 0x0099 	http2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA             uint16  = 0x009A 	http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHA             uint16  = 0x009B 	http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256           uint16  = 0x009C 	http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384           uint16  = 0x009D 	http2cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256       uint16  = 0x009E 	http2cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384       uint16  = 0x009F 	http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256        uint16  = 0x00A0 	http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384        uint16  = 0x00A1 	http2cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256       uint16  = 0x00A2 	http2cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384       uint16  = 0x00A3 	http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256        uint16  = 0x00A4 	http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384        uint16  = 0x00A5 	http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256       uint16  = 0x00A6 	http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384       uint16  = 0x00A7 	http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256           uint16  = 0x00A8 	http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384           uint16  = 0x00A9 	http2cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256       uint16  = 0x00AA 	http2cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384       uint16  = 0x00AB 	http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256       uint16  = 0x00AC 	http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384       uint16  = 0x00AD 	http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256           uint16  = 0x00AE 	http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384           uint16  = 0x00AF 	http2cipher_TLS_PSK_WITH_NULL_SHA256                  uint16  = 0x00B0 	http2cipher_TLS_PSK_WITH_NULL_SHA384                  uint16  = 0x00B1 	http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256       uint16  = 0x00B2 	http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384       uint16  = 0x00B3 	http2cipher_TLS_DHE_PSK_WITH_NULL_SHA256              uint16  = 0x00B4 	http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384              uint16  = 0x00B5 	http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256       uint16  = 0x00B6 	http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384       uint16  = 0x00B7 	http2cipher_TLS_RSA_PSK_WITH_NULL_SHA256              uint16  = 0x00B8 	http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384              uint16  = 0x00B9 	http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256      uint16  = 0x00BA 	http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256   uint16  = 0x00BB 	http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256   uint16  = 0x00BC 	http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256  uint16  = 0x00BD 	http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256  uint16  = 0x00BE 	http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256  uint16  = 0x00BF 	http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256      uint16  = 0x00C0 	http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256   uint16  = 0x00C1 	http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256   uint16  = 0x00C2 	http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256  uint16  = 0x00C3 	http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256  uint16  = 0x00C4 	http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256  uint16  = 0x00C5 		http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV  uint16  = 0x00FF 		http2cipher_TLS_FALLBACK_SCSV  uint16  = 0x5600 		http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA                  uint16  = 0xC001 	http2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA               uint16  = 0xC002 	http2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA          uint16  = 0xC003 	http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA           uint16  = 0xC004 	http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA           uint16  = 0xC005 	http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA                 uint16  = 0xC006 	http2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA              uint16  = 0xC007 	http2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA         uint16  = 0xC008 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA          uint16  = 0xC009 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA          uint16  = 0xC00A 	http2cipher_TLS_ECDH_RSA_WITH_NULL_SHA                    uint16  = 0xC00B 	http2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA                 uint16  = 0xC00C 	http2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA            uint16  = 0xC00D 	http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA             uint16  = 0xC00E 	http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA             uint16  = 0xC00F 	http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHA                   uint16  = 0xC010 	http2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA                uint16  = 0xC011 	http2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA           uint16  = 0xC012 	http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA            uint16  = 0xC013 	http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA            uint16  = 0xC014 	http2cipher_TLS_ECDH_anon_WITH_NULL_SHA                   uint16  = 0xC015 	http2cipher_TLS_ECDH_anon_WITH_RC4_128_SHA                uint16  = 0xC016 	http2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA           uint16  = 0xC017 	http2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA            uint16  = 0xC018 	http2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA            uint16  = 0xC019 	http2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA             uint16  = 0xC01A 	http2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA         uint16  = 0xC01B 	http2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA         uint16  = 0xC01C 	http2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA              uint16  = 0xC01D 	http2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA          uint16  = 0xC01E 	http2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA          uint16  = 0xC01F 	http2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA              uint16  = 0xC020 	http2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA          uint16  = 0xC021 	http2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA          uint16  = 0xC022 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       uint16  = 0xC023 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384       uint16  = 0xC024 	http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256        uint16  = 0xC025 	http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384        uint16  = 0xC026 	http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         uint16  = 0xC027 	http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384         uint16  = 0xC028 	http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256          uint16  = 0xC029 	http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384          uint16  = 0xC02A 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       uint16  = 0xC02B 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       uint16  = 0xC02C 	http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256        uint16  = 0xC02D 	http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384        uint16  = 0xC02E 	http2cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         uint16  = 0xC02F 	http2cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         uint16  = 0xC030 	http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256          uint16  = 0xC031 	http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384          uint16  = 0xC032 	http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA                uint16  = 0xC033 	http2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA           uint16  = 0xC034 	http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA            uint16  = 0xC035 	http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA            uint16  = 0xC036 	http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256         uint16  = 0xC037 	http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384         uint16  = 0xC038 	http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA                   uint16  = 0xC039 	http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256                uint16  = 0xC03A 	http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384                uint16  = 0xC03B 	http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256              uint16  = 0xC03C 	http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384              uint16  = 0xC03D 	http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256           uint16  = 0xC03E 	http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384           uint16  = 0xC03F 	http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256           uint16  = 0xC040 	http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384           uint16  = 0xC041 	http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256          uint16  = 0xC042 	http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384          uint16  = 0xC043 	http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256          uint16  = 0xC044 	http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384          uint16  = 0xC045 	http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256          uint16  = 0xC046 	http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384          uint16  = 0xC047 	http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256      uint16  = 0xC048 	http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384      uint16  = 0xC049 	http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256       uint16  = 0xC04A 	http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384       uint16  = 0xC04B 	http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256        uint16  = 0xC04C 	http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384        uint16  = 0xC04D 	http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256         uint16  = 0xC04E 	http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384         uint16  = 0xC04F 	http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256              uint16  = 0xC050 	http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384              uint16  = 0xC051 	http2cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256          uint16  = 0xC052 	http2cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384          uint16  = 0xC053 	http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256           uint16  = 0xC054 	http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384           uint16  = 0xC055 	http2cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256          uint16  = 0xC056 	http2cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384          uint16  = 0xC057 	http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256           uint16  = 0xC058 	http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384           uint16  = 0xC059 	http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256          uint16  = 0xC05A 	http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384          uint16  = 0xC05B 	http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256      uint16  = 0xC05C 	http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384      uint16  = 0xC05D 	http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256       uint16  = 0xC05E 	http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384       uint16  = 0xC05F 	http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256        uint16  = 0xC060 	http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384        uint16  = 0xC061 	http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256         uint16  = 0xC062 	http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384         uint16  = 0xC063 	http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256              uint16  = 0xC064 	http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384              uint16  = 0xC065 	http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256          uint16  = 0xC066 	http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384          uint16  = 0xC067 	http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256          uint16  = 0xC068 	http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384          uint16  = 0xC069 	http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256              uint16  = 0xC06A 	http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384              uint16  = 0xC06B 	http2cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256          uint16  = 0xC06C 	http2cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384          uint16  = 0xC06D 	http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256          uint16  = 0xC06E 	http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384          uint16  = 0xC06F 	http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256        uint16  = 0xC070 	http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384        uint16  = 0xC071 	http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  uint16  = 0xC072 	http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  uint16  = 0xC073 	http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256   uint16  = 0xC074 	http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384   uint16  = 0xC075 	http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256    uint16  = 0xC076 	http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384    uint16  = 0xC077 	http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256     uint16  = 0xC078 	http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384     uint16  = 0xC079 	http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256          uint16  = 0xC07A 	http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384          uint16  = 0xC07B 	http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256      uint16  = 0xC07C 	http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384      uint16  = 0xC07D 	http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256       uint16  = 0xC07E 	http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384       uint16  = 0xC07F 	http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256      uint16  = 0xC080 	http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384      uint16  = 0xC081 	http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256       uint16  = 0xC082 	http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384       uint16  = 0xC083 	http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256      uint16  = 0xC084 	http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384      uint16  = 0xC085 	http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256  uint16  = 0xC086 	http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384  uint16  = 0xC087 	http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256   uint16  = 0xC088 	http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384   uint16  = 0xC089 	http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256    uint16  = 0xC08A 	http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384    uint16  = 0xC08B 	http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256     uint16  = 0xC08C 	http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384     uint16  = 0xC08D 	http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256          uint16  = 0xC08E 	http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384          uint16  = 0xC08F 	http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256      uint16  = 0xC090 	http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384      uint16  = 0xC091 	http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256      uint16  = 0xC092 	http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384      uint16  = 0xC093 	http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256          uint16  = 0xC094 	http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384          uint16  = 0xC095 	http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256      uint16  = 0xC096 	http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384      uint16  = 0xC097 	http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256      uint16  = 0xC098 	http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384      uint16  = 0xC099 	http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256    uint16  = 0xC09A 	http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384    uint16  = 0xC09B 	http2cipher_TLS_RSA_WITH_AES_128_CCM                      uint16  = 0xC09C 	http2cipher_TLS_RSA_WITH_AES_256_CCM                      uint16  = 0xC09D 	http2cipher_TLS_DHE_RSA_WITH_AES_128_CCM                  uint16  = 0xC09E 	http2cipher_TLS_DHE_RSA_WITH_AES_256_CCM                  uint16  = 0xC09F 	http2cipher_TLS_RSA_WITH_AES_128_CCM_8                    uint16  = 0xC0A0 	http2cipher_TLS_RSA_WITH_AES_256_CCM_8                    uint16  = 0xC0A1 	http2cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8                uint16  = 0xC0A2 	http2cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8                uint16  = 0xC0A3 	http2cipher_TLS_PSK_WITH_AES_128_CCM                      uint16  = 0xC0A4 	http2cipher_TLS_PSK_WITH_AES_256_CCM                      uint16  = 0xC0A5 	http2cipher_TLS_DHE_PSK_WITH_AES_128_CCM                  uint16  = 0xC0A6 	http2cipher_TLS_DHE_PSK_WITH_AES_256_CCM                  uint16  = 0xC0A7 	http2cipher_TLS_PSK_WITH_AES_128_CCM_8                    uint16  = 0xC0A8 	http2cipher_TLS_PSK_WITH_AES_256_CCM_8                    uint16  = 0xC0A9 	http2cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8                uint16  = 0xC0AA 	http2cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8                uint16  = 0xC0AB 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM              uint16  = 0xC0AC 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM              uint16  = 0xC0AD 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8            uint16  = 0xC0AE 	http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8            uint16  = 0xC0AF 		http2cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256    uint16  = 0xCCA8 	http2cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256  uint16  = 0xCCA9 	http2cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256      uint16  = 0xCCAA 	http2cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256          uint16  = 0xCCAB 	http2cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256    uint16  = 0xCCAC 	http2cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256      uint16  = 0xCCAD 	http2cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256      uint16  = 0xCCAE )func  http2isBadCipher cipher  uint16 ) bool  {	switch  cipher  {	case  http2cipher_TLS_NULL_WITH_NULL_NULL ,		http2cipher_TLS_RSA_WITH_NULL_MD5 ,		http2cipher_TLS_RSA_WITH_NULL_SHA ,		http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 ,		http2cipher_TLS_RSA_WITH_RC4_128_MD5 ,		http2cipher_TLS_RSA_WITH_RC4_128_SHA ,		http2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 ,		http2cipher_TLS_RSA_WITH_IDEA_CBC_SHA ,		http2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA ,		http2cipher_TLS_RSA_WITH_DES_CBC_SHA ,		http2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 ,		http2cipher_TLS_DH_anon_WITH_RC4_128_MD5 ,		http2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_DES_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_KRB5_WITH_DES_CBC_SHA ,		http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_KRB5_WITH_RC4_128_SHA ,		http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHA ,		http2cipher_TLS_KRB5_WITH_DES_CBC_MD5 ,		http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 ,		http2cipher_TLS_KRB5_WITH_RC4_128_MD5 ,		http2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 ,		http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA ,		http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA ,		http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA ,		http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 ,		http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 ,		http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 ,		http2cipher_TLS_PSK_WITH_NULL_SHA ,		http2cipher_TLS_DHE_PSK_WITH_NULL_SHA ,		http2cipher_TLS_RSA_PSK_WITH_NULL_SHA ,		http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_RSA_WITH_NULL_SHA256 ,		http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 ,		http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 ,		http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ,		http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 ,		http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA ,		http2cipher_TLS_PSK_WITH_RC4_128_SHA ,		http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHA ,		http2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHA ,		http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_RSA_WITH_SEED_CBC_SHA ,		http2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA ,		http2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA ,		http2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA ,		http2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA ,		http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHA ,		http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_PSK_WITH_NULL_SHA256 ,		http2cipher_TLS_PSK_WITH_NULL_SHA384 ,		http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_DHE_PSK_WITH_NULL_SHA256 ,		http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_NULL_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384 ,		http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 ,		http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 ,		http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 ,		http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 ,		http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV ,		http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA ,		http2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA ,		http2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA ,		http2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ,		http2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_ECDH_RSA_WITH_NULL_SHA ,		http2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA ,		http2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHA ,		http2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA ,		http2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_ECDH_anon_WITH_NULL_SHA ,		http2cipher_TLS_ECDH_anon_WITH_RC4_128_SHA ,		http2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 ,		http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 ,		http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA ,		http2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA ,		http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA ,		http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA ,		http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA ,		http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 ,		http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 ,		http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 ,		http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 ,		http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 ,		http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 ,		http2cipher_TLS_RSA_WITH_AES_128_CCM ,		http2cipher_TLS_RSA_WITH_AES_256_CCM ,		http2cipher_TLS_RSA_WITH_AES_128_CCM_8 ,		http2cipher_TLS_RSA_WITH_AES_256_CCM_8 ,		http2cipher_TLS_PSK_WITH_AES_128_CCM ,		http2cipher_TLS_PSK_WITH_AES_256_CCM ,		http2cipher_TLS_PSK_WITH_AES_128_CCM_8 ,		http2cipher_TLS_PSK_WITH_AES_256_CCM_8 :		return  true 	default :		return  false 	}}type  http2ClientConnPool  interface  {		GetClientConn (req *Request , addr string ) (*http2ClientConn , error )	MarkDead (*http2ClientConn )}type  http2clientConnPoolIdleCloser  interface  {	http2ClientConnPool 	closeIdleConnections ()}var  (	_ http2clientConnPoolIdleCloser  = (*http2clientConnPool )(nil )	_ http2clientConnPoolIdleCloser  = http2noDialClientConnPool {})type  http2clientConnPool  struct  {	t  *http2Transport 	mu  sync .Mutex  		conns         map [string ][]*http2ClientConn  	dialing       map [string ]*http2dialCall      	keys          map [*http2ClientConn ][]string 	addConnCalls  map [string ]*http2addConnCall  }func  (p  *http2clientConnPool ) GetClientConn req  *Request , addr  string ) (*http2ClientConn , error ) {	return  p .getClientConn (req , addr , http2dialOnMiss )}const  (	http2dialOnMiss    = true 	http2noDialOnMiss  = false )func  (p  *http2clientConnPool ) getClientConn req  *Request , addr  string , dialOnMiss  bool ) (*http2ClientConn , error ) {		if  http2isConnectionCloseRequest (req ) && dialOnMiss  {				http2traceGetConn (req , addr )		const  singleUse  = true 		cc , err  := p .t .dialClientConn (req .Context (), addr , singleUse )		if  err  != nil  {			return  nil , err 		}		return  cc , nil 	}	for  {		p .mu .Lock ()		for  _ , cc  := range  p .conns [addr ] {			if  cc .ReserveNewRequest () {								if  !cc .getConnCalled  {					http2traceGetConn (req , addr )				}				cc .getConnCalled  = false 				p .mu .Unlock ()				return  cc , nil 			}		}		if  !dialOnMiss  {			p .mu .Unlock ()			return  nil , http2ErrNoCachedConn 		}		http2traceGetConn (req , addr )		call  := p .getStartDialLocked (req .Context (), addr )		p .mu .Unlock ()		<-call .done 		if  http2shouldRetryDial (call , req ) {			continue 		}		cc , err  := call .res , call .err 		if  err  != nil  {			return  nil , err 		}		if  cc .ReserveNewRequest () {			return  cc , nil 		}	}}type  http2dialCall  struct  {	_ http2incomparable 	p  *http2clientConnPool 		ctx   context .Context 	done  chan  struct {}    	res   *http2ClientConn  	err   error             }func  (p  *http2clientConnPool ) getStartDialLocked ctx  context .Context , addr  string ) *http2dialCall  {	if  call , ok  := p .dialing [addr ]; ok  {				return  call 	}	call  := &http2dialCall {p : p , done : make (chan  struct {}), ctx : ctx }	if  p .dialing  == nil  {		p .dialing  = make (map [string ]*http2dialCall )	}	p .dialing [addr ] = call 	go  call .dial (call .ctx , addr )	return  call }func  (c  *http2dialCall ) dial ctx  context .Context , addr  string ) {	const  singleUse  = false  	c .res , c .err  = c .p .t .dialClientConn (ctx , addr , singleUse )	c .p .mu .Lock ()	delete (c .p .dialing , addr )	if  c .err  == nil  {		c .p .addConnLocked (addr , c .res )	}	c .p .mu .Unlock ()	close (c .done )}func  (p  *http2clientConnPool ) addConnIfNeeded key  string , t  *http2Transport , c  *tls .Conn ) (used  bool , err  error ) {	p .mu .Lock ()	for  _ , cc  := range  p .conns [key ] {		if  cc .CanTakeNewRequest () {			p .mu .Unlock ()			return  false , nil 		}	}	call , dup  := p .addConnCalls [key ]	if  !dup  {		if  p .addConnCalls  == nil  {			p .addConnCalls  = make (map [string ]*http2addConnCall )		}		call  = &http2addConnCall {			p :    p ,			done : make (chan  struct {}),		}		p .addConnCalls [key ] = call 		go  call .run (t , key , c )	}	p .mu .Unlock ()	<-call .done 	if  call .err  != nil  {		return  false , call .err 	}	return  !dup , nil }type  http2addConnCall  struct  {	_    http2incomparable 	p     *http2clientConnPool 	done  chan  struct {} 	err   error }func  (c  *http2addConnCall ) run t  *http2Transport , key  string , tc  *tls .Conn ) {	cc , err  := t .NewClientConn (tc )	p  := c .p 	p .mu .Lock ()	if  err  != nil  {		c .err  = err 	} else  {		cc .getConnCalled  = true  		p .addConnLocked (key , cc )	}	delete (p .addConnCalls , key )	p .mu .Unlock ()	close (c .done )}func  (p  *http2clientConnPool ) addConnLocked key  string , cc  *http2ClientConn ) {	for  _ , v  := range  p .conns [key ] {		if  v  == cc  {			return 		}	}	if  p .conns  == nil  {		p .conns  = make (map [string ][]*http2ClientConn )	}	if  p .keys  == nil  {		p .keys  = make (map [*http2ClientConn ][]string )	}	p .conns [key ] = append (p .conns [key ], cc )	p .keys [cc ] = append (p .keys [cc ], key )}func  (p  *http2clientConnPool ) MarkDead cc  *http2ClientConn ) {	p .mu .Lock ()	defer  p .mu .Unlock ()	for  _ , key  := range  p .keys [cc ] {		vv , ok  := p .conns [key ]		if  !ok  {			continue 		}		newList  := http2filterOutClientConn (vv , cc )		if  len (newList ) > 0  {			p .conns [key ] = newList 		} else  {			delete (p .conns , key )		}	}	delete (p .keys , cc )}func  (p  *http2clientConnPool ) closeIdleConnections 	p .mu .Lock ()	defer  p .mu .Unlock ()		for  _ , vv  := range  p .conns  {		for  _ , cc  := range  vv  {			cc .closeIfIdle ()		}	}}func  http2filterOutClientConn in  []*http2ClientConn , exclude  *http2ClientConn ) []*http2ClientConn  {	out  := in [:0 ]	for  _ , v  := range  in  {		if  v  != exclude  {			out  = append (out , v )		}	}		if  len (in ) != len (out ) {		in [len (in )-1 ] = nil 	}	return  out }type  http2noDialClientConnPool  struct { *http2clientConnPool  }func  (p  http2noDialClientConnPool ) GetClientConn req  *Request , addr  string ) (*http2ClientConn , error ) {	return  p .getClientConn (req , addr , http2noDialOnMiss )}func  http2shouldRetryDial call  *http2dialCall , req  *Request ) bool  {	if  call .err  == nil  {				return  false 	}	if  call .ctx  == req .Context () {				return  false 	}	if  !errors .Is (call .err , context .Canceled ) && !errors .Is (call .err , context .DeadlineExceeded ) {				return  false 	}		return  call .ctx .Err () != nil }var  http2dataChunkPools  = [...]sync .Pool {	{New : func () interface {} { return  new ([1  << 10 ]byte ) }},	{New : func () interface {} { return  new ([2  << 10 ]byte ) }},	{New : func () interface {} { return  new ([4  << 10 ]byte ) }},	{New : func () interface {} { return  new ([8  << 10 ]byte ) }},	{New : func () interface {} { return  new ([16  << 10 ]byte ) }},}func  http2getDataBufferChunk size  int64 ) []byte  {	switch  {	case  size  <= 1 <<10 :		return  http2dataChunkPools [0 ].Get ().(*[1  << 10 ]byte )[:]	case  size  <= 2 <<10 :		return  http2dataChunkPools [1 ].Get ().(*[2  << 10 ]byte )[:]	case  size  <= 4 <<10 :		return  http2dataChunkPools [2 ].Get ().(*[4  << 10 ]byte )[:]	case  size  <= 8 <<10 :		return  http2dataChunkPools [3 ].Get ().(*[8  << 10 ]byte )[:]	default :		return  http2dataChunkPools [4 ].Get ().(*[16  << 10 ]byte )[:]	}}func  http2putDataBufferChunk p  []byte ) {	switch  len (p ) {	case  1  << 10 :		http2dataChunkPools [0 ].Put ((*[1  << 10 ]byte )(p ))	case  2  << 10 :		http2dataChunkPools [1 ].Put ((*[2  << 10 ]byte )(p ))	case  4  << 10 :		http2dataChunkPools [2 ].Put ((*[4  << 10 ]byte )(p ))	case  8  << 10 :		http2dataChunkPools [3 ].Put ((*[8  << 10 ]byte )(p ))	case  16  << 10 :		http2dataChunkPools [4 ].Put ((*[16  << 10 ]byte )(p ))	default :		panic (fmt .Sprintf ("unexpected buffer len=%v" , len (p )))	}}type  http2dataBuffer  struct  {	chunks    [][]byte 	r         int    	w         int    	size      int    	expected  int64  }var  http2errReadEmpty  = errors .New ("read from empty dataBuffer" )func  (b  *http2dataBuffer ) Read p  []byte ) (int , error ) {	if  b .size  == 0  {		return  0 , http2errReadEmpty 	}	var  ntotal  int 	for  len (p ) > 0  && b .size  > 0  {		readFrom  := b .bytesFromFirstChunk ()		n  := copy (p , readFrom )		p  = p [n :]		ntotal  += n 		b .r  += n 		b .size  -= n 				if  b .r  == len (b .chunks [0 ]) {			http2putDataBufferChunk (b .chunks [0 ])			end  := len (b .chunks ) - 1 			copy (b .chunks [:end ], b .chunks [1 :])			b .chunks [end ] = nil 			b .chunks  = b .chunks [:end ]			b .r  = 0 		}	}	return  ntotal , nil }func  (b  *http2dataBuffer ) bytesFromFirstChunk byte  {	if  len (b .chunks ) == 1  {		return  b .chunks [0 ][b .r :b .w ]	}	return  b .chunks [0 ][b .r :]}func  (b  *http2dataBuffer ) Len int  {	return  b .size }func  (b  *http2dataBuffer ) Write p  []byte ) (int , error ) {	ntotal  := len (p )	for  len (p ) > 0  {				want  := int64 (len (p ))		if  b .expected  > want  {			want  = b .expected 		}		chunk  := b .lastChunkOrAlloc (want )		n  := copy (chunk [b .w :], p )		p  = p [n :]		b .w  += n 		b .size  += n 		b .expected  -= int64 (n )	}	return  ntotal , nil }func  (b  *http2dataBuffer ) lastChunkOrAlloc want  int64 ) []byte  {	if  len (b .chunks ) != 0  {		last  := b .chunks [len (b .chunks )-1 ]		if  b .w  < len (last ) {			return  last 		}	}	chunk  := http2getDataBufferChunk (want )	b .chunks  = append (b .chunks , chunk )	b .w  = 0 	return  chunk }type  http2ErrCode  uint32 const  (	http2ErrCodeNo                  http2ErrCode  = 0x0 	http2ErrCodeProtocol            http2ErrCode  = 0x1 	http2ErrCodeInternal            http2ErrCode  = 0x2 	http2ErrCodeFlowControl         http2ErrCode  = 0x3 	http2ErrCodeSettingsTimeout     http2ErrCode  = 0x4 	http2ErrCodeStreamClosed        http2ErrCode  = 0x5 	http2ErrCodeFrameSize           http2ErrCode  = 0x6 	http2ErrCodeRefusedStream       http2ErrCode  = 0x7 	http2ErrCodeCancel              http2ErrCode  = 0x8 	http2ErrCodeCompression         http2ErrCode  = 0x9 	http2ErrCodeConnect             http2ErrCode  = 0xa 	http2ErrCodeEnhanceYourCalm     http2ErrCode  = 0xb 	http2ErrCodeInadequateSecurity  http2ErrCode  = 0xc 	http2ErrCodeHTTP11Required      http2ErrCode  = 0xd )var  http2errCodeName  = map [http2ErrCode ]string {	http2ErrCodeNo :                 "NO_ERROR" ,	http2ErrCodeProtocol :           "PROTOCOL_ERROR" ,	http2ErrCodeInternal :           "INTERNAL_ERROR" ,	http2ErrCodeFlowControl :        "FLOW_CONTROL_ERROR" ,	http2ErrCodeSettingsTimeout :    "SETTINGS_TIMEOUT" ,	http2ErrCodeStreamClosed :       "STREAM_CLOSED" ,	http2ErrCodeFrameSize :          "FRAME_SIZE_ERROR" ,	http2ErrCodeRefusedStream :      "REFUSED_STREAM" ,	http2ErrCodeCancel :             "CANCEL" ,	http2ErrCodeCompression :        "COMPRESSION_ERROR" ,	http2ErrCodeConnect :            "CONNECT_ERROR" ,	http2ErrCodeEnhanceYourCalm :    "ENHANCE_YOUR_CALM" ,	http2ErrCodeInadequateSecurity : "INADEQUATE_SECURITY" ,	http2ErrCodeHTTP11Required :     "HTTP_1_1_REQUIRED" ,}func  (e  http2ErrCode ) String string  {	if  s , ok  := http2errCodeName [e ]; ok  {		return  s 	}	return  fmt .Sprintf ("unknown error code 0x%x" , uint32 (e ))}func  (e  http2ErrCode ) stringToken string  {	if  s , ok  := http2errCodeName [e ]; ok  {		return  s 	}	return  fmt .Sprintf ("ERR_UNKNOWN_%d" , uint32 (e ))}type  http2ConnectionError  http2ErrCode func  (e  http2ConnectionError ) Error string  {	return  fmt .Sprintf ("connection error: %s" , http2ErrCode (e ))}type  http2StreamError  struct  {	StreamID  uint32 	Code      http2ErrCode 	Cause     error  }var  http2errFromPeer  = errors .New ("received from peer" )func  http2streamError id  uint32 , code  http2ErrCode ) http2StreamError  {	return  http2StreamError {StreamID : id , Code : code }}func  (e  http2StreamError ) Error string  {	if  e .Cause  != nil  {		return  fmt .Sprintf ("stream error: stream ID %d; %v; %v" , e .StreamID , e .Code , e .Cause )	}	return  fmt .Sprintf ("stream error: stream ID %d; %v" , e .StreamID , e .Code )}type  http2goAwayFlowError  struct {}func  (http2goAwayFlowError ) Error string  { return  "connection exceeded flow control window size"  }type  http2connError  struct  {	Code    http2ErrCode  	Reason  string        }func  (e  http2connError ) Error string  {	return  fmt .Sprintf ("http2: connection error: %v: %v" , e .Code , e .Reason )}type  http2pseudoHeaderError  string func  (e  http2pseudoHeaderError ) Error string  {	return  fmt .Sprintf ("invalid pseudo-header %q" , string (e ))}type  http2duplicatePseudoHeaderError  string func  (e  http2duplicatePseudoHeaderError ) Error string  {	return  fmt .Sprintf ("duplicate pseudo-header %q" , string (e ))}type  http2headerFieldNameError  string func  (e  http2headerFieldNameError ) Error string  {	return  fmt .Sprintf ("invalid header field name %q" , string (e ))}type  http2headerFieldValueError  string func  (e  http2headerFieldValueError ) Error string  {	return  fmt .Sprintf ("invalid header field value for %q" , string (e ))}var  (	http2errMixPseudoHeaderTypes  = errors .New ("mix of request and response pseudo headers" )	http2errPseudoAfterRegular    = errors .New ("pseudo header field after regular" ))const  http2inflowMinRefresh  = 4  << 10 type  http2inflow  struct  {	avail   int32 	unsent  int32 }func  (f  *http2inflow ) init n  int32 ) {	f .avail  = n }func  (f  *http2inflow ) add n  int ) (connAdd  int32 ) {	if  n  < 0  {		panic ("negative update" )	}	unsent  := int64 (f .unsent ) + int64 (n )		const  maxWindow  = 1 <<31  - 1 	if  unsent +int64 (f .avail ) > maxWindow  {		panic ("flow control update exceeds maximum window size" )	}	f .unsent  = int32 (unsent )	if  f .unsent  < http2inflowMinRefresh  && f .unsent  < f .avail  {				return  0 	}	f .avail  += f .unsent 	f .unsent  = 0 	return  int32 (unsent )}func  (f  *http2inflow ) take n  uint32 ) bool  {	if  n  > uint32 (f .avail ) {		return  false 	}	f .avail  -= int32 (n )	return  true }func  http2takeInflows f1 , f2  *http2inflow , n  uint32 ) bool  {	if  n  > uint32 (f1 .avail ) || n  > uint32 (f2 .avail ) {		return  false 	}	f1 .avail  -= int32 (n )	f2 .avail  -= int32 (n )	return  true }type  http2outflow  struct  {	_ http2incomparable 		n  int32 		conn  *http2outflow }func  (f  *http2outflow ) setConnFlow cf  *http2outflow ) { f .conn  = cf  }func  (f  *http2outflow ) available int32  {	n  := f .n 	if  f .conn  != nil  && f .conn .n  < n  {		n  = f .conn .n 	}	return  n }func  (f  *http2outflow ) take n  int32 ) {	if  n  > f .available () {		panic ("internal error: took too much" )	}	f .n  -= n 	if  f .conn  != nil  {		f .conn .n  -= n 	}}func  (f  *http2outflow ) add n  int32 ) bool  {	sum  := f .n  + n 	if  (sum  > n ) == (f .n  > 0 ) {		f .n  = sum 		return  true 	}	return  false }const  http2frameHeaderLen  = 9 var  http2padZeros  = make ([]byte , 255 ) type  http2FrameType  uint8 const  (	http2FrameData          http2FrameType  = 0x0 	http2FrameHeaders       http2FrameType  = 0x1 	http2FramePriority      http2FrameType  = 0x2 	http2FrameRSTStream     http2FrameType  = 0x3 	http2FrameSettings      http2FrameType  = 0x4 	http2FramePushPromise   http2FrameType  = 0x5 	http2FramePing          http2FrameType  = 0x6 	http2FrameGoAway        http2FrameType  = 0x7 	http2FrameWindowUpdate  http2FrameType  = 0x8 	http2FrameContinuation  http2FrameType  = 0x9 )var  http2frameName  = map [http2FrameType ]string {	http2FrameData :         "DATA" ,	http2FrameHeaders :      "HEADERS" ,	http2FramePriority :     "PRIORITY" ,	http2FrameRSTStream :    "RST_STREAM" ,	http2FrameSettings :     "SETTINGS" ,	http2FramePushPromise :  "PUSH_PROMISE" ,	http2FramePing :         "PING" ,	http2FrameGoAway :       "GOAWAY" ,	http2FrameWindowUpdate : "WINDOW_UPDATE" ,	http2FrameContinuation : "CONTINUATION" ,}func  (t  http2FrameType ) String string  {	if  s , ok  := http2frameName [t ]; ok  {		return  s 	}	return  fmt .Sprintf ("UNKNOWN_FRAME_TYPE_%d" , uint8 (t ))}type  http2Flags  uint8 func  (f  http2Flags ) Has v  http2Flags ) bool  {	return  (f  & v ) == v }const  (		http2FlagDataEndStream  http2Flags  = 0x1 	http2FlagDataPadded     http2Flags  = 0x8 		http2FlagHeadersEndStream   http2Flags  = 0x1 	http2FlagHeadersEndHeaders  http2Flags  = 0x4 	http2FlagHeadersPadded      http2Flags  = 0x8 	http2FlagHeadersPriority    http2Flags  = 0x20 		http2FlagSettingsAck  http2Flags  = 0x1 		http2FlagPingAck  http2Flags  = 0x1 		http2FlagContinuationEndHeaders  http2Flags  = 0x4 	http2FlagPushPromiseEndHeaders  http2Flags  = 0x4 	http2FlagPushPromisePadded      http2Flags  = 0x8 )var  http2flagName  = map [http2FrameType ]map [http2Flags ]string {	http2FrameData : {		http2FlagDataEndStream : "END_STREAM" ,		http2FlagDataPadded :    "PADDED" ,	},	http2FrameHeaders : {		http2FlagHeadersEndStream :  "END_STREAM" ,		http2FlagHeadersEndHeaders : "END_HEADERS" ,		http2FlagHeadersPadded :     "PADDED" ,		http2FlagHeadersPriority :   "PRIORITY" ,	},	http2FrameSettings : {		http2FlagSettingsAck : "ACK" ,	},	http2FramePing : {		http2FlagPingAck : "ACK" ,	},	http2FrameContinuation : {		http2FlagContinuationEndHeaders : "END_HEADERS" ,	},	http2FramePushPromise : {		http2FlagPushPromiseEndHeaders : "END_HEADERS" ,		http2FlagPushPromisePadded :     "PADDED" ,	},}type  http2frameParser  func (fc *http2frameCache , fh http2FrameHeader , countError func (string ), payload []byte ) (http2Frame , error )var  http2frameParsers  = map [http2FrameType ]http2frameParser {	http2FrameData :         http2parseDataFrame ,	http2FrameHeaders :      http2parseHeadersFrame ,	http2FramePriority :     http2parsePriorityFrame ,	http2FrameRSTStream :    http2parseRSTStreamFrame ,	http2FrameSettings :     http2parseSettingsFrame ,	http2FramePushPromise :  http2parsePushPromise ,	http2FramePing :         http2parsePingFrame ,	http2FrameGoAway :       http2parseGoAwayFrame ,	http2FrameWindowUpdate : http2parseWindowUpdateFrame ,	http2FrameContinuation : http2parseContinuationFrame ,}func  http2typeFrameParser t  http2FrameType ) http2frameParser  {	if  f  := http2frameParsers [t ]; f  != nil  {		return  f 	}	return  http2parseUnknownFrame }type  http2FrameHeader  struct  {	valid  bool  		Type  http2FrameType 		Flags  http2Flags 		Length  uint32 		StreamID  uint32 }func  (h  http2FrameHeader ) Header http2FrameHeader  { return  h  }func  (h  http2FrameHeader ) String string  {	var  buf  bytes .Buffer 	buf .WriteString ("[FrameHeader " )	h .writeDebug (&buf )	buf .WriteByte (']' )	return  buf .String ()}func  (h  http2FrameHeader ) writeDebug buf  *bytes .Buffer ) {	buf .WriteString (h .Type .String ())	if  h .Flags  != 0  {		buf .WriteString (" flags=" )		set  := 0 		for  i  := uint8 (0 ); i  < 8 ; i ++ {			if  h .Flags &(1 <<i ) == 0  {				continue 			}			set ++			if  set  > 1  {				buf .WriteByte ('|' )			}			name  := http2flagName [h .Type ][http2Flags (1 <<i )]			if  name  != ""  {				buf .WriteString (name )			} else  {				fmt .Fprintf (buf , "0x%x" , 1 <<i )			}		}	}	if  h .StreamID  != 0  {		fmt .Fprintf (buf , " stream=%d" , h .StreamID )	}	fmt .Fprintf (buf , " len=%d" , h .Length )}func  (h  *http2FrameHeader ) checkValid 	if  !h .valid  {		panic ("Frame accessor called on non-owned Frame" )	}}func  (h  *http2FrameHeader ) invalidate h .valid  = false  }var  http2fhBytes  = sync .Pool {	New : func () interface {} {		buf  := make ([]byte , http2frameHeaderLen )		return  &buf 	},}func  http2ReadFrameHeader r  io .Reader ) (http2FrameHeader , error ) {	bufp  := http2fhBytes .Get ().(*[]byte )	defer  http2fhBytes .Put (bufp )	return  http2readFrameHeader (*bufp , r )}func  http2readFrameHeader buf  []byte , r  io .Reader ) (http2FrameHeader , error ) {	_ , err  := io .ReadFull (r , buf [:http2frameHeaderLen ])	if  err  != nil  {		return  http2FrameHeader {}, err 	}	return  http2FrameHeader {		Length :   (uint32 (buf [0 ])<<16  | uint32 (buf [1 ])<<8  | uint32 (buf [2 ])),		Type :     http2FrameType (buf [3 ]),		Flags :    http2Flags (buf [4 ]),		StreamID : binary .BigEndian .Uint32 (buf [5 :]) & (1 <<31  - 1 ),		valid :    true ,	}, nil }type  http2Frame  interface  {	Header () http2FrameHeader 		invalidate ()}type  http2Framer  struct  {	r          io .Reader 	lastFrame  http2Frame 	errDetail  error 		countError  func (errToken string )		lastHeaderStream  uint32 	maxReadSize  uint32 	headerBuf    [http2frameHeaderLen ]byte 		getReadBuf  func (size uint32 ) []byte 	readBuf     []byte  	maxWriteSize  uint32  	w     io .Writer 	wbuf  []byte 		AllowIllegalWrites  bool 		AllowIllegalReads  bool 		ReadMetaHeaders  *hpack .Decoder 		MaxHeaderListSize  uint32 		logReads , logWrites  bool 	debugFramer        *http2Framer  	debugFramerBuf     *bytes .Buffer 	debugReadLoggerf   func (string , ...interface {})	debugWriteLoggerf  func (string , ...interface {})	frameCache  *http2frameCache  }func  (fr  *http2Framer ) maxHeaderListSize uint32  {	if  fr .MaxHeaderListSize  == 0  {		return  16  << 20  	}	return  fr .MaxHeaderListSize }func  (f  *http2Framer ) startWrite ftype  http2FrameType , flags  http2Flags , streamID  uint32 ) {		f .wbuf  = append (f .wbuf [:0 ],		0 , 		0 ,		0 ,		byte (ftype ),		byte (flags ),		byte (streamID >>24 ),		byte (streamID >>16 ),		byte (streamID >>8 ),		byte (streamID ))}func  (f  *http2Framer ) endWrite error  {		length  := len (f .wbuf ) - http2frameHeaderLen 	if  length  >= (1  << 24 ) {		return  http2ErrFrameTooLarge 	}	_ = append (f .wbuf [:0 ],		byte (length >>16 ),		byte (length >>8 ),		byte (length ))	if  f .logWrites  {		f .logWrite ()	}	n , err  := f .w .Write (f .wbuf )	if  err  == nil  && n  != len (f .wbuf ) {		err  = io .ErrShortWrite 	}	return  err }func  (f  *http2Framer ) logWrite 	if  f .debugFramer  == nil  {		f .debugFramerBuf  = new (bytes .Buffer )		f .debugFramer  = http2NewFramer (nil , f .debugFramerBuf )		f .debugFramer .logReads  = false  				f .debugFramer .AllowIllegalReads  = true 	}	f .debugFramerBuf .Write (f .wbuf )	fr , err  := f .debugFramer .ReadFrame ()	if  err  != nil  {		f .debugWriteLoggerf ("http2: Framer %p: failed to decode just-written frame" , f )		return 	}	f .debugWriteLoggerf ("http2: Framer %p: wrote %v" , f , http2summarizeFrame (fr ))}func  (f  *http2Framer ) writeByte v  byte ) { f .wbuf  = append (f .wbuf , v ) }func  (f  *http2Framer ) writeBytes v  []byte ) { f .wbuf  = append (f .wbuf , v ...) }func  (f  *http2Framer ) writeUint16 v  uint16 ) { f .wbuf  = append (f .wbuf , byte (v >>8 ), byte (v )) }func  (f  *http2Framer ) writeUint32 v  uint32 ) {	f .wbuf  = append (f .wbuf , byte (v >>24 ), byte (v >>16 ), byte (v >>8 ), byte (v ))}const  (	http2minMaxFrameSize  = 1  << 14 	http2maxFrameSize     = 1 <<24  - 1 )func  (fr  *http2Framer ) SetReuseFrames 	if  fr .frameCache  != nil  {		return 	}	fr .frameCache  = &http2frameCache {}}type  http2frameCache  struct  {	dataFrame  http2DataFrame }func  (fc  *http2frameCache ) getDataFrame http2DataFrame  {	if  fc  == nil  {		return  &http2DataFrame {}	}	return  &fc .dataFrame }func  http2NewFramer w  io .Writer , r  io .Reader ) *http2Framer  {	fr  := &http2Framer {		w :                 w ,		r :                 r ,		countError :        func (string ) {},		logReads :          http2logFrameReads ,		logWrites :         http2logFrameWrites ,		debugReadLoggerf :  log .Printf ,		debugWriteLoggerf : log .Printf ,	}	fr .getReadBuf  = func (size  uint32 ) []byte  {		if  cap (fr .readBuf ) >= int (size ) {			return  fr .readBuf [:size ]		}		fr .readBuf  = make ([]byte , size )		return  fr .readBuf 	}	fr .SetMaxReadFrameSize (http2maxFrameSize )	return  fr }func  (fr  *http2Framer ) SetMaxReadFrameSize v  uint32 ) {	if  v  > http2maxFrameSize  {		v  = http2maxFrameSize 	}	fr .maxReadSize  = v }func  (fr  *http2Framer ) ErrorDetail error  {	return  fr .errDetail }var  http2ErrFrameTooLarge  = errors .New ("http2: frame too large" )func  http2terminalReadFrameError err  error ) bool  {	if  _ , ok  := err .(http2StreamError ); ok  {		return  false 	}	return  err  != nil }func  (fr  *http2Framer ) ReadFrame http2Frame , error ) {	fr .errDetail  = nil 	if  fr .lastFrame  != nil  {		fr .lastFrame .invalidate ()	}	fh , err  := http2readFrameHeader (fr .headerBuf [:], fr .r )	if  err  != nil  {		return  nil , err 	}	if  fh .Length  > fr .maxReadSize  {		return  nil , http2ErrFrameTooLarge 	}	payload  := fr .getReadBuf (fh .Length )	if  _ , err  := io .ReadFull (fr .r , payload ); err  != nil  {		return  nil , err 	}	f , err  := http2typeFrameParser (fh .Type )(fr .frameCache , fh , fr .countError , payload )	if  err  != nil  {		if  ce , ok  := err .(http2connError ); ok  {			return  nil , fr .connError (ce .Code , ce .Reason )		}		return  nil , err 	}	if  err  := fr .checkFrameOrder (f ); err  != nil  {		return  nil , err 	}	if  fr .logReads  {		fr .debugReadLoggerf ("http2: Framer %p: read %v" , fr , http2summarizeFrame (f ))	}	if  fh .Type  == http2FrameHeaders  && fr .ReadMetaHeaders  != nil  {		return  fr .readMetaFrame (f .(*http2HeadersFrame ))	}	return  f , nil }func  (fr  *http2Framer ) connError code  http2ErrCode , reason  string ) error  {	fr .errDetail  = errors .New (reason )	return  http2ConnectionError (code )}func  (fr  *http2Framer ) checkFrameOrder f  http2Frame ) error  {	last  := fr .lastFrame 	fr .lastFrame  = f 	if  fr .AllowIllegalReads  {		return  nil 	}	fh  := f .Header ()	if  fr .lastHeaderStream  != 0  {		if  fh .Type  != http2FrameContinuation  {			return  fr .connError (http2ErrCodeProtocol ,				fmt .Sprintf ("got %s for stream %d; expected CONTINUATION following %s for stream %d" ,					fh .Type , fh .StreamID ,					last .Header ().Type , fr .lastHeaderStream ))		}		if  fh .StreamID  != fr .lastHeaderStream  {			return  fr .connError (http2ErrCodeProtocol ,				fmt .Sprintf ("got CONTINUATION for stream %d; expected stream %d" ,					fh .StreamID , fr .lastHeaderStream ))		}	} else  if  fh .Type  == http2FrameContinuation  {		return  fr .connError (http2ErrCodeProtocol , fmt .Sprintf ("unexpected CONTINUATION for stream %d" , fh .StreamID ))	}	switch  fh .Type  {	case  http2FrameHeaders , http2FrameContinuation :		if  fh .Flags .Has (http2FlagHeadersEndHeaders ) {			fr .lastHeaderStream  = 0 		} else  {			fr .lastHeaderStream  = fh .StreamID 		}	}	return  nil }type  http2DataFrame  struct  {	http2FrameHeader 	data  []byte }func  (f  *http2DataFrame ) StreamEnded bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagDataEndStream )}func  (f  *http2DataFrame ) Data byte  {	f .checkValid ()	return  f .data }func  http2parseDataFrame fc  *http2frameCache , fh  http2FrameHeader , countError  func (string ), payload  []byte ) (http2Frame , error ) {	if  fh .StreamID  == 0  {				countError ("frame_data_stream_0" )		return  nil , http2connError {http2ErrCodeProtocol , "DATA frame with stream ID 0" }	}	f  := fc .getDataFrame ()	f .http2FrameHeader  = fh 	var  padSize  byte 	if  fh .Flags .Has (http2FlagDataPadded ) {		var  err  error 		payload , padSize , err  = http2readByte (payload )		if  err  != nil  {			countError ("frame_data_pad_byte_short" )			return  nil , err 		}	}	if  int (padSize ) > len (payload ) {				countError ("frame_data_pad_too_big" )		return  nil , http2connError {http2ErrCodeProtocol , "pad size larger than data payload" }	}	f .data  = payload [:len (payload )-int (padSize )]	return  f , nil }var  (	http2errStreamID     = errors .New ("invalid stream ID" )	http2errDepStreamID  = errors .New ("invalid dependent stream ID" )	http2errPadLength    = errors .New ("pad length too large" )	http2errPadBytes     = errors .New ("padding bytes must all be zeros unless AllowIllegalWrites is enabled" ))func  http2validStreamIDOrZero streamID  uint32 ) bool  {	return  streamID &(1 <<31 ) == 0 }func  http2validStreamID streamID  uint32 ) bool  {	return  streamID  != 0  && streamID &(1 <<31 ) == 0 }func  (f  *http2Framer ) WriteData streamID  uint32 , endStream  bool , data  []byte ) error  {	return  f .WriteDataPadded (streamID , endStream , data , nil )}func  (f  *http2Framer ) WriteDataPadded streamID  uint32 , endStream  bool , data , pad  []byte ) error  {	if  err  := f .startWriteDataPadded (streamID , endStream , data , pad ); err  != nil  {		return  err 	}	return  f .endWrite ()}func  (f  *http2Framer ) startWriteDataPadded streamID  uint32 , endStream  bool , data , pad  []byte ) error  {	if  !http2validStreamID (streamID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	if  len (pad ) > 0  {		if  len (pad ) > 255  {			return  http2errPadLength 		}		if  !f .AllowIllegalWrites  {			for  _ , b  := range  pad  {				if  b  != 0  {										return  http2errPadBytes 				}			}		}	}	var  flags  http2Flags 	if  endStream  {		flags  |= http2FlagDataEndStream 	}	if  pad  != nil  {		flags  |= http2FlagDataPadded 	}	f .startWrite (http2FrameData , flags , streamID )	if  pad  != nil  {		f .wbuf  = append (f .wbuf , byte (len (pad )))	}	f .wbuf  = append (f .wbuf , data ...)	f .wbuf  = append (f .wbuf , pad ...)	return  nil }type  http2SettingsFrame  struct  {	http2FrameHeader 	p  []byte }func  http2parseSettingsFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (http2Frame , error ) {	if  fh .Flags .Has (http2FlagSettingsAck ) && fh .Length  > 0  {				countError ("frame_settings_ack_with_length" )		return  nil , http2ConnectionError (http2ErrCodeFrameSize )	}	if  fh .StreamID  != 0  {				countError ("frame_settings_has_stream" )		return  nil , http2ConnectionError (http2ErrCodeProtocol )	}	if  len (p )%6  != 0  {		countError ("frame_settings_mod_6" )				return  nil , http2ConnectionError (http2ErrCodeFrameSize )	}	f  := &http2SettingsFrame {http2FrameHeader : fh , p : p }	if  v , ok  := f .Value (http2SettingInitialWindowSize ); ok  && v  > (1 <<31 )-1  {		countError ("frame_settings_window_size_too_big" )				return  nil , http2ConnectionError (http2ErrCodeFlowControl )	}	return  f , nil }func  (f  *http2SettingsFrame ) IsAck bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagSettingsAck )}func  (f  *http2SettingsFrame ) Value id  http2SettingID ) (v  uint32 , ok  bool ) {	f .checkValid ()	for  i  := 0 ; i  < f .NumSettings (); i ++ {		if  s  := f .Setting (i ); s .ID  == id  {			return  s .Val , true 		}	}	return  0 , false }func  (f  *http2SettingsFrame ) Setting i  int ) http2Setting  {	buf  := f .p 	return  http2Setting {		ID :  http2SettingID (binary .BigEndian .Uint16 (buf [i *6  : i *6 +2 ])),		Val : binary .BigEndian .Uint32 (buf [i *6 +2  : i *6 +6 ]),	}}func  (f  *http2SettingsFrame ) NumSettings int  { return  len (f .p ) / 6  }func  (f  *http2SettingsFrame ) HasDuplicates bool  {	num  := f .NumSettings ()	if  num  == 0  {		return  false 	}		if  num  < 10  {		for  i  := 0 ; i  < num ; i ++ {			idi  := f .Setting (i ).ID 			for  j  := i  + 1 ; j  < num ; j ++ {				idj  := f .Setting (j ).ID 				if  idi  == idj  {					return  true 				}			}		}		return  false 	}	seen  := map [http2SettingID ]bool {}	for  i  := 0 ; i  < num ; i ++ {		id  := f .Setting (i ).ID 		if  seen [id ] {			return  true 		}		seen [id ] = true 	}	return  false }func  (f  *http2SettingsFrame ) ForeachSetting fn  func (http2Setting ) error ) error  {	f .checkValid ()	for  i  := 0 ; i  < f .NumSettings (); i ++ {		if  err  := fn (f .Setting (i )); err  != nil  {			return  err 		}	}	return  nil }func  (f  *http2Framer ) WriteSettings settings  ...http2Setting ) error  {	f .startWrite (http2FrameSettings , 0 , 0 )	for  _ , s  := range  settings  {		f .writeUint16 (uint16 (s .ID ))		f .writeUint32 (s .Val )	}	return  f .endWrite ()}func  (f  *http2Framer ) WriteSettingsAck error  {	f .startWrite (http2FrameSettings , http2FlagSettingsAck , 0 )	return  f .endWrite ()}type  http2PingFrame  struct  {	http2FrameHeader 	Data  [8 ]byte }func  (f  *http2PingFrame ) IsAck bool  { return  f .Flags .Has (http2FlagPingAck ) }func  http2parsePingFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), payload  []byte ) (http2Frame , error ) {	if  len (payload ) != 8  {		countError ("frame_ping_length" )		return  nil , http2ConnectionError (http2ErrCodeFrameSize )	}	if  fh .StreamID  != 0  {		countError ("frame_ping_has_stream" )		return  nil , http2ConnectionError (http2ErrCodeProtocol )	}	f  := &http2PingFrame {http2FrameHeader : fh }	copy (f .Data [:], payload )	return  f , nil }func  (f  *http2Framer ) WritePing ack  bool , data  [8 ]byte ) error  {	var  flags  http2Flags 	if  ack  {		flags  = http2FlagPingAck 	}	f .startWrite (http2FramePing , flags , 0 )	f .writeBytes (data [:])	return  f .endWrite ()}type  http2GoAwayFrame  struct  {	http2FrameHeader 	LastStreamID  uint32 	ErrCode       http2ErrCode 	debugData     []byte }func  (f  *http2GoAwayFrame ) DebugData byte  {	f .checkValid ()	return  f .debugData }func  http2parseGoAwayFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (http2Frame , error ) {	if  fh .StreamID  != 0  {		countError ("frame_goaway_has_stream" )		return  nil , http2ConnectionError (http2ErrCodeProtocol )	}	if  len (p ) < 8  {		countError ("frame_goaway_short" )		return  nil , http2ConnectionError (http2ErrCodeFrameSize )	}	return  &http2GoAwayFrame {		http2FrameHeader : fh ,		LastStreamID :     binary .BigEndian .Uint32 (p [:4 ]) & (1 <<31  - 1 ),		ErrCode :          http2ErrCode (binary .BigEndian .Uint32 (p [4 :8 ])),		debugData :        p [8 :],	}, nil }func  (f  *http2Framer ) WriteGoAway maxStreamID  uint32 , code  http2ErrCode , debugData  []byte ) error  {	f .startWrite (http2FrameGoAway , 0 , 0 )	f .writeUint32 (maxStreamID  & (1 <<31  - 1 ))	f .writeUint32 (uint32 (code ))	f .writeBytes (debugData )	return  f .endWrite ()}type  http2UnknownFrame  struct  {	http2FrameHeader 	p  []byte }func  (f  *http2UnknownFrame ) Payload byte  {	f .checkValid ()	return  f .p }func  http2parseUnknownFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (http2Frame , error ) {	return  &http2UnknownFrame {fh , p }, nil }type  http2WindowUpdateFrame  struct  {	http2FrameHeader 	Increment  uint32  }func  http2parseWindowUpdateFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (http2Frame , error ) {	if  len (p ) != 4  {		countError ("frame_windowupdate_bad_len" )		return  nil , http2ConnectionError (http2ErrCodeFrameSize )	}	inc  := binary .BigEndian .Uint32 (p [:4 ]) & 0x7fffffff  	if  inc  == 0  {				if  fh .StreamID  == 0  {			countError ("frame_windowupdate_zero_inc_conn" )			return  nil , http2ConnectionError (http2ErrCodeProtocol )		}		countError ("frame_windowupdate_zero_inc_stream" )		return  nil , http2streamError (fh .StreamID , http2ErrCodeProtocol )	}	return  &http2WindowUpdateFrame {		http2FrameHeader : fh ,		Increment :        inc ,	}, nil }func  (f  *http2Framer ) WriteWindowUpdate streamID , incr  uint32 ) error  {		if  (incr  < 1  || incr  > 2147483647 ) && !f .AllowIllegalWrites  {		return  errors .New ("illegal window increment value" )	}	f .startWrite (http2FrameWindowUpdate , 0 , streamID )	f .writeUint32 (incr )	return  f .endWrite ()}type  http2HeadersFrame  struct  {	http2FrameHeader 		Priority  http2PriorityParam 	headerFragBuf  []byte  }func  (f  *http2HeadersFrame ) HeaderBlockFragment byte  {	f .checkValid ()	return  f .headerFragBuf }func  (f  *http2HeadersFrame ) HeadersEnded bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagHeadersEndHeaders )}func  (f  *http2HeadersFrame ) StreamEnded bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagHeadersEndStream )}func  (f  *http2HeadersFrame ) HasPriority bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagHeadersPriority )}func  http2parseHeadersFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (_  http2Frame , err  error ) {	hf  := &http2HeadersFrame {		http2FrameHeader : fh ,	}	if  fh .StreamID  == 0  {				countError ("frame_headers_zero_stream" )		return  nil , http2connError {http2ErrCodeProtocol , "HEADERS frame with stream ID 0" }	}	var  padLength  uint8 	if  fh .Flags .Has (http2FlagHeadersPadded ) {		if  p , padLength , err  = http2readByte (p ); err  != nil  {			countError ("frame_headers_pad_short" )			return 		}	}	if  fh .Flags .Has (http2FlagHeadersPriority ) {		var  v  uint32 		p , v , err  = http2readUint32 (p )		if  err  != nil  {			countError ("frame_headers_prio_short" )			return  nil , err 		}		hf .Priority .StreamDep  = v  & 0x7fffffff 		hf .Priority .Exclusive  = (v  != hf .Priority .StreamDep ) 		p , hf .Priority .Weight , err  = http2readByte (p )		if  err  != nil  {			countError ("frame_headers_prio_weight_short" )			return  nil , err 		}	}	if  len (p )-int (padLength ) < 0  {		countError ("frame_headers_pad_too_big" )		return  nil , http2streamError (fh .StreamID , http2ErrCodeProtocol )	}	hf .headerFragBuf  = p [:len (p )-int (padLength )]	return  hf , nil }type  http2HeadersFrameParam  struct  {		StreamID  uint32 		BlockFragment  []byte 		EndStream  bool 		EndHeaders  bool 		PadLength  uint8 		Priority  http2PriorityParam }func  (f  *http2Framer ) WriteHeaders p  http2HeadersFrameParam ) error  {	if  !http2validStreamID (p .StreamID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	var  flags  http2Flags 	if  p .PadLength  != 0  {		flags  |= http2FlagHeadersPadded 	}	if  p .EndStream  {		flags  |= http2FlagHeadersEndStream 	}	if  p .EndHeaders  {		flags  |= http2FlagHeadersEndHeaders 	}	if  !p .Priority .IsZero () {		flags  |= http2FlagHeadersPriority 	}	f .startWrite (http2FrameHeaders , flags , p .StreamID )	if  p .PadLength  != 0  {		f .writeByte (p .PadLength )	}	if  !p .Priority .IsZero () {		v  := p .Priority .StreamDep 		if  !http2validStreamIDOrZero (v ) && !f .AllowIllegalWrites  {			return  http2errDepStreamID 		}		if  p .Priority .Exclusive  {			v  |= 1  << 31 		}		f .writeUint32 (v )		f .writeByte (p .Priority .Weight )	}	f .wbuf  = append (f .wbuf , p .BlockFragment ...)	f .wbuf  = append (f .wbuf , http2padZeros [:p .PadLength ]...)	return  f .endWrite ()}type  http2PriorityFrame  struct  {	http2FrameHeader 	http2PriorityParam }type  http2PriorityParam  struct  {		StreamDep  uint32 		Exclusive  bool 		Weight  uint8 }func  (p  http2PriorityParam ) IsZero bool  {	return  p  == http2PriorityParam {}}func  http2parsePriorityFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), payload  []byte ) (http2Frame , error ) {	if  fh .StreamID  == 0  {		countError ("frame_priority_zero_stream" )		return  nil , http2connError {http2ErrCodeProtocol , "PRIORITY frame with stream ID 0" }	}	if  len (payload ) != 5  {		countError ("frame_priority_bad_length" )		return  nil , http2connError {http2ErrCodeFrameSize , fmt .Sprintf ("PRIORITY frame payload size was %d; want 5" , len (payload ))}	}	v  := binary .BigEndian .Uint32 (payload [:4 ])	streamID  := v  & 0x7fffffff  	return  &http2PriorityFrame {		http2FrameHeader : fh ,		http2PriorityParam : http2PriorityParam {			Weight :    payload [4 ],			StreamDep : streamID ,			Exclusive : streamID  != v , 		},	}, nil }func  (f  *http2Framer ) WritePriority streamID  uint32 , p  http2PriorityParam ) error  {	if  !http2validStreamID (streamID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	if  !http2validStreamIDOrZero (p .StreamDep ) {		return  http2errDepStreamID 	}	f .startWrite (http2FramePriority , 0 , streamID )	v  := p .StreamDep 	if  p .Exclusive  {		v  |= 1  << 31 	}	f .writeUint32 (v )	f .writeByte (p .Weight )	return  f .endWrite ()}type  http2RSTStreamFrame  struct  {	http2FrameHeader 	ErrCode  http2ErrCode }func  http2parseRSTStreamFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (http2Frame , error ) {	if  len (p ) != 4  {		countError ("frame_rststream_bad_len" )		return  nil , http2ConnectionError (http2ErrCodeFrameSize )	}	if  fh .StreamID  == 0  {		countError ("frame_rststream_zero_stream" )		return  nil , http2ConnectionError (http2ErrCodeProtocol )	}	return  &http2RSTStreamFrame {fh , http2ErrCode (binary .BigEndian .Uint32 (p [:4 ]))}, nil }func  (f  *http2Framer ) WriteRSTStream streamID  uint32 , code  http2ErrCode ) error  {	if  !http2validStreamID (streamID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	f .startWrite (http2FrameRSTStream , 0 , streamID )	f .writeUint32 (uint32 (code ))	return  f .endWrite ()}type  http2ContinuationFrame  struct  {	http2FrameHeader 	headerFragBuf  []byte }func  http2parseContinuationFrame _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (http2Frame , error ) {	if  fh .StreamID  == 0  {		countError ("frame_continuation_zero_stream" )		return  nil , http2connError {http2ErrCodeProtocol , "CONTINUATION frame with stream ID 0" }	}	return  &http2ContinuationFrame {fh , p }, nil }func  (f  *http2ContinuationFrame ) HeaderBlockFragment byte  {	f .checkValid ()	return  f .headerFragBuf }func  (f  *http2ContinuationFrame ) HeadersEnded bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagContinuationEndHeaders )}func  (f  *http2Framer ) WriteContinuation streamID  uint32 , endHeaders  bool , headerBlockFragment  []byte ) error  {	if  !http2validStreamID (streamID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	var  flags  http2Flags 	if  endHeaders  {		flags  |= http2FlagContinuationEndHeaders 	}	f .startWrite (http2FrameContinuation , flags , streamID )	f .wbuf  = append (f .wbuf , headerBlockFragment ...)	return  f .endWrite ()}type  http2PushPromiseFrame  struct  {	http2FrameHeader 	PromiseID      uint32 	headerFragBuf  []byte  }func  (f  *http2PushPromiseFrame ) HeaderBlockFragment byte  {	f .checkValid ()	return  f .headerFragBuf }func  (f  *http2PushPromiseFrame ) HeadersEnded bool  {	return  f .http2FrameHeader .Flags .Has (http2FlagPushPromiseEndHeaders )}func  http2parsePushPromise _  *http2frameCache , fh  http2FrameHeader , countError  func (string ), p  []byte ) (_  http2Frame , err  error ) {	pp  := &http2PushPromiseFrame {		http2FrameHeader : fh ,	}	if  pp .StreamID  == 0  {				countError ("frame_pushpromise_zero_stream" )		return  nil , http2ConnectionError (http2ErrCodeProtocol )	}		var  padLength  uint8 	if  fh .Flags .Has (http2FlagPushPromisePadded ) {		if  p , padLength , err  = http2readByte (p ); err  != nil  {			countError ("frame_pushpromise_pad_short" )			return 		}	}	p , pp .PromiseID , err  = http2readUint32 (p )	if  err  != nil  {		countError ("frame_pushpromise_promiseid_short" )		return 	}	pp .PromiseID  = pp .PromiseID  & (1 <<31  - 1 )	if  int (padLength ) > len (p ) {				countError ("frame_pushpromise_pad_too_big" )		return  nil , http2ConnectionError (http2ErrCodeProtocol )	}	pp .headerFragBuf  = p [:len (p )-int (padLength )]	return  pp , nil }type  http2PushPromiseParam  struct  {		StreamID  uint32 		PromiseID  uint32 		BlockFragment  []byte 		EndHeaders  bool 		PadLength  uint8 }func  (f  *http2Framer ) WritePushPromise p  http2PushPromiseParam ) error  {	if  !http2validStreamID (p .StreamID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	var  flags  http2Flags 	if  p .PadLength  != 0  {		flags  |= http2FlagPushPromisePadded 	}	if  p .EndHeaders  {		flags  |= http2FlagPushPromiseEndHeaders 	}	f .startWrite (http2FramePushPromise , flags , p .StreamID )	if  p .PadLength  != 0  {		f .writeByte (p .PadLength )	}	if  !http2validStreamID (p .PromiseID ) && !f .AllowIllegalWrites  {		return  http2errStreamID 	}	f .writeUint32 (p .PromiseID )	f .wbuf  = append (f .wbuf , p .BlockFragment ...)	f .wbuf  = append (f .wbuf , http2padZeros [:p .PadLength ]...)	return  f .endWrite ()}func  (f  *http2Framer ) WriteRawFrame t  http2FrameType , flags  http2Flags , streamID  uint32 , payload  []byte ) error  {	f .startWrite (t , flags , streamID )	f .writeBytes (payload )	return  f .endWrite ()}func  http2readByte p  []byte ) (remain  []byte , b  byte , err  error ) {	if  len (p ) == 0  {		return  nil , 0 , io .ErrUnexpectedEOF 	}	return  p [1 :], p [0 ], nil }func  http2readUint32 p  []byte ) (remain  []byte , v  uint32 , err  error ) {	if  len (p ) < 4  {		return  nil , 0 , io .ErrUnexpectedEOF 	}	return  p [4 :], binary .BigEndian .Uint32 (p [:4 ]), nil }type  http2streamEnder  interface  {	StreamEnded () bool }type  http2headersEnder  interface  {	HeadersEnded () bool }type  http2headersOrContinuation  interface  {	http2headersEnder 	HeaderBlockFragment () []byte }type  http2MetaHeadersFrame  struct  {	*http2HeadersFrame 		Fields  []hpack .HeaderField 		Truncated  bool }func  (mh  *http2MetaHeadersFrame ) PseudoValue pseudo  string ) string  {	for  _ , hf  := range  mh .Fields  {		if  !hf .IsPseudo () {			return  "" 		}		if  hf .Name [1 :] == pseudo  {			return  hf .Value 		}	}	return  "" }func  (mh  *http2MetaHeadersFrame ) RegularFields hpack .HeaderField  {	for  i , hf  := range  mh .Fields  {		if  !hf .IsPseudo () {			return  mh .Fields [i :]		}	}	return  nil }func  (mh  *http2MetaHeadersFrame ) PseudoFields hpack .HeaderField  {	for  i , hf  := range  mh .Fields  {		if  !hf .IsPseudo () {			return  mh .Fields [:i ]		}	}	return  mh .Fields }func  (mh  *http2MetaHeadersFrame ) checkPseudos error  {	var  isRequest , isResponse  bool 	pf  := mh .PseudoFields ()	for  i , hf  := range  pf  {		switch  hf .Name  {		case  ":method" , ":path" , ":scheme" , ":authority" :			isRequest  = true 		case  ":status" :			isResponse  = true 		default :			return  http2pseudoHeaderError (hf .Name )		}				for  _ , hf2  := range  pf [:i ] {			if  hf .Name  == hf2 .Name  {				return  http2duplicatePseudoHeaderError (hf .Name )			}		}	}	if  isRequest  && isResponse  {		return  http2errMixPseudoHeaderTypes 	}	return  nil }func  (fr  *http2Framer ) maxHeaderStringLen int  {	v  := int (fr .maxHeaderListSize ())	if  v  < 0  {				return  0 	}	return  v }func  (fr  *http2Framer ) readMetaFrame hf  *http2HeadersFrame ) (http2Frame , error ) {	if  fr .AllowIllegalReads  {		return  nil , errors .New ("illegal use of AllowIllegalReads with ReadMetaHeaders" )	}	mh  := &http2MetaHeadersFrame {		http2HeadersFrame : hf ,	}	var  remainSize  = fr .maxHeaderListSize ()	var  sawRegular  bool 	var  invalid  error  	hdec  := fr .ReadMetaHeaders 	hdec .SetEmitEnabled (true )	hdec .SetMaxStringLength (fr .maxHeaderStringLen ())	hdec .SetEmitFunc (func (hf  hpack .HeaderField ) {		if  http2VerboseLogs  && fr .logReads  {			fr .debugReadLoggerf ("http2: decoded hpack field %+v" , hf )		}		if  !httpguts .ValidHeaderFieldValue (hf .Value ) {						invalid  = http2headerFieldValueError (hf .Name )		}		isPseudo  := strings .HasPrefix (hf .Name , ":" )		if  isPseudo  {			if  sawRegular  {				invalid  = http2errPseudoAfterRegular 			}		} else  {			sawRegular  = true 			if  !http2validWireHeaderFieldName (hf .Name ) {				invalid  = http2headerFieldNameError (hf .Name )			}		}		if  invalid  != nil  {			hdec .SetEmitEnabled (false )			return 		}		size  := hf .Size ()		if  size  > remainSize  {			hdec .SetEmitEnabled (false )			mh .Truncated  = true 			remainSize  = 0 			return 		}		remainSize  -= size 		mh .Fields  = append (mh .Fields , hf )	})		defer  hdec .SetEmitFunc (func (hf  hpack .HeaderField ) {})	var  hc  http2headersOrContinuation  = hf 	for  {		frag  := hc .HeaderBlockFragment ()				if  int64 (len (frag )) > int64 (2 *remainSize ) {			if  http2VerboseLogs  {				log .Printf ("http2: header list too large" )			}						return  mh , http2ConnectionError (http2ErrCodeProtocol )		}				if  invalid  != nil  {			if  http2VerboseLogs  {				log .Printf ("http2: invalid header: %v" , invalid )			}						return  mh , http2ConnectionError (http2ErrCodeProtocol )		}		if  _ , err  := hdec .Write (frag ); err  != nil  {			return  mh , http2ConnectionError (http2ErrCodeCompression )		}		if  hc .HeadersEnded () {			break 		}		if  f , err  := fr .ReadFrame (); err  != nil  {			return  nil , err 		} else  {			hc  = f .(*http2ContinuationFrame ) 		}	}	mh .http2HeadersFrame .headerFragBuf  = nil 	mh .http2HeadersFrame .invalidate ()	if  err  := hdec .Close (); err  != nil  {		return  mh , http2ConnectionError (http2ErrCodeCompression )	}	if  invalid  != nil  {		fr .errDetail  = invalid 		if  http2VerboseLogs  {			log .Printf ("http2: invalid header: %v" , invalid )		}		return  nil , http2StreamError {mh .StreamID , http2ErrCodeProtocol , invalid }	}	if  err  := mh .checkPseudos (); err  != nil  {		fr .errDetail  = err 		if  http2VerboseLogs  {			log .Printf ("http2: invalid pseudo headers: %v" , err )		}		return  nil , http2StreamError {mh .StreamID , http2ErrCodeProtocol , err }	}	return  mh , nil }func  http2summarizeFrame f  http2Frame ) string  {	var  buf  bytes .Buffer 	f .Header ().writeDebug (&buf )	switch  f := f .(type ) {	case  *http2SettingsFrame :		n  := 0 		f .ForeachSetting (func (s  http2Setting ) error  {			n ++			if  n  == 1  {				buf .WriteString (", settings:" )			}			fmt .Fprintf (&buf , " %v=%v," , s .ID , s .Val )			return  nil 		})		if  n  > 0  {			buf .Truncate (buf .Len () - 1 ) 		}	case  *http2DataFrame :		data  := f .Data ()		const  max  = 256 		if  len (data ) > max  {			data  = data [:max ]		}		fmt .Fprintf (&buf , " data=%q" , data )		if  len (f .Data ()) > max  {			fmt .Fprintf (&buf , " (%d bytes omitted)" , len (f .Data ())-max )		}	case  *http2WindowUpdateFrame :		if  f .StreamID  == 0  {			buf .WriteString (" (conn)" )		}		fmt .Fprintf (&buf , " incr=%v" , f .Increment )	case  *http2PingFrame :		fmt .Fprintf (&buf , " ping=%q" , f .Data [:])	case  *http2GoAwayFrame :		fmt .Fprintf (&buf , " LastStreamID=%v ErrCode=%v Debug=%q" ,			f .LastStreamID , f .ErrCode , f .debugData )	case  *http2RSTStreamFrame :		fmt .Fprintf (&buf , " ErrCode=%v" , f .ErrCode )	}	return  buf .String ()}var  http2DebugGoroutines  = os .Getenv ("DEBUG_HTTP2_GOROUTINES" ) == "1" type  http2goroutineLock  uint64 func  http2newGoroutineLock http2goroutineLock  {	if  !http2DebugGoroutines  {		return  0 	}	return  http2goroutineLock (http2curGoroutineID ())}func  (g  http2goroutineLock ) check 	if  !http2DebugGoroutines  {		return 	}	if  http2curGoroutineID () != uint64 (g ) {		panic ("running on the wrong goroutine" )	}}func  (g  http2goroutineLock ) checkNotOn 	if  !http2DebugGoroutines  {		return 	}	if  http2curGoroutineID () == uint64 (g ) {		panic ("running on the wrong goroutine" )	}}var  http2goroutineSpace  = []byte ("goroutine " )func  http2curGoroutineID uint64  {	bp  := http2littleBuf .Get ().(*[]byte )	defer  http2littleBuf .Put (bp )	b  := *bp 	b  = b [:runtime .Stack (b , false )]		b  = bytes .TrimPrefix (b , http2goroutineSpace )	i  := bytes .IndexByte (b , ' ' )	if  i  < 0  {		panic (fmt .Sprintf ("No space found in %q" , b ))	}	b  = b [:i ]	n , err  := http2parseUintBytes (b , 10 , 64 )	if  err  != nil  {		panic (fmt .Sprintf ("Failed to parse goroutine ID out of %q: %v" , b , err ))	}	return  n }var  http2littleBuf  = sync .Pool {	New : func () interface {} {		buf  := make ([]byte , 64 )		return  &buf 	},}func  http2parseUintBytes s  []byte , base  int , bitSize  int ) (n  uint64 , err  error ) {	var  cutoff , maxVal  uint64 	if  bitSize  == 0  {		bitSize  = int (strconv .IntSize )	}	s0  := s 	switch  {	case  len (s ) < 1 :		err  = strconv .ErrSyntax 		goto  Error 	case  2  <= base  && base  <= 36 :			case  base  == 0 :				switch  {		case  s [0 ] == '0'  && len (s ) > 1  && (s [1 ] == 'x'  || s [1 ] == 'X' ):			base  = 16 			s  = s [2 :]			if  len (s ) < 1  {				err  = strconv .ErrSyntax 				goto  Error 			}		case  s [0 ] == '0' :			base  = 8 		default :			base  = 10 		}	default :		err  = errors .New ("invalid base "  + strconv .Itoa (base ))		goto  Error 	}	n  = 0 	cutoff  = http2cutoff64 (base )	maxVal  = 1 <<uint (bitSize ) - 1 	for  i  := 0 ; i  < len (s ); i ++ {		var  v  byte 		d  := s [i ]		switch  {		case  '0'  <= d  && d  <= '9' :			v  = d  - '0' 		case  'a'  <= d  && d  <= 'z' :			v  = d  - 'a'  + 10 		case  'A'  <= d  && d  <= 'Z' :			v  = d  - 'A'  + 10 		default :			n  = 0 			err  = strconv .ErrSyntax 			goto  Error 		}		if  int (v ) >= base  {			n  = 0 			err  = strconv .ErrSyntax 			goto  Error 		}		if  n  >= cutoff  {						n  = 1 <<64  - 1 			err  = strconv .ErrRange 			goto  Error 		}		n  *= uint64 (base )		n1  := n  + uint64 (v )		if  n1  < n  || n1  > maxVal  {						n  = 1 <<64  - 1 			err  = strconv .ErrRange 			goto  Error 		}		n  = n1 	}	return  n , nil Error :	return  n , &strconv .NumError {Func : "ParseUint" , Num : string (s0 ), Err : err }}func  http2cutoff64 base  int ) uint64  {	if  base  < 2  {		return  0 	}	return  (1 <<64 -1 )/uint64 (base ) + 1 }var  (	http2commonBuildOnce    sync .Once 	http2commonLowerHeader  map [string ]string  	http2commonCanonHeader  map [string ]string  )func  http2buildCommonHeaderMapsOnce 	http2commonBuildOnce .Do (http2buildCommonHeaderMaps )}func  http2buildCommonHeaderMaps 	common  := []string {		"accept" ,		"accept-charset" ,		"accept-encoding" ,		"accept-language" ,		"accept-ranges" ,		"age" ,		"access-control-allow-credentials" ,		"access-control-allow-headers" ,		"access-control-allow-methods" ,		"access-control-allow-origin" ,		"access-control-expose-headers" ,		"access-control-max-age" ,		"access-control-request-headers" ,		"access-control-request-method" ,		"allow" ,		"authorization" ,		"cache-control" ,		"content-disposition" ,		"content-encoding" ,		"content-language" ,		"content-length" ,		"content-location" ,		"content-range" ,		"content-type" ,		"cookie" ,		"date" ,		"etag" ,		"expect" ,		"expires" ,		"from" ,		"host" ,		"if-match" ,		"if-modified-since" ,		"if-none-match" ,		"if-unmodified-since" ,		"last-modified" ,		"link" ,		"location" ,		"max-forwards" ,		"origin" ,		"proxy-authenticate" ,		"proxy-authorization" ,		"range" ,		"referer" ,		"refresh" ,		"retry-after" ,		"server" ,		"set-cookie" ,		"strict-transport-security" ,		"trailer" ,		"transfer-encoding" ,		"user-agent" ,		"vary" ,		"via" ,		"www-authenticate" ,		"x-forwarded-for" ,		"x-forwarded-proto" ,	}	http2commonLowerHeader  = make (map [string ]string , len (common ))	http2commonCanonHeader  = make (map [string ]string , len (common ))	for  _ , v  := range  common  {		chk  := CanonicalHeaderKey (v )		http2commonLowerHeader [chk ] = v 		http2commonCanonHeader [v ] = chk 	}}func  http2lowerHeader v  string ) (lower  string , ascii  bool ) {	http2buildCommonHeaderMapsOnce ()	if  s , ok  := http2commonLowerHeader [v ]; ok  {		return  s , true 	}	return  http2asciiToLower (v )}func  http2canonicalHeader v  string ) string  {	http2buildCommonHeaderMapsOnce ()	if  s , ok  := http2commonCanonHeader [v ]; ok  {		return  s 	}	return  CanonicalHeaderKey (v )}var  (	http2VerboseLogs     bool 	http2logFrameWrites  bool 	http2logFrameReads   bool 	http2inTests         bool )func  init 	e  := os .Getenv ("GODEBUG" )	if  strings .Contains (e , "http2debug=1" ) {		http2VerboseLogs  = true 	}	if  strings .Contains (e , "http2debug=2" ) {		http2VerboseLogs  = true 		http2logFrameWrites  = true 		http2logFrameReads  = true 	}}const  (		http2ClientPreface  = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 		http2initialMaxFrameSize  = 16384 		http2NextProtoTLS  = "h2" 		http2initialHeaderTableSize  = 4096 	http2initialWindowSize  = 65535  	http2defaultMaxReadFrameSize  = 1  << 20 )var  (	http2clientPreface  = []byte (http2ClientPreface ))type  http2streamState  int const  (	http2stateIdle  http2streamState  = iota 	http2stateOpen 	http2stateHalfClosedLocal 	http2stateHalfClosedRemote 	http2stateClosed )var  http2stateName  = [...]string {	http2stateIdle :             "Idle" ,	http2stateOpen :             "Open" ,	http2stateHalfClosedLocal :  "HalfClosedLocal" ,	http2stateHalfClosedRemote : "HalfClosedRemote" ,	http2stateClosed :           "Closed" ,}func  (st  http2streamState ) String string  {	return  http2stateName [st ]}type  http2Setting  struct  {		ID  http2SettingID 		Val  uint32 }func  (s  http2Setting ) String string  {	return  fmt .Sprintf ("[%v = %d]" , s .ID , s .Val )}func  (s  http2Setting ) Valid error  {		switch  s .ID  {	case  http2SettingEnablePush :		if  s .Val  != 1  && s .Val  != 0  {			return  http2ConnectionError (http2ErrCodeProtocol )		}	case  http2SettingInitialWindowSize :		if  s .Val  > 1 <<31 -1  {			return  http2ConnectionError (http2ErrCodeFlowControl )		}	case  http2SettingMaxFrameSize :		if  s .Val  < 16384  || s .Val  > 1 <<24 -1  {			return  http2ConnectionError (http2ErrCodeProtocol )		}	}	return  nil }type  http2SettingID  uint16 const  (	http2SettingHeaderTableSize       http2SettingID  = 0x1 	http2SettingEnablePush            http2SettingID  = 0x2 	http2SettingMaxConcurrentStreams  http2SettingID  = 0x3 	http2SettingInitialWindowSize     http2SettingID  = 0x4 	http2SettingMaxFrameSize          http2SettingID  = 0x5 	http2SettingMaxHeaderListSize     http2SettingID  = 0x6 )var  http2settingName  = map [http2SettingID ]string {	http2SettingHeaderTableSize :      "HEADER_TABLE_SIZE" ,	http2SettingEnablePush :           "ENABLE_PUSH" ,	http2SettingMaxConcurrentStreams : "MAX_CONCURRENT_STREAMS" ,	http2SettingInitialWindowSize :    "INITIAL_WINDOW_SIZE" ,	http2SettingMaxFrameSize :         "MAX_FRAME_SIZE" ,	http2SettingMaxHeaderListSize :    "MAX_HEADER_LIST_SIZE" ,}func  (s  http2SettingID ) String string  {	if  v , ok  := http2settingName [s ]; ok  {		return  v 	}	return  fmt .Sprintf ("UNKNOWN_SETTING_%d" , uint16 (s ))}func  http2validWireHeaderFieldName v  string ) bool  {	if  len (v ) == 0  {		return  false 	}	for  _ , r  := range  v  {		if  !httpguts .IsTokenRune (r ) {			return  false 		}		if  'A'  <= r  && r  <= 'Z'  {			return  false 		}	}	return  true }func  http2httpCodeString code  int ) string  {	switch  code  {	case  200 :		return  "200" 	case  404 :		return  "404" 	}	return  strconv .Itoa (code )}type  http2stringWriter  interface  {	WriteString (s string ) (n int , err error )}type  http2closeWaiter  chan  struct {}func  (cw  *http2closeWaiter ) Init 	*cw  = make (chan  struct {})}func  (cw  http2closeWaiter ) Close 	close (cw )}func  (cw  http2closeWaiter ) Wait 	<-cw }type  http2bufferedWriter  struct  {	_  http2incomparable 	w   io .Writer      	bw  *bufio .Writer  }func  http2newBufferedWriter w  io .Writer ) *http2bufferedWriter  {	return  &http2bufferedWriter {w : w }}const  http2bufWriterPoolBufferSize  = 4  << 10 var  http2bufWriterPool  = sync .Pool {	New : func () interface {} {		return  bufio .NewWriterSize (nil , http2bufWriterPoolBufferSize )	},}func  (w  *http2bufferedWriter ) Available int  {	if  w .bw  == nil  {		return  http2bufWriterPoolBufferSize 	}	return  w .bw .Available ()}func  (w  *http2bufferedWriter ) Write p  []byte ) (n  int , err  error ) {	if  w .bw  == nil  {		bw  := http2bufWriterPool .Get ().(*bufio .Writer )		bw .Reset (w .w )		w .bw  = bw 	}	return  w .bw .Write (p )}func  (w  *http2bufferedWriter ) Flush error  {	bw  := w .bw 	if  bw  == nil  {		return  nil 	}	err  := bw .Flush ()	bw .Reset (nil )	http2bufWriterPool .Put (bw )	w .bw  = nil 	return  err }func  http2mustUint31 v  int32 ) uint32  {	if  v  < 0  || v  > 2147483647  {		panic ("out of range" )	}	return  uint32 (v )}func  http2bodyAllowedForStatus status  int ) bool  {	switch  {	case  status  >= 100  && status  <= 199 :		return  false 	case  status  == 204 :		return  false 	case  status  == 304 :		return  false 	}	return  true }type  http2httpError  struct  {	_       http2incomparable 	msg      string 	timeout  bool }func  (e  *http2httpError ) Error string  { return  e .msg  }func  (e  *http2httpError ) Timeout bool  { return  e .timeout  }func  (e  *http2httpError ) Temporary bool  { return  true  }var  http2errTimeout  error  = &http2httpError {msg : "http2: timeout awaiting response headers" , timeout : true }type  http2connectionStater  interface  {	ConnectionState () tls .ConnectionState }var  http2sorterPool  = sync .Pool {New : func () interface {} { return  new (http2sorter ) }}type  http2sorter  struct  {	v  []string  }func  (s  *http2sorter ) Len int  { return  len (s .v ) }func  (s  *http2sorter ) Swap i , j  int ) { s .v [i ], s .v [j ] = s .v [j ], s .v [i ] }func  (s  *http2sorter ) Less i , j  int ) bool  { return  s .v [i ] < s .v [j ] }func  (s  *http2sorter ) Keys h  Header ) []string  {	keys  := s .v [:0 ]	for  k  := range  h  {		keys  = append (keys , k )	}	s .v  = keys 	sort .Sort (s )	return  keys }func  (s  *http2sorter ) SortStrings ss  []string ) {		save  := s .v 	s .v  = ss 	sort .Sort (s )	s .v  = save }func  http2validPseudoPath v  string ) bool  {	return  (len (v ) > 0  && v [0 ] == '/' ) || v  == "*" }type  http2incomparable  [0 ]func ()type  http2synctestGroupInterface  interface  {	Join ()	Now () time .Time 	NewTimer (d time .Duration ) http2timer 	AfterFunc (d time .Duration , f func ()) http2timer 	ContextWithTimeout (ctx context .Context , d time .Duration ) (context .Context , context .CancelFunc )}type  http2pipe  struct  {	mu        sync .Mutex 	c         sync .Cond        	b         http2pipeBuffer  	unread    int              	err       error            	breakErr  error            	donec     chan  struct {}   	readFn    func ()          }type  http2pipeBuffer  interface  {	Len () int 	io .Writer 	io .Reader }func  (p  *http2pipe ) setBuffer b  http2pipeBuffer ) {	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .err  != nil  || p .breakErr  != nil  {		return 	}	p .b  = b }func  (p  *http2pipe ) Len int  {	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .b  == nil  {		return  p .unread 	}	return  p .b .Len ()}func  (p  *http2pipe ) Read d  []byte ) (n  int , err  error ) {	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .c .L  == nil  {		p .c .L  = &p .mu 	}	for  {		if  p .breakErr  != nil  {			return  0 , p .breakErr 		}		if  p .b  != nil  && p .b .Len () > 0  {			return  p .b .Read (d )		}		if  p .err  != nil  {			if  p .readFn  != nil  {				p .readFn ()     				p .readFn  = nil  			}			p .b  = nil 			return  0 , p .err 		}		p .c .Wait ()	}}var  (	http2errClosedPipeWrite         = errors .New ("write on closed buffer" )	http2errUninitializedPipeWrite  = errors .New ("write on uninitialized buffer" ))func  (p  *http2pipe ) Write d  []byte ) (n  int , err  error ) {	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .c .L  == nil  {		p .c .L  = &p .mu 	}	defer  p .c .Signal ()	if  p .err  != nil  || p .breakErr  != nil  {		return  0 , http2errClosedPipeWrite 	}		if  p .b  == nil  {		return  0 , http2errUninitializedPipeWrite 	}	return  p .b .Write (d )}func  (p  *http2pipe ) CloseWithError err  error ) { p .closeWithError (&p .err , err , nil ) }func  (p  *http2pipe ) BreakWithError err  error ) { p .closeWithError (&p .breakErr , err , nil ) }func  (p  *http2pipe ) closeWithErrorAndCode err  error , fn  func ()) { p .closeWithError (&p .err , err , fn ) }func  (p  *http2pipe ) closeWithError dst  *error , err  error , fn  func ()) {	if  err  == nil  {		panic ("err must be non-nil" )	}	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .c .L  == nil  {		p .c .L  = &p .mu 	}	defer  p .c .Signal ()	if  *dst  != nil  {				return 	}	p .readFn  = fn 	if  dst  == &p .breakErr  {		if  p .b  != nil  {			p .unread  += p .b .Len ()		}		p .b  = nil 	}	*dst  = err 	p .closeDoneLocked ()}func  (p  *http2pipe ) closeDoneLocked 	if  p .donec  == nil  {		return 	}		select 	case  <- p .donec :	default :		close (p .donec )	}}func  (p  *http2pipe ) Err error  {	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .breakErr  != nil  {		return  p .breakErr 	}	return  p .err }func  (p  *http2pipe ) Done chan  struct {} {	p .mu .Lock ()	defer  p .mu .Unlock ()	if  p .donec  == nil  {		p .donec  = make (chan  struct {})		if  p .err  != nil  || p .breakErr  != nil  {						p .closeDoneLocked ()		}	}	return  p .donec }const  (	http2prefaceTimeout          = 10  * time .Second 	http2firstSettingsTimeout    = 2  * time .Second  	http2handlerChunkWriteSize   = 4  << 10 	http2defaultMaxStreams       = 250  	http2maxQueuedControlFrames  = 10000 )var  (	http2errClientDisconnected  = errors .New ("client disconnected" )	http2errClosedBody          = errors .New ("body closed by handler" )	http2errHandlerComplete     = errors .New ("http2: request body closed due to handler exiting" )	http2errStreamClosed        = errors .New ("http2: stream closed" ))var  http2responseWriterStatePool  = sync .Pool {	New : func () interface {} {		rws  := &http2responseWriterState {}		rws .bw  = bufio .NewWriterSize (http2chunkWriter {rws }, http2handlerChunkWriteSize )		return  rws 	},}var  (	http2testHookOnConn         func ()	http2testHookGetServerConn  func (*http2serverConn )	http2testHookOnPanicMu      *sync .Mutex  	http2testHookOnPanic        func (sc *http2serverConn , panicVal interface {}) (rePanic bool ))type  http2Server  struct  {		MaxHandlers  int 		MaxConcurrentStreams  uint32 		MaxDecoderHeaderTableSize  uint32 		MaxEncoderHeaderTableSize  uint32 		MaxReadFrameSize  uint32 		PermitProhibitedCipherSuites  bool 		IdleTimeout  time .Duration 		MaxUploadBufferPerConnection  int32 		MaxUploadBufferPerStream  int32 		NewWriteScheduler  func () http2WriteScheduler 		CountError  func (errType string )		state  *http2serverInternalState 		group  http2synctestGroupInterface }func  (s  *http2Server ) markNewGoroutine 	if  s .group  != nil  {		s .group .Join ()	}}func  (s  *http2Server ) now time .Time  {	if  s .group  != nil  {		return  s .group .Now ()	}	return  time .Now ()}func  (s  *http2Server ) newTimer d  time .Duration ) http2timer  {	if  s .group  != nil  {		return  s .group .NewTimer (d )	}	return  http2timeTimer {time .NewTimer (d )}}func  (s  *http2Server ) afterFunc d  time .Duration , f  func ()) http2timer  {	if  s .group  != nil  {		return  s .group .AfterFunc (d , f )	}	return  http2timeTimer {time .AfterFunc (d , f )}}func  (s  *http2Server ) initialConnRecvWindowSize int32  {	if  s .MaxUploadBufferPerConnection  >= http2initialWindowSize  {		return  s .MaxUploadBufferPerConnection 	}	return  1  << 20 }func  (s  *http2Server ) initialStreamRecvWindowSize int32  {	if  s .MaxUploadBufferPerStream  > 0  {		return  s .MaxUploadBufferPerStream 	}	return  1  << 20 }func  (s  *http2Server ) maxReadFrameSize uint32  {	if  v  := s .MaxReadFrameSize ; v  >= http2minMaxFrameSize  && v  <= http2maxFrameSize  {		return  v 	}	return  http2defaultMaxReadFrameSize }func  (s  *http2Server ) maxConcurrentStreams uint32  {	if  v  := s .MaxConcurrentStreams ; v  > 0  {		return  v 	}	return  http2defaultMaxStreams }func  (s  *http2Server ) maxDecoderHeaderTableSize uint32  {	if  v  := s .MaxDecoderHeaderTableSize ; v  > 0  {		return  v 	}	return  http2initialHeaderTableSize }func  (s  *http2Server ) maxEncoderHeaderTableSize uint32  {	if  v  := s .MaxEncoderHeaderTableSize ; v  > 0  {		return  v 	}	return  http2initialHeaderTableSize }func  (s  *http2Server ) maxQueuedControlFrames int  {		return  http2maxQueuedControlFrames }type  http2serverInternalState  struct  {	mu           sync .Mutex 	activeConns  map [*http2serverConn ]struct {}}func  (s  *http2serverInternalState ) registerConn sc  *http2serverConn ) {	if  s  == nil  {		return  	}	s .mu .Lock ()	s .activeConns [sc ] = struct {}{}	s .mu .Unlock ()}func  (s  *http2serverInternalState ) unregisterConn sc  *http2serverConn ) {	if  s  == nil  {		return  	}	s .mu .Lock ()	delete (s .activeConns , sc )	s .mu .Unlock ()}func  (s  *http2serverInternalState ) startGracefulShutdown 	if  s  == nil  {		return  	}	s .mu .Lock ()	for  sc  := range  s .activeConns  {		sc .startGracefulShutdown ()	}	s .mu .Unlock ()}func  http2ConfigureServer s  *Server , conf  *http2Server ) error  {	if  s  == nil  {		panic ("nil *http.Server" )	}	if  conf  == nil  {		conf  = new (http2Server )	}	conf .state  = &http2serverInternalState {activeConns : make (map [*http2serverConn ]struct {})}	if  h1 , h2  := s , conf ; h2 .IdleTimeout  == 0  {		if  h1 .IdleTimeout  != 0  {			h2 .IdleTimeout  = h1 .IdleTimeout 		} else  {			h2 .IdleTimeout  = h1 .ReadTimeout 		}	}	s .RegisterOnShutdown (conf .state .startGracefulShutdown )	if  s .TLSConfig  == nil  {		s .TLSConfig  = new (tls .Config )	} else  if  s .TLSConfig .CipherSuites  != nil  && s .TLSConfig .MinVersion  < tls .VersionTLS13  {				haveRequired  := false 		for  _ , cs  := range  s .TLSConfig .CipherSuites  {			switch  cs  {			case  tls .TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,								tls .TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :				haveRequired  = true 			}		}		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)" )		}	}		s .TLSConfig .PreferServerCipherSuites  = true 	if  !http2strSliceContains (s .TLSConfig .NextProtos , http2NextProtoTLS ) {		s .TLSConfig .NextProtos  = append (s .TLSConfig .NextProtos , http2NextProtoTLS )	}	if  !http2strSliceContains (s .TLSConfig .NextProtos , "http/1.1" ) {		s .TLSConfig .NextProtos  = append (s .TLSConfig .NextProtos , "http/1.1" )	}	if  s .TLSNextProto  == nil  {		s .TLSNextProto  = map [string ]func (*Server , *tls .Conn , Handler ){}	}	protoHandler  := func (hs  *Server , c  *tls .Conn , h  Handler ) {		if  http2testHookOnConn  != nil  {			http2testHookOnConn ()		}				var  ctx  context .Context 		type  baseContexter  interface  {			BaseContext () context .Context 		}		if  bc , ok  := h .(baseContexter ); ok  {			ctx  = bc .BaseContext ()		}		conf .ServeConn (c , &http2ServeConnOpts {			Context :    ctx ,			Handler :    h ,			BaseConfig : hs ,		})	}	s .TLSNextProto [http2NextProtoTLS ] = protoHandler 	return  nil }type  http2ServeConnOpts  struct  {		Context  context .Context 		BaseConfig  *Server 		Handler  Handler 		UpgradeRequest  *Request 		Settings  []byte 		SawClientPreface  bool }func  (o  *http2ServeConnOpts ) context context .Context  {	if  o  != nil  && o .Context  != nil  {		return  o .Context 	}	return  context .Background ()}func  (o  *http2ServeConnOpts ) baseConfig Server  {	if  o  != nil  && o .BaseConfig  != nil  {		return  o .BaseConfig 	}	return  new (Server )}func  (o  *http2ServeConnOpts ) handler Handler  {	if  o  != nil  {		if  o .Handler  != nil  {			return  o .Handler 		}		if  o .BaseConfig  != nil  && o .BaseConfig .Handler  != nil  {			return  o .BaseConfig .Handler 		}	}	return  DefaultServeMux }func  (s  *http2Server ) ServeConn c  net .Conn , opts  *http2ServeConnOpts ) {	s .serveConn (c , opts , nil )}func  (s  *http2Server ) serveConn c  net .Conn , opts  *http2ServeConnOpts , newf  func (*http2serverConn )) {	baseCtx , cancel  := http2serverConnBaseContext (c , opts )	defer  cancel ()	sc  := &http2serverConn {		srv :                         s ,		hs :                          opts .baseConfig (),		conn :                        c ,		baseCtx :                     baseCtx ,		remoteAddrStr :               c .RemoteAddr ().String (),		bw :                          http2newBufferedWriter (c ),		handler :                     opts .handler (),		streams :                     make (map [uint32 ]*http2stream ),		readFrameCh :                 make (chan  http2readFrameResult ),		wantWriteFrameCh :            make (chan  http2FrameWriteRequest , 8 ),		serveMsgCh :                  make (chan  interface {}, 8 ),		wroteFrameCh :                make (chan  http2frameWriteResult , 1 ), 		bodyReadCh :                  make (chan  http2bodyReadMsg ),         		doneServing :                 make (chan  struct {}),		clientMaxStreams :            math .MaxUint32 , 		advMaxStreams :               s .maxConcurrentStreams (),		initialStreamSendWindowSize : http2initialWindowSize ,		maxFrameSize :                http2initialMaxFrameSize ,		serveG :                      http2newGoroutineLock (),		pushEnabled :                 true ,		sawClientPreface :            opts .SawClientPreface ,	}	if  newf  != nil  {		newf (sc )	}	s .state .registerConn (sc )	defer  s .state .unregisterConn (sc )		if  sc .hs .WriteTimeout  > 0  {		sc .conn .SetWriteDeadline (time .Time {})	}	if  s .NewWriteScheduler  != nil  {		sc .writeSched  = s .NewWriteScheduler ()	} else  {		sc .writeSched  = http2newRoundRobinWriteScheduler ()	}		sc .flow .add (http2initialWindowSize )	sc .inflow .init (http2initialWindowSize )	sc .hpackEncoder  = hpack .NewEncoder (&sc .headerWriteBuf )	sc .hpackEncoder .SetMaxDynamicTableSizeLimit (s .maxEncoderHeaderTableSize ())	fr  := http2NewFramer (sc .bw , c )	if  s .CountError  != nil  {		fr .countError  = s .CountError 	}	fr .ReadMetaHeaders  = hpack .NewDecoder (s .maxDecoderHeaderTableSize (), nil )	fr .MaxHeaderListSize  = sc .maxHeaderListSize ()	fr .SetMaxReadFrameSize (s .maxReadFrameSize ())	sc .framer  = fr 	if  tc , ok  := c .(http2connectionStater ); ok  {		sc .tlsState  = new (tls .ConnectionState )		*sc .tlsState  = tc .ConnectionState ()				if  sc .tlsState .Version  < tls .VersionTLS12  {			sc .rejectConn (http2ErrCodeInadequateSecurity , "TLS version too low" )			return 		}		if  sc .tlsState .ServerName  == ""  {					}		if  !s .PermitProhibitedCipherSuites  && http2isBadCipher (sc .tlsState .CipherSuite ) {						sc .rejectConn (http2ErrCodeInadequateSecurity , fmt .Sprintf ("Prohibited TLS 1.2 Cipher Suite: %x" , sc .tlsState .CipherSuite ))			return 		}	}	if  opts .Settings  != nil  {		fr  := &http2SettingsFrame {			http2FrameHeader : http2FrameHeader {valid : true },			p :                opts .Settings ,		}		if  err  := fr .ForeachSetting (sc .processSetting ); err  != nil  {			sc .rejectConn (http2ErrCodeProtocol , "invalid settings" )			return 		}		opts .Settings  = nil 	}	if  hook  := http2testHookGetServerConn ; hook  != nil  {		hook (sc )	}	if  opts .UpgradeRequest  != nil  {		sc .upgradeRequest (opts .UpgradeRequest )		opts .UpgradeRequest  = nil 	}	sc .serve ()}func  http2serverConnBaseContext c  net .Conn , opts  *http2ServeConnOpts ) (ctx  context .Context , cancel  func ()) {	ctx , cancel  = context .WithCancel (opts .context ())	ctx  = context .WithValue (ctx , LocalAddrContextKey , c .LocalAddr ())	if  hs  := opts .baseConfig (); hs  != nil  {		ctx  = context .WithValue (ctx , ServerContextKey , hs )	}	return }func  (sc  *http2serverConn ) rejectConn err  http2ErrCode , debug  string ) {	sc .vlogf ("http2: server rejecting conn: %v, %s" , err , debug )		sc .framer .WriteGoAway (0 , err , []byte (debug ))	sc .bw .Flush ()	sc .conn .Close ()}type  http2serverConn  struct  {		srv               *http2Server 	hs                *Server 	conn              net .Conn 	bw                *http2bufferedWriter  	handler           Handler 	baseCtx           context .Context 	framer            *http2Framer 	doneServing       chan  struct {}               	readFrameCh       chan  http2readFrameResult    	wantWriteFrameCh  chan  http2FrameWriteRequest  	wroteFrameCh      chan  http2frameWriteResult   	bodyReadCh        chan  http2bodyReadMsg        	serveMsgCh        chan  interface {}            	flow              http2outflow                 	inflow            http2inflow                  	tlsState          *tls .ConnectionState         	remoteAddrStr     string 	writeSched        http2WriteScheduler 		serveG                       http2goroutineLock  	pushEnabled                  bool 	sawClientPreface             bool  	sawFirstSettings             bool  	needToSendSettingsAck        bool 	unackedSettings              int     	queuedControlFrames          int     	clientMaxStreams             uint32  	advMaxStreams                uint32  	curClientStreams             uint32  	curPushedStreams             uint32  	curHandlers                  uint32  	maxClientStreamID            uint32  	maxPushPromiseID             uint32  	streams                      map [uint32 ]*http2stream 	unstartedHandlers            []http2unstartedHandler 	initialStreamSendWindowSize  int32 	maxFrameSize                 int32 	peerMaxHeaderListSize        uint32             	canonHeader                  map [string ]string  	canonHeaderKeysSize          int                	writingFrame                 bool               	writingFrameAsync            bool               	needsFrameFlush              bool               	inGoAway                     bool               	inFrameScheduleLoop          bool               	needToSendGoAway             bool               	goAwayCode                   http2ErrCode 	shutdownTimer                http2timer  	idleTimer                    http2timer  		headerWriteBuf  bytes .Buffer 	hpackEncoder    *hpack .Encoder 		shutdownOnce  sync .Once }func  (sc  *http2serverConn ) maxHeaderListSize uint32  {	n  := sc .hs .MaxHeaderBytes 	if  n  <= 0  {		n  = DefaultMaxHeaderBytes 	}		const  perFieldOverhead  = 32  	const  typicalHeaders  = 10    	return  uint32 (n  + typicalHeaders *perFieldOverhead )}func  (sc  *http2serverConn ) curOpenStreams uint32  {	sc .serveG .check ()	return  sc .curClientStreams  + sc .curPushedStreams }type  http2stream  struct  {		sc         *http2serverConn 	id         uint32 	body       *http2pipe        	cw         http2closeWaiter  	ctx        context .Context 	cancelCtx  func ()		bodyBytes         int64         	declBodyBytes     int64         	flow              http2outflow  	inflow            http2inflow   	state             http2streamState 	resetQueued       bool        	gotTrailerHeader  bool        	wroteHeaders      bool        	readDeadline      http2timer  	writeDeadline     http2timer  	closeErr          error       	trailer     Header  	reqTrailer  Header  }func  (sc  *http2serverConn ) Framer http2Framer  { return  sc .framer  }func  (sc  *http2serverConn ) CloseConn error  { return  sc .conn .Close () }func  (sc  *http2serverConn ) Flush error  { return  sc .bw .Flush () }func  (sc  *http2serverConn ) HeaderEncoder hpack .Encoder , *bytes .Buffer ) {	return  sc .hpackEncoder , &sc .headerWriteBuf }func  (sc  *http2serverConn ) state streamID  uint32 ) (http2streamState , *http2stream ) {	sc .serveG .check ()		if  st , ok  := sc .streams [streamID ]; ok  {		return  st .state , st 	}		if  streamID %2  == 1  {		if  streamID  <= sc .maxClientStreamID  {			return  http2stateClosed , nil 		}	} else  {		if  streamID  <= sc .maxPushPromiseID  {			return  http2stateClosed , nil 		}	}	return  http2stateIdle , nil }func  (sc  *http2serverConn ) setConnState state  ConnState ) {	if  sc .hs .ConnState  != nil  {		sc .hs .ConnState (sc .conn , state )	}}func  (sc  *http2serverConn ) vlogf format  string , args  ...interface {}) {	if  http2VerboseLogs  {		sc .logf (format , args ...)	}}func  (sc  *http2serverConn ) logf format  string , args  ...interface {}) {	if  lg  := sc .hs .ErrorLog ; lg  != nil  {		lg .Printf (format , args ...)	} else  {		log .Printf (format , args ...)	}}func  http2errno v  error ) uintptr  {	if  rv  := reflect .ValueOf (v ); rv .Kind () == reflect .Uintptr  {		return  uintptr (rv .Uint ())	}	return  0 }func  http2isClosedConnError err  error ) bool  {	if  err  == nil  {		return  false 	}	if  errors .Is (err , net .ErrClosed ) {		return  true 	}		if  runtime .GOOS  == "windows"  {		if  oe , ok  := err .(*net .OpError ); ok  && oe .Op  == "read"  {			if  se , ok  := oe .Err .(*os .SyscallError ); ok  && se .Syscall  == "wsarecv"  {				const  WSAECONNABORTED  = 10053 				const  WSAECONNRESET  = 10054 				if  n  := http2errno (se .Err ); n  == WSAECONNRESET  || n  == WSAECONNABORTED  {					return  true 				}			}		}	}	return  false }func  (sc  *http2serverConn ) condlogf err  error , format  string , args  ...interface {}) {	if  err  == nil  {		return 	}	if  err  == io .EOF  || err  == io .ErrUnexpectedEOF  || http2isClosedConnError (err ) || err  == http2errPrefaceTimeout  {				sc .vlogf (format , args ...)	} else  {		sc .logf (format , args ...)	}}const  http2maxCachedCanonicalHeadersKeysSize  = 2048 func  (sc  *http2serverConn ) canonicalHeader v  string ) string  {	sc .serveG .check ()	http2buildCommonHeaderMapsOnce ()	cv , ok  := http2commonCanonHeader [v ]	if  ok  {		return  cv 	}	cv , ok  = sc .canonHeader [v ]	if  ok  {		return  cv 	}	if  sc .canonHeader  == nil  {		sc .canonHeader  = make (map [string ]string )	}	cv  = CanonicalHeaderKey (v )	size  := 100  + len (v )*2  	if  sc .canonHeaderKeysSize +size  <= http2maxCachedCanonicalHeadersKeysSize  {		sc .canonHeader [v ] = cv 		sc .canonHeaderKeysSize  += size 	}	return  cv }type  http2readFrameResult  struct  {	f    http2Frame  	err  error 		readMore  func ()}func  (sc  *http2serverConn ) readFrames 	sc .srv .markNewGoroutine ()	gate  := make (chan  struct {})	gateDone  := func () { gate  <- struct {}{} }	for  {		f , err  := sc .framer .ReadFrame ()		select 		case  sc .readFrameCh  <-  http2readFrameResult {f , err , gateDone }:		case  <- sc .doneServing :			return 		}		select 		case  <- gate :		case  <- sc .doneServing :			return 		}		if  http2terminalReadFrameError (err ) {			return 		}	}}type  http2frameWriteResult  struct  {	_   http2incomparable 	wr   http2FrameWriteRequest  	err  error                   }func  (sc  *http2serverConn ) writeFrameAsync wr  http2FrameWriteRequest , wd  *http2writeData ) {	sc .srv .markNewGoroutine ()	var  err  error 	if  wd  == nil  {		err  = wr .write .writeFrame (sc )	} else  {		err  = sc .framer .endWrite ()	}	sc .wroteFrameCh  <- http2frameWriteResult {wr : wr , err : err }}func  (sc  *http2serverConn ) closeAllStreamsOnConnClose 	sc .serveG .check ()	for  _ , st  := range  sc .streams  {		sc .closeStream (st , http2errClientDisconnected )	}}func  (sc  *http2serverConn ) stopShutdownTimer 	sc .serveG .check ()	if  t  := sc .shutdownTimer ; t  != nil  {		t .Stop ()	}}func  (sc  *http2serverConn ) notePanic 		if  http2testHookOnPanicMu  != nil  {		http2testHookOnPanicMu .Lock ()		defer  http2testHookOnPanicMu .Unlock ()	}	if  http2testHookOnPanic  != nil  {		if  e  := recover (); e  != nil  {			if  http2testHookOnPanic (sc , e ) {				panic (e )			}		}	}}func  (sc  *http2serverConn ) serve 	sc .serveG .check ()	defer  sc .notePanic ()	defer  sc .conn .Close ()	defer  sc .closeAllStreamsOnConnClose ()	defer  sc .stopShutdownTimer ()	defer  close (sc .doneServing ) 	if  http2VerboseLogs  {		sc .vlogf ("http2: server connection from %v on %p" , sc .conn .RemoteAddr (), sc .hs )	}	sc .writeFrame (http2FrameWriteRequest {		write : http2writeSettings {			{http2SettingMaxFrameSize , sc .srv .maxReadFrameSize ()},			{http2SettingMaxConcurrentStreams , sc .advMaxStreams },			{http2SettingMaxHeaderListSize , sc .maxHeaderListSize ()},			{http2SettingHeaderTableSize , sc .srv .maxDecoderHeaderTableSize ()},			{http2SettingInitialWindowSize , uint32 (sc .srv .initialStreamRecvWindowSize ())},		},	})	sc .unackedSettings ++		if  diff  := sc .srv .initialConnRecvWindowSize () - http2initialWindowSize ; diff  > 0  {		sc .sendWindowUpdate (nil , int (diff ))	}	if  err  := sc .readPreface (); err  != nil  {		sc .condlogf (err , "http2: server: error reading preface from client %v: %v" , sc .conn .RemoteAddr (), err )		return 	}		sc .setConnState (StateActive )	sc .setConnState (StateIdle )	if  sc .srv .IdleTimeout  > 0  {		sc .idleTimer  = sc .srv .afterFunc (sc .srv .IdleTimeout , sc .onIdleTimer )		defer  sc .idleTimer .Stop ()	}	go  sc .readFrames () 	settingsTimer  := sc .srv .afterFunc (http2firstSettingsTimeout , sc .onSettingsTimer )	defer  settingsTimer .Stop ()	loopNum  := 0 	for  {		loopNum ++		select 		case  wr  := <- sc .wantWriteFrameCh :			if  se , ok  := wr .write .(http2StreamError ); ok  {				sc .resetStream (se )				break 			}			sc .writeFrame (wr )		case  res  := <- sc .wroteFrameCh :			sc .wroteFrame (res )		case  res  := <- sc .readFrameCh :						if  sc .writingFrameAsync  {				select 				case  wroteRes  := <- sc .wroteFrameCh :					sc .wroteFrame (wroteRes )				default :				}			}			if  !sc .processFrameFromReader (res ) {				return 			}			res .readMore ()			if  settingsTimer  != nil  {				settingsTimer .Stop ()				settingsTimer  = nil 			}		case  m  := <- sc .bodyReadCh :			sc .noteBodyRead (m .st , m .n )		case  msg  := <- sc .serveMsgCh :			switch  v := msg .(type ) {			case  func (int ):				v (loopNum ) 			case  *http2serverMessage :				switch  v  {				case  http2settingsTimerMsg :					sc .logf ("timeout waiting for SETTINGS frames from %v" , sc .conn .RemoteAddr ())					return 				case  http2idleTimerMsg :					sc .vlogf ("connection is idle" )					sc .goAway (http2ErrCodeNo )				case  http2shutdownTimerMsg :					sc .vlogf ("GOAWAY close timer fired; closing conn from %v" , sc .conn .RemoteAddr ())					return 				case  http2gracefulShutdownMsg :					sc .startGracefulShutdownInternal ()				case  http2handlerDoneMsg :					sc .handlerDone ()				default :					panic ("unknown timer" )				}			case  *http2startPushRequest :				sc .startPush (v )			case  func (*http2serverConn ):				v (sc )			default :				panic (fmt .Sprintf ("unexpected type %T" , v ))			}		}				if  sc .queuedControlFrames  > sc .srv .maxQueuedControlFrames () {			sc .vlogf ("http2: too many control frames in send queue, closing connection" )			return 		}				sentGoAway  := sc .inGoAway  && !sc .needToSendGoAway  && !sc .writingFrame 		gracefulShutdownComplete  := sc .goAwayCode  == http2ErrCodeNo  && sc .curOpenStreams () == 0 		if  sentGoAway  && sc .shutdownTimer  == nil  && (sc .goAwayCode  != http2ErrCodeNo  || gracefulShutdownComplete ) {			sc .shutDownIn (http2goAwayTimeout )		}	}}type  http2serverMessage  int var  (	http2settingsTimerMsg     = new (http2serverMessage )	http2idleTimerMsg         = new (http2serverMessage )	http2shutdownTimerMsg     = new (http2serverMessage )	http2gracefulShutdownMsg  = new (http2serverMessage )	http2handlerDoneMsg       = new (http2serverMessage ))func  (sc  *http2serverConn ) onSettingsTimer sc .sendServeMsg (http2settingsTimerMsg ) }func  (sc  *http2serverConn ) onIdleTimer sc .sendServeMsg (http2idleTimerMsg ) }func  (sc  *http2serverConn ) onShutdownTimer sc .sendServeMsg (http2shutdownTimerMsg ) }func  (sc  *http2serverConn ) sendServeMsg msg  interface {}) {	sc .serveG .checkNotOn () 	select 	case  sc .serveMsgCh  <-  msg :	case  <- sc .doneServing :	}}var  http2errPrefaceTimeout  = errors .New ("timeout waiting for client preface" )func  (sc  *http2serverConn ) readPreface error  {	if  sc .sawClientPreface  {		return  nil 	}	errc  := make (chan  error , 1 )	go  func () {				buf  := make ([]byte , len (http2ClientPreface ))		if  _ , err  := io .ReadFull (sc .conn , buf ); err  != nil  {			errc  <- err 		} else  if  !bytes .Equal (buf , http2clientPreface ) {			errc  <- fmt .Errorf ("bogus greeting %q" , buf )		} else  {			errc  <- nil 		}	}()	timer  := sc .srv .newTimer (http2prefaceTimeout ) 	defer  timer .Stop ()	select 	case  <- timer .C ():		return  http2errPrefaceTimeout 	case  err  := <- errc :		if  err  == nil  {			if  http2VerboseLogs  {				sc .vlogf ("http2: server: client %v said hello" , sc .conn .RemoteAddr ())			}		}		return  err 	}}var  http2errChanPool  = sync .Pool {	New : func () interface {} { return  make (chan  error , 1 ) },}var  http2writeDataPool  = sync .Pool {	New : func () interface {} { return  new (http2writeData ) },}func  (sc  *http2serverConn ) writeDataFromHandler stream  *http2stream , data  []byte , endStream  bool ) error  {	ch  := http2errChanPool .Get ().(chan  error )	writeArg  := http2writeDataPool .Get ().(*http2writeData )	*writeArg  = http2writeData {stream .id , data , endStream }	err  := sc .writeFrameFromHandler (http2FrameWriteRequest {		write :  writeArg ,		stream : stream ,		done :   ch ,	})	if  err  != nil  {		return  err 	}	var  frameWriteDone  bool  	select 	case  err  = <- ch :		frameWriteDone  = true 	case  <- sc .doneServing :		return  http2errClientDisconnected 	case  <- stream .cw :				select 		case  err  = <- ch :			frameWriteDone  = true 		default :			return  http2errStreamClosed 		}	}	http2errChanPool .Put (ch )	if  frameWriteDone  {		http2writeDataPool .Put (writeArg )	}	return  err }func  (sc  *http2serverConn ) writeFrameFromHandler wr  http2FrameWriteRequest ) error  {	sc .serveG .checkNotOn () 	select 	case  sc .wantWriteFrameCh  <-  wr :		return  nil 	case  <- sc .doneServing :				return  http2errClientDisconnected 	}}func  (sc  *http2serverConn ) writeFrame wr  http2FrameWriteRequest ) {	sc .serveG .check ()		var  ignoreWrite  bool 		if  wr .StreamID () != 0  {		_ , isReset  := wr .write .(http2StreamError )		if  state , _  := sc .state (wr .StreamID ()); state  == http2stateClosed  && !isReset  {			ignoreWrite  = true 		}	}		switch  wr .write .(type ) {	case  *http2writeResHeaders :		wr .stream .wroteHeaders  = true 	case  http2write100ContinueHeadersFrame :		if  wr .stream .wroteHeaders  {						if  wr .done  != nil  {				panic ("wr.done != nil for write100ContinueHeadersFrame" )			}			ignoreWrite  = true 		}	}	if  !ignoreWrite  {		if  wr .isControl () {			sc .queuedControlFrames ++						if  sc .queuedControlFrames  < 0  {				sc .conn .Close ()			}		}		sc .writeSched .Push (wr )	}	sc .scheduleFrameWrite ()}func  (sc  *http2serverConn ) startFrameWrite wr  http2FrameWriteRequest ) {	sc .serveG .check ()	if  sc .writingFrame  {		panic ("internal error: can only be writing one frame at a time" )	}	st  := wr .stream 	if  st  != nil  {		switch  st .state  {		case  http2stateHalfClosedLocal :			switch  wr .write .(type ) {			case  http2StreamError , http2handlerPanicRST , http2writeWindowUpdate :							default :				panic (fmt .Sprintf ("internal error: attempt to send frame on a half-closed-local stream: %v" , wr ))			}		case  http2stateClosed :			panic (fmt .Sprintf ("internal error: attempt to send frame on a closed stream: %v" , wr ))		}	}	if  wpp , ok  := wr .write .(*http2writePushPromise ); ok  {		var  err  error 		wpp .promisedID , err  = wpp .allocatePromisedID ()		if  err  != nil  {			sc .writingFrameAsync  = false 			wr .replyToWriter (err )			return 		}	}	sc .writingFrame  = true 	sc .needsFrameFlush  = true 	if  wr .write .staysWithinBuffer (sc .bw .Available ()) {		sc .writingFrameAsync  = false 		err  := wr .write .writeFrame (sc )		sc .wroteFrame (http2frameWriteResult {wr : wr , err : err })	} else  if  wd , ok  := wr .write .(*http2writeData ); ok  {				sc .framer .startWriteDataPadded (wd .streamID , wd .endStream , wd .p , nil )		sc .writingFrameAsync  = true 		go  sc .writeFrameAsync (wr , wd )	} else  {		sc .writingFrameAsync  = true 		go  sc .writeFrameAsync (wr , nil )	}}var  http2errHandlerPanicked  = errors .New ("http2: handler panicked" )func  (sc  *http2serverConn ) wroteFrame res  http2frameWriteResult ) {	sc .serveG .check ()	if  !sc .writingFrame  {		panic ("internal error: expected to be already writing a frame" )	}	sc .writingFrame  = false 	sc .writingFrameAsync  = false 	wr  := res .wr 	if  http2writeEndsStream (wr .write ) {		st  := wr .stream 		if  st  == nil  {			panic ("internal error: expecting non-nil stream" )		}		switch  st .state  {		case  http2stateOpen :						st .state  = http2stateHalfClosedLocal 						sc .resetStream (http2streamError (st .id , http2ErrCodeNo ))		case  http2stateHalfClosedRemote :			sc .closeStream (st , http2errHandlerComplete )		}	} else  {		switch  v := wr .write .(type ) {		case  http2StreamError :						if  st , ok  := sc .streams [v .StreamID ]; ok  {				sc .closeStream (st , v )			}		case  http2handlerPanicRST :			sc .closeStream (wr .stream , http2errHandlerPanicked )		}	}		wr .replyToWriter (res .err )	sc .scheduleFrameWrite ()}func  (sc  *http2serverConn ) scheduleFrameWrite 	sc .serveG .check ()	if  sc .writingFrame  || sc .inFrameScheduleLoop  {		return 	}	sc .inFrameScheduleLoop  = true 	for  !sc .writingFrameAsync  {		if  sc .needToSendGoAway  {			sc .needToSendGoAway  = false 			sc .startFrameWrite (http2FrameWriteRequest {				write : &http2writeGoAway {					maxStreamID : sc .maxClientStreamID ,					code :        sc .goAwayCode ,				},			})			continue 		}		if  sc .needToSendSettingsAck  {			sc .needToSendSettingsAck  = false 			sc .startFrameWrite (http2FrameWriteRequest {write : http2writeSettingsAck {}})			continue 		}		if  !sc .inGoAway  || sc .goAwayCode  == http2ErrCodeNo  {			if  wr , ok  := sc .writeSched .Pop (); ok  {				if  wr .isControl () {					sc .queuedControlFrames --				}				sc .startFrameWrite (wr )				continue 			}		}		if  sc .needsFrameFlush  {			sc .startFrameWrite (http2FrameWriteRequest {write : http2flushFrameWriter {}})			sc .needsFrameFlush  = false  			continue 		}		break 	}	sc .inFrameScheduleLoop  = false }func  (sc  *http2serverConn ) startGracefulShutdown 	sc .serveG .checkNotOn () 	sc .shutdownOnce .Do (func () { sc .sendServeMsg (http2gracefulShutdownMsg ) })}var  http2goAwayTimeout  = 1  * time .Second func  (sc  *http2serverConn ) startGracefulShutdownInternal 	sc .goAway (http2ErrCodeNo )}func  (sc  *http2serverConn ) goAway code  http2ErrCode ) {	sc .serveG .check ()	if  sc .inGoAway  {		if  sc .goAwayCode  == http2ErrCodeNo  {			sc .goAwayCode  = code 		}		return 	}	sc .inGoAway  = true 	sc .needToSendGoAway  = true 	sc .goAwayCode  = code 	sc .scheduleFrameWrite ()}func  (sc  *http2serverConn ) shutDownIn d  time .Duration ) {	sc .serveG .check ()	sc .shutdownTimer  = sc .srv .afterFunc (d , sc .onShutdownTimer )}func  (sc  *http2serverConn ) resetStream se  http2StreamError ) {	sc .serveG .check ()	sc .writeFrame (http2FrameWriteRequest {write : se })	if  st , ok  := sc .streams [se .StreamID ]; ok  {		st .resetQueued  = true 	}}func  (sc  *http2serverConn ) processFrameFromReader res  http2readFrameResult ) bool  {	sc .serveG .check ()	err  := res .err 	if  err  != nil  {		if  err  == http2ErrFrameTooLarge  {			sc .goAway (http2ErrCodeFrameSize )			return  true  		}		clientGone  := err  == io .EOF  || err  == io .ErrUnexpectedEOF  || http2isClosedConnError (err )		if  clientGone  {						return  false 		}	} else  {		f  := res .f 		if  http2VerboseLogs  {			sc .vlogf ("http2: server read frame %v" , http2summarizeFrame (f ))		}		err  = sc .processFrame (f )		if  err  == nil  {			return  true 		}	}	switch  ev := err .(type ) {	case  http2StreamError :		sc .resetStream (ev )		return  true 	case  http2goAwayFlowError :		sc .goAway (http2ErrCodeFlowControl )		return  true 	case  http2ConnectionError :		if  res .f  != nil  {			if  id  := res .f .Header ().StreamID ; id  > sc .maxClientStreamID  {				sc .maxClientStreamID  = id 			}		}		sc .logf ("http2: server connection error from %v: %v" , sc .conn .RemoteAddr (), ev )		sc .goAway (http2ErrCode (ev ))		return  true  	default :		if  res .err  != nil  {			sc .vlogf ("http2: server closing client connection; error reading frame from client %s: %v" , sc .conn .RemoteAddr (), err )		} else  {			sc .logf ("http2: server closing client connection: %v" , err )		}		return  false 	}}func  (sc  *http2serverConn ) processFrame f  http2Frame ) error  {	sc .serveG .check ()		if  !sc .sawFirstSettings  {		if  _ , ok  := f .(*http2SettingsFrame ); !ok  {			return  sc .countError ("first_settings" , http2ConnectionError (http2ErrCodeProtocol ))		}		sc .sawFirstSettings  = true 	}		if  sc .inGoAway  && (sc .goAwayCode  != http2ErrCodeNo  || f .Header ().StreamID  > sc .maxClientStreamID ) {		if  f , ok  := f .(*http2DataFrame ); ok  {			if  !sc .inflow .take (f .Length ) {				return  sc .countError ("data_flow" , http2streamError (f .Header ().StreamID , http2ErrCodeFlowControl ))			}			sc .sendWindowUpdate (nil , int (f .Length )) 		}		return  nil 	}	switch  f := f .(type ) {	case  *http2SettingsFrame :		return  sc .processSettings (f )	case  *http2MetaHeadersFrame :		return  sc .processHeaders (f )	case  *http2WindowUpdateFrame :		return  sc .processWindowUpdate (f )	case  *http2PingFrame :		return  sc .processPing (f )	case  *http2DataFrame :		return  sc .processData (f )	case  *http2RSTStreamFrame :		return  sc .processResetStream (f )	case  *http2PriorityFrame :		return  sc .processPriority (f )	case  *http2GoAwayFrame :		return  sc .processGoAway (f )	case  *http2PushPromiseFrame :				return  sc .countError ("push_promise" , http2ConnectionError (http2ErrCodeProtocol ))	default :		sc .vlogf ("http2: server ignoring frame: %v" , f .Header ())		return  nil 	}}func  (sc  *http2serverConn ) processPing f  *http2PingFrame ) error  {	sc .serveG .check ()	if  f .IsAck () {				return  nil 	}	if  f .StreamID  != 0  {				return  sc .countError ("ping_on_stream" , http2ConnectionError (http2ErrCodeProtocol ))	}	sc .writeFrame (http2FrameWriteRequest {write : http2writePingAck {f }})	return  nil }func  (sc  *http2serverConn ) processWindowUpdate f  *http2WindowUpdateFrame ) error  {	sc .serveG .check ()	switch  {	case  f .StreamID  != 0 : 		state , st  := sc .state (f .StreamID )		if  state  == http2stateIdle  {						return  sc .countError ("stream_idle" , http2ConnectionError (http2ErrCodeProtocol ))		}		if  st  == nil  {						return  nil 		}		if  !st .flow .add (int32 (f .Increment )) {			return  sc .countError ("bad_flow" , http2streamError (f .StreamID , http2ErrCodeFlowControl ))		}	default : 		if  !sc .flow .add (int32 (f .Increment )) {			return  http2goAwayFlowError {}		}	}	sc .scheduleFrameWrite ()	return  nil }func  (sc  *http2serverConn ) processResetStream f  *http2RSTStreamFrame ) error  {	sc .serveG .check ()	state , st  := sc .state (f .StreamID )	if  state  == http2stateIdle  {				return  sc .countError ("reset_idle_stream" , http2ConnectionError (http2ErrCodeProtocol ))	}	if  st  != nil  {		st .cancelCtx ()		sc .closeStream (st , http2streamError (f .StreamID , f .ErrCode ))	}	return  nil }func  (sc  *http2serverConn ) closeStream st  *http2stream , err  error ) {	sc .serveG .check ()	if  st .state  == http2stateIdle  || st .state  == http2stateClosed  {		panic (fmt .Sprintf ("invariant; can't close stream in state %v" , st .state ))	}	st .state  = http2stateClosed 	if  st .readDeadline  != nil  {		st .readDeadline .Stop ()	}	if  st .writeDeadline  != nil  {		st .writeDeadline .Stop ()	}	if  st .isPushed () {		sc .curPushedStreams --	} else  {		sc .curClientStreams --	}	delete (sc .streams , st .id )	if  len (sc .streams ) == 0  {		sc .setConnState (StateIdle )		if  sc .srv .IdleTimeout  > 0  && sc .idleTimer  != nil  {			sc .idleTimer .Reset (sc .srv .IdleTimeout )		}		if  http2h1ServerKeepAlivesDisabled (sc .hs ) {			sc .startGracefulShutdownInternal ()		}	}	if  p  := st .body ; p  != nil  {				sc .sendWindowUpdate (nil , p .Len ())		p .CloseWithError (err )	}	if  e , ok  := err .(http2StreamError ); ok  {		if  e .Cause  != nil  {			err  = e .Cause 		} else  {			err  = http2errStreamClosed 		}	}	st .closeErr  = err 	st .cancelCtx ()	st .cw .Close () 	sc .writeSched .CloseStream (st .id )}func  (sc  *http2serverConn ) processSettings f  *http2SettingsFrame ) error  {	sc .serveG .check ()	if  f .IsAck () {		sc .unackedSettings --		if  sc .unackedSettings  < 0  {						return  sc .countError ("ack_mystery" , http2ConnectionError (http2ErrCodeProtocol ))		}		return  nil 	}	if  f .NumSettings () > 100  || f .HasDuplicates () {				return  sc .countError ("settings_big_or_dups" , http2ConnectionError (http2ErrCodeProtocol ))	}	if  err  := f .ForeachSetting (sc .processSetting ); err  != nil  {		return  err 	}		sc .needToSendSettingsAck  = true 	sc .scheduleFrameWrite ()	return  nil }func  (sc  *http2serverConn ) processSetting s  http2Setting ) error  {	sc .serveG .check ()	if  err  := s .Valid (); err  != nil  {		return  err 	}	if  http2VerboseLogs  {		sc .vlogf ("http2: server processing setting %v" , s )	}	switch  s .ID  {	case  http2SettingHeaderTableSize :		sc .hpackEncoder .SetMaxDynamicTableSize (s .Val )	case  http2SettingEnablePush :		sc .pushEnabled  = s .Val  != 0 	case  http2SettingMaxConcurrentStreams :		sc .clientMaxStreams  = s .Val 	case  http2SettingInitialWindowSize :		return  sc .processSettingInitialWindowSize (s .Val )	case  http2SettingMaxFrameSize :		sc .maxFrameSize  = int32 (s .Val ) 	case  http2SettingMaxHeaderListSize :		sc .peerMaxHeaderListSize  = s .Val 	default :				if  http2VerboseLogs  {			sc .vlogf ("http2: server ignoring unknown setting %v" , s )		}	}	return  nil }func  (sc  *http2serverConn ) processSettingInitialWindowSize val  uint32 ) error  {	sc .serveG .check ()			old  := sc .initialStreamSendWindowSize 	sc .initialStreamSendWindowSize  = int32 (val )	growth  := int32 (val ) - old  	for  _ , st  := range  sc .streams  {		if  !st .flow .add (growth ) {						return  sc .countError ("setting_win_size" , http2ConnectionError (http2ErrCodeFlowControl ))		}	}	return  nil }func  (sc  *http2serverConn ) processData f  *http2DataFrame ) error  {	sc .serveG .check ()	id  := f .Header ().StreamID 	data  := f .Data ()	state , st  := sc .state (id )	if  id  == 0  || state  == http2stateIdle  {				return  sc .countError ("data_on_idle" , http2ConnectionError (http2ErrCodeProtocol ))	}		if  st  == nil  || state  != http2stateOpen  || st .gotTrailerHeader  || st .resetQueued  {						if  !sc .inflow .take (f .Length ) {			return  sc .countError ("data_flow" , http2streamError (id , http2ErrCodeFlowControl ))		}		sc .sendWindowUpdate (nil , int (f .Length )) 		if  st  != nil  && st .resetQueued  {						return  nil 		}		return  sc .countError ("closed" , http2streamError (id , http2ErrCodeStreamClosed ))	}	if  st .body  == nil  {		panic ("internal error: should have a body in this state" )	}		if  st .declBodyBytes  != -1  && st .bodyBytes +int64 (len (data )) > st .declBodyBytes  {		if  !sc .inflow .take (f .Length ) {			return  sc .countError ("data_flow" , http2streamError (id , http2ErrCodeFlowControl ))		}		sc .sendWindowUpdate (nil , int (f .Length )) 		st .body .CloseWithError (fmt .Errorf ("sender tried to send more than declared Content-Length of %d bytes" , st .declBodyBytes ))				return  sc .countError ("send_too_much" , http2streamError (id , http2ErrCodeProtocol ))	}	if  f .Length  > 0  {				if  !http2takeInflows (&sc .inflow , &st .inflow , f .Length ) {			return  sc .countError ("flow_on_data_length" , http2streamError (id , http2ErrCodeFlowControl ))		}		if  len (data ) > 0  {			st .bodyBytes  += int64 (len (data ))			wrote , err  := st .body .Write (data )			if  err  != nil  {								sc .sendWindowUpdate (nil , int (f .Length )-wrote )				return  nil 			}			if  wrote  != len (data ) {				panic ("internal error: bad Writer" )			}		}				pad  := int32 (f .Length ) - int32 (len (data ))		sc .sendWindowUpdate32 (nil , pad )		sc .sendWindowUpdate32 (st , pad )	}	if  f .StreamEnded () {		st .endStream ()	}	return  nil }func  (sc  *http2serverConn ) processGoAway f  *http2GoAwayFrame ) error  {	sc .serveG .check ()	if  f .ErrCode  != http2ErrCodeNo  {		sc .logf ("http2: received GOAWAY %+v, starting graceful shutdown" , f )	} else  {		sc .vlogf ("http2: received GOAWAY %+v, starting graceful shutdown" , f )	}	sc .startGracefulShutdownInternal ()		sc .pushEnabled  = false 	return  nil }func  (st  *http2stream ) isPushed bool  {	return  st .id %2  == 0 }func  (st  *http2stream ) endStream 	sc  := st .sc 	sc .serveG .check ()	if  st .declBodyBytes  != -1  && st .declBodyBytes  != st .bodyBytes  {		st .body .CloseWithError (fmt .Errorf ("request declared a Content-Length of %d but only wrote %d bytes" ,			st .declBodyBytes , st .bodyBytes ))	} else  {		st .body .closeWithErrorAndCode (io .EOF , st .copyTrailersToHandlerRequest )		st .body .CloseWithError (io .EOF )	}	st .state  = http2stateHalfClosedRemote }func  (st  *http2stream ) copyTrailersToHandlerRequest 	for  k , vv  := range  st .trailer  {		if  _ , ok  := st .reqTrailer [k ]; ok  {						st .reqTrailer [k ] = vv 		}	}}func  (st  *http2stream ) onReadTimeout 	if  st .body  != nil  {				st .body .CloseWithError (fmt .Errorf ("%w" , os .ErrDeadlineExceeded ))	}}func  (st  *http2stream ) onWriteTimeout 	st .sc .writeFrameFromHandler (http2FrameWriteRequest {write : http2StreamError {		StreamID : st .id ,		Code :     http2ErrCodeInternal ,		Cause :    os .ErrDeadlineExceeded ,	}})}func  (sc  *http2serverConn ) processHeaders f  *http2MetaHeadersFrame ) error  {	sc .serveG .check ()	id  := f .StreamID 		if  id %2  != 1  {		return  sc .countError ("headers_even" , http2ConnectionError (http2ErrCodeProtocol ))	}		if  st  := sc .streams [f .StreamID ]; st  != nil  {		if  st .resetQueued  {						return  nil 		}				if  st .state  == http2stateHalfClosedRemote  {			return  sc .countError ("headers_half_closed" , http2streamError (id , http2ErrCodeStreamClosed ))		}		return  st .processTrailerHeaders (f )	}		if  id  <= sc .maxClientStreamID  {		return  sc .countError ("stream_went_down" , http2ConnectionError (http2ErrCodeProtocol ))	}	sc .maxClientStreamID  = id 	if  sc .idleTimer  != nil  {		sc .idleTimer .Stop ()	}		if  sc .curClientStreams +1  > sc .advMaxStreams  {		if  sc .unackedSettings  == 0  {						return  sc .countError ("over_max_streams" , http2streamError (id , http2ErrCodeProtocol ))		}				return  sc .countError ("over_max_streams_race" , http2streamError (id , http2ErrCodeRefusedStream ))	}	initialState  := http2stateOpen 	if  f .StreamEnded () {		initialState  = http2stateHalfClosedRemote 	}	st  := sc .newStream (id , 0 , initialState )	if  f .HasPriority () {		if  err  := sc .checkPriority (f .StreamID , f .Priority ); err  != nil  {			return  err 		}		sc .writeSched .AdjustStream (st .id , f .Priority )	}	rw , req , err  := sc .newWriterAndRequest (st , f )	if  err  != nil  {		return  err 	}	st .reqTrailer  = req .Trailer 	if  st .reqTrailer  != nil  {		st .trailer  = make (Header )	}	st .body  = req .Body .(*http2requestBody ).pipe  	st .declBodyBytes  = req .ContentLength 	handler  := sc .handler .ServeHTTP 	if  f .Truncated  {				handler  = http2handleHeaderListTooLong 	} else  if  err  := http2checkValidHTTP2RequestHeaders (req .Header ); err  != nil  {		handler  = http2new400Handler (err )	}		if  sc .hs .ReadTimeout  > 0  {		sc .conn .SetReadDeadline (time .Time {})		st .readDeadline  = sc .srv .afterFunc (sc .hs .ReadTimeout , st .onReadTimeout )	}	return  sc .scheduleHandler (id , rw , req , handler )}func  (sc  *http2serverConn ) upgradeRequest req  *Request ) {	sc .serveG .check ()	id  := uint32 (1 )	sc .maxClientStreamID  = id 	st  := sc .newStream (id , 0 , http2stateHalfClosedRemote )	st .reqTrailer  = req .Trailer 	if  st .reqTrailer  != nil  {		st .trailer  = make (Header )	}	rw  := sc .newResponseWriter (st , req )		if  sc .hs .ReadTimeout  > 0  {		sc .conn .SetReadDeadline (time .Time {})	}		sc .curHandlers ++	go  sc .runHandler (rw , req , sc .handler .ServeHTTP )}func  (st  *http2stream ) processTrailerHeaders f  *http2MetaHeadersFrame ) error  {	sc  := st .sc 	sc .serveG .check ()	if  st .gotTrailerHeader  {		return  sc .countError ("dup_trailers" , http2ConnectionError (http2ErrCodeProtocol ))	}	st .gotTrailerHeader  = true 	if  !f .StreamEnded () {		return  sc .countError ("trailers_not_ended" , http2streamError (st .id , http2ErrCodeProtocol ))	}	if  len (f .PseudoFields ()) > 0  {		return  sc .countError ("trailers_pseudo" , http2streamError (st .id , http2ErrCodeProtocol ))	}	if  st .trailer  != nil  {		for  _ , hf  := range  f .RegularFields () {			key  := sc .canonicalHeader (hf .Name )			if  !httpguts .ValidTrailerHeader (key ) {								return  sc .countError ("trailers_bogus" , http2streamError (st .id , http2ErrCodeProtocol ))			}			st .trailer [key ] = append (st .trailer [key ], hf .Value )		}	}	st .endStream ()	return  nil }func  (sc  *http2serverConn ) checkPriority streamID  uint32 , p  http2PriorityParam ) error  {	if  streamID  == p .StreamDep  {				return  sc .countError ("priority" , http2streamError (streamID , http2ErrCodeProtocol ))	}	return  nil }func  (sc  *http2serverConn ) processPriority f  *http2PriorityFrame ) error  {	if  err  := sc .checkPriority (f .StreamID , f .http2PriorityParam ); err  != nil  {		return  err 	}	sc .writeSched .AdjustStream (f .StreamID , f .http2PriorityParam )	return  nil }func  (sc  *http2serverConn ) newStream id , pusherID  uint32 , state  http2streamState ) *http2stream  {	sc .serveG .check ()	if  id  == 0  {		panic ("internal error: cannot create stream with id 0" )	}	ctx , cancelCtx  := context .WithCancel (sc .baseCtx )	st  := &http2stream {		sc :        sc ,		id :        id ,		state :     state ,		ctx :       ctx ,		cancelCtx : cancelCtx ,	}	st .cw .Init ()	st .flow .conn  = &sc .flow  	st .flow .add (sc .initialStreamSendWindowSize )	st .inflow .init (sc .srv .initialStreamRecvWindowSize ())	if  sc .hs .WriteTimeout  > 0  {		st .writeDeadline  = sc .srv .afterFunc (sc .hs .WriteTimeout , st .onWriteTimeout )	}	sc .streams [id ] = st 	sc .writeSched .OpenStream (st .id , http2OpenStreamOptions {PusherID : pusherID })	if  st .isPushed () {		sc .curPushedStreams ++	} else  {		sc .curClientStreams ++	}	if  sc .curOpenStreams () == 1  {		sc .setConnState (StateActive )	}	return  st }func  (sc  *http2serverConn ) newWriterAndRequest st  *http2stream , f  *http2MetaHeadersFrame ) (*http2responseWriter , *Request , error ) {	sc .serveG .check ()	rp  := http2requestParam {		method :    f .PseudoValue ("method" ),		scheme :    f .PseudoValue ("scheme" ),		authority : f .PseudoValue ("authority" ),		path :      f .PseudoValue ("path" ),	}	isConnect  := rp .method  == "CONNECT" 	if  isConnect  {		if  rp .path  != ""  || rp .scheme  != ""  || rp .authority  == ""  {			return  nil , nil , sc .countError ("bad_connect" , http2streamError (f .StreamID , http2ErrCodeProtocol ))		}	} else  if  rp .method  == ""  || rp .path  == ""  || (rp .scheme  != "https"  && rp .scheme  != "http" ) {				return  nil , nil , sc .countError ("bad_path_method" , http2streamError (f .StreamID , http2ErrCodeProtocol ))	}	rp .header  = make (Header )	for  _ , hf  := range  f .RegularFields () {		rp .header .Add (sc .canonicalHeader (hf .Name ), hf .Value )	}	if  rp .authority  == ""  {		rp .authority  = rp .header .Get ("Host" )	}	rw , req , err  := sc .newWriterAndRequestNoBody (st , rp )	if  err  != nil  {		return  nil , nil , err 	}	bodyOpen  := !f .StreamEnded ()	if  bodyOpen  {		if  vv , ok  := rp .header ["Content-Length" ]; ok  {			if  cl , err  := strconv .ParseUint (vv [0 ], 10 , 63 ); err  == nil  {				req .ContentLength  = int64 (cl )			} else  {				req .ContentLength  = 0 			}		} else  {			req .ContentLength  = -1 		}		req .Body .(*http2requestBody ).pipe  = &http2pipe {			b : &http2dataBuffer {expected : req .ContentLength },		}	}	return  rw , req , nil }type  http2requestParam  struct  {	method                   string 	scheme , authority , path  string 	header                   Header }func  (sc  *http2serverConn ) newWriterAndRequestNoBody st  *http2stream , rp  http2requestParam ) (*http2responseWriter , *Request , error ) {	sc .serveG .check ()	var  tlsState  *tls .ConnectionState  	if  rp .scheme  == "https"  {		tlsState  = sc .tlsState 	}	needsContinue  := httpguts .HeaderValuesContainsToken (rp .header ["Expect" ], "100-continue" )	if  needsContinue  {		rp .header .Del ("Expect" )	}		if  cookies  := rp .header ["Cookie" ]; len (cookies ) > 1  {		rp .header .Set ("Cookie" , strings .Join (cookies , "; " ))	}		var  trailer  Header 	for  _ , v  := range  rp .header ["Trailer" ] {		for  _ , key  := range  strings .Split (v , "," ) {			key  = CanonicalHeaderKey (textproto .TrimString (key ))			switch  key  {			case  "Transfer-Encoding" , "Trailer" , "Content-Length" :							default :				if  trailer  == nil  {					trailer  = make (Header )				}				trailer [key ] = nil 			}		}	}	delete (rp .header , "Trailer" )	var  url_  *url .URL 	var  requestURI  string 	if  rp .method  == "CONNECT"  {		url_  = &url .URL {Host : rp .authority }		requestURI  = rp .authority  	} else  {		var  err  error 		url_ , err  = url .ParseRequestURI (rp .path )		if  err  != nil  {			return  nil , nil , sc .countError ("bad_path" , http2streamError (st .id , http2ErrCodeProtocol ))		}		requestURI  = rp .path 	}	body  := &http2requestBody {		conn :          sc ,		stream :        st ,		needsContinue : needsContinue ,	}	req  := &Request {		Method :     rp .method ,		URL :        url_ ,		RemoteAddr : sc .remoteAddrStr ,		Header :     rp .header ,		RequestURI : requestURI ,		Proto :      "HTTP/2.0" ,		ProtoMajor : 2 ,		ProtoMinor : 0 ,		TLS :        tlsState ,		Host :       rp .authority ,		Body :       body ,		Trailer :    trailer ,	}	req  = req .WithContext (st .ctx )	rw  := sc .newResponseWriter (st , req )	return  rw , req , nil }func  (sc  *http2serverConn ) newResponseWriter st  *http2stream , req  *Request ) *http2responseWriter  {	rws  := http2responseWriterStatePool .Get ().(*http2responseWriterState )	bwSave  := rws .bw 	*rws  = http2responseWriterState {} 	rws .conn  = sc 	rws .bw  = bwSave 	rws .bw .Reset (http2chunkWriter {rws })	rws .stream  = st 	rws .req  = req 	return  &http2responseWriter {rws : rws }}type  http2unstartedHandler  struct  {	streamID  uint32 	rw        *http2responseWriter 	req       *Request 	handler   func (ResponseWriter , *Request )}func  (sc  *http2serverConn ) scheduleHandler streamID  uint32 , rw  *http2responseWriter , req  *Request , handler  func (ResponseWriter , *Request )) error  {	sc .serveG .check ()	maxHandlers  := sc .advMaxStreams 	if  sc .curHandlers  < maxHandlers  {		sc .curHandlers ++		go  sc .runHandler (rw , req , handler )		return  nil 	}	if  len (sc .unstartedHandlers ) > int (4 *sc .advMaxStreams ) {		return  sc .countError ("too_many_early_resets" , http2ConnectionError (http2ErrCodeEnhanceYourCalm ))	}	sc .unstartedHandlers  = append (sc .unstartedHandlers , http2unstartedHandler {		streamID : streamID ,		rw :       rw ,		req :      req ,		handler :  handler ,	})	return  nil }func  (sc  *http2serverConn ) handlerDone 	sc .serveG .check ()	sc .curHandlers --	i  := 0 	maxHandlers  := sc .advMaxStreams 	for  ; i  < len (sc .unstartedHandlers ); i ++ {		u  := sc .unstartedHandlers [i ]		if  sc .streams [u .streamID ] == nil  {						continue 		}		if  sc .curHandlers  >= maxHandlers  {			break 		}		sc .curHandlers ++		go  sc .runHandler (u .rw , u .req , u .handler )		sc .unstartedHandlers [i ] = http2unstartedHandler {} 	}	sc .unstartedHandlers  = sc .unstartedHandlers [i :]	if  len (sc .unstartedHandlers ) == 0  {		sc .unstartedHandlers  = nil 	}}func  (sc  *http2serverConn ) runHandler rw  *http2responseWriter , req  *Request , handler  func (ResponseWriter , *Request )) {	sc .srv .markNewGoroutine ()	defer  sc .sendServeMsg (http2handlerDoneMsg )	didPanic  := true 	defer  func () {		rw .rws .stream .cancelCtx ()		if  req .MultipartForm  != nil  {			req .MultipartForm .RemoveAll ()		}		if  didPanic  {			e  := recover ()			sc .writeFrameFromHandler (http2FrameWriteRequest {				write :  http2handlerPanicRST {rw .rws .stream .id },				stream : rw .rws .stream ,			})						if  e  != nil  && e  != ErrAbortHandler  {				const  size  = 64  << 10 				buf  := make ([]byte , size )				buf  = buf [:runtime .Stack (buf , false )]				sc .logf ("http2: panic serving %v: %v\n%s" , sc .conn .RemoteAddr (), e , buf )			}			return 		}		rw .handlerDone ()	}()	handler (rw , req )	didPanic  = false }func  http2handleHeaderListTooLong w  ResponseWriter , r  *Request ) {		const  statusRequestHeaderFieldsTooLarge  = 431  	w .WriteHeader (statusRequestHeaderFieldsTooLarge )	io .WriteString (w , "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>" )}func  (sc  *http2serverConn ) writeHeaders st  *http2stream , headerData  *http2writeResHeaders ) error  {	sc .serveG .checkNotOn () 	var  errc  chan  error 	if  headerData .h  != nil  {				errc  = http2errChanPool .Get ().(chan  error )	}	if  err  := sc .writeFrameFromHandler (http2FrameWriteRequest {		write :  headerData ,		stream : st ,		done :   errc ,	}); err  != nil  {		return  err 	}	if  errc  != nil  {		select 		case  err  := <- errc :			http2errChanPool .Put (errc )			return  err 		case  <- sc .doneServing :			return  http2errClientDisconnected 		case  <- st .cw :			return  http2errStreamClosed 		}	}	return  nil }func  (sc  *http2serverConn ) write100ContinueHeaders st  *http2stream ) {	sc .writeFrameFromHandler (http2FrameWriteRequest {		write :  http2write100ContinueHeadersFrame {st .id },		stream : st ,	})}type  http2bodyReadMsg  struct  {	st  *http2stream 	n   int }func  (sc  *http2serverConn ) noteBodyReadFromHandler st  *http2stream , n  int , err  error ) {	sc .serveG .checkNotOn () 	if  n  > 0  {		select 		case  sc .bodyReadCh  <-  http2bodyReadMsg {st , n }:		case  <- sc .doneServing :		}	}}func  (sc  *http2serverConn ) noteBodyRead st  *http2stream , n  int ) {	sc .serveG .check ()	sc .sendWindowUpdate (nil , n ) 	if  st .state  != http2stateHalfClosedRemote  && st .state  != http2stateClosed  {				sc .sendWindowUpdate (st , n )	}}func  (sc  *http2serverConn ) sendWindowUpdate32 st  *http2stream , n  int32 ) {	sc .sendWindowUpdate (st , int (n ))}func  (sc  *http2serverConn ) sendWindowUpdate st  *http2stream , n  int ) {	sc .serveG .check ()	var  streamID  uint32 	var  send  int32 	if  st  == nil  {		send  = sc .inflow .add (n )	} else  {		streamID  = st .id 		send  = st .inflow .add (n )	}	if  send  == 0  {		return 	}	sc .writeFrame (http2FrameWriteRequest {		write :  http2writeWindowUpdate {streamID : streamID , n : uint32 (send )},		stream : st ,	})}type  http2requestBody  struct  {	_             http2incomparable 	stream         *http2stream 	conn           *http2serverConn 	closeOnce      sync .Once   	sawEOF         bool        	pipe           *http2pipe  	needsContinue  bool        }func  (b  *http2requestBody ) Close error  {	b .closeOnce .Do (func () {		if  b .pipe  != nil  {			b .pipe .BreakWithError (http2errClosedBody )		}	})	return  nil }func  (b  *http2requestBody ) Read p  []byte ) (n  int , err  error ) {	if  b .needsContinue  {		b .needsContinue  = false 		b .conn .write100ContinueHeaders (b .stream )	}	if  b .pipe  == nil  || b .sawEOF  {		return  0 , io .EOF 	}	n , err  = b .pipe .Read (p )	if  err  == io .EOF  {		b .sawEOF  = true 	}	if  b .conn  == nil  && http2inTests  {		return 	}	b .conn .noteBodyReadFromHandler (b .stream , n , err )	return }type  http2responseWriter  struct  {	rws  *http2responseWriterState }var  (	_ CloseNotifier      = (*http2responseWriter )(nil )	_ Flusher            = (*http2responseWriter )(nil )	_ http2stringWriter  = (*http2responseWriter )(nil ))type  http2responseWriterState  struct  {		stream  *http2stream 	req     *Request 	conn    *http2serverConn 		bw  *bufio .Writer  		handlerHeader  Header    	snapHeader     Header    	trailers       []string  	status         int       	wroteHeader    bool      	sentHeader     bool      	handlerDone    bool      	sentContentLen  int64  	wroteBytes      int64 	closeNotifierMu  sync .Mutex  	closeNotifierCh  chan  bool   }type  http2chunkWriter  struct { rws  *http2responseWriterState  }func  (cw  http2chunkWriter ) Write p  []byte ) (n  int , err  error ) {	n , err  = cw .rws .writeChunk (p )	if  err  == http2errStreamClosed  {				err  = cw .rws .stream .closeErr 	}	return  n , err }func  (rws  *http2responseWriterState ) hasTrailers bool  { return  len (rws .trailers ) > 0  }func  (rws  *http2responseWriterState ) hasNonemptyTrailers bool  {	for  _ , trailer  := range  rws .trailers  {		if  _ , ok  := rws .handlerHeader [trailer ]; ok  {			return  true 		}	}	return  false }func  (rws  *http2responseWriterState ) declareTrailer k  string ) {	k  = CanonicalHeaderKey (k )	if  !httpguts .ValidTrailerHeader (k ) {				rws .conn .logf ("ignoring invalid trailer %q" , k )		return 	}	if  !http2strSliceContains (rws .trailers , k ) {		rws .trailers  = append (rws .trailers , k )	}}func  (rws  *http2responseWriterState ) writeChunk p  []byte ) (n  int , err  error ) {	if  !rws .wroteHeader  {		rws .writeHeader (200 )	}	if  rws .handlerDone  {		rws .promoteUndeclaredTrailers ()	}	isHeadResp  := rws .req .Method  == "HEAD" 	if  !rws .sentHeader  {		rws .sentHeader  = true 		var  ctype , clen  string 		if  clen  = rws .snapHeader .Get ("Content-Length" ); clen  != ""  {			rws .snapHeader .Del ("Content-Length" )			if  cl , err  := strconv .ParseUint (clen , 10 , 63 ); err  == nil  {				rws .sentContentLen  = int64 (cl )			} else  {				clen  = "" 			}		}		_ , hasContentLength  := rws .snapHeader ["Content-Length" ]		if  !hasContentLength  && clen  == ""  && rws .handlerDone  && http2bodyAllowedForStatus (rws .status ) && (len (p ) > 0  || !isHeadResp ) {			clen  = strconv .Itoa (len (p ))		}		_ , hasContentType  := rws .snapHeader ["Content-Type" ]				ce  := rws .snapHeader .Get ("Content-Encoding" )		hasCE  := len (ce ) > 0 		if  !hasCE  && !hasContentType  && http2bodyAllowedForStatus (rws .status ) && len (p ) > 0  {			ctype  = DetectContentType (p )		}		var  date  string 		if  _ , ok  := rws .snapHeader ["Date" ]; !ok  {						date  = rws .conn .srv .now ().UTC ().Format (TimeFormat )		}		for  _ , v  := range  rws .snapHeader ["Trailer" ] {			http2foreachHeaderElement (v , rws .declareTrailer )		}				if  _ , ok  := rws .snapHeader ["Connection" ]; ok  {			v  := rws .snapHeader .Get ("Connection" )			delete (rws .snapHeader , "Connection" )			if  v  == "close"  {				rws .conn .startGracefulShutdown ()			}		}		endStream  := (rws .handlerDone  && !rws .hasTrailers () && len (p ) == 0 ) || isHeadResp 		err  = rws .conn .writeHeaders (rws .stream , &http2writeResHeaders {			streamID :      rws .stream .id ,			httpResCode :   rws .status ,			h :             rws .snapHeader ,			endStream :     endStream ,			contentType :   ctype ,			contentLength : clen ,			date :          date ,		})		if  err  != nil  {			return  0 , err 		}		if  endStream  {			return  0 , nil 		}	}	if  isHeadResp  {		return  len (p ), nil 	}	if  len (p ) == 0  && !rws .handlerDone  {		return  0 , nil 	}		hasNonemptyTrailers  := rws .hasNonemptyTrailers ()	endStream  := rws .handlerDone  && !hasNonemptyTrailers 	if  len (p ) > 0  || endStream  {				if  err  := rws .conn .writeDataFromHandler (rws .stream , p , endStream ); err  != nil  {			return  0 , err 		}	}	if  rws .handlerDone  && hasNonemptyTrailers  {		err  = rws .conn .writeHeaders (rws .stream , &http2writeResHeaders {			streamID :  rws .stream .id ,			h :         rws .handlerHeader ,			trailers :  rws .trailers ,			endStream : true ,		})		return  len (p ), err 	}	return  len (p ), nil }const  http2TrailerPrefix  = "Trailer:" func  (rws  *http2responseWriterState ) promoteUndeclaredTrailers 	for  k , vv  := range  rws .handlerHeader  {		if  !strings .HasPrefix (k , http2TrailerPrefix ) {			continue 		}		trailerKey  := strings .TrimPrefix (k , http2TrailerPrefix )		rws .declareTrailer (trailerKey )		rws .handlerHeader [CanonicalHeaderKey (trailerKey )] = vv 	}	if  len (rws .trailers ) > 1  {		sorter  := http2sorterPool .Get ().(*http2sorter )		sorter .SortStrings (rws .trailers )		http2sorterPool .Put (sorter )	}}func  (w  *http2responseWriter ) SetReadDeadline deadline  time .Time ) error  {	st  := w .rws .stream 	if  !deadline .IsZero () && deadline .Before (w .rws .conn .srv .now ()) {				st .onReadTimeout ()		return  nil 	}	w .rws .conn .sendServeMsg (func (sc  *http2serverConn ) {		if  st .readDeadline  != nil  {			if  !st .readDeadline .Stop () {								return 			}		}		if  deadline .IsZero () {			st .readDeadline  = nil 		} else  if  st .readDeadline  == nil  {			st .readDeadline  = sc .srv .afterFunc (deadline .Sub (sc .srv .now ()), st .onReadTimeout )		} else  {			st .readDeadline .Reset (deadline .Sub (sc .srv .now ()))		}	})	return  nil }func  (w  *http2responseWriter ) SetWriteDeadline deadline  time .Time ) error  {	st  := w .rws .stream 	if  !deadline .IsZero () && deadline .Before (w .rws .conn .srv .now ()) {				st .onWriteTimeout ()		return  nil 	}	w .rws .conn .sendServeMsg (func (sc  *http2serverConn ) {		if  st .writeDeadline  != nil  {			if  !st .writeDeadline .Stop () {								return 			}		}		if  deadline .IsZero () {			st .writeDeadline  = nil 		} else  if  st .writeDeadline  == nil  {			st .writeDeadline  = sc .srv .afterFunc (deadline .Sub (sc .srv .now ()), st .onWriteTimeout )		} else  {			st .writeDeadline .Reset (deadline .Sub (sc .srv .now ()))		}	})	return  nil }func  (w  *http2responseWriter ) Flush 	w .FlushError ()}func  (w  *http2responseWriter ) FlushError error  {	rws  := w .rws 	if  rws  == nil  {		panic ("Header called after Handler finished" )	}	var  err  error 	if  rws .bw .Buffered () > 0  {		err  = rws .bw .Flush ()	} else  {				_, err  = http2chunkWriter {rws }.Write (nil )		if  err  == nil  {			select 			case  <- rws .stream .cw :				err  = rws .stream .closeErr 			default :			}		}	}	return  err }func  (w  *http2responseWriter ) CloseNotify chan  bool  {	rws  := w .rws 	if  rws  == nil  {		panic ("CloseNotify called after Handler finished" )	}	rws .closeNotifierMu .Lock ()	ch  := rws .closeNotifierCh 	if  ch  == nil  {		ch  = make (chan  bool , 1 )		rws .closeNotifierCh  = ch 		cw  := rws .stream .cw 		go  func () {			cw .Wait () 			ch  <- true 		}()	}	rws .closeNotifierMu .Unlock ()	return  ch }func  (w  *http2responseWriter ) Header Header  {	rws  := w .rws 	if  rws  == nil  {		panic ("Header called after Handler finished" )	}	if  rws .handlerHeader  == nil  {		rws .handlerHeader  = make (Header )	}	return  rws .handlerHeader }func  http2checkWriteHeaderCode code  int ) {		if  code  < 100  || code  > 999  {		panic (fmt .Sprintf ("invalid WriteHeader code %v" , code ))	}}func  (w  *http2responseWriter ) WriteHeader code  int ) {	rws  := w .rws 	if  rws  == nil  {		panic ("WriteHeader called after Handler finished" )	}	rws .writeHeader (code )}func  (rws  *http2responseWriterState ) writeHeader code  int ) {	if  rws .wroteHeader  {		return 	}	http2checkWriteHeaderCode (code )		if  code  >= 100  && code  <= 199  {				h  := rws .handlerHeader 		_ , cl  := h ["Content-Length" ]		_ , te  := h ["Transfer-Encoding" ]		if  cl  || te  {			h  = h .Clone ()			h .Del ("Content-Length" )			h .Del ("Transfer-Encoding" )		}		rws .conn .writeHeaders (rws .stream , &http2writeResHeaders {			streamID :    rws .stream .id ,			httpResCode : code ,			h :           h ,			endStream :   rws .handlerDone  && !rws .hasTrailers (),		})		return 	}	rws .wroteHeader  = true 	rws .status  = code 	if  len (rws .handlerHeader ) > 0  {		rws .snapHeader  = http2cloneHeader (rws .handlerHeader )	}}func  http2cloneHeader h  Header ) Header  {	h2  := make (Header , len (h ))	for  k , vv  := range  h  {		vv2  := make ([]string , len (vv ))		copy (vv2 , vv )		h2 [k ] = vv2 	}	return  h2 }func  (w  *http2responseWriter ) Write p  []byte ) (n  int , err  error ) {	return  w .write (len (p ), p , "" )}func  (w  *http2responseWriter ) WriteString s  string ) (n  int , err  error ) {	return  w .write (len (s ), nil , s )}func  (w  *http2responseWriter ) write lenData  int , dataB  []byte , dataS  string ) (n  int , err  error ) {	rws  := w .rws 	if  rws  == nil  {		panic ("Write called after Handler finished" )	}	if  !rws .wroteHeader  {		w .WriteHeader (200 )	}	if  !http2bodyAllowedForStatus (rws .status ) {		return  0 , ErrBodyNotAllowed 	}	rws .wroteBytes  += int64 (len (dataB )) + int64 (len (dataS )) 	if  rws .sentContentLen  != 0  && rws .wroteBytes  > rws .sentContentLen  {				return  0 , errors .New ("http2: handler wrote more than declared Content-Length" )	}	if  dataB  != nil  {		return  rws .bw .Write (dataB )	} else  {		return  rws .bw .WriteString (dataS )	}}func  (w  *http2responseWriter ) handlerDone 	rws  := w .rws 	rws .handlerDone  = true 	w .Flush ()	w .rws  = nil 	http2responseWriterStatePool .Put (rws )}var  (	http2ErrRecursivePush     = errors .New ("http2: recursive push not allowed" )	http2ErrPushLimitReached  = errors .New ("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS" ))var  _ Pusher  = (*http2responseWriter )(nil )func  (w  *http2responseWriter ) Push target  string , opts  *PushOptions ) error  {	st  := w .rws .stream 	sc  := st .sc 	sc .serveG .checkNotOn ()		if  st .isPushed () {		return  http2ErrRecursivePush 	}	if  opts  == nil  {		opts  = new (PushOptions )	}		if  opts .Method  == ""  {		opts .Method  = "GET" 	}	if  opts .Header  == nil  {		opts .Header  = Header {}	}	wantScheme  := "http" 	if  w .rws .req .TLS  != nil  {		wantScheme  = "https" 	}		u , err  := url .Parse (target )	if  err  != nil  {		return  err 	}	if  u .Scheme  == ""  {		if  !strings .HasPrefix (target , "/" ) {			return  fmt .Errorf ("target must be an absolute URL or an absolute path: %q" , target )		}		u .Scheme  = wantScheme 		u .Host  = w .rws .req .Host 	} else  {		if  u .Scheme  != wantScheme  {			return  fmt .Errorf ("cannot push URL with scheme %q from request with scheme %q" , u .Scheme , wantScheme )		}		if  u .Host  == ""  {			return  errors .New ("URL must have a host" )		}	}	for  k  := range  opts .Header  {		if  strings .HasPrefix (k , ":" ) {			return  fmt .Errorf ("promised request headers cannot include pseudo header %q" , k )		}				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 )		}	}	if  err  := http2checkValidHTTP2RequestHeaders (opts .Header ); err  != nil  {		return  err 	}		if  opts .Method  != "GET"  && opts .Method  != "HEAD"  {		return  fmt .Errorf ("method %q must be GET or HEAD" , opts .Method )	}	msg  := &http2startPushRequest {		parent : st ,		method : opts .Method ,		url :    u ,		header : http2cloneHeader (opts .Header ),		done :   http2errChanPool .Get ().(chan  error ),	}	select 	case  <- sc .doneServing :		return  http2errClientDisconnected 	case  <- st .cw :		return  http2errStreamClosed 	case  sc .serveMsgCh  <-  msg :	}	select 	case  <- sc .doneServing :		return  http2errClientDisconnected 	case  <- st .cw :		return  http2errStreamClosed 	case  err  := <- msg .done :		http2errChanPool .Put (msg .done )		return  err 	}}type  http2startPushRequest  struct  {	parent  *http2stream 	method  string 	url     *url .URL 	header  Header 	done    chan  error }func  (sc  *http2serverConn ) startPush msg  *http2startPushRequest ) {	sc .serveG .check ()		if  msg .parent .state  != http2stateOpen  && msg .parent .state  != http2stateHalfClosedRemote  {				msg .done  <- http2errStreamClosed 		return 	}		if  !sc .pushEnabled  {		msg .done  <- ErrNotSupported 		return 	}		allocatePromisedID  := func () (uint32 , error ) {		sc .serveG .check ()				if  !sc .pushEnabled  {			return  0 , ErrNotSupported 		}				if  sc .curPushedStreams +1  > sc .clientMaxStreams  {			return  0 , http2ErrPushLimitReached 		}				if  sc .maxPushPromiseID +2  >= 1 <<31  {			sc .startGracefulShutdownInternal ()			return  0 , http2ErrPushLimitReached 		}		sc .maxPushPromiseID  += 2 		promisedID  := sc .maxPushPromiseID 				promised  := sc .newStream (promisedID , msg .parent .id , http2stateHalfClosedRemote )		rw , req , err  := sc .newWriterAndRequestNoBody (promised , http2requestParam {			method :    msg .method ,			scheme :    msg .url .Scheme ,			authority : msg .url .Host ,			path :      msg .url .RequestURI (),			header :    http2cloneHeader (msg .header ), 		})		if  err  != nil  {						panic (fmt .Sprintf ("newWriterAndRequestNoBody(%+v): %v" , msg .url , err ))		}		sc .curHandlers ++		go  sc .runHandler (rw , req , sc .handler .ServeHTTP )		return  promisedID , nil 	}	sc .writeFrame (http2FrameWriteRequest {		write : &http2writePushPromise {			streamID :           msg .parent .id ,			method :             msg .method ,			url :                msg .url ,			h :                  msg .header ,			allocatePromisedID : allocatePromisedID ,		},		stream : msg .parent ,		done :   msg .done ,	})}func  http2foreachHeaderElement v  string , fn  func (string )) {	v  = textproto .TrimString (v )	if  v  == ""  {		return 	}	if  !strings .Contains (v , "," ) {		fn (v )		return 	}	for  _ , f  := range  strings .Split (v , "," ) {		if  f  = textproto .TrimString (f ); f  != ""  {			fn (f )		}	}}var  http2connHeaders  = []string {	"Connection" ,	"Keep-Alive" ,	"Proxy-Connection" ,	"Transfer-Encoding" ,	"Upgrade" ,}func  http2checkValidHTTP2RequestHeaders h  Header ) error  {	for  _ , k  := range  http2connHeaders  {		if  _ , ok  := h [k ]; ok  {			return  fmt .Errorf ("request header %q is not valid in HTTP/2" , k )		}	}	te  := h ["Te" ]	if  len (te ) > 0  && (len (te ) > 1  || (te [0 ] != "trailers"  && te [0 ] != "" )) {		return  errors .New (`request header "TE" may only be "trailers" in HTTP/2` )	}	return  nil }func  http2new400Handler err  error ) HandlerFunc  {	return  func (w  ResponseWriter , r  *Request ) {		Error (w , err .Error(), StatusBadRequest )	}}func  http2h1ServerKeepAlivesDisabled hs  *Server ) bool  {	var  x  interface {} = hs 	type  I  interface  {		doKeepAlives () bool 	}	if  hs , ok  := x .(I ); ok  {		return  !hs .doKeepAlives ()	}	return  false }func  (sc  *http2serverConn ) countError name  string , err  error ) error  {	if  sc  == nil  || sc .srv  == nil  {		return  err 	}	f  := sc .srv .CountError 	if  f  == nil  {		return  err 	}	var  typ  string 	var  code  http2ErrCode 	switch  e := err .(type ) {	case  http2ConnectionError :		typ  = "conn" 		code  = http2ErrCode (e )	case  http2StreamError :		typ  = "stream" 		code  = http2ErrCode (e .Code )	default :		return  err 	}	codeStr  := http2errCodeName [code ]	if  codeStr  == ""  {		codeStr  = strconv .Itoa (int (code ))	}	f (fmt .Sprintf ("%s_%s_%s" , typ , codeStr , name ))	return  err }type  http2timer  = interface  {	C () <-chan  time .Time 	Reset (d time .Duration ) bool 	Stop () bool }type  http2timeTimer  struct  {	*time .Timer }func  (t  http2timeTimer ) C chan  time .Time  { return  t .Timer .C  }const  (		http2transportDefaultConnFlow  = 1  << 30 		http2transportDefaultStreamFlow  = 4  << 20 	http2defaultUserAgent  = "Go-http-client/2.0" 		http2initialMaxConcurrentStreams  = 100 		http2defaultMaxConcurrentStreams  = 1000 )type  http2Transport  struct  {		DialTLSContext  func (ctx context .Context , network, addr string , cfg *tls .Config ) (net .Conn , error )		DialTLS  func (network, addr string , cfg *tls .Config ) (net .Conn , error )		TLSClientConfig  *tls .Config 		ConnPool  http2ClientConnPool 		DisableCompression  bool 		AllowHTTP  bool 		MaxHeaderListSize  uint32 		MaxReadFrameSize  uint32 		MaxDecoderHeaderTableSize  uint32 		MaxEncoderHeaderTableSize  uint32 		StrictMaxConcurrentStreams  bool 		IdleConnTimeout  time .Duration 		ReadIdleTimeout  time .Duration 		PingTimeout  time .Duration 		WriteByteTimeout  time .Duration 		CountError  func (errType string )		t1  *Transport 	connPoolOnce   sync .Once 	connPoolOrDef  http2ClientConnPool  	*http2transportTestHooks }type  http2transportTestHooks  struct  {	newclientconn  func (*http2ClientConn )	group          http2synctestGroupInterface }func  (t  *http2Transport ) markNewGoroutine 	if  t  != nil  && t .http2transportTestHooks  != nil  {		t .http2transportTestHooks .group .Join ()	}}func  (t  *http2Transport ) newTimer d  time .Duration ) http2timer  {	if  t .http2transportTestHooks  != nil  {		return  t .http2transportTestHooks .group .NewTimer (d )	}	return  http2timeTimer {time .NewTimer (d )}}func  (t  *http2Transport ) afterFunc d  time .Duration , f  func ()) http2timer  {	if  t .http2transportTestHooks  != nil  {		return  t .http2transportTestHooks .group .AfterFunc (d , f )	}	return  http2timeTimer {time .AfterFunc (d , f )}}func  (t  *http2Transport ) contextWithTimeout ctx  context .Context , d  time .Duration ) (context .Context , context .CancelFunc ) {	if  t .http2transportTestHooks  != nil  {		return  t .http2transportTestHooks .group .ContextWithTimeout (ctx , d )	}	return  context .WithTimeout (ctx , d )}func  (t  *http2Transport ) maxHeaderListSize uint32  {	if  t .MaxHeaderListSize  == 0  {		return  10  << 20 	}	if  t .MaxHeaderListSize  == 0xffffffff  {		return  0 	}	return  t .MaxHeaderListSize }func  (t  *http2Transport ) maxFrameReadSize uint32  {	if  t .MaxReadFrameSize  == 0  {		return  0  	}	if  t .MaxReadFrameSize  < http2minMaxFrameSize  {		return  http2minMaxFrameSize 	}	if  t .MaxReadFrameSize  > http2maxFrameSize  {		return  http2maxFrameSize 	}	return  t .MaxReadFrameSize }func  (t  *http2Transport ) disableCompression bool  {	return  t .DisableCompression  || (t .t1  != nil  && t .t1 .DisableCompression )}func  (t  *http2Transport ) pingTimeout time .Duration  {	if  t .PingTimeout  == 0  {		return  15  * time .Second 	}	return  t .PingTimeout }func  http2ConfigureTransport t1  *Transport ) error  {	_ , err  := http2ConfigureTransports (t1 )	return  err }func  http2ConfigureTransports t1  *Transport ) (*http2Transport , error ) {	return  http2configureTransports (t1 )}func  http2configureTransports t1  *Transport ) (*http2Transport , error ) {	connPool  := new (http2clientConnPool )	t2  := &http2Transport {		ConnPool : http2noDialClientConnPool {connPool },		t1 :       t1 ,	}	connPool .t  = t2 	if  err  := http2registerHTTPSProtocol (t1 , http2noDialH2RoundTripper {t2 }); err  != nil  {		return  nil , err 	}	if  t1 .TLSClientConfig  == nil  {		t1 .TLSClientConfig  = new (tls .Config )	}	if  !http2strSliceContains (t1 .TLSClientConfig .NextProtos , "h2" ) {		t1 .TLSClientConfig .NextProtos  = append ([]string {"h2" }, t1 .TLSClientConfig .NextProtos ...)	}	if  !http2strSliceContains (t1 .TLSClientConfig .NextProtos , "http/1.1" ) {		t1 .TLSClientConfig .NextProtos  = append (t1 .TLSClientConfig .NextProtos , "http/1.1" )	}	upgradeFn  := func (authority  string , c  *tls .Conn ) RoundTripper  {		addr  := http2authorityAddr ("https" , authority )		if  used , err  := connPool .addConnIfNeeded (addr , t2 , c ); err  != nil  {			go  c .Close ()			return  http2erringRoundTripper {err }		} else  if  !used  {						go  c .Close ()		}		return  t2 	}	if  m  := t1 .TLSNextProto ; len (m ) == 0  {		t1 .TLSNextProto  = map [string ]func (string , *tls .Conn ) RoundTripper {			"h2" : upgradeFn ,		}	} else  {		m ["h2" ] = upgradeFn 	}	return  t2 , nil }func  (t  *http2Transport ) connPool http2ClientConnPool  {	t .connPoolOnce .Do (t .initConnPool )	return  t .connPoolOrDef }func  (t  *http2Transport ) initConnPool 	if  t .ConnPool  != nil  {		t .connPoolOrDef  = t .ConnPool 	} else  {		t .connPoolOrDef  = &http2clientConnPool {t : t }	}}type  http2ClientConn  struct  {	t              *http2Transport 	tconn          net .Conn              	tlsState       *tls .ConnectionState  	reused         uint32                	singleUse      bool                  	getConnCalled  bool                  		readerDone  chan  struct {} 	readerErr   error          	idleTimeout  time .Duration  	idleTimer    http2timer 	mu               sync .Mutex    	cond             *sync .Cond    	flow             http2outflow  	inflow           http2inflow   	doNotReuse       bool          	closing          bool 	closed           bool 	seenSettings     bool                           	wantSettingsAck  bool                           	goAway           *http2GoAwayFrame              	goAwayDebug      string                         	streams          map [uint32 ]*http2clientStream  	streamsReserved  int                            	nextStreamID     uint32 	pendingRequests  int                        	pings            map [[8 ]byte ]chan  struct {} 	br               *bufio .Reader 	lastActive       time .Time 	lastIdle         time .Time  		maxFrameSize            uint32 	maxConcurrentStreams    uint32 	peerMaxHeaderListSize   uint64 	peerMaxHeaderTableSize  uint32 	initialWindowSize       uint32 		reqHeaderMu  chan  struct {}		wmu   sync .Mutex 	bw    *bufio .Writer 	fr    *http2Framer 	werr  error         	hbuf  bytes .Buffer  	henc  *hpack .Encoder }type  http2clientStream  struct  {	cc  *http2ClientConn 		ctx        context .Context 	reqCancel  <-chan  struct {}	trace          *httptrace .ClientTrace  	ID             uint32 	bufPipe        http2pipe  	requestedGzip  bool 	isHead         bool 	abortOnce  sync .Once 	abort      chan  struct {} 	abortErr   error          	peerClosed  chan  struct {} 	donec       chan  struct {} 	on100       chan  struct {} 	respHeaderRecv  chan  struct {} 	res             *Response      	flow         http2outflow  	inflow       http2inflow   	bytesRemain  int64         	readErr      error         	reqBody               io .ReadCloser 	reqBodyContentLength  int64          	reqBodyClosed         chan  struct {} 		sentEndStream  bool  	sentHeaders    bool 		firstByte     bool   	pastHeaders   bool   	pastTrailers  bool   	num1xx        uint8  	readClosed    bool   	readAborted   bool   	trailer     Header   	resTrailer  *Header  }var  http2got1xxFuncForTests  func (int , textproto .MIMEHeader ) error func  (cs  *http2clientStream ) get1xxTraceFunc func (int , textproto .MIMEHeader ) error  {	if  fn  := http2got1xxFuncForTests ; fn  != nil  {		return  fn 	}	return  http2traceGot1xxResponseFunc (cs .trace )}func  (cs  *http2clientStream ) abortStream err  error ) {	cs .cc .mu .Lock ()	defer  cs .cc .mu .Unlock ()	cs .abortStreamLocked (err )}func  (cs  *http2clientStream ) abortStreamLocked err  error ) {	cs .abortOnce .Do (func () {		cs .abortErr  = err 		close (cs .abort )	})	if  cs .reqBody  != nil  {		cs .closeReqBodyLocked ()	}		if  cs .cc .cond  != nil  {				cs .cc .cond .Broadcast ()	}}func  (cs  *http2clientStream ) abortRequestBodyWrite 	cc  := cs .cc 	cc .mu .Lock ()	defer  cc .mu .Unlock ()	if  cs .reqBody  != nil  && cs .reqBodyClosed  == nil  {		cs .closeReqBodyLocked ()		cc .cond .Broadcast ()	}}func  (cs  *http2clientStream ) closeReqBodyLocked 	if  cs .reqBodyClosed  != nil  {		return 	}	cs .reqBodyClosed  = make (chan  struct {})	reqBodyClosed  := cs .reqBodyClosed 	go  func () {		cs .cc .t .markNewGoroutine ()		cs .reqBody .Close ()		close (reqBodyClosed )	}()}type  http2stickyErrWriter  struct  {	conn     net .Conn 	timeout  time .Duration 	err      *error }func  (sew  http2stickyErrWriter ) Write p  []byte ) (n  int , err  error ) {	if  *sew .err  != nil  {		return  0 , *sew .err 	}	for  {		if  sew .timeout  != 0  {			sew .conn .SetWriteDeadline (time .Now ().Add (sew .timeout ))		}		nn , err  := sew .conn .Write (p [n :])		n  += nn 		if  n  < len (p ) && nn  > 0  && errors .Is (err , os .ErrDeadlineExceeded ) {						continue 		}		if  sew .timeout  != 0  {			sew .conn .SetWriteDeadline (time .Time {})		}		*sew .err  = err 		return  n , err 	}}type  http2noCachedConnError  struct {}func  (http2noCachedConnError ) IsHTTP2NoCachedConnError func  (http2noCachedConnError ) Error string  { return  "http2: no cached connection was available"  }func  http2isNoCachedConnError err  error ) bool  {	_ , ok  := err .(interface { IsHTTP2NoCachedConnError () })	return  ok }var  http2ErrNoCachedConn  error  = http2noCachedConnError {}type  http2RoundTripOpt  struct  {		OnlyCachedConn  bool }func  (t  *http2Transport ) RoundTrip req  *Request ) (*Response , error ) {	return  t .RoundTripOpt (req , http2RoundTripOpt {})}func  http2authorityAddr scheme  string , authority  string ) (addr  string ) {	host , port , err  := net .SplitHostPort (authority )	if  err  != nil  { 		host  = authority 		port  = "" 	}	if  port  == ""  { 		port  = "443" 		if  scheme  == "http"  {			port  = "80" 		}	}	if  a , err  := idna .ToASCII (host ); err  == nil  {		host  = a 	}		if  strings .HasPrefix (host , "[" ) && strings .HasSuffix (host , "]" ) {		return  host  + ":"  + port 	}	return  net .JoinHostPort (host , port )}func  (t  *http2Transport ) RoundTripOpt req  *Request , opt  http2RoundTripOpt ) (*Response , error ) {	if  !(req .URL .Scheme  == "https"  || (req .URL .Scheme  == "http"  && t .AllowHTTP )) {		return  nil , errors .New ("http2: unsupported scheme" )	}	addr  := http2authorityAddr (req .URL .Scheme , req .URL .Host )	for  retry  := 0 ; ; retry ++ {		cc , err  := t .connPool ().GetClientConn (req , addr )		if  err  != nil  {			t .vlogf ("http2: Transport failed to get client conn for %s: %v" , addr , err )			return  nil , err 		}		reused  := !atomic .CompareAndSwapUint32 (&cc .reused , 0 , 1 )		http2traceGotConn (req , cc , reused )		res , err  := cc .RoundTrip (req )		if  err  != nil  && retry  <= 6  {			roundTripErr  := err 			if  req , err  = http2shouldRetryRequest (req , err ); err  == nil  {								if  retry  == 0  {					t .vlogf ("RoundTrip retrying after failure: %v" , roundTripErr )					continue 				}				backoff  := float64 (uint (1 ) << (uint (retry ) - 1 ))				backoff  += backoff  * (0.1  * mathrand .Float64 ())				d  := time .Second  * time .Duration (backoff )				tm  := t .newTimer (d )				select 				case  <- tm .C ():					t .vlogf ("RoundTrip retrying after failure: %v" , roundTripErr )					continue 				case  <- req .Context ().Done ():					tm .Stop ()					err  = req .Context ().Err ()				}			}		}		if  err  != nil  {			t .vlogf ("RoundTrip failure: %v" , err )			return  nil , err 		}		return  res , nil 	}}func  (t  *http2Transport ) CloseIdleConnections 	if  cp , ok  := t .connPool ().(http2clientConnPoolIdleCloser ); ok  {		cp .closeIdleConnections ()	}}var  (	http2errClientConnClosed     = errors .New ("http2: client conn is closed" )	http2errClientConnUnusable   = errors .New ("http2: client conn not usable" )	http2errClientConnGotGoAway  = errors .New ("http2: Transport received Server's graceful shutdown GOAWAY" ))func  http2shouldRetryRequest req  *Request , err  error ) (*Request , error ) {	if  !http2canRetryError (err ) {		return  nil , err 	}		if  req .Body  == nil  || req .Body  == NoBody  {		return  req , nil 	}		if  req .GetBody  != nil  {		body , err  := req .GetBody ()		if  err  != nil  {			return  nil , err 		}		newReq  := *req 		newReq .Body  = body 		return  &newReq , nil 	}		if  err  == http2errClientConnUnusable  {		return  req , nil 	}	return  nil , fmt .Errorf ("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error" , err )}func  http2canRetryError err  error ) bool  {	if  err  == http2errClientConnUnusable  || err  == http2errClientConnGotGoAway  {		return  true 	}	if  se , ok  := err .(http2StreamError ); ok  {		if  se .Code  == http2ErrCodeProtocol  && se .Cause  == http2errFromPeer  {						return  true 		}		return  se .Code  == http2ErrCodeRefusedStream 	}	return  false }func  (t  *http2Transport ) dialClientConn ctx  context .Context , addr  string , singleUse  bool ) (*http2ClientConn , error ) {	if  t .http2transportTestHooks  != nil  {		return  t .newClientConn (nil , singleUse )	}	host , _ , err  := net .SplitHostPort (addr )	if  err  != nil  {		return  nil , err 	}	tconn , err  := t .dialTLS (ctx , "tcp" , addr , t .newTLSConfig (host ))	if  err  != nil  {		return  nil , err 	}	return  t .newClientConn (tconn , singleUse )}func  (t  *http2Transport ) newTLSConfig host  string ) *tls .Config  {	cfg  := new (tls .Config )	if  t .TLSClientConfig  != nil  {		*cfg  = *t .TLSClientConfig .Clone ()	}	if  !http2strSliceContains (cfg .NextProtos , http2NextProtoTLS ) {		cfg .NextProtos  = append ([]string {http2NextProtoTLS }, cfg .NextProtos ...)	}	if  cfg .ServerName  == ""  {		cfg .ServerName  = host 	}	return  cfg }func  (t  *http2Transport ) dialTLS ctx  context .Context , network , addr  string , tlsCfg  *tls .Config ) (net .Conn , error ) {	if  t .DialTLSContext  != nil  {		return  t .DialTLSContext (ctx , network , addr , tlsCfg )	} else  if  t .DialTLS  != nil  {		return  t .DialTLS (network , addr , tlsCfg )	}	tlsCn , err  := t .dialTLSWithContext (ctx , network , addr , tlsCfg )	if  err  != nil  {		return  nil , err 	}	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  tlsCn , nil }func  (t  *http2Transport ) disableKeepAlives bool  {	return  t .t1  != nil  && t .t1 .DisableKeepAlives }func  (t  *http2Transport ) expectContinueTimeout time .Duration  {	if  t .t1  == nil  {		return  0 	}	return  t .t1 .ExpectContinueTimeout }func  (t  *http2Transport ) maxDecoderHeaderTableSize uint32  {	if  v  := t .MaxDecoderHeaderTableSize ; v  > 0  {		return  v 	}	return  http2initialHeaderTableSize }func  (t  *http2Transport ) maxEncoderHeaderTableSize uint32  {	if  v  := t .MaxEncoderHeaderTableSize ; v  > 0  {		return  v 	}	return  http2initialHeaderTableSize }func  (t  *http2Transport ) NewClientConn c  net .Conn ) (*http2ClientConn , error ) {	return  t .newClientConn (c , t .disableKeepAlives ())}func  (t  *http2Transport ) newClientConn c  net .Conn , singleUse  bool ) (*http2ClientConn , error ) {	cc  := &http2ClientConn {		t :                     t ,		tconn :                 c ,		readerDone :            make (chan  struct {}),		nextStreamID :          1 ,		maxFrameSize :          16  << 10 ,                         		initialWindowSize :     65535 ,                            		maxConcurrentStreams :  http2initialMaxConcurrentStreams , 		peerMaxHeaderListSize : 0xffffffffffffffff ,               		streams :               make (map [uint32 ]*http2clientStream ),		singleUse :             singleUse ,		wantSettingsAck :       true ,		pings :                 make (map [[8 ]byte ]chan  struct {}),		reqHeaderMu :           make (chan  struct {}, 1 ),	}	if  t .http2transportTestHooks  != nil  {		t .markNewGoroutine ()		t .http2transportTestHooks .newclientconn (cc )		c  = cc .tconn 	}	if  http2VerboseLogs  {		t .vlogf ("http2: Transport creating client conn %p to %v" , cc , c .RemoteAddr ())	}	cc .cond  = sync .NewCond (&cc .mu )	cc .flow .add (int32 (http2initialWindowSize ))		cc .bw  = bufio .NewWriter (http2stickyErrWriter {		conn :    c ,		timeout : t .WriteByteTimeout ,		err :     &cc .werr ,	})	cc .br  = bufio .NewReader (c )	cc .fr  = http2NewFramer (cc .bw , cc .br )	if  t .maxFrameReadSize () != 0  {		cc .fr .SetMaxReadFrameSize (t .maxFrameReadSize ())	}	if  t .CountError  != nil  {		cc .fr .countError  = t .CountError 	}	maxHeaderTableSize  := t .maxDecoderHeaderTableSize ()	cc .fr .ReadMetaHeaders  = hpack .NewDecoder (maxHeaderTableSize , nil )	cc .fr .MaxHeaderListSize  = t .maxHeaderListSize ()	cc .henc  = hpack .NewEncoder (&cc .hbuf )	cc .henc .SetMaxDynamicTableSizeLimit (t .maxEncoderHeaderTableSize ())	cc .peerMaxHeaderTableSize  = http2initialHeaderTableSize 	if  t .AllowHTTP  {		cc .nextStreamID  = 3 	}	if  cs , ok  := c .(http2connectionStater ); ok  {		state  := cs .ConnectionState ()		cc .tlsState  = &state 	}	initialSettings  := []http2Setting {		{ID : http2SettingEnablePush , Val : 0 },		{ID : http2SettingInitialWindowSize , Val : http2transportDefaultStreamFlow },	}	if  max  := t .maxFrameReadSize (); max  != 0  {		initialSettings  = append (initialSettings , http2Setting {ID : http2SettingMaxFrameSize , Val : max })	}	if  max  := t .maxHeaderListSize (); max  != 0  {		initialSettings  = append (initialSettings , http2Setting {ID : http2SettingMaxHeaderListSize , Val : max })	}	if  maxHeaderTableSize  != http2initialHeaderTableSize  {		initialSettings  = append (initialSettings , http2Setting {ID : http2SettingHeaderTableSize , Val : maxHeaderTableSize })	}	cc .bw .Write (http2clientPreface )	cc .fr .WriteSettings (initialSettings ...)	cc .fr .WriteWindowUpdate (0 , http2transportDefaultConnFlow )	cc .inflow .init (http2transportDefaultConnFlow  + http2initialWindowSize )	cc .bw .Flush ()	if  cc .werr  != nil  {		cc .Close ()		return  nil , cc .werr 	}		if  d  := t .idleConnTimeout (); d  != 0  {		cc .idleTimeout  = d 		cc .idleTimer  = t .afterFunc (d , cc .onIdleTimeout )	}	go  cc .readLoop ()	return  cc , nil }func  (cc  *http2ClientConn ) healthCheck 	pingTimeout  := cc .t .pingTimeout ()		ctx , cancel  := cc .t .contextWithTimeout (context .Background (), pingTimeout )	defer  cancel ()	cc .vlogf ("http2: Transport sending health check" )	err  := cc .Ping (ctx )	if  err  != nil  {		cc .vlogf ("http2: Transport health check failure: %v" , err )		cc .closeForLostPing ()	} else  {		cc .vlogf ("http2: Transport health check success" )	}}func  (cc  *http2ClientConn ) SetDoNotReuse 	cc .mu .Lock ()	defer  cc .mu .Unlock ()	cc .doNotReuse  = true }func  (cc  *http2ClientConn ) setGoAway f  *http2GoAwayFrame ) {	cc .mu .Lock ()	defer  cc .mu .Unlock ()	old  := cc .goAway 	cc .goAway  = f 		if  cc .goAwayDebug  == ""  {		cc .goAwayDebug  = string (f .DebugData ())	}	if  old  != nil  && old .ErrCode  != http2ErrCodeNo  {		cc .goAway .ErrCode  = old .ErrCode 	}	last  := f .LastStreamID 	for  streamID , cs  := range  cc .streams  {		if  streamID  <= last  {						continue 		}		if  streamID  == 1  && cc .goAway .ErrCode  != http2ErrCodeNo  {						cs .abortStreamLocked (fmt .Errorf ("http2: Transport received GOAWAY from server ErrCode:%v" , cc .goAway .ErrCode ))		} else  {						cs .abortStreamLocked (http2errClientConnGotGoAway )		}	}}func  (cc  *http2ClientConn ) CanTakeNewRequest bool  {	cc .mu .Lock ()	defer  cc .mu .Unlock ()	return  cc .canTakeNewRequestLocked ()}func  (cc  *http2ClientConn ) ReserveNewRequest bool  {	cc .mu .Lock ()	defer  cc .mu .Unlock ()	if  st  := cc .idleStateLocked (); !st .canTakeNewRequest  {		return  false 	}	cc .streamsReserved ++	return  true }type  http2ClientConnState  struct  {		Closed  bool 		Closing  bool 		StreamsActive  int 		StreamsReserved  int 		StreamsPending  int 		MaxConcurrentStreams  uint32 		LastIdle  time .Time }func  (cc  *http2ClientConn ) State http2ClientConnState  {	cc .wmu .Lock ()	maxConcurrent  := cc .maxConcurrentStreams 	if  !cc .seenSettings  {		maxConcurrent  = 0 	}	cc .wmu .Unlock ()	cc .mu .Lock ()	defer  cc .mu .Unlock ()	return  http2ClientConnState {		Closed :               cc .closed ,		Closing :              cc .closing  || cc .singleUse  || cc .doNotReuse  || cc .goAway  != nil ,		StreamsActive :        len (cc .streams ),		StreamsReserved :      cc .streamsReserved ,		StreamsPending :       cc .pendingRequests ,		LastIdle :             cc .lastIdle ,		MaxConcurrentStreams : maxConcurrent ,	}}type  http2clientConnIdleState  struct  {	canTakeNewRequest  bool }func  (cc  *http2ClientConn ) idleState http2clientConnIdleState  {	cc .mu .Lock ()	defer  cc .mu .Unlock ()	return  cc .idleStateLocked ()}func  (cc  *http2ClientConn ) idleStateLocked st  http2clientConnIdleState ) {	if  cc .singleUse  && cc .nextStreamID  > 1  {		return 	}	var  maxConcurrentOkay  bool 	if  cc .t .StrictMaxConcurrentStreams  {				maxConcurrentOkay  = true 	} else  {		maxConcurrentOkay  = int64 (len (cc .streams )+cc .streamsReserved +1 ) <= int64 (cc .maxConcurrentStreams )	}	st .canTakeNewRequest  = cc .goAway  == nil  && !cc .closed  && !cc .closing  && maxConcurrentOkay  &&		!cc .doNotReuse  &&		int64 (cc .nextStreamID )+2 *int64 (cc .pendingRequests ) < math .MaxInt32  &&		!cc .tooIdleLocked ()	return }func  (cc  *http2ClientConn ) canTakeNewRequestLocked bool  {	st  := cc .idleStateLocked ()	return  st .canTakeNewRequest }func  (cc  *http2ClientConn ) tooIdleLocked bool  {		return  cc .idleTimeout  != 0  && !cc .lastIdle .IsZero () && time .Since (cc .lastIdle .Round (0 )) > cc .idleTimeout }func  (cc  *http2ClientConn ) onIdleTimeout 	cc .closeIfIdle ()}func  (cc  *http2ClientConn ) closeConn 	t  := time .AfterFunc (250 *time .Millisecond , cc .forceCloseConn )	defer  t .Stop ()	cc .tconn .Close ()}func  (cc  *http2ClientConn ) forceCloseConn 	tc , ok  := cc .tconn .(*tls .Conn )	if  !ok  {		return 	}	if  nc  := tc .NetConn (); nc  != nil  {		nc .Close ()	}}func  (cc  *http2ClientConn ) closeIfIdle 	cc .mu .Lock ()	if  len (cc .streams ) > 0  || cc .streamsReserved  > 0  {		cc .mu .Unlock ()		return 	}	cc .closed  = true 	nextID  := cc .nextStreamID 		cc .mu .Unlock ()	if  http2VerboseLogs  {		cc .vlogf ("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)" , cc , cc .singleUse , nextID -2 )	}	cc .closeConn ()}func  (cc  *http2ClientConn ) isDoNotReuseAndIdle bool  {	cc .mu .Lock ()	defer  cc .mu .Unlock ()	return  cc .doNotReuse  && len (cc .streams ) == 0 }var  http2shutdownEnterWaitStateHook  = func () {}func  (cc  *http2ClientConn ) Shutdown ctx  context .Context ) error  {	if  err  := cc .sendGoAway (); err  != nil  {		return  err 	}		done  := make (chan  struct {})	cancelled  := false  	go  func () {		cc .t .markNewGoroutine ()		cc .mu .Lock ()		defer  cc .mu .Unlock ()		for  {			if  len (cc .streams ) == 0  || cc .closed  {				cc .closed  = true 				close (done )				break 			}			if  cancelled  {				break 			}			cc .cond .Wait ()		}	}()	http2shutdownEnterWaitStateHook ()	select 	case  <- done :		cc .closeConn ()		return  nil 	case  <- ctx .Done ():		cc .mu .Lock ()				cancelled  = true 		cc .cond .Broadcast ()		cc .mu .Unlock ()		return  ctx .Err ()	}}func  (cc  *http2ClientConn ) sendGoAway error  {	cc .mu .Lock ()	closing  := cc .closing 	cc .closing  = true 	maxStreamID  := cc .nextStreamID 	cc .mu .Unlock ()	if  closing  {				return  nil 	}	cc .wmu .Lock ()	defer  cc .wmu .Unlock ()		if  err  := cc .fr .WriteGoAway (maxStreamID , http2ErrCodeNo , nil ); err  != nil  {		return  err 	}	if  err  := cc .bw .Flush (); err  != nil  {		return  err 	}		return  nil }func  (cc  *http2ClientConn ) closeForError err  error ) {	cc .mu .Lock ()	cc .closed  = true 	for  _ , cs  := range  cc .streams  {		cs .abortStreamLocked (err )	}	cc .cond .Broadcast ()	cc .mu .Unlock ()	cc .closeConn ()}func  (cc  *http2ClientConn ) Close error  {	err  := errors .New ("http2: client connection force closed via ClientConn.Close" )	cc .closeForError (err )	return  nil }func  (cc  *http2ClientConn ) closeForLostPing 	err  := errors .New ("http2: client connection lost" )	if  f  := cc .t .CountError ; f  != nil  {		f ("conn_close_lost_ping" )	}	cc .closeForError (err )}var  http2errRequestCanceled  = errors .New ("net/http: request canceled" )func  http2commaSeparatedTrailers req  *Request ) (string , error ) {	keys  := make ([]string , 0 , len (req .Trailer ))	for  k  := range  req .Trailer  {		k  = http2canonicalHeader (k )		switch  k  {		case  "Transfer-Encoding" , "Trailer" , "Content-Length" :			return  "" , fmt .Errorf ("invalid Trailer key %q" , k )		}		keys  = append (keys , k )	}	if  len (keys ) > 0  {		sort .Strings (keys )		return  strings .Join (keys , "," ), nil 	}	return  "" , nil }func  (cc  *http2ClientConn ) responseHeaderTimeout time .Duration  {	if  cc .t .t1  != nil  {		return  cc .t .t1 .ResponseHeaderTimeout 	}		return  0 }func  http2checkConnHeaders req  *Request ) error  {	if  v  := req .Header .Get ("Upgrade" ); v  != ""  {		return  fmt .Errorf ("http2: invalid Upgrade request header: %q" , req .Header ["Upgrade" ])	}	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 ] != ""  && !http2asciiEqualFold (vv [0 ], "close" ) && !http2asciiEqualFold (vv [0 ], "keep-alive" )) {		return  fmt .Errorf ("http2: invalid Connection request header: %q" , vv )	}	return  nil }func  http2actualContentLength req  *Request ) int64  {	if  req .Body  == nil  || req .Body  == NoBody  {		return  0 	}	if  req .ContentLength  != 0  {		return  req .ContentLength 	}	return  -1 }func  (cc  *http2ClientConn ) decrStreamReservations 	cc .mu .Lock ()	defer  cc .mu .Unlock ()	cc .decrStreamReservationsLocked ()}func  (cc  *http2ClientConn ) decrStreamReservationsLocked 	if  cc .streamsReserved  > 0  {		cc .streamsReserved --	}}func  (cc  *http2ClientConn ) RoundTrip req  *Request ) (*Response , error ) {	return  cc .roundTrip (req , nil )}func  (cc  *http2ClientConn ) roundTrip req  *Request , streamf  func (*http2clientStream )) (*Response , error ) {	ctx  := req .Context ()	cs  := &http2clientStream {		cc :                   cc ,		ctx :                  ctx ,		reqCancel :            req .Cancel ,		isHead :               req .Method  == "HEAD" ,		reqBody :              req .Body ,		reqBodyContentLength : http2actualContentLength (req ),		trace :                httptrace .ContextClientTrace (ctx ),		peerClosed :           make (chan  struct {}),		abort :                make (chan  struct {}),		respHeaderRecv :       make (chan  struct {}),		donec :                make (chan  struct {}),	}		if  !cc .t .disableCompression () &&		req .Header .Get ("Accept-Encoding" ) == ""  &&		req .Header .Get ("Range" ) == ""  &&		!cs .isHead  {				cs .requestedGzip  = true 	}	go  cs .doRequest (req , streamf )	waitDone  := func () error  {		select 		case  <- cs .donec :			return  nil 		case  <- ctx .Done ():			return  ctx .Err ()		case  <- cs .reqCancel :			return  http2errRequestCanceled 		}	}	handleResponseHeaders  := func () (*Response , error ) {		res  := cs .res 		if  res .StatusCode  > 299  {						cs .abortRequestBodyWrite ()		}		res .Request  = req 		res .TLS  = cc .tlsState 		if  res .Body  == http2noBody  && http2actualContentLength (req ) == 0  {						if  err  := waitDone (); err  != nil  {				return  nil , err 			}		}		return  res , nil 	}	cancelRequest  := func (cs  *http2clientStream , err  error ) error  {		cs .cc .mu .Lock ()		bodyClosed  := cs .reqBodyClosed 		cs .cc .mu .Unlock ()				if  bodyClosed  != nil  {			<-bodyClosed 		}		return  err 	}	for  {		select 		case  <- cs .respHeaderRecv :			return  handleResponseHeaders ()		case  <- cs .abort :			select 			case  <- cs .respHeaderRecv :								return  handleResponseHeaders ()			default :				waitDone ()				return  nil , cs .abortErr 			}		case  <- ctx .Done ():			err  := ctx .Err ()			cs .abortStream (err )			return  nil , cancelRequest (cs , err )		case  <- cs .reqCancel :			cs .abortStream (http2errRequestCanceled )			return  nil , cancelRequest (cs , http2errRequestCanceled )		}	}}func  (cs  *http2clientStream ) doRequest req  *Request , streamf  func (*http2clientStream )) {	cs .cc .t .markNewGoroutine ()	err  := cs .writeRequest (req , streamf )	cs .cleanupWriteRequest (err )}func  (cs  *http2clientStream ) writeRequest req  *Request , streamf  func (*http2clientStream )) (err  error ) {	cc  := cs .cc 	ctx  := cs .ctx 	if  err  := http2checkConnHeaders (req ); err  != nil  {		return  err 	}		if  cc .reqHeaderMu  == nil  {		panic ("RoundTrip on uninitialized ClientConn" ) 	}	select 	case  cc .reqHeaderMu  <-  struct {}{}:	case  <- cs .reqCancel :		return  http2errRequestCanceled 	case  <- ctx .Done ():		return  ctx .Err ()	}	cc .mu .Lock ()	if  cc .idleTimer  != nil  {		cc .idleTimer .Stop ()	}	cc .decrStreamReservationsLocked ()	if  err  := cc .awaitOpenSlotForStreamLocked (cs ); err  != nil  {		cc .mu .Unlock ()		<-cc .reqHeaderMu 		return  err 	}	cc .addStreamLocked (cs ) 	if  http2isConnectionCloseRequest (req ) {		cc .doNotReuse  = true 	}	cc .mu .Unlock ()	if  streamf  != nil  {		streamf (cs )	}	continueTimeout  := cc .t .expectContinueTimeout ()	if  continueTimeout  != 0  {		if  !httpguts .HeaderValuesContainsToken (req .Header ["Expect" ], "100-continue" ) {			continueTimeout  = 0 		} else  {			cs .on100  = make (chan  struct {}, 1 )		}	}		err  = cs .encodeAndWriteHeaders (req )	<-cc .reqHeaderMu 	if  err  != nil  {		return  err 	}	hasBody  := cs .reqBodyContentLength  != 0 	if  !hasBody  {		cs .sentEndStream  = true 	} else  {		if  continueTimeout  != 0  {			http2traceWait100Continue (cs .trace )			timer  := time .NewTimer (continueTimeout )			select 			case  <- timer .C :				err  = nil 			case  <- cs .on100 :				err  = nil 			case  <- cs .abort :				err  = cs .abortErr 			case  <- ctx .Done ():				err  = ctx .Err ()			case  <- cs .reqCancel :				err  = http2errRequestCanceled 			}			timer .Stop ()			if  err  != nil  {				http2traceWroteRequest (cs .trace , err )				return  err 			}		}		if  err  = cs .writeRequestBody (req ); err  != nil  {			if  err  != http2errStopReqBodyWrite  {				http2traceWroteRequest (cs .trace , err )				return  err 			}		} else  {			cs .sentEndStream  = true 		}	}	http2traceWroteRequest (cs .trace , err )	var  respHeaderTimer  <-chan  time .Time 	var  respHeaderRecv  chan  struct {}	if  d  := cc .responseHeaderTimeout (); d  != 0  {		timer  := cc .t .newTimer (d )		defer  timer .Stop ()		respHeaderTimer  = timer .C ()		respHeaderRecv  = cs .respHeaderRecv 	}		for  {		select 		case  <- cs .peerClosed :			return  nil 		case  <- respHeaderTimer :			return  http2errTimeout 		case  <- respHeaderRecv :			respHeaderRecv  = nil 			respHeaderTimer  = nil  		case  <- cs .abort :			return  cs .abortErr 		case  <- ctx .Done ():			return  ctx .Err ()		case  <- cs .reqCancel :			return  http2errRequestCanceled 		}	}}func  (cs  *http2clientStream ) encodeAndWriteHeaders req  *Request ) error  {	cc  := cs .cc 	ctx  := cs .ctx 	cc .wmu .Lock ()	defer  cc .wmu .Unlock ()		select 	case  <- cs .abort :		return  cs .abortErr 	case  <- ctx .Done ():		return  ctx .Err ()	case  <- cs .reqCancel :		return  http2errRequestCanceled 	default :	}		trailers , err  := http2commaSeparatedTrailers (req )	if  err  != nil  {		return  err 	}	hasTrailers  := trailers  != "" 	contentLen  := http2actualContentLength (req )	hasBody  := contentLen  != 0 	hdrs , err  := cc .encodeHeaders (req , cs .requestedGzip , trailers , contentLen )	if  err  != nil  {		return  err 	}		endStream  := !hasBody  && !hasTrailers 	cs .sentHeaders  = true 	err  = cc .writeHeaders (cs .ID , endStream , int (cc .maxFrameSize ), hdrs )	http2traceWroteHeaders (cs .trace )	return  err }func  (cs  *http2clientStream ) cleanupWriteRequest err  error ) {	cc  := cs .cc 	if  cs .ID  == 0  {				cc .decrStreamReservations ()	}		cc .mu .Lock ()	mustCloseBody  := false 	if  cs .reqBody  != nil  && cs .reqBodyClosed  == nil  {		mustCloseBody  = true 		cs .reqBodyClosed  = make (chan  struct {})	}	bodyClosed  := cs .reqBodyClosed 	cc .mu .Unlock ()	if  mustCloseBody  {		cs .reqBody .Close ()		close (bodyClosed )	}	if  bodyClosed  != nil  {		<-bodyClosed 	}	if  err  != nil  && cs .sentEndStream  {				select 		case  <- cs .peerClosed :			err  = nil 		default :		}	}	if  err  != nil  {		cs .abortStream (err ) 		if  cs .sentHeaders  {			if  se , ok  := err .(http2StreamError ); ok  {				if  se .Cause  != http2errFromPeer  {					cc .writeStreamReset (cs .ID , se .Code , err )				}			} else  {				cc .writeStreamReset (cs .ID , http2ErrCodeCancel , err )			}		}		cs .bufPipe .CloseWithError (err ) 	} else  {		if  cs .sentHeaders  && !cs .sentEndStream  {			cc .writeStreamReset (cs .ID , http2ErrCodeNo , nil )		}		cs .bufPipe .CloseWithError (http2errRequestCanceled )	}	if  cs .ID  != 0  {		cc .forgetStreamID (cs .ID )	}	cc .wmu .Lock ()	werr  := cc .werr 	cc .wmu .Unlock ()	if  werr  != nil  {		cc .Close ()	}	close (cs .donec )}func  (cc  *http2ClientConn ) awaitOpenSlotForStreamLocked cs  *http2clientStream ) error  {	for  {		cc .lastActive  = time .Now ()		if  cc .closed  || !cc .canTakeNewRequestLocked () {			return  http2errClientConnUnusable 		}		cc .lastIdle  = time .Time {}		if  int64 (len (cc .streams )) < int64 (cc .maxConcurrentStreams ) {			return  nil 		}		cc .pendingRequests ++		cc .cond .Wait ()		cc .pendingRequests --		select 		case  <- cs .abort :			return  cs .abortErr 		default :		}	}}func  (cc  *http2ClientConn ) writeHeaders streamID  uint32 , endStream  bool , maxFrameSize  int , hdrs  []byte ) error  {	first  := true  	for  len (hdrs ) > 0  && cc .werr  == nil  {		chunk  := hdrs 		if  len (chunk ) > maxFrameSize  {			chunk  = chunk [:maxFrameSize ]		}		hdrs  = hdrs [len (chunk ):]		endHeaders  := len (hdrs ) == 0 		if  first  {			cc .fr .WriteHeaders (http2HeadersFrameParam {				StreamID :      streamID ,				BlockFragment : chunk ,				EndStream :     endStream ,				EndHeaders :    endHeaders ,			})			first  = false 		} else  {			cc .fr .WriteContinuation (streamID , endHeaders , chunk )		}	}	cc .bw .Flush ()	return  cc .werr }var  (		http2errStopReqBodyWrite  = errors .New ("http2: aborting request body write" )		http2errStopReqBodyWriteAndCancel  = errors .New ("http2: canceling request" )	http2errReqBodyTooLong  = errors .New ("http2: request body larger than specified content length" ))func  (cs  *http2clientStream ) frameScratchBufferLen maxFrameSize  int ) int  {	const  max  = 512  << 10 	n  := int64 (maxFrameSize )	if  n  > max  {		n  = max 	}	if  cl  := cs .reqBodyContentLength ; cl  != -1  && cl +1  < n  {				n  = cl  + 1 	}	if  n  < 1  {		return  1 	}	return  int (n ) }var  http2bufPools  [7 ]sync .Pool  func  http2bufPoolIndex size  int ) int  {	if  size  <= 16384  {		return  0 	}	size  -= 1 	bits  := bits .Len (uint (size ))	index  := bits  - 14 	if  index  >= len (http2bufPools ) {		return  len (http2bufPools ) - 1 	}	return  index }func  (cs  *http2clientStream ) writeRequestBody req  *Request ) (err  error ) {	cc  := cs .cc 	body  := cs .reqBody 	sentEnd  := false  	hasTrailers  := req .Trailer  != nil 	remainLen  := cs .reqBodyContentLength 	hasContentLen  := remainLen  != -1 	cc .mu .Lock ()	maxFrameSize  := int (cc .maxFrameSize )	cc .mu .Unlock ()		scratchLen  := cs .frameScratchBufferLen (maxFrameSize )	var  buf  []byte 	index  := http2bufPoolIndex (scratchLen )	if  bp , ok  := http2bufPools [index ].Get ().(*[]byte ); ok  && len (*bp ) >= scratchLen  {		defer  http2bufPools [index ].Put (bp )		buf  = *bp 	} else  {		buf  = make ([]byte , scratchLen )		defer  http2bufPools [index ].Put (&buf )	}	var  sawEOF  bool 	for  !sawEOF  {		n , err  := body .Read (buf )		if  hasContentLen  {			remainLen  -= int64 (n )			if  remainLen  == 0  && err  == nil  {								var  scratch  [1 ]byte 				var  n1  int 				n1 , err  = body .Read (scratch [:])				remainLen  -= int64 (n1 )			}			if  remainLen  < 0  {				err  = http2errReqBodyTooLong 				return  err 			}		}		if  err  != nil  {			cc .mu .Lock ()			bodyClosed  := cs .reqBodyClosed  != nil 			cc .mu .Unlock ()			switch  {			case  bodyClosed :				return  http2errStopReqBodyWrite 			case  err  == io .EOF :				sawEOF  = true 				err  = nil 			default :				return  err 			}		}		remain  := buf [:n ]		for  len (remain ) > 0  && err  == nil  {			var  allowed  int32 			allowed , err  = cs .awaitFlowControl (len (remain ))			if  err  != nil  {				return  err 			}			cc .wmu .Lock ()			data  := remain [:allowed ]			remain  = remain [allowed :]			sentEnd  = sawEOF  && len (remain ) == 0  && !hasTrailers 			err  = cc .fr .WriteData (cs .ID , sentEnd , data )			if  err  == nil  {								err  = cc .bw .Flush ()			}			cc .wmu .Unlock ()		}		if  err  != nil  {			return  err 		}	}	if  sentEnd  {				return  nil 	}		cc .mu .Lock ()	trailer  := req .Trailer 	err  = cs .abortErr 	cc .mu .Unlock ()	if  err  != nil  {		return  err 	}	cc .wmu .Lock ()	defer  cc .wmu .Unlock ()	var  trls  []byte 	if  len (trailer ) > 0  {		trls , err  = cc .encodeTrailers (trailer )		if  err  != nil  {			return  err 		}	}		if  len (trls ) > 0  {		err  = cc .writeHeaders (cs .ID , true , maxFrameSize , trls )	} else  {		err  = cc .fr .WriteData (cs .ID , true , nil )	}	if  ferr  := cc .bw .Flush (); ferr  != nil  && err  == nil  {		err  = ferr 	}	return  err }func  (cs  *http2clientStream ) awaitFlowControl maxBytes  int ) (taken  int32 , err  error ) {	cc  := cs .cc 	ctx  := cs .ctx 	cc .mu .Lock ()	defer  cc .mu .Unlock ()	for  {		if  cc .closed  {			return  0 , http2errClientConnClosed 		}		if  cs .reqBodyClosed  != nil  {			return  0 , http2errStopReqBodyWrite 		}		select 		case  <- cs .abort :			return  0 , cs .abortErr 		case  <- ctx .Done ():			return  0 , ctx .Err ()		case  <- cs .reqCancel :			return  0 , http2errRequestCanceled 		default :		}		if  a  := cs .flow .available (); a  > 0  {			take  := a 			if  int (take ) > maxBytes  {				take  = int32 (maxBytes ) 			}			if  take  > int32 (cc .maxFrameSize ) {				take  = int32 (cc .maxFrameSize )			}			cs .flow .take (take )			return  take , nil 		}		cc .cond .Wait ()	}}func  http2validateHeaders hdrs  Header ) string  {	for  k , vv  := range  hdrs  {		if  !httpguts .ValidHeaderFieldName (k ) {			return  fmt .Sprintf ("name %q" , k )		}		for  _ , v  := range  vv  {			if  !httpguts .ValidHeaderFieldValue (v ) {								return  fmt .Sprintf ("value for header %q" , k )			}		}	}	return  "" }var  http2errNilRequestURL  = errors .New ("http2: Request.URI is nil" )func  (cc  *http2ClientConn ) encodeHeaders req  *Request , addGzipHeader  bool , trailers  string , contentLength  int64 ) ([]byte , error ) {	cc .hbuf .Reset ()	if  req .URL  == nil  {		return  nil , http2errNilRequestURL 	}	host  := req .Host 	if  host  == ""  {		host  = req .URL .Host 	}	host , err  := httpguts .PunycodeHostPort (host )	if  err  != nil  {		return  nil , err 	}	if  !httpguts .ValidHostHeader (host ) {		return  nil , errors .New ("http2: invalid Host header" )	}	var  path  string 	if  req .Method  != "CONNECT"  {		path  = req .URL .RequestURI ()		if  !http2validPseudoPath (path ) {			orig  := path 			path  = strings .TrimPrefix (path , req .URL .Scheme +"://" +host )			if  !http2validPseudoPath (path ) {				if  req .URL .Opaque  != ""  {					return  nil , fmt .Errorf ("invalid request :path %q from URL.Opaque = %q" , orig , req .URL .Opaque )				} else  {					return  nil , fmt .Errorf ("invalid request :path %q" , orig )				}			}		}	}		if  err  := http2validateHeaders (req .Header ); err  != ""  {		return  nil , fmt .Errorf ("invalid HTTP header %s" , err )	}	if  err  := http2validateHeaders (req .Trailer ); err  != ""  {		return  nil , fmt .Errorf ("invalid HTTP trailer %s" , err )	}	enumerateHeaders  := func (f  func (name , value  string )) {				f (":authority" , host )		m  := req .Method 		if  m  == ""  {			m  = MethodGet 		}		f (":method" , m )		if  req .Method  != "CONNECT"  {			f (":path" , path )			f (":scheme" , req .URL .Scheme )		}		if  trailers  != ""  {			f ("trailer" , trailers )		}		var  didUA  bool 		for  k , vv  := range  req .Header  {			if  http2asciiEqualFold (k , "host" ) || http2asciiEqualFold (k , "content-length" ) {								continue 			} else  if  http2asciiEqualFold (k , "connection" ) ||				http2asciiEqualFold (k , "proxy-connection" ) ||				http2asciiEqualFold (k , "transfer-encoding" ) ||				http2asciiEqualFold (k , "upgrade" ) ||				http2asciiEqualFold (k , "keep-alive" ) {								continue 			} else  if  http2asciiEqualFold (k , "user-agent" ) {								didUA  = true 				if  len (vv ) < 1  {					continue 				}				vv  = vv [:1 ]				if  vv [0 ] == ""  {					continue 				}			} else  if  http2asciiEqualFold (k , "cookie" ) {								for  _ , v  := range  vv  {					for  {						p  := strings .IndexByte (v , ';' )						if  p  < 0  {							break 						}						f ("cookie" , v [:p ])						p ++												for  p +1  <= len (v ) && v [p ] == ' '  {							p ++						}						v  = v [p :]					}					if  len (v ) > 0  {						f ("cookie" , v )					}				}				continue 			}			for  _ , v  := range  vv  {				f (k , v )			}		}		if  http2shouldSendReqContentLength (req .Method , contentLength ) {			f ("content-length" , strconv .FormatInt (contentLength , 10 ))		}		if  addGzipHeader  {			f ("accept-encoding" , "gzip" )		}		if  !didUA  {			f ("user-agent" , http2defaultUserAgent )		}	}		hlSize  := uint64 (0 )	enumerateHeaders (func (name , value  string ) {		hf  := hpack .HeaderField {Name : name , Value : value }		hlSize  += uint64 (hf .Size ())	})	if  hlSize  > cc .peerMaxHeaderListSize  {		return  nil , http2errRequestHeaderListSize 	}	trace  := httptrace .ContextClientTrace (req .Context ())	traceHeaders  := http2traceHasWroteHeaderField (trace )		enumerateHeaders (func (name , value  string ) {		name , ascii  := http2lowerHeader (name )		if  !ascii  {						return 		}		cc .writeHeader (name , value )		if  traceHeaders  {			http2traceWroteHeaderField (trace , name , value )		}	})	return  cc .hbuf .Bytes (), nil }func  http2shouldSendReqContentLength method  string , contentLength  int64 ) bool  {	if  contentLength  > 0  {		return  true 	}	if  contentLength  < 0  {		return  false 	}		switch  method  {	case  "POST" , "PUT" , "PATCH" :		return  true 	default :		return  false 	}}func  (cc  *http2ClientConn ) encodeTrailers trailer  Header ) ([]byte , error ) {	cc .hbuf .Reset ()	hlSize  := uint64 (0 )	for  k , vv  := range  trailer  {		for  _ , v  := range  vv  {			hf  := hpack .HeaderField {Name : k , Value : v }			hlSize  += uint64 (hf .Size ())		}	}	if  hlSize  > cc .peerMaxHeaderListSize  {		return  nil , http2errRequestHeaderListSize 	}	for  k , vv  := range  trailer  {		lowKey , ascii  := http2lowerHeader (k )		if  !ascii  {						continue 		}				for  _ , v  := range  vv  {			cc .writeHeader (lowKey , v )		}	}	return  cc .hbuf .Bytes (), nil }func  (cc  *http2ClientConn ) writeHeader name , value  string ) {	if  http2VerboseLogs  {		log .Printf ("http2: Transport encoding header %q = %q" , name , value )	}	cc .henc .WriteField (hpack .HeaderField {Name : name , Value : value })}type  http2resAndError  struct  {	_   http2incomparable 	res  *Response 	err  error }func  (cc  *http2ClientConn ) addStreamLocked cs  *http2clientStream ) {	cs .flow .add (int32 (cc .initialWindowSize ))	cs .flow .setConnFlow (&cc .flow )	cs .inflow .init (http2transportDefaultStreamFlow )	cs .ID  = cc .nextStreamID 	cc .nextStreamID  += 2 	cc .streams [cs .ID ] = cs 	if  cs .ID  == 0  {		panic ("assigned stream ID 0" )	}}func  (cc  *http2ClientConn ) forgetStreamID id  uint32 ) {	cc .mu .Lock ()	slen  := len (cc .streams )	delete (cc .streams , id )	if  len (cc .streams ) != slen -1  {		panic ("forgetting unknown stream id" )	}	cc .lastActive  = time .Now ()	if  len (cc .streams ) == 0  && cc .idleTimer  != nil  {		cc .idleTimer .Reset (cc .idleTimeout )		cc .lastIdle  = time .Now ()	}		cc .cond .Broadcast ()	closeOnIdle  := cc .singleUse  || cc .doNotReuse  || cc .t .disableKeepAlives () || cc .goAway  != nil 	if  closeOnIdle  && cc .streamsReserved  == 0  && len (cc .streams ) == 0  {		if  http2VerboseLogs  {			cc .vlogf ("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)" , cc , cc .singleUse , cc .nextStreamID -2 )		}		cc .closed  = true 		defer  cc .closeConn ()	}	cc .mu .Unlock ()}type  http2clientConnReadLoop  struct  {	_  http2incomparable 	cc  *http2ClientConn }func  (cc  *http2ClientConn ) readLoop 	cc .t .markNewGoroutine ()	rl  := &http2clientConnReadLoop {cc : cc }	defer  rl .cleanup ()	cc .readerErr  = rl .run ()	if  ce , ok  := cc .readerErr .(http2ConnectionError ); ok  {		cc .wmu .Lock ()		cc .fr .WriteGoAway (0 , http2ErrCode (ce ), nil )		cc .wmu .Unlock ()	}}type  http2GoAwayError  struct  {	LastStreamID  uint32 	ErrCode       http2ErrCode 	DebugData     string }func  (e  http2GoAwayError ) Error string  {	return  fmt .Sprintf ("http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q" ,		e .LastStreamID , e .ErrCode , e .DebugData )}func  http2isEOFOrNetReadError err  error ) bool  {	if  err  == io .EOF  {		return  true 	}	ne , ok  := err .(*net .OpError )	return  ok  && ne .Op  == "read" }func  (rl  *http2clientConnReadLoop ) cleanup 	cc  := rl .cc 	cc .t .connPool ().MarkDead (cc )	defer  cc .closeConn ()	defer  close (cc .readerDone )	if  cc .idleTimer  != nil  {		cc .idleTimer .Stop ()	}		err  := cc .readerErr 	cc .mu .Lock ()	if  cc .goAway  != nil  && http2isEOFOrNetReadError (err ) {		err  = http2GoAwayError {			LastStreamID : cc .goAway .LastStreamID ,			ErrCode :      cc .goAway .ErrCode ,			DebugData :    cc .goAwayDebug ,		}	} else  if  err  == io .EOF  {		err  = io .ErrUnexpectedEOF 	}	cc .closed  = true 	for  _ , cs  := range  cc .streams  {		select 		case  <- cs .peerClosed :					default :			cs .abortStreamLocked (err )		}	}	cc .cond .Broadcast ()	cc .mu .Unlock ()}func  (cc  *http2ClientConn ) countReadFrameError err  error ) {	f  := cc .t .CountError 	if  f  == nil  || err  == nil  {		return 	}	if  ce , ok  := err .(http2ConnectionError ); ok  {		errCode  := http2ErrCode (ce )		f (fmt .Sprintf ("read_frame_conn_error_%s" , errCode .stringToken ()))		return 	}	if  errors .Is (err , io .EOF ) {		f ("read_frame_eof" )		return 	}	if  errors .Is (err , io .ErrUnexpectedEOF ) {		f ("read_frame_unexpected_eof" )		return 	}	if  errors .Is (err , http2ErrFrameTooLarge ) {		f ("read_frame_too_large" )		return 	}	f ("read_frame_other" )}func  (rl  *http2clientConnReadLoop ) run error  {	cc  := rl .cc 	gotSettings  := false 	readIdleTimeout  := cc .t .ReadIdleTimeout 	var  t  http2timer 	if  readIdleTimeout  != 0  {		t  = cc .t .afterFunc (readIdleTimeout , cc .healthCheck )	}	for  {		f , err  := cc .fr .ReadFrame ()		if  t  != nil  {			t .Reset (readIdleTimeout )		}		if  err  != nil  {			cc .vlogf ("http2: Transport readFrame error on conn %p: (%T) %v" , cc , err , err )		}		if  se , ok  := err .(http2StreamError ); ok  {			if  cs  := rl .streamByID (se .StreamID ); cs  != nil  {				if  se .Cause  == nil  {					se .Cause  = cc .fr .errDetail 				}				rl .endStreamError (cs , se )			}			continue 		} else  if  err  != nil  {			cc .countReadFrameError (err )			return  err 		}		if  http2VerboseLogs  {			cc .vlogf ("http2: Transport received %s" , http2summarizeFrame (f ))		}		if  !gotSettings  {			if  _ , ok  := f .(*http2SettingsFrame ); !ok  {				cc .logf ("protocol error: received %T before a SETTINGS frame" , f )				return  http2ConnectionError (http2ErrCodeProtocol )			}			gotSettings  = true 		}		switch  f := f .(type ) {		case  *http2MetaHeadersFrame :			err  = rl .processHeaders (f )		case  *http2DataFrame :			err  = rl .processData (f )		case  *http2GoAwayFrame :			err  = rl .processGoAway (f )		case  *http2RSTStreamFrame :			err  = rl .processResetStream (f )		case  *http2SettingsFrame :			err  = rl .processSettings (f )		case  *http2PushPromiseFrame :			err  = rl .processPushPromise (f )		case  *http2WindowUpdateFrame :			err  = rl .processWindowUpdate (f )		case  *http2PingFrame :			err  = rl .processPing (f )		default :			cc .logf ("Transport: unhandled response frame type %T" , f )		}		if  err  != nil  {			if  http2VerboseLogs  {				cc .vlogf ("http2: Transport conn %p received error from processing frame %v: %v" , cc , http2summarizeFrame (f ), err )			}			return  err 		}	}}func  (rl  *http2clientConnReadLoop ) processHeaders f  *http2MetaHeadersFrame ) error  {	cs  := rl .streamByID (f .StreamID )	if  cs  == nil  {				return  nil 	}	if  cs .readClosed  {		rl .endStreamError (cs , http2StreamError {			StreamID : f .StreamID ,			Code :     http2ErrCodeProtocol ,			Cause :    errors .New ("protocol error: headers after END_STREAM" ),		})		return  nil 	}	if  !cs .firstByte  {		if  cs .trace  != nil  {						http2traceFirstResponseByte (cs .trace )		}		cs .firstByte  = true 	}	if  !cs .pastHeaders  {		cs .pastHeaders  = true 	} else  {		return  rl .processTrailers (cs , f )	}	res , err  := rl .handleResponse (cs , f )	if  err  != nil  {		if  _ , ok  := err .(http2ConnectionError ); ok  {			return  err 		}				rl .endStreamError (cs , http2StreamError {			StreamID : f .StreamID ,			Code :     http2ErrCodeProtocol ,			Cause :    err ,		})		return  nil  	}	if  res  == nil  {				return  nil 	}	cs .resTrailer  = &res .Trailer 	cs .res  = res 	close (cs .respHeaderRecv )	if  f .StreamEnded () {		rl .endStream (cs )	}	return  nil }func  (rl  *http2clientConnReadLoop ) handleResponse cs  *http2clientStream , f  *http2MetaHeadersFrame ) (*Response , error ) {	if  f .Truncated  {		return  nil , http2errResponseHeaderListSize 	}	status  := f .PseudoValue ("status" )	if  status  == ""  {		return  nil , errors .New ("malformed response from server: missing status pseudo header" )	}	statusCode , err  := strconv .Atoi (status )	if  err  != nil  {		return  nil , errors .New ("malformed response from server: malformed non-numeric status pseudo header" )	}	regularFields  := f .RegularFields ()	strs  := make ([]string , len (regularFields ))	header  := make (Header , len (regularFields ))	res  := &Response {		Proto :      "HTTP/2.0" ,		ProtoMajor : 2 ,		Header :     header ,		StatusCode : statusCode ,		Status :     status  + " "  + StatusText (statusCode ),	}	for  _ , hf  := range  regularFields  {		key  := http2canonicalHeader (hf .Name )		if  key  == "Trailer"  {			t  := res .Trailer 			if  t  == nil  {				t  = make (Header )				res .Trailer  = t 			}			http2foreachHeaderElement (hf .Value , func (v  string ) {				t [http2canonicalHeader (v )] = nil 			})		} else  {			vv  := header [key ]			if  vv  == nil  && len (strs ) > 0  {								vv , strs  = strs [:1 :1 ], strs [1 :]				vv [0 ] = hf .Value 				header [key ] = vv 			} else  {				header [key ] = append (vv , hf .Value )			}		}	}	if  statusCode  >= 100  && statusCode  <= 199  {		if  f .StreamEnded () {			return  nil , errors .New ("1xx informational response with END_STREAM flag" )		}		cs .num1xx ++		const  max1xxResponses  = 5  		if  cs .num1xx  > max1xxResponses  {			return  nil , errors .New ("http2: too many 1xx informational responses" )		}		if  fn  := cs .get1xxTraceFunc (); fn  != nil  {			if  err  := fn (statusCode , textproto .MIMEHeader (header )); err  != nil  {				return  nil , err 			}		}		if  statusCode  == 100  {			http2traceGot100Continue (cs .trace )			select 			case  cs .on100  <-  struct {}{}:			default :			}		}		cs .pastHeaders  = false  		return  nil , nil 	}	res .ContentLength  = -1 	if  clens  := res .Header ["Content-Length" ]; len (clens ) == 1  {		if  cl , err  := strconv .ParseUint (clens [0 ], 10 , 63 ); err  == nil  {			res .ContentLength  = int64 (cl )		} else  {					}	} else  if  len (clens ) > 1  {			} else  if  f .StreamEnded () && !cs .isHead  {		res .ContentLength  = 0 	}	if  cs .isHead  {		res .Body  = http2noBody 		return  res , nil 	}	if  f .StreamEnded () {		if  res .ContentLength  > 0  {			res .Body  = http2missingBody {}		} else  {			res .Body  = http2noBody 		}		return  res , nil 	}	cs .bufPipe .setBuffer (&http2dataBuffer {expected : res .ContentLength })	cs .bytesRemain  = res .ContentLength 	res .Body  = http2transportResponseBody {cs }	if  cs .requestedGzip  && http2asciiEqualFold (res .Header .Get ("Content-Encoding" ), "gzip" ) {		res .Header .Del ("Content-Encoding" )		res .Header .Del ("Content-Length" )		res .ContentLength  = -1 		res .Body  = &http2gzipReader {body : res .Body }		res .Uncompressed  = true 	}	return  res , nil }func  (rl  *http2clientConnReadLoop ) processTrailers cs  *http2clientStream , f  *http2MetaHeadersFrame ) error  {	if  cs .pastTrailers  {				return  http2ConnectionError (http2ErrCodeProtocol )	}	cs .pastTrailers  = true 	if  !f .StreamEnded () {				return  http2ConnectionError (http2ErrCodeProtocol )	}	if  len (f .PseudoFields ()) > 0  {				return  http2ConnectionError (http2ErrCodeProtocol )	}	trailer  := make (Header )	for  _ , hf  := range  f .RegularFields () {		key  := http2canonicalHeader (hf .Name )		trailer [key ] = append (trailer [key ], hf .Value )	}	cs .trailer  = trailer 	rl .endStream (cs )	return  nil }type  http2transportResponseBody  struct  {	cs  *http2clientStream }func  (b  http2transportResponseBody ) Read p  []byte ) (n  int , err  error ) {	cs  := b .cs 	cc  := cs .cc 	if  cs .readErr  != nil  {		return  0 , cs .readErr 	}	n , err  = b .cs .bufPipe .Read (p )	if  cs .bytesRemain  != -1  {		if  int64 (n ) > cs .bytesRemain  {			n  = int (cs .bytesRemain )			if  err  == nil  {				err  = errors .New ("net/http: server replied with more than declared Content-Length; truncated" )				cs .abortStream (err )			}			cs .readErr  = err 			return  int (cs .bytesRemain ), err 		}		cs .bytesRemain  -= int64 (n )		if  err  == io .EOF  && cs .bytesRemain  > 0  {			err  = io .ErrUnexpectedEOF 			cs .readErr  = err 			return  n , err 		}	}	if  n  == 0  {				return 	}	cc .mu .Lock ()	connAdd  := cc .inflow .add (n )	var  streamAdd  int32 	if  err  == nil  { 		streamAdd  = cs .inflow .add (n )	}	cc .mu .Unlock ()	if  connAdd  != 0  || streamAdd  != 0  {		cc .wmu .Lock ()		defer  cc .wmu .Unlock ()		if  connAdd  != 0  {			cc .fr .WriteWindowUpdate (0 , http2mustUint31 (connAdd ))		}		if  streamAdd  != 0  {			cc .fr .WriteWindowUpdate (cs .ID , http2mustUint31 (streamAdd ))		}		cc .bw .Flush ()	}	return }var  http2errClosedResponseBody  = errors .New ("http2: response body closed" )func  (b  http2transportResponseBody ) Close error  {	cs  := b .cs 	cc  := cs .cc 	cs .bufPipe .BreakWithError (http2errClosedResponseBody )	cs .abortStream (http2errClosedResponseBody )	unread  := cs .bufPipe .Len ()	if  unread  > 0  {		cc .mu .Lock ()				connAdd  := cc .inflow .add (unread )		cc .mu .Unlock ()				cc .wmu .Lock ()				if  connAdd  > 0  {			cc .fr .WriteWindowUpdate (0 , uint32 (connAdd ))		}		cc .bw .Flush ()		cc .wmu .Unlock ()	}	select 	case  <- cs .donec :	case  <- cs .ctx .Done ():				return  nil 	case  <- cs .reqCancel :		return  http2errRequestCanceled 	}	return  nil }func  (rl  *http2clientConnReadLoop ) processData f  *http2DataFrame ) error  {	cc  := rl .cc 	cs  := rl .streamByID (f .StreamID )	data  := f .Data ()	if  cs  == nil  {		cc .mu .Lock ()		neverSent  := cc .nextStreamID 		cc .mu .Unlock ()		if  f .StreamID  >= neverSent  {						cc .logf ("http2: Transport received unsolicited DATA frame; closing connection" )			return  http2ConnectionError (http2ErrCodeProtocol )		}						if  f .Length  > 0  {			cc .mu .Lock ()			ok  := cc .inflow .take (f .Length )			connAdd  := cc .inflow .add (int (f .Length ))			cc .mu .Unlock ()			if  !ok  {				return  http2ConnectionError (http2ErrCodeFlowControl )			}			if  connAdd  > 0  {				cc .wmu .Lock ()				cc .fr .WriteWindowUpdate (0 , uint32 (connAdd ))				cc .bw .Flush ()				cc .wmu .Unlock ()			}		}		return  nil 	}	if  cs .readClosed  {		cc .logf ("protocol error: received DATA after END_STREAM" )		rl .endStreamError (cs , http2StreamError {			StreamID : f .StreamID ,			Code :     http2ErrCodeProtocol ,		})		return  nil 	}	if  !cs .pastHeaders  {		cc .logf ("protocol error: received DATA before a HEADERS frame" )		rl .endStreamError (cs , http2StreamError {			StreamID : f .StreamID ,			Code :     http2ErrCodeProtocol ,		})		return  nil 	}	if  f .Length  > 0  {		if  cs .isHead  && len (data ) > 0  {			cc .logf ("protocol error: received DATA on a HEAD request" )			rl .endStreamError (cs , http2StreamError {				StreamID : f .StreamID ,				Code :     http2ErrCodeProtocol ,			})			return  nil 		}				cc .mu .Lock ()		if  !http2takeInflows (&cc .inflow , &cs .inflow , f .Length ) {			cc .mu .Unlock ()			return  http2ConnectionError (http2ErrCodeFlowControl )		}				var  refund  int 		if  pad  := int (f .Length ) - len (data ); pad  > 0  {			refund  += pad 		}		didReset  := false 		var  err  error 		if  len (data ) > 0  {			if  _, err  = cs .bufPipe .Write (data ); err  != nil  {								didReset  = true 				refund  += len (data )			}		}		sendConn  := cc .inflow .add (refund )		var  sendStream  int32 		if  !didReset  {			sendStream  = cs .inflow .add (refund )		}		cc .mu .Unlock ()		if  sendConn  > 0  || sendStream  > 0  {			cc .wmu .Lock ()			if  sendConn  > 0  {				cc .fr .WriteWindowUpdate (0 , uint32 (sendConn ))			}			if  sendStream  > 0  {				cc .fr .WriteWindowUpdate (cs .ID , uint32 (sendStream ))			}			cc .bw .Flush ()			cc .wmu .Unlock ()		}		if  err  != nil  {			rl .endStreamError (cs , err )			return  nil 		}	}	if  f .StreamEnded () {		rl .endStream (cs )	}	return  nil }func  (rl  *http2clientConnReadLoop ) endStream cs  *http2clientStream ) {		if  !cs .readClosed  {		cs .readClosed  = true 				rl .cc .mu .Lock ()		defer  rl .cc .mu .Unlock ()		cs .bufPipe .closeWithErrorAndCode (io .EOF , cs .copyTrailers )		close (cs .peerClosed )	}}func  (rl  *http2clientConnReadLoop ) endStreamError cs  *http2clientStream , err  error ) {	cs .readAborted  = true 	cs .abortStream (err )}func  (rl  *http2clientConnReadLoop ) streamByID id  uint32 ) *http2clientStream  {	rl .cc .mu .Lock ()	defer  rl .cc .mu .Unlock ()	cs  := rl .cc .streams [id ]	if  cs  != nil  && !cs .readAborted  {		return  cs 	}	return  nil }func  (cs  *http2clientStream ) copyTrailers 	for  k , vv  := range  cs .trailer  {		t  := cs .resTrailer 		if  *t  == nil  {			*t  = make (Header )		}		(*t )[k ] = vv 	}}func  (rl  *http2clientConnReadLoop ) processGoAway f  *http2GoAwayFrame ) error  {	cc  := rl .cc 	cc .t .connPool ().MarkDead (cc )	if  f .ErrCode  != 0  {				cc .vlogf ("transport got GOAWAY with error code = %v" , f .ErrCode )		if  fn  := cc .t .CountError ; fn  != nil  {			fn ("recv_goaway_"  + f .ErrCode .stringToken ())		}	}	cc .setGoAway (f )	return  nil }func  (rl  *http2clientConnReadLoop ) processSettings f  *http2SettingsFrame ) error  {	cc  := rl .cc 		cc .wmu .Lock ()	defer  cc .wmu .Unlock ()	if  err  := rl .processSettingsNoWrite (f ); err  != nil  {		return  err 	}	if  !f .IsAck () {		cc .fr .WriteSettingsAck ()		cc .bw .Flush ()	}	return  nil }func  (rl  *http2clientConnReadLoop ) processSettingsNoWrite f  *http2SettingsFrame ) error  {	cc  := rl .cc 	cc .mu .Lock ()	defer  cc .mu .Unlock ()	if  f .IsAck () {		if  cc .wantSettingsAck  {			cc .wantSettingsAck  = false 			return  nil 		}		return  http2ConnectionError (http2ErrCodeProtocol )	}	var  seenMaxConcurrentStreams  bool 	err  := f .ForeachSetting (func (s  http2Setting ) error  {		switch  s .ID  {		case  http2SettingMaxFrameSize :			cc .maxFrameSize  = s .Val 		case  http2SettingMaxConcurrentStreams :			cc .maxConcurrentStreams  = s .Val 			seenMaxConcurrentStreams  = true 		case  http2SettingMaxHeaderListSize :			cc .peerMaxHeaderListSize  = uint64 (s .Val )		case  http2SettingInitialWindowSize :						if  s .Val  > math .MaxInt32  {				return  http2ConnectionError (http2ErrCodeFlowControl )			}						delta  := int32 (s .Val ) - int32 (cc .initialWindowSize )			for  _ , cs  := range  cc .streams  {				cs .flow .add (delta )			}			cc .cond .Broadcast ()			cc .initialWindowSize  = s .Val 		case  http2SettingHeaderTableSize :			cc .henc .SetMaxDynamicTableSize (s .Val )			cc .peerMaxHeaderTableSize  = s .Val 		default :			cc .vlogf ("Unhandled Setting: %v" , s )		}		return  nil 	})	if  err  != nil  {		return  err 	}	if  !cc .seenSettings  {		if  !seenMaxConcurrentStreams  {						cc .maxConcurrentStreams  = http2defaultMaxConcurrentStreams 		}		cc .seenSettings  = true 	}	return  nil }func  (rl  *http2clientConnReadLoop ) processWindowUpdate f  *http2WindowUpdateFrame ) error  {	cc  := rl .cc 	cs  := rl .streamByID (f .StreamID )	if  f .StreamID  != 0  && cs  == nil  {		return  nil 	}	cc .mu .Lock ()	defer  cc .mu .Unlock ()	fl  := &cc .flow 	if  cs  != nil  {		fl  = &cs .flow 	}	if  !fl .add (int32 (f .Increment )) {				if  cs  != nil  {			rl .endStreamError (cs , http2StreamError {				StreamID : f .StreamID ,				Code :     http2ErrCodeFlowControl ,			})			return  nil 		}		return  http2ConnectionError (http2ErrCodeFlowControl )	}	cc .cond .Broadcast ()	return  nil }func  (rl  *http2clientConnReadLoop ) processResetStream f  *http2RSTStreamFrame ) error  {	cs  := rl .streamByID (f .StreamID )	if  cs  == nil  {				return  nil 	}	serr  := http2streamError (cs .ID , f .ErrCode )	serr .Cause  = http2errFromPeer 	if  f .ErrCode  == http2ErrCodeProtocol  {		rl .cc .SetDoNotReuse ()	}	if  fn  := cs .cc .t .CountError ; fn  != nil  {		fn ("recv_rststream_"  + f .ErrCode .stringToken ())	}	cs .abortStream (serr )	cs .bufPipe .CloseWithError (serr )	return  nil }func  (cc  *http2ClientConn ) Ping ctx  context .Context ) error  {	c  := make (chan  struct {})		var  p  [8 ]byte 	for  {		if  _ , err  := rand .Read (p [:]); err  != nil  {			return  err 		}		cc .mu .Lock ()				if  _ , found  := cc .pings [p ]; !found  {			cc .pings [p ] = c 			cc .mu .Unlock ()			break 		}		cc .mu .Unlock ()	}	var  pingError  error 	errc  := make (chan  struct {})	go  func () {		cc .t .markNewGoroutine ()		cc .wmu .Lock ()		defer  cc .wmu .Unlock ()		if  pingError  = cc .fr .WritePing (false , p ); pingError  != nil  {			close (errc )			return 		}		if  pingError  = cc .bw .Flush (); pingError  != nil  {			close (errc )			return 		}	}()	select 	case  <- c :		return  nil 	case  <- errc :		return  pingError 	case  <- ctx .Done ():		return  ctx .Err ()	case  <- cc .readerDone :				return  cc .readerErr 	}}func  (rl  *http2clientConnReadLoop ) processPing f  *http2PingFrame ) error  {	if  f .IsAck () {		cc  := rl .cc 		cc .mu .Lock ()		defer  cc .mu .Unlock ()				if  c , ok  := cc .pings [f .Data ]; ok  {			close (c )			delete (cc .pings , f .Data )		}		return  nil 	}	cc  := rl .cc 	cc .wmu .Lock ()	defer  cc .wmu .Unlock ()	if  err  := cc .fr .WritePing (true , f .Data ); err  != nil  {		return  err 	}	return  cc .bw .Flush ()}func  (rl  *http2clientConnReadLoop ) processPushPromise f  *http2PushPromiseFrame ) error  {		return  http2ConnectionError (http2ErrCodeProtocol )}func  (cc  *http2ClientConn ) writeStreamReset streamID  uint32 , code  http2ErrCode , err  error ) {		cc .wmu .Lock ()	cc .fr .WriteRSTStream (streamID , code )	cc .bw .Flush ()	cc .wmu .Unlock ()}var  (	http2errResponseHeaderListSize  = errors .New ("http2: response header list larger than advertised limit" )	http2errRequestHeaderListSize   = errors .New ("http2: request header list larger than peer's advertised limit" ))func  (cc  *http2ClientConn ) logf format  string , args  ...interface {}) {	cc .t .logf (format , args ...)}func  (cc  *http2ClientConn ) vlogf format  string , args  ...interface {}) {	cc .t .vlogf (format , args ...)}func  (t  *http2Transport ) vlogf format  string , args  ...interface {}) {	if  http2VerboseLogs  {		t .logf (format , args ...)	}}func  (t  *http2Transport ) logf format  string , args  ...interface {}) {	log .Printf (format , args ...)}var  http2noBody  io .ReadCloser  = http2noBodyReader {}type  http2noBodyReader  struct {}func  (http2noBodyReader ) Close error  { return  nil  }func  (http2noBodyReader ) Read byte ) (int , error ) { return  0 , io .EOF  }type  http2missingBody  struct {}func  (http2missingBody ) Close error  { return  nil  }func  (http2missingBody ) Read byte ) (int , error ) { return  0 , io .ErrUnexpectedEOF  }func  http2strSliceContains ss  []string , s  string ) bool  {	for  _ , v  := range  ss  {		if  v  == s  {			return  true 		}	}	return  false }type  http2erringRoundTripper  struct { err  error  }func  (rt  http2erringRoundTripper ) RoundTripErr error  { return  rt .err  }func  (rt  http2erringRoundTripper ) RoundTrip Request ) (*Response , error ) { return  nil , rt .err  }type  http2gzipReader  struct  {	_    http2incomparable 	body  io .ReadCloser  	zr    *gzip .Reader   	zerr  error          }func  (gz  *http2gzipReader ) Read p  []byte ) (n  int , err  error ) {	if  gz .zerr  != nil  {		return  0 , gz .zerr 	}	if  gz .zr  == nil  {		gz .zr , err  = gzip .NewReader (gz .body )		if  err  != nil  {			gz .zerr  = err 			return  0 , err 		}	}	return  gz .zr .Read (p )}func  (gz  *http2gzipReader ) Close error  {	if  err  := gz .body .Close (); err  != nil  {		return  err 	}	gz .zerr  = fs .ErrClosed 	return  nil }type  http2errorReader  struct { err  error  }func  (r  http2errorReader ) Read p  []byte ) (int , error ) { return  0 , r .err  }func  http2isConnectionCloseRequest req  *Request ) bool  {	return  req .Close  || httpguts .HeaderValuesContainsToken (req .Header ["Connection" ], "close" )}func  http2registerHTTPSProtocol t  *Transport , rt  http2noDialH2RoundTripper ) (err  error ) {	defer  func () {		if  e  := recover (); e  != nil  {			err  = fmt .Errorf ("%v" , e )		}	}()	t .RegisterProtocol ("https" , rt )	return  nil }type  http2noDialH2RoundTripper  struct { *http2Transport  }func  (rt  http2noDialH2RoundTripper ) RoundTrip req  *Request ) (*Response , error ) {	res , err  := rt .http2Transport .RoundTrip (req )	if  http2isNoCachedConnError (err ) {		return  nil , ErrSkipAltProtocol 	}	return  res , err }func  (t  *http2Transport ) idleConnTimeout time .Duration  {		if  t .IdleConnTimeout  != 0  {		return  t .IdleConnTimeout 	}	if  t .t1  != nil  {		return  t .t1 .IdleConnTimeout 	}	return  0 }func  http2traceGetConn req  *Request , hostPort  string ) {	trace  := httptrace .ContextClientTrace (req .Context ())	if  trace  == nil  || trace .GetConn  == nil  {		return 	}	trace .GetConn (hostPort )}func  http2traceGotConn req  *Request , cc  *http2ClientConn , reused  bool ) {	trace  := httptrace .ContextClientTrace (req .Context ())	if  trace  == nil  || trace .GotConn  == nil  {		return 	}	ci  := httptrace .GotConnInfo {Conn : cc .tconn }	ci .Reused  = reused 	cc .mu .Lock ()	ci .WasIdle  = len (cc .streams ) == 0  && reused 	if  ci .WasIdle  && !cc .lastActive .IsZero () {		ci .IdleTime  = time .Since (cc .lastActive )	}	cc .mu .Unlock ()	trace .GotConn (ci )}func  http2traceWroteHeaders trace  *httptrace .ClientTrace ) {	if  trace  != nil  && trace .WroteHeaders  != nil  {		trace .WroteHeaders ()	}}func  http2traceGot100Continue trace  *httptrace .ClientTrace ) {	if  trace  != nil  && trace .Got100Continue  != nil  {		trace .Got100Continue ()	}}func  http2traceWait100Continue trace  *httptrace .ClientTrace ) {	if  trace  != nil  && trace .Wait100Continue  != nil  {		trace .Wait100Continue ()	}}func  http2traceWroteRequest trace  *httptrace .ClientTrace , err  error ) {	if  trace  != nil  && trace .WroteRequest  != nil  {		trace .WroteRequest (httptrace .WroteRequestInfo {Err : err })	}}func  http2traceFirstResponseByte trace  *httptrace .ClientTrace ) {	if  trace  != nil  && trace .GotFirstResponseByte  != nil  {		trace .GotFirstResponseByte ()	}}func  http2traceHasWroteHeaderField trace  *httptrace .ClientTrace ) bool  {	return  trace  != nil  && trace .WroteHeaderField  != nil }func  http2traceWroteHeaderField trace  *httptrace .ClientTrace , k , v  string ) {	if  trace  != nil  && trace .WroteHeaderField  != nil  {		trace .WroteHeaderField (k , []string {v })	}}func  http2traceGot1xxResponseFunc trace  *httptrace .ClientTrace ) func (int , textproto .MIMEHeader ) error  {	if  trace  != nil  {		return  trace .Got1xxResponse 	}	return  nil }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 ) 	return  tlsCn , nil }type  http2writeFramer  interface  {	writeFrame (http2writeContext ) error 		staysWithinBuffer (size int ) bool }type  http2writeContext  interface  {	Framer () *http2Framer 	Flush () error 	CloseConn () error 		HeaderEncoder () (*hpack .Encoder , *bytes .Buffer )}func  http2writeEndsStream w  http2writeFramer ) bool  {	switch  v := w .(type ) {	case  *http2writeData :		return  v .endStream 	case  *http2writeResHeaders :		return  v .endStream 	case  nil :				panic ("writeEndsStream called on nil writeFramer" )	}	return  false }type  http2flushFrameWriter  struct {}func  (http2flushFrameWriter ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Flush ()}func  (http2flushFrameWriter ) staysWithinBuffer max  int ) bool  { return  false  }type  http2writeSettings  []http2Setting func  (s  http2writeSettings ) staysWithinBuffer max  int ) bool  {	const  settingSize  = 6  	return  http2frameHeaderLen +settingSize *len (s ) <= max }func  (s  http2writeSettings ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WriteSettings ([]http2Setting (s )...)}type  http2writeGoAway  struct  {	maxStreamID  uint32 	code         http2ErrCode }func  (p  *http2writeGoAway ) writeFrame ctx  http2writeContext ) error  {	err  := ctx .Framer ().WriteGoAway (p .maxStreamID , p .code , nil )	ctx .Flush () 	return  err }func  (*http2writeGoAway ) staysWithinBuffer max  int ) bool  { return  false  } type  http2writeData  struct  {	streamID   uint32 	p          []byte 	endStream  bool }func  (w  *http2writeData ) String string  {	return  fmt .Sprintf ("writeData(stream=%d, p=%d, endStream=%v)" , w .streamID , len (w .p ), w .endStream )}func  (w  *http2writeData ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WriteData (w .streamID , w .endStream , w .p )}func  (w  *http2writeData ) staysWithinBuffer max  int ) bool  {	return  http2frameHeaderLen +len (w .p ) <= max }type  http2handlerPanicRST  struct  {	StreamID  uint32 }func  (hp  http2handlerPanicRST ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WriteRSTStream (hp .StreamID , http2ErrCodeInternal )}func  (hp  http2handlerPanicRST ) staysWithinBuffer max  int ) bool  { return  http2frameHeaderLen +4  <= max  }func  (se  http2StreamError ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WriteRSTStream (se .StreamID , se .Code )}func  (se  http2StreamError ) staysWithinBuffer max  int ) bool  { return  http2frameHeaderLen +4  <= max  }type  http2writePingAck  struct { pf  *http2PingFrame  }func  (w  http2writePingAck ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WritePing (true , w .pf .Data )}func  (w  http2writePingAck ) staysWithinBuffer max  int ) bool  {	return  http2frameHeaderLen +len (w .pf .Data ) <= max }type  http2writeSettingsAck  struct {}func  (http2writeSettingsAck ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WriteSettingsAck ()}func  (http2writeSettingsAck ) staysWithinBuffer max  int ) bool  { return  http2frameHeaderLen  <= max  }func  http2splitHeaderBlock ctx  http2writeContext , headerBlock  []byte , fn  func (ctx  http2writeContext , frag  []byte , firstFrag , lastFrag  bool ) error ) error  {		const  maxFrameSize  = 16384 	first  := true 	for  len (headerBlock ) > 0  {		frag  := headerBlock 		if  len (frag ) > maxFrameSize  {			frag  = frag [:maxFrameSize ]		}		headerBlock  = headerBlock [len (frag ):]		if  err  := fn (ctx , frag , first , len (headerBlock ) == 0 ); err  != nil  {			return  err 		}		first  = false 	}	return  nil }type  http2writeResHeaders  struct  {	streamID     uint32 	httpResCode  int       	h            Header    	trailers     []string  	endStream    bool 	date           string 	contentType    string 	contentLength  string }func  http2encKV enc  *hpack .Encoder , k , v  string ) {	if  http2VerboseLogs  {		log .Printf ("http2: server encoding header %q = %q" , k , v )	}	enc .WriteField (hpack .HeaderField {Name : k , Value : v })}func  (w  *http2writeResHeaders ) staysWithinBuffer max  int ) bool  {		return  false }func  (w  *http2writeResHeaders ) writeFrame ctx  http2writeContext ) error  {	enc , buf  := ctx .HeaderEncoder ()	buf .Reset ()	if  w .httpResCode  != 0  {		http2encKV (enc , ":status" , http2httpCodeString (w .httpResCode ))	}	http2encodeHeaders (enc , w .h , w .trailers )	if  w .contentType  != ""  {		http2encKV (enc , "content-type" , w .contentType )	}	if  w .contentLength  != ""  {		http2encKV (enc , "content-length" , w .contentLength )	}	if  w .date  != ""  {		http2encKV (enc , "date" , w .date )	}	headerBlock  := buf .Bytes ()	if  len (headerBlock ) == 0  && w .trailers  == nil  {		panic ("unexpected empty hpack" )	}	return  http2splitHeaderBlock (ctx , headerBlock , w .writeHeaderBlock )}func  (w  *http2writeResHeaders ) writeHeaderBlock ctx  http2writeContext , frag  []byte , firstFrag , lastFrag  bool ) error  {	if  firstFrag  {		return  ctx .Framer ().WriteHeaders (http2HeadersFrameParam {			StreamID :      w .streamID ,			BlockFragment : frag ,			EndStream :     w .endStream ,			EndHeaders :    lastFrag ,		})	} else  {		return  ctx .Framer ().WriteContinuation (w .streamID , lastFrag , frag )	}}type  http2writePushPromise  struct  {	streamID  uint32    	method    string    	url       *url .URL  	h         Header 		allocatePromisedID  func () (uint32 , error )	promisedID          uint32 }func  (w  *http2writePushPromise ) staysWithinBuffer max  int ) bool  {		return  false }func  (w  *http2writePushPromise ) writeFrame ctx  http2writeContext ) error  {	enc , buf  := ctx .HeaderEncoder ()	buf .Reset ()	http2encKV (enc , ":method" , w .method )	http2encKV (enc , ":scheme" , w .url .Scheme )	http2encKV (enc , ":authority" , w .url .Host )	http2encKV (enc , ":path" , w .url .RequestURI ())	http2encodeHeaders (enc , w .h , nil )	headerBlock  := buf .Bytes ()	if  len (headerBlock ) == 0  {		panic ("unexpected empty hpack" )	}	return  http2splitHeaderBlock (ctx , headerBlock , w .writeHeaderBlock )}func  (w  *http2writePushPromise ) writeHeaderBlock ctx  http2writeContext , frag  []byte , firstFrag , lastFrag  bool ) error  {	if  firstFrag  {		return  ctx .Framer ().WritePushPromise (http2PushPromiseParam {			StreamID :      w .streamID ,			PromiseID :     w .promisedID ,			BlockFragment : frag ,			EndHeaders :    lastFrag ,		})	} else  {		return  ctx .Framer ().WriteContinuation (w .streamID , lastFrag , frag )	}}type  http2write100ContinueHeadersFrame  struct  {	streamID  uint32 }func  (w  http2write100ContinueHeadersFrame ) writeFrame ctx  http2writeContext ) error  {	enc , buf  := ctx .HeaderEncoder ()	buf .Reset ()	http2encKV (enc , ":status" , "100" )	return  ctx .Framer ().WriteHeaders (http2HeadersFrameParam {		StreamID :      w .streamID ,		BlockFragment : buf .Bytes (),		EndStream :     false ,		EndHeaders :    true ,	})}func  (w  http2write100ContinueHeadersFrame ) staysWithinBuffer max  int ) bool  {		return  9 +2 *(len (":status" )+len ("100" )) <= max }type  http2writeWindowUpdate  struct  {	streamID  uint32  	n         uint32 }func  (wu  http2writeWindowUpdate ) staysWithinBuffer max  int ) bool  { return  http2frameHeaderLen +4  <= max  }func  (wu  http2writeWindowUpdate ) writeFrame ctx  http2writeContext ) error  {	return  ctx .Framer ().WriteWindowUpdate (wu .streamID , wu .n )}func  http2encodeHeaders enc  *hpack .Encoder , h  Header , keys  []string ) {	if  keys  == nil  {		sorter  := http2sorterPool .Get ().(*http2sorter )				defer  http2sorterPool .Put (sorter )		keys  = sorter .Keys (h )	}	for  _ , k  := range  keys  {		vv  := h [k ]		k , ascii  := http2lowerHeader (k )		if  !ascii  {						continue 		}		if  !http2validWireHeaderFieldName (k ) {						continue 		}		isTE  := k  == "transfer-encoding" 		for  _ , v  := range  vv  {			if  !httpguts .ValidHeaderFieldValue (v ) {								continue 			}						if  isTE  && v  != "trailers"  {				continue 			}			http2encKV (enc , k , v )		}	}}type  http2WriteScheduler  interface  {		OpenStream (streamID uint32 , options http2OpenStreamOptions )		CloseStream (streamID uint32 )		AdjustStream (streamID uint32 , priority http2PriorityParam )		Push (wr http2FrameWriteRequest )		Pop () (wr http2FrameWriteRequest , ok bool )}type  http2OpenStreamOptions  struct  {		PusherID  uint32 }type  http2FrameWriteRequest  struct  {		write  http2writeFramer 		stream  *http2stream 		done  chan  error }func  (wr  http2FrameWriteRequest ) StreamID uint32  {	if  wr .stream  == nil  {		if  se , ok  := wr .write .(http2StreamError ); ok  {						return  se .StreamID 		}		return  0 	}	return  wr .stream .id }func  (wr  http2FrameWriteRequest ) isControl bool  {	return  wr .stream  == nil }func  (wr  http2FrameWriteRequest ) DataSize int  {	if  wd , ok  := wr .write .(*http2writeData ); ok  {		return  len (wd .p )	}	return  0 }func  (wr  http2FrameWriteRequest ) Consume n  int32 ) (http2FrameWriteRequest , http2FrameWriteRequest , int ) {	var  empty  http2FrameWriteRequest 		wd , ok  := wr .write .(*http2writeData )	if  !ok  || len (wd .p ) == 0  {		return  wr , empty , 1 	}		allowed  := wr .stream .flow .available ()	if  n  < allowed  {		allowed  = n 	}	if  wr .stream .sc .maxFrameSize  < allowed  {		allowed  = wr .stream .sc .maxFrameSize 	}	if  allowed  <= 0  {		return  empty , empty , 0 	}	if  len (wd .p ) > int (allowed ) {		wr .stream .flow .take (allowed )		consumed  := http2FrameWriteRequest {			stream : wr .stream ,			write : &http2writeData {				streamID : wd .streamID ,				p :        wd .p [:allowed ],								endStream : false ,			},						done : nil ,		}		rest  := http2FrameWriteRequest {			stream : wr .stream ,			write : &http2writeData {				streamID :  wd .streamID ,				p :         wd .p [allowed :],				endStream : wd .endStream ,			},			done : wr .done ,		}		return  consumed , rest , 2 	}		wr .stream .flow .take (int32 (len (wd .p )))	return  wr , empty , 1 }func  (wr  http2FrameWriteRequest ) String string  {	var  des  string 	if  s , ok  := wr .write .(fmt .Stringer ); ok  {		des  = s .String ()	} else  {		des  = fmt .Sprintf ("%T" , wr .write )	}	return  fmt .Sprintf ("[FrameWriteRequest stream=%d, ch=%v, writer=%v]" , wr .StreamID (), wr .done  != nil , des )}func  (wr  *http2FrameWriteRequest ) replyToWriter err  error ) {	if  wr .done  == nil  {		return 	}	select 	case  wr .done  <-  err :	default :		panic (fmt .Sprintf ("unbuffered done channel passed in for type %T" , wr .write ))	}	wr .write  = nil  }type  http2writeQueue  struct  {	s           []http2FrameWriteRequest 	prev , next  *http2writeQueue }func  (q  *http2writeQueue ) empty bool  { return  len (q .s ) == 0  }func  (q  *http2writeQueue ) push wr  http2FrameWriteRequest ) {	q .s  = append (q .s , wr )}func  (q  *http2writeQueue ) shift http2FrameWriteRequest  {	if  len (q .s ) == 0  {		panic ("invalid use of queue" )	}	wr  := q .s [0 ]		copy (q .s , q .s [1 :])	q .s [len (q .s )-1 ] = http2FrameWriteRequest {}	q .s  = q .s [:len (q .s )-1 ]	return  wr }func  (q  *http2writeQueue ) consume n  int32 ) (http2FrameWriteRequest , bool ) {	if  len (q .s ) == 0  {		return  http2FrameWriteRequest {}, false 	}	consumed , rest , numresult  := q .s [0 ].Consume (n )	switch  numresult  {	case  0 :		return  http2FrameWriteRequest {}, false 	case  1 :		q .shift ()	case  2 :		q .s [0 ] = rest 	}	return  consumed , true }type  http2writeQueuePool  []*http2writeQueue func  (p  *http2writeQueuePool ) put q  *http2writeQueue ) {	for  i  := range  q .s  {		q .s [i ] = http2FrameWriteRequest {}	}	q .s  = q .s [:0 ]	*p  = append (*p , q )}func  (p  *http2writeQueuePool ) get http2writeQueue  {	ln  := len (*p )	if  ln  == 0  {		return  new (http2writeQueue )	}	x  := ln  - 1 	q  := (*p )[x ]	(*p )[x ] = nil 	*p  = (*p )[:x ]	return  q }const  http2priorityDefaultWeight  = 15  type  http2PriorityWriteSchedulerConfig  struct  {		MaxClosedNodesInTree  int 		MaxIdleNodesInTree  int 		ThrottleOutOfOrderWrites  bool }func  http2NewPriorityWriteScheduler cfg  *http2PriorityWriteSchedulerConfig ) http2WriteScheduler  {	if  cfg  == nil  {				cfg  = &http2PriorityWriteSchedulerConfig {			MaxClosedNodesInTree :     10 ,			MaxIdleNodesInTree :       10 ,			ThrottleOutOfOrderWrites : false ,		}	}	ws  := &http2priorityWriteScheduler {		nodes :                make (map [uint32 ]*http2priorityNode ),		maxClosedNodesInTree : cfg .MaxClosedNodesInTree ,		maxIdleNodesInTree :   cfg .MaxIdleNodesInTree ,		enableWriteThrottle :  cfg .ThrottleOutOfOrderWrites ,	}	ws .nodes [0 ] = &ws .root 	if  cfg .ThrottleOutOfOrderWrites  {		ws .writeThrottleLimit  = 1024 	} else  {		ws .writeThrottleLimit  = math .MaxInt32 	}	return  ws }type  http2priorityNodeState  int const  (	http2priorityNodeOpen  http2priorityNodeState  = iota 	http2priorityNodeClosed 	http2priorityNodeIdle )type  http2priorityNode  struct  {	q             http2writeQueue         	id            uint32                  	weight        uint8                   	state         http2priorityNodeState  	bytes         int64                   	subtreeBytes  int64                   		parent      *http2priorityNode 	kids        *http2priorityNode  	prev , next  *http2priorityNode  }func  (n  *http2priorityNode ) setParent parent  *http2priorityNode ) {	if  n  == parent  {		panic ("setParent to self" )	}	if  n .parent  == parent  {		return 	}		if  parent  := n .parent ; parent  != nil  {		if  n .prev  == nil  {			parent .kids  = n .next 		} else  {			n .prev .next  = n .next 		}		if  n .next  != nil  {			n .next .prev  = n .prev 		}	}		n .parent  = parent 	if  parent  == nil  {		n .next  = nil 		n .prev  = nil 	} else  {		n .next  = parent .kids 		n .prev  = nil 		if  n .next  != nil  {			n .next .prev  = n 		}		parent .kids  = n 	}}func  (n  *http2priorityNode ) addBytes b  int64 ) {	n .bytes  += b 	for  ; n  != nil ; n  = n .parent  {		n .subtreeBytes  += b 	}}func  (n  *http2priorityNode ) walkReadyInOrder openParent  bool , tmp  *[]*http2priorityNode , f  func (*http2priorityNode , bool ) bool ) bool  {	if  !n .q .empty () && f (n , openParent ) {		return  true 	}	if  n .kids  == nil  {		return  false 	}		if  n .id  != 0  {		openParent  = openParent  || (n .state  == http2priorityNodeOpen )	}		w  := n .kids .weight 	needSort  := false 	for  k  := n .kids .next ; k  != nil ; k  = k .next  {		if  k .weight  != w  {			needSort  = true 			break 		}	}	if  !needSort  {		for  k  := n .kids ; k  != nil ; k  = k .next  {			if  k .walkReadyInOrder (openParent , tmp , f ) {				return  true 			}		}		return  false 	}		*tmp  = (*tmp )[:0 ]	for  n .kids  != nil  {		*tmp  = append (*tmp , n .kids )		n .kids .setParent (nil )	}	sort .Sort (http2sortPriorityNodeSiblings (*tmp ))	for  i  := len (*tmp ) - 1 ; i  >= 0 ; i -- {		(*tmp )[i ].setParent (n ) 	}	for  k  := n .kids ; k  != nil ; k  = k .next  {		if  k .walkReadyInOrder (openParent , tmp , f ) {			return  true 		}	}	return  false }type  http2sortPriorityNodeSiblings  []*http2priorityNode func  (z  http2sortPriorityNodeSiblings ) Len int  { return  len (z ) }func  (z  http2sortPriorityNodeSiblings ) Swap i , k  int ) { z [i ], z [k ] = z [k ], z [i ] }func  (z  http2sortPriorityNodeSiblings ) Less i , k  int ) bool  {		wi , bi  := float64 (z [i ].weight +1 ), float64 (z [i ].subtreeBytes )	wk , bk  := float64 (z [k ].weight +1 ), float64 (z [k ].subtreeBytes )	if  bi  == 0  && bk  == 0  {		return  wi  >= wk 	}	if  bk  == 0  {		return  false 	}	return  bi /bk  <= wi /wk }type  http2priorityWriteScheduler  struct  {		root  http2priorityNode 		nodes  map [uint32 ]*http2priorityNode 		maxID  uint32 		closedNodes , idleNodes  []*http2priorityNode 		maxClosedNodesInTree  int 	maxIdleNodesInTree    int 	writeThrottleLimit    int32 	enableWriteThrottle   bool 		tmp  []*http2priorityNode 		queuePool  http2writeQueuePool }func  (ws  *http2priorityWriteScheduler ) OpenStream streamID  uint32 , options  http2OpenStreamOptions ) {		if  curr  := ws .nodes [streamID ]; curr  != nil  {		if  curr .state  != http2priorityNodeIdle  {			panic (fmt .Sprintf ("stream %d already opened" , streamID ))		}		curr .state  = http2priorityNodeOpen 		return 	}		parent  := ws .nodes [options .PusherID ]	if  parent  == nil  {		parent  = &ws .root 	}	n  := &http2priorityNode {		q :      *ws .queuePool .get (),		id :     streamID ,		weight : http2priorityDefaultWeight ,		state :  http2priorityNodeOpen ,	}	n .setParent (parent )	ws .nodes [streamID ] = n 	if  streamID  > ws .maxID  {		ws .maxID  = streamID 	}}func  (ws  *http2priorityWriteScheduler ) CloseStream streamID  uint32 ) {	if  streamID  == 0  {		panic ("violation of WriteScheduler interface: cannot close stream 0" )	}	if  ws .nodes [streamID ] == nil  {		panic (fmt .Sprintf ("violation of WriteScheduler interface: unknown stream %d" , streamID ))	}	if  ws .nodes [streamID ].state  != http2priorityNodeOpen  {		panic (fmt .Sprintf ("violation of WriteScheduler interface: stream %d already closed" , streamID ))	}	n  := ws .nodes [streamID ]	n .state  = http2priorityNodeClosed 	n .addBytes (-n .bytes )	q  := n .q 	ws .queuePool .put (&q )	n .q .s  = nil 	if  ws .maxClosedNodesInTree  > 0  {		ws .addClosedOrIdleNode (&ws .closedNodes , ws .maxClosedNodesInTree , n )	} else  {		ws .removeNode (n )	}}func  (ws  *http2priorityWriteScheduler ) AdjustStream streamID  uint32 , priority  http2PriorityParam ) {	if  streamID  == 0  {		panic ("adjustPriority on root" )	}		n  := ws .nodes [streamID ]	if  n  == nil  {		if  streamID  <= ws .maxID  || ws .maxIdleNodesInTree  == 0  {			return 		}		ws .maxID  = streamID 		n  = &http2priorityNode {			q :      *ws .queuePool .get (),			id :     streamID ,			weight : http2priorityDefaultWeight ,			state :  http2priorityNodeIdle ,		}		n .setParent (&ws .root )		ws .nodes [streamID ] = n 		ws .addClosedOrIdleNode (&ws .idleNodes , ws .maxIdleNodesInTree , n )	}		parent  := ws .nodes [priority .StreamDep ]	if  parent  == nil  {		n .setParent (&ws .root )		n .weight  = http2priorityDefaultWeight 		return 	}		if  n  == parent  {		return 	}		for  x  := parent .parent ; x  != nil ; x  = x .parent  {		if  x  == n  {			parent .setParent (n .parent )			break 		}	}		if  priority .Exclusive  {		k  := parent .kids 		for  k  != nil  {			next  := k .next 			if  k  != n  {				k .setParent (n )			}			k  = next 		}	}	n .setParent (parent )	n .weight  = priority .Weight }func  (ws  *http2priorityWriteScheduler ) Push wr  http2FrameWriteRequest ) {	var  n  *http2priorityNode 	if  wr .isControl () {		n  = &ws .root 	} else  {		id  := wr .StreamID ()		n  = ws .nodes [id ]		if  n  == nil  {						if  wr .DataSize () > 0  {				panic ("add DATA on non-open stream" )			}			n  = &ws .root 		}	}	n .q .push (wr )}func  (ws  *http2priorityWriteScheduler ) Pop wr  http2FrameWriteRequest , ok  bool ) {	ws .root .walkReadyInOrder (false , &ws .tmp , func (n  *http2priorityNode , openParent  bool ) bool  {		limit  := int32 (math .MaxInt32 )		if  openParent  {			limit  = ws .writeThrottleLimit 		}		wr , ok  = n .q .consume (limit )		if  !ok  {			return  false 		}		n .addBytes (int64 (wr .DataSize ()))				if  openParent  {			ws .writeThrottleLimit  += 1024 			if  ws .writeThrottleLimit  < 0  {				ws .writeThrottleLimit  = math .MaxInt32 			}		} else  if  ws .enableWriteThrottle  {			ws .writeThrottleLimit  = 1024 		}		return  true 	})	return  wr , ok }func  (ws  *http2priorityWriteScheduler ) addClosedOrIdleNode list  *[]*http2priorityNode , maxSize  int , n  *http2priorityNode ) {	if  maxSize  == 0  {		return 	}	if  len (*list ) == maxSize  {				ws .removeNode ((*list )[0 ])		x  := (*list )[1 :]		copy (*list , x )		*list  = (*list )[:len (x )]	}	*list  = append (*list , n )}func  (ws  *http2priorityWriteScheduler ) removeNode n  *http2priorityNode ) {	for  n .kids  != nil  {		n .kids .setParent (n .parent )	}	n .setParent (nil )	delete (ws .nodes , n .id )}func  http2NewRandomWriteScheduler http2WriteScheduler  {	return  &http2randomWriteScheduler {sq : make (map [uint32 ]*http2writeQueue )}}type  http2randomWriteScheduler  struct  {		zero  http2writeQueue 		sq  map [uint32 ]*http2writeQueue 		queuePool  http2writeQueuePool }func  (ws  *http2randomWriteScheduler ) OpenStream streamID  uint32 , options  http2OpenStreamOptions ) {	}func  (ws  *http2randomWriteScheduler ) CloseStream streamID  uint32 ) {	q , ok  := ws .sq [streamID ]	if  !ok  {		return 	}	delete (ws .sq , streamID )	ws .queuePool .put (q )}func  (ws  *http2randomWriteScheduler ) AdjustStream streamID  uint32 , priority  http2PriorityParam ) {	}func  (ws  *http2randomWriteScheduler ) Push wr  http2FrameWriteRequest ) {	if  wr .isControl () {		ws .zero .push (wr )		return 	}	id  := wr .StreamID ()	q , ok  := ws .sq [id ]	if  !ok  {		q  = ws .queuePool .get ()		ws .sq [id ] = q 	}	q .push (wr )}func  (ws  *http2randomWriteScheduler ) Pop http2FrameWriteRequest , bool ) {		if  !ws .zero .empty () {		return  ws .zero .shift (), true 	}		for  streamID , q  := range  ws .sq  {		if  wr , ok  := q .consume (math .MaxInt32 ); ok  {			if  q .empty () {				delete (ws .sq , streamID )				ws .queuePool .put (q )			}			return  wr , true 		}	}	return  http2FrameWriteRequest {}, false }type  http2roundRobinWriteScheduler  struct  {		control  http2writeQueue 		streams  map [uint32 ]*http2writeQueue 		head  *http2writeQueue 		queuePool  http2writeQueuePool }func  http2newRoundRobinWriteScheduler http2WriteScheduler  {	ws  := &http2roundRobinWriteScheduler {		streams : make (map [uint32 ]*http2writeQueue ),	}	return  ws }func  (ws  *http2roundRobinWriteScheduler ) OpenStream streamID  uint32 , options  http2OpenStreamOptions ) {	if  ws .streams [streamID ] != nil  {		panic (fmt .Errorf ("stream %d already opened" , streamID ))	}	q  := ws .queuePool .get ()	ws .streams [streamID ] = q 	if  ws .head  == nil  {		ws .head  = q 		q .next  = q 		q .prev  = q 	} else  {				q .prev  = ws .head .prev 		q .next  = ws .head 		q .prev .next  = q 		q .next .prev  = q 	}}func  (ws  *http2roundRobinWriteScheduler ) CloseStream streamID  uint32 ) {	q  := ws .streams [streamID ]	if  q  == nil  {		return 	}	if  q .next  == q  {				ws .head  = nil 	} else  {		q .prev .next  = q .next 		q .next .prev  = q .prev 		if  ws .head  == q  {			ws .head  = q .next 		}	}	delete (ws .streams , streamID )	ws .queuePool .put (q )}func  (ws  *http2roundRobinWriteScheduler ) AdjustStream streamID  uint32 , priority  http2PriorityParam ) {}func  (ws  *http2roundRobinWriteScheduler ) Push wr  http2FrameWriteRequest ) {	if  wr .isControl () {		ws .control .push (wr )		return 	}	q  := ws .streams [wr .StreamID ()]	if  q  == nil  {				if  wr .DataSize () > 0  {			panic ("add DATA on non-open stream" )		}		ws .control .push (wr )		return 	}	q .push (wr )}func  (ws  *http2roundRobinWriteScheduler ) Pop http2FrameWriteRequest , bool ) {		if  !ws .control .empty () {		return  ws .control .shift (), true 	}	if  ws .head  == nil  {		return  http2FrameWriteRequest {}, false 	}	q  := ws .head 	for  {		if  wr , ok  := q .consume (math .MaxInt32 ); ok  {			ws .head  = q .next 			return  wr , true 		}		q  = q .next 		if  q  == ws .head  {			break 		}	}	return  http2FrameWriteRequest {}, false } The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .