package  httpimport  (	"bufio" 	"bytes" 	"compress/gzip" 	"context" 	"crypto/rand" 	"crypto/tls" 	"encoding/binary" 	"errors" 	"fmt" 	"io" 	"io/fs" 	"log" 	"math" 	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  (	http2dataChunkSizeClasses = []int {		1  << 10 ,		2  << 10 ,		4  << 10 ,		8  << 10 ,		16  << 10 ,	}	http2dataChunkPools = [...]sync .Pool {		{New : func () interface {} { return  make ([]byte , 1 <<10 ) }},		{New : func () interface {} { return  make ([]byte , 2 <<10 ) }},		{New : func () interface {} { return  make ([]byte , 4 <<10 ) }},		{New : func () interface {} { return  make ([]byte , 8 <<10 ) }},		{New : func () interface {} { return  make ([]byte , 16 <<10 ) }},	})func  http2getDataBufferChunk(size  int64 ) []byte  {	i  := 0 	for  ; i  < len (http2dataChunkSizeClasses )-1 ; i ++ {		if  size  <= int64 (http2dataChunkSizeClasses [i ]) {			break 		}	}	return  http2dataChunkPools [i ].Get ().([]byte )}func  http2putDataBufferChunk(p  []byte ) {	for  i , n  := range  http2dataChunkSizeClasses  {		if  len (p ) == n  {			http2dataChunkPools [i ].Put (p )			return 		}	}	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  := fr .maxHeaderListSize ()	if  uint32 (int (v )) == v  {		return  int (v )	}		return  0 }func  (fr  *http2Framer ) readMetaFrame (hf  *http2HeadersFrame ) (*http2MetaHeadersFrame , 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 			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  _ , err  := hdec .Write (frag ); err  != nil  {			return  nil , 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  nil , 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 ()}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 }func  http2tlsUnderlyingConn(tc  *tls .Conn ) net .Conn  {	return  tc .NetConn ()}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  http2gate chan  struct {}func  (g  http2gate ) Done () { g  <- struct {}{} }func  (g  http2gate ) Wait () { <-g  }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  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" )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 	}	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 }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 ) {	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 ,	}	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               *time .Timer  	idleTimer                   *time .Timer  		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     *time .Timer  	writeDeadline    *time .Timer  	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 	}		str  := err .Error()	if  strings .Contains (str , "use of closed network connection" ) {		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 () {	gate  := make (http2gate )	gateDone  := gate .Done 	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 ) {	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  = time .AfterFunc (sc .srv .IdleTimeout , sc .onIdleTimer )		defer  sc .idleTimer .Stop ()	}	go  sc .readFrames () 	settingsTimer  := time .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 )		}	}}func  (sc  *http2serverConn ) awaitGracefulShutdown (sharedCh  <-chan  struct {}, privateCh  chan  struct {}) {	select 	case  <- sc .doneServing :	case  <- sharedCh :		close (privateCh )	}}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  := time .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  = time .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 :		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 .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 .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 () {		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 {})		if  st .body  != nil  {			st .readDeadline  = time .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  = time .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 )) {	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      	dirty         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  = time .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  {			rws .dirty  = true 			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  {			rws .dirty  = true 			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 ,		})		if  err  != nil  {			rws .dirty  = 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 (time .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  = time .AfterFunc (deadline .Sub (time .Now ()), st .onReadTimeout )		} else  {			st .readDeadline .Reset (deadline .Sub (time .Now ()))		}	})	return  nil }func  (w  *http2responseWriter ) SetWriteDeadline (deadline  time .Time ) error  {	st  := w .rws .stream 	if  !deadline .IsZero () && deadline .Before (time .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  = time .AfterFunc (deadline .Sub (time .Now ()), st .onWriteTimeout )		} else  {			st .writeDeadline .Reset (deadline .Sub (time .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" )		}		if  rws .conn .writeHeaders (rws .stream , &http2writeResHeaders {			streamID :    rws .stream .id ,			httpResCode : code ,			h :           h ,			endStream :   rws .handlerDone  && !rws .hasTrailers (),		}) != nil  {			rws .dirty  = true 		}		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 	dirty  := rws .dirty 	rws .handlerDone  = true 	w .Flush ()	w .rws  = nil 	if  !dirty  {				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 ))		}		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 }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 		ReadIdleTimeout time .Duration 		PingTimeout time .Duration 		WriteByteTimeout time .Duration 		CountError func (errType string )		t1 *Transport 	connPoolOnce  sync .Once 	connPoolOrDef http2ClientConnPool  }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  	tconnClosed   bool 	tlsState      *tls .ConnectionState  	reused        uint32                	singleUse     bool                  	getConnCalled bool                  		readerDone chan  struct {} 	readerErr  error          	idleTimeout time .Duration  	idleTimer   *time .Timer 	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 .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 )}var  http2retryBackoffHook func (time .Duration ) *time .Timer func  http2backoffNewTimer(d  time .Duration ) *time .Timer  {	if  http2retryBackoffHook  != nil  {		return  http2retryBackoffHook (d )	}	return  time .NewTimer (d )}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 )				timer  := http2backoffNewTimer (d )				select 				case  <- timer .C :					t .vlogf ("RoundTrip retrying after failure: %v" , roundTripErr )					continue 				case  <- req .Context ().Done ():					timer .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 ) {	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  d  := t .idleConnTimeout (); d  != 0  {		cc .idleTimeout  = d 		cc .idleTimer  = time .AfterFunc (d , cc .onIdleTimeout )	}	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 	}	go  cc .readLoop ()	return  cc , nil }func  (cc  *http2ClientConn ) healthCheck () {	pingTimeout  := cc .t .pingTimeout ()		ctx , cancel  := context .WithTimeout (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  {			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  := http2tlsUnderlyingConn (tc ); 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 .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 ) {	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 {}),	}	go  cs .doRequest (req )	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 ) {	err  := cs .writeRequest (req )	cs .cleanupWriteRequest (err )}func  (cs  *http2clientStream ) writeRequest (req  *Request ) (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  !cc .t .disableCompression () &&		req .Header .Get ("Accept-Encoding" ) == ""  &&		req .Header .Get ("Range" ) == ""  &&		!cs .isHead  {				cs .requestedGzip  = true 	}	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  := time .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  http2bufPool sync .Pool  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 	if  bp , ok  := http2bufPool .Get ().(*[]byte ); ok  && len (*bp ) >= scratchLen  {		defer  http2bufPool .Put (bp )		buf  = *bp 	} else  {		buf  = make ([]byte , scratchLen )		defer  http2bufPool .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 ()	}}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 )				}			}		}	}		for  k , vv  := range  req .Header  {		if  !httpguts .ValidHeaderFieldName (k ) {			return  nil , fmt .Errorf ("invalid HTTP header name %q" , k )		}		for  _ , v  := range  vv  {			if  !httpguts .ValidHeaderFieldValue (v ) {								return  nil , fmt .Errorf ("invalid HTTP header value for header %q" , k )			}		}	}	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 () {	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  *time .Timer 	if  readIdleTimeout  != 0  {		t  = time .AfterFunc (readIdleTimeout , cc .healthCheck )		defer  t .Stop ()	}	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 .firstByte  {		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 )) {		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 ()	}	errc  := make (chan  error , 1 )	go  func () {		cc .wmu .Lock ()		defer  cc .wmu .Unlock ()		if  err  := cc .fr .WritePing (false , p ); err  != nil  {			errc  <- err 			return 		}		if  err  := cc .bw .Flush (); err  != nil  {			errc  <- err 			return 		}	}()	select 	case  <- c :		return  nil 	case  err  := <- errc :		return  err 	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 .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 ()	}}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  k  := n .kids ; k  != nil ; k  = k .next  {		k .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.6.7 . (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 @Go100and1  (reachable from the left QR code) to get the latest news of Golds .