package http
import (
mathrand
)
func (, string) bool {
if len() != len() {
return false
}
for := 0; < len(); ++ {
if http2lower([]) != http2lower([]) {
return false
}
}
return true
}
func ( byte) byte {
if 'A' <= && <= 'Z' {
return + ('a' - 'A')
}
return
}
func ( string) bool {
for := 0; < len(); ++ {
if [] < ' ' || [] > '~' {
return false
}
}
return true
}
func ( string) ( string, bool) {
if !http2isASCIIPrint() {
return "", false
}
return strings.ToLower(), 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 ( uint16) bool {
switch {
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 ( *http2clientConnPool) ( *Request, string) (*http2ClientConn, error) {
return .getClientConn(, , http2dialOnMiss)
}
const (
http2dialOnMiss = true
http2noDialOnMiss = false
)
func ( *http2clientConnPool) ( *Request, string, bool) (*http2ClientConn, error) {
if http2isConnectionCloseRequest() && {
http2traceGetConn(, )
const = true
, := .t.dialClientConn(.Context(), , )
if != nil {
return nil,
}
return , nil
}
for {
.mu.Lock()
for , := range .conns[] {
if .ReserveNewRequest() {
if !.getConnCalled {
http2traceGetConn(, )
}
.getConnCalled = false
.mu.Unlock()
return , nil
}
}
if ! {
.mu.Unlock()
return nil, http2ErrNoCachedConn
}
http2traceGetConn(, )
:= .getStartDialLocked(.Context(), )
.mu.Unlock()
<-.done
if http2shouldRetryDial(, ) {
continue
}
, := .res, .err
if != nil {
return nil,
}
if .ReserveNewRequest() {
return , nil
}
}
}
type http2dialCall struct {
_ http2incomparable
p *http2clientConnPool
ctx context.Context
done chan struct{}
res *http2ClientConn
err error
}
func ( *http2clientConnPool) ( context.Context, string) *http2dialCall {
if , := .dialing[]; {
return
}
:= &http2dialCall{p: , done: make(chan struct{}), ctx: }
if .dialing == nil {
.dialing = make(map[string]*http2dialCall)
}
.dialing[] =
go .dial(.ctx, )
return
}
func ( *http2dialCall) ( context.Context, string) {
const = false
.res, .err = .p.t.dialClientConn(, , )
.p.mu.Lock()
delete(.p.dialing, )
if .err == nil {
.p.addConnLocked(, .res)
}
.p.mu.Unlock()
close(.done)
}
func ( *http2clientConnPool) ( string, *http2Transport, *tls.Conn) ( bool, error) {
.mu.Lock()
for , := range .conns[] {
if .CanTakeNewRequest() {
.mu.Unlock()
return false, nil
}
}
, := .addConnCalls[]
if ! {
if .addConnCalls == nil {
.addConnCalls = make(map[string]*http2addConnCall)
}
= &http2addConnCall{
p: ,
done: make(chan struct{}),
}
.addConnCalls[] =
go .run(, , )
}
.mu.Unlock()
<-.done
if .err != nil {
return false, .err
}
return !, nil
}
type http2addConnCall struct {
_ http2incomparable
p *http2clientConnPool
done chan struct{}
err error
}
func ( *http2addConnCall) ( *http2Transport, string, *tls.Conn) {
, := .NewClientConn()
:= .p
.mu.Lock()
if != nil {
.err =
} else {
.getConnCalled = true
.addConnLocked(, )
}
delete(.addConnCalls, )
.mu.Unlock()
close(.done)
}
func ( *http2clientConnPool) ( string, *http2ClientConn) {
for , := range .conns[] {
if == {
return
}
}
if .conns == nil {
.conns = make(map[string][]*http2ClientConn)
}
if .keys == nil {
.keys = make(map[*http2ClientConn][]string)
}
.conns[] = append(.conns[], )
.keys[] = append(.keys[], )
}
func ( *http2clientConnPool) ( *http2ClientConn) {
.mu.Lock()
defer .mu.Unlock()
for , := range .keys[] {
, := .conns[]
if ! {
continue
}
:= http2filterOutClientConn(, )
if len() > 0 {
.conns[] =
} else {
delete(.conns, )
}
}
delete(.keys, )
}
func ( *http2clientConnPool) () {
.mu.Lock()
defer .mu.Unlock()
for , := range .conns {
for , := range {
.closeIfIdle()
}
}
}
func ( []*http2ClientConn, *http2ClientConn) []*http2ClientConn {
:= [:0]
for , := range {
if != {
= append(, )
}
}
if len() != len() {
[len()-1] = nil
}
return
}
type http2noDialClientConnPool struct{ *http2clientConnPool }
func ( http2noDialClientConnPool) ( *Request, string) (*http2ClientConn, error) {
return .getClientConn(, , http2noDialOnMiss)
}
func ( *http2dialCall, *Request) bool {
if .err == nil {
return false
}
if .ctx == .Context() {
return false
}
if !errors.Is(.err, context.Canceled) && !errors.Is(.err, context.DeadlineExceeded) {
return false
}
return .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 ( int64) []byte {
:= 0
for ; < len(http2dataChunkSizeClasses)-1; ++ {
if <= int64(http2dataChunkSizeClasses[]) {
break
}
}
return http2dataChunkPools[].Get().([]byte)
}
func ( []byte) {
for , := range http2dataChunkSizeClasses {
if len() == {
http2dataChunkPools[].Put()
return
}
}
panic(fmt.Sprintf("unexpected buffer len=%v", len()))
}
type http2dataBuffer struct {
chunks [][]byte
r int
w int
size int
expected int64
}
var http2errReadEmpty = errors.New("read from empty dataBuffer")
func ( *http2dataBuffer) ( []byte) (int, error) {
if .size == 0 {
return 0, http2errReadEmpty
}
var int
for len() > 0 && .size > 0 {
:= .bytesFromFirstChunk()
:= copy(, )
= [:]
+=
.r +=
.size -=
if .r == len(.chunks[0]) {
http2putDataBufferChunk(.chunks[0])
:= len(.chunks) - 1
copy(.chunks[:], .chunks[1:])
.chunks[] = nil
.chunks = .chunks[:]
.r = 0
}
}
return , nil
}
func ( *http2dataBuffer) () []byte {
if len(.chunks) == 1 {
return .chunks[0][.r:.w]
}
return .chunks[0][.r:]
}
func ( *http2dataBuffer) () int {
return .size
}
func ( *http2dataBuffer) ( []byte) (int, error) {
:= len()
for len() > 0 {
:= int64(len())
if .expected > {
= .expected
}
:= .lastChunkOrAlloc()
:= copy([.w:], )
= [:]
.w +=
.size +=
.expected -= int64()
}
return , nil
}
func ( *http2dataBuffer) ( int64) []byte {
if len(.chunks) != 0 {
:= .chunks[len(.chunks)-1]
if .w < len() {
return
}
}
:= http2getDataBufferChunk()
.chunks = append(.chunks, )
.w = 0
return
}
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 ( http2ErrCode) () string {
if , := http2errCodeName[]; {
return
}
return fmt.Sprintf("unknown error code 0x%x", uint32())
}
func ( http2ErrCode) () string {
if , := http2errCodeName[]; {
return
}
return fmt.Sprintf("ERR_UNKNOWN_%d", uint32())
}
type http2ConnectionError http2ErrCode
func ( http2ConnectionError) () string {
return fmt.Sprintf("connection error: %s", http2ErrCode())
}
type http2StreamError struct {
StreamID uint32
Code http2ErrCode
Cause error
}
var http2errFromPeer = errors.New("received from peer")
func ( uint32, http2ErrCode) http2StreamError {
return http2StreamError{StreamID: , Code: }
}
func ( http2StreamError) () string {
if .Cause != nil {
return fmt.Sprintf("stream error: stream ID %d; %v; %v", .StreamID, .Code, .Cause)
}
return fmt.Sprintf("stream error: stream ID %d; %v", .StreamID, .Code)
}
type http2goAwayFlowError struct{}
func (http2goAwayFlowError) () string { return "connection exceeded flow control window size" }
type http2connError struct {
Code http2ErrCode
Reason string
}
func ( http2connError) () string {
return fmt.Sprintf("http2: connection error: %v: %v", .Code, .Reason)
}
type http2pseudoHeaderError string
func ( http2pseudoHeaderError) () string {
return fmt.Sprintf("invalid pseudo-header %q", string())
}
type http2duplicatePseudoHeaderError string
func ( http2duplicatePseudoHeaderError) () string {
return fmt.Sprintf("duplicate pseudo-header %q", string())
}
type http2headerFieldNameError string
func ( http2headerFieldNameError) () string {
return fmt.Sprintf("invalid header field name %q", string())
}
type http2headerFieldValueError string
func ( http2headerFieldValueError) () string {
return fmt.Sprintf("invalid header field value for %q", string())
}
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 ( *http2inflow) ( int32) {
.avail =
}
func ( *http2inflow) ( int) ( int32) {
if < 0 {
panic("negative update")
}
:= int64(.unsent) + int64()
const = 1<<31 - 1
if +int64(.avail) > {
panic("flow control update exceeds maximum window size")
}
.unsent = int32()
if .unsent < http2inflowMinRefresh && .unsent < .avail {
return 0
}
.avail += .unsent
.unsent = 0
return int32()
}
func ( *http2inflow) ( uint32) bool {
if > uint32(.avail) {
return false
}
.avail -= int32()
return true
}
func (, *http2inflow, uint32) bool {
if > uint32(.avail) || > uint32(.avail) {
return false
}
.avail -= int32()
.avail -= int32()
return true
}
type http2outflow struct {
_ http2incomparable
n int32
conn *http2outflow
}
func ( *http2outflow) ( *http2outflow) { .conn = }
func ( *http2outflow) () int32 {
:= .n
if .conn != nil && .conn.n < {
= .conn.n
}
return
}
func ( *http2outflow) ( int32) {
if > .available() {
panic("internal error: took too much")
}
.n -=
if .conn != nil {
.conn.n -=
}
}
func ( *http2outflow) ( int32) bool {
:= .n +
if ( > ) == (.n > 0) {
.n =
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 ( http2FrameType) () string {
if , := http2frameName[]; {
return
}
return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8())
}
type http2Flags uint8
func ( http2Flags) ( http2Flags) bool {
return ( & ) ==
}
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 ( http2FrameType) http2frameParser {
if := http2frameParsers[]; != nil {
return
}
return http2parseUnknownFrame
}
type http2FrameHeader struct {
valid bool
Type http2FrameType
Flags http2Flags
Length uint32
StreamID uint32
}
func ( http2FrameHeader) () http2FrameHeader { return }
func ( http2FrameHeader) () string {
var bytes.Buffer
.WriteString("[FrameHeader ")
.writeDebug(&)
.WriteByte(']')
return .String()
}
func ( http2FrameHeader) ( *bytes.Buffer) {
.WriteString(.Type.String())
if .Flags != 0 {
.WriteString(" flags=")
:= 0
for := uint8(0); < 8; ++ {
if .Flags&(1<<) == 0 {
continue
}
++
if > 1 {
.WriteByte('|')
}
:= http2flagName[.Type][http2Flags(1<<)]
if != "" {
.WriteString()
} else {
fmt.Fprintf(, "0x%x", 1<<)
}
}
}
if .StreamID != 0 {
fmt.Fprintf(, " stream=%d", .StreamID)
}
fmt.Fprintf(, " len=%d", .Length)
}
func ( *http2FrameHeader) () {
if !.valid {
panic("Frame accessor called on non-owned Frame")
}
}
func ( *http2FrameHeader) () { .valid = false }
var http2fhBytes = sync.Pool{
New: func() interface{} {
:= make([]byte, http2frameHeaderLen)
return &
},
}
func ( io.Reader) (http2FrameHeader, error) {
:= http2fhBytes.Get().(*[]byte)
defer http2fhBytes.Put()
return http2readFrameHeader(*, )
}
func ( []byte, io.Reader) (http2FrameHeader, error) {
, := io.ReadFull(, [:http2frameHeaderLen])
if != nil {
return http2FrameHeader{},
}
return http2FrameHeader{
Length: (uint32([0])<<16 | uint32([1])<<8 | uint32([2])),
Type: http2FrameType([3]),
Flags: http2Flags([4]),
StreamID: binary.BigEndian.Uint32([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 ( *http2Framer) () uint32 {
if .MaxHeaderListSize == 0 {
return 16 << 20
}
return .MaxHeaderListSize
}
func ( *http2Framer) ( http2FrameType, http2Flags, uint32) {
.wbuf = append(.wbuf[:0],
0,
0,
0,
byte(),
byte(),
byte(>>24),
byte(>>16),
byte(>>8),
byte())
}
func ( *http2Framer) () error {
:= len(.wbuf) - http2frameHeaderLen
if >= (1 << 24) {
return http2ErrFrameTooLarge
}
_ = append(.wbuf[:0],
byte(>>16),
byte(>>8),
byte())
if .logWrites {
.logWrite()
}
, := .w.Write(.wbuf)
if == nil && != len(.wbuf) {
= io.ErrShortWrite
}
return
}
func ( *http2Framer) () {
if .debugFramer == nil {
.debugFramerBuf = new(bytes.Buffer)
.debugFramer = http2NewFramer(nil, .debugFramerBuf)
.debugFramer.logReads = false
.debugFramer.AllowIllegalReads = true
}
.debugFramerBuf.Write(.wbuf)
, := .debugFramer.ReadFrame()
if != nil {
.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", )
return
}
.debugWriteLoggerf("http2: Framer %p: wrote %v", , http2summarizeFrame())
}
func ( *http2Framer) ( byte) { .wbuf = append(.wbuf, ) }
func ( *http2Framer) ( []byte) { .wbuf = append(.wbuf, ...) }
func ( *http2Framer) ( uint16) { .wbuf = append(.wbuf, byte(>>8), byte()) }
func ( *http2Framer) ( uint32) {
.wbuf = append(.wbuf, byte(>>24), byte(>>16), byte(>>8), byte())
}
const (
http2minMaxFrameSize = 1 << 14
http2maxFrameSize = 1<<24 - 1
)
func ( *http2Framer) () {
if .frameCache != nil {
return
}
.frameCache = &http2frameCache{}
}
type http2frameCache struct {
dataFrame http2DataFrame
}
func ( *http2frameCache) () *http2DataFrame {
if == nil {
return &http2DataFrame{}
}
return &.dataFrame
}
func ( io.Writer, io.Reader) *http2Framer {
:= &http2Framer{
w: ,
r: ,
countError: func(string) {},
logReads: http2logFrameReads,
logWrites: http2logFrameWrites,
debugReadLoggerf: log.Printf,
debugWriteLoggerf: log.Printf,
}
.getReadBuf = func( uint32) []byte {
if cap(.readBuf) >= int() {
return .readBuf[:]
}
.readBuf = make([]byte, )
return .readBuf
}
.SetMaxReadFrameSize(http2maxFrameSize)
return
}
func ( *http2Framer) ( uint32) {
if > http2maxFrameSize {
= http2maxFrameSize
}
.maxReadSize =
}
func ( *http2Framer) () error {
return .errDetail
}
var http2ErrFrameTooLarge = errors.New("http2: frame too large")
func ( error) bool {
if , := .(http2StreamError); {
return false
}
return != nil
}
func ( *http2Framer) () (http2Frame, error) {
.errDetail = nil
if .lastFrame != nil {
.lastFrame.invalidate()
}
, := http2readFrameHeader(.headerBuf[:], .r)
if != nil {
return nil,
}
if .Length > .maxReadSize {
return nil, http2ErrFrameTooLarge
}
:= .getReadBuf(.Length)
if , := io.ReadFull(.r, ); != nil {
return nil,
}
, := http2typeFrameParser(.Type)(.frameCache, , .countError, )
if != nil {
if , := .(http2connError); {
return nil, .connError(.Code, .Reason)
}
return nil,
}
if := .checkFrameOrder(); != nil {
return nil,
}
if .logReads {
.debugReadLoggerf("http2: Framer %p: read %v", , http2summarizeFrame())
}
if .Type == http2FrameHeaders && .ReadMetaHeaders != nil {
return .readMetaFrame(.(*http2HeadersFrame))
}
return , nil
}
func ( *http2Framer) ( http2ErrCode, string) error {
.errDetail = errors.New()
return http2ConnectionError()
}
func ( *http2Framer) ( http2Frame) error {
:= .lastFrame
.lastFrame =
if .AllowIllegalReads {
return nil
}
:= .Header()
if .lastHeaderStream != 0 {
if .Type != http2FrameContinuation {
return .connError(http2ErrCodeProtocol,
fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
.Type, .StreamID,
.Header().Type, .lastHeaderStream))
}
if .StreamID != .lastHeaderStream {
return .connError(http2ErrCodeProtocol,
fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
.StreamID, .lastHeaderStream))
}
} else if .Type == http2FrameContinuation {
return .connError(http2ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", .StreamID))
}
switch .Type {
case http2FrameHeaders, http2FrameContinuation:
if .Flags.Has(http2FlagHeadersEndHeaders) {
.lastHeaderStream = 0
} else {
.lastHeaderStream = .StreamID
}
}
return nil
}
type http2DataFrame struct {
http2FrameHeader
data []byte
}
func ( *http2DataFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagDataEndStream)
}
func ( *http2DataFrame) () []byte {
.checkValid()
return .data
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if .StreamID == 0 {
("frame_data_stream_0")
return nil, http2connError{http2ErrCodeProtocol, "DATA frame with stream ID 0"}
}
:= .getDataFrame()
.http2FrameHeader =
var byte
if .Flags.Has(http2FlagDataPadded) {
var error
, , = http2readByte()
if != nil {
("frame_data_pad_byte_short")
return nil,
}
}
if int() > len() {
("frame_data_pad_too_big")
return nil, http2connError{http2ErrCodeProtocol, "pad size larger than data payload"}
}
.data = [:len()-int()]
return , 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 ( uint32) bool {
return &(1<<31) == 0
}
func ( uint32) bool {
return != 0 && &(1<<31) == 0
}
func ( *http2Framer) ( uint32, bool, []byte) error {
return .WriteDataPadded(, , , nil)
}
func ( *http2Framer) ( uint32, bool, , []byte) error {
if := .startWriteDataPadded(, , , ); != nil {
return
}
return .endWrite()
}
func ( *http2Framer) ( uint32, bool, , []byte) error {
if !http2validStreamID() && !.AllowIllegalWrites {
return http2errStreamID
}
if len() > 0 {
if len() > 255 {
return http2errPadLength
}
if !.AllowIllegalWrites {
for , := range {
if != 0 {
return http2errPadBytes
}
}
}
}
var http2Flags
if {
|= http2FlagDataEndStream
}
if != nil {
|= http2FlagDataPadded
}
.startWrite(http2FrameData, , )
if != nil {
.wbuf = append(.wbuf, byte(len()))
}
.wbuf = append(.wbuf, ...)
.wbuf = append(.wbuf, ...)
return nil
}
type http2SettingsFrame struct {
http2FrameHeader
p []byte
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if .Flags.Has(http2FlagSettingsAck) && .Length > 0 {
("frame_settings_ack_with_length")
return nil, http2ConnectionError(http2ErrCodeFrameSize)
}
if .StreamID != 0 {
("frame_settings_has_stream")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
if len()%6 != 0 {
("frame_settings_mod_6")
return nil, http2ConnectionError(http2ErrCodeFrameSize)
}
:= &http2SettingsFrame{http2FrameHeader: , p: }
if , := .Value(http2SettingInitialWindowSize); && > (1<<31)-1 {
("frame_settings_window_size_too_big")
return nil, http2ConnectionError(http2ErrCodeFlowControl)
}
return , nil
}
func ( *http2SettingsFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagSettingsAck)
}
func ( *http2SettingsFrame) ( http2SettingID) ( uint32, bool) {
.checkValid()
for := 0; < .NumSettings(); ++ {
if := .Setting(); .ID == {
return .Val, true
}
}
return 0, false
}
func ( *http2SettingsFrame) ( int) http2Setting {
:= .p
return http2Setting{
ID: http2SettingID(binary.BigEndian.Uint16([*6 : *6+2])),
Val: binary.BigEndian.Uint32([*6+2 : *6+6]),
}
}
func ( *http2SettingsFrame) () int { return len(.p) / 6 }
func ( *http2SettingsFrame) () bool {
:= .NumSettings()
if == 0 {
return false
}
if < 10 {
for := 0; < ; ++ {
:= .Setting().ID
for := + 1; < ; ++ {
:= .Setting().ID
if == {
return true
}
}
}
return false
}
:= map[http2SettingID]bool{}
for := 0; < ; ++ {
:= .Setting().ID
if [] {
return true
}
[] = true
}
return false
}
func ( *http2SettingsFrame) ( func(http2Setting) error) error {
.checkValid()
for := 0; < .NumSettings(); ++ {
if := (.Setting()); != nil {
return
}
}
return nil
}
func ( *http2Framer) ( ...http2Setting) error {
.startWrite(http2FrameSettings, 0, 0)
for , := range {
.writeUint16(uint16(.ID))
.writeUint32(.Val)
}
return .endWrite()
}
func ( *http2Framer) () error {
.startWrite(http2FrameSettings, http2FlagSettingsAck, 0)
return .endWrite()
}
type http2PingFrame struct {
http2FrameHeader
Data [8]byte
}
func ( *http2PingFrame) () bool { return .Flags.Has(http2FlagPingAck) }
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if len() != 8 {
("frame_ping_length")
return nil, http2ConnectionError(http2ErrCodeFrameSize)
}
if .StreamID != 0 {
("frame_ping_has_stream")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
:= &http2PingFrame{http2FrameHeader: }
copy(.Data[:], )
return , nil
}
func ( *http2Framer) ( bool, [8]byte) error {
var http2Flags
if {
= http2FlagPingAck
}
.startWrite(http2FramePing, , 0)
.writeBytes([:])
return .endWrite()
}
type http2GoAwayFrame struct {
http2FrameHeader
LastStreamID uint32
ErrCode http2ErrCode
debugData []byte
}
func ( *http2GoAwayFrame) () []byte {
.checkValid()
return .debugData
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if .StreamID != 0 {
("frame_goaway_has_stream")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
if len() < 8 {
("frame_goaway_short")
return nil, http2ConnectionError(http2ErrCodeFrameSize)
}
return &http2GoAwayFrame{
http2FrameHeader: ,
LastStreamID: binary.BigEndian.Uint32([:4]) & (1<<31 - 1),
ErrCode: http2ErrCode(binary.BigEndian.Uint32([4:8])),
debugData: [8:],
}, nil
}
func ( *http2Framer) ( uint32, http2ErrCode, []byte) error {
.startWrite(http2FrameGoAway, 0, 0)
.writeUint32( & (1<<31 - 1))
.writeUint32(uint32())
.writeBytes()
return .endWrite()
}
type http2UnknownFrame struct {
http2FrameHeader
p []byte
}
func ( *http2UnknownFrame) () []byte {
.checkValid()
return .p
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
return &http2UnknownFrame{, }, nil
}
type http2WindowUpdateFrame struct {
http2FrameHeader
Increment uint32
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if len() != 4 {
("frame_windowupdate_bad_len")
return nil, http2ConnectionError(http2ErrCodeFrameSize)
}
:= binary.BigEndian.Uint32([:4]) & 0x7fffffff
if == 0 {
if .StreamID == 0 {
("frame_windowupdate_zero_inc_conn")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
("frame_windowupdate_zero_inc_stream")
return nil, http2streamError(.StreamID, http2ErrCodeProtocol)
}
return &http2WindowUpdateFrame{
http2FrameHeader: ,
Increment: ,
}, nil
}
func ( *http2Framer) (, uint32) error {
if ( < 1 || > 2147483647) && !.AllowIllegalWrites {
return errors.New("illegal window increment value")
}
.startWrite(http2FrameWindowUpdate, 0, )
.writeUint32()
return .endWrite()
}
type http2HeadersFrame struct {
http2FrameHeader
Priority http2PriorityParam
headerFragBuf []byte
}
func ( *http2HeadersFrame) () []byte {
.checkValid()
return .headerFragBuf
}
func ( *http2HeadersFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagHeadersEndHeaders)
}
func ( *http2HeadersFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagHeadersEndStream)
}
func ( *http2HeadersFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagHeadersPriority)
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) ( http2Frame, error) {
:= &http2HeadersFrame{
http2FrameHeader: ,
}
if .StreamID == 0 {
("frame_headers_zero_stream")
return nil, http2connError{http2ErrCodeProtocol, "HEADERS frame with stream ID 0"}
}
var uint8
if .Flags.Has(http2FlagHeadersPadded) {
if , , = http2readByte(); != nil {
("frame_headers_pad_short")
return
}
}
if .Flags.Has(http2FlagHeadersPriority) {
var uint32
, , = http2readUint32()
if != nil {
("frame_headers_prio_short")
return nil,
}
.Priority.StreamDep = & 0x7fffffff
.Priority.Exclusive = ( != .Priority.StreamDep)
, .Priority.Weight, = http2readByte()
if != nil {
("frame_headers_prio_weight_short")
return nil,
}
}
if len()-int() < 0 {
("frame_headers_pad_too_big")
return nil, http2streamError(.StreamID, http2ErrCodeProtocol)
}
.headerFragBuf = [:len()-int()]
return , nil
}
type http2HeadersFrameParam struct {
StreamID uint32
BlockFragment []byte
EndStream bool
EndHeaders bool
PadLength uint8
Priority http2PriorityParam
}
func ( *http2Framer) ( http2HeadersFrameParam) error {
if !http2validStreamID(.StreamID) && !.AllowIllegalWrites {
return http2errStreamID
}
var http2Flags
if .PadLength != 0 {
|= http2FlagHeadersPadded
}
if .EndStream {
|= http2FlagHeadersEndStream
}
if .EndHeaders {
|= http2FlagHeadersEndHeaders
}
if !.Priority.IsZero() {
|= http2FlagHeadersPriority
}
.startWrite(http2FrameHeaders, , .StreamID)
if .PadLength != 0 {
.writeByte(.PadLength)
}
if !.Priority.IsZero() {
:= .Priority.StreamDep
if !http2validStreamIDOrZero() && !.AllowIllegalWrites {
return http2errDepStreamID
}
if .Priority.Exclusive {
|= 1 << 31
}
.writeUint32()
.writeByte(.Priority.Weight)
}
.wbuf = append(.wbuf, .BlockFragment...)
.wbuf = append(.wbuf, http2padZeros[:.PadLength]...)
return .endWrite()
}
type http2PriorityFrame struct {
http2FrameHeader
http2PriorityParam
}
type http2PriorityParam struct {
StreamDep uint32
Exclusive bool
Weight uint8
}
func ( http2PriorityParam) () bool {
return == http2PriorityParam{}
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if .StreamID == 0 {
("frame_priority_zero_stream")
return nil, http2connError{http2ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
}
if len() != 5 {
("frame_priority_bad_length")
return nil, http2connError{http2ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len())}
}
:= binary.BigEndian.Uint32([:4])
:= & 0x7fffffff
return &http2PriorityFrame{
http2FrameHeader: ,
http2PriorityParam: http2PriorityParam{
Weight: [4],
StreamDep: ,
Exclusive: != ,
},
}, nil
}
func ( *http2Framer) ( uint32, http2PriorityParam) error {
if !http2validStreamID() && !.AllowIllegalWrites {
return http2errStreamID
}
if !http2validStreamIDOrZero(.StreamDep) {
return http2errDepStreamID
}
.startWrite(http2FramePriority, 0, )
:= .StreamDep
if .Exclusive {
|= 1 << 31
}
.writeUint32()
.writeByte(.Weight)
return .endWrite()
}
type http2RSTStreamFrame struct {
http2FrameHeader
ErrCode http2ErrCode
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if len() != 4 {
("frame_rststream_bad_len")
return nil, http2ConnectionError(http2ErrCodeFrameSize)
}
if .StreamID == 0 {
("frame_rststream_zero_stream")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
return &http2RSTStreamFrame{, http2ErrCode(binary.BigEndian.Uint32([:4]))}, nil
}
func ( *http2Framer) ( uint32, http2ErrCode) error {
if !http2validStreamID() && !.AllowIllegalWrites {
return http2errStreamID
}
.startWrite(http2FrameRSTStream, 0, )
.writeUint32(uint32())
return .endWrite()
}
type http2ContinuationFrame struct {
http2FrameHeader
headerFragBuf []byte
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) (http2Frame, error) {
if .StreamID == 0 {
("frame_continuation_zero_stream")
return nil, http2connError{http2ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
}
return &http2ContinuationFrame{, }, nil
}
func ( *http2ContinuationFrame) () []byte {
.checkValid()
return .headerFragBuf
}
func ( *http2ContinuationFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagContinuationEndHeaders)
}
func ( *http2Framer) ( uint32, bool, []byte) error {
if !http2validStreamID() && !.AllowIllegalWrites {
return http2errStreamID
}
var http2Flags
if {
|= http2FlagContinuationEndHeaders
}
.startWrite(http2FrameContinuation, , )
.wbuf = append(.wbuf, ...)
return .endWrite()
}
type http2PushPromiseFrame struct {
http2FrameHeader
PromiseID uint32
headerFragBuf []byte
}
func ( *http2PushPromiseFrame) () []byte {
.checkValid()
return .headerFragBuf
}
func ( *http2PushPromiseFrame) () bool {
return .http2FrameHeader.Flags.Has(http2FlagPushPromiseEndHeaders)
}
func ( *http2frameCache, http2FrameHeader, func(string), []byte) ( http2Frame, error) {
:= &http2PushPromiseFrame{
http2FrameHeader: ,
}
if .StreamID == 0 {
("frame_pushpromise_zero_stream")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
var uint8
if .Flags.Has(http2FlagPushPromisePadded) {
if , , = http2readByte(); != nil {
("frame_pushpromise_pad_short")
return
}
}
, .PromiseID, = http2readUint32()
if != nil {
("frame_pushpromise_promiseid_short")
return
}
.PromiseID = .PromiseID & (1<<31 - 1)
if int() > len() {
("frame_pushpromise_pad_too_big")
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
.headerFragBuf = [:len()-int()]
return , nil
}
type http2PushPromiseParam struct {
StreamID uint32
PromiseID uint32
BlockFragment []byte
EndHeaders bool
PadLength uint8
}
func ( *http2Framer) ( http2PushPromiseParam) error {
if !http2validStreamID(.StreamID) && !.AllowIllegalWrites {
return http2errStreamID
}
var http2Flags
if .PadLength != 0 {
|= http2FlagPushPromisePadded
}
if .EndHeaders {
|= http2FlagPushPromiseEndHeaders
}
.startWrite(http2FramePushPromise, , .StreamID)
if .PadLength != 0 {
.writeByte(.PadLength)
}
if !http2validStreamID(.PromiseID) && !.AllowIllegalWrites {
return http2errStreamID
}
.writeUint32(.PromiseID)
.wbuf = append(.wbuf, .BlockFragment...)
.wbuf = append(.wbuf, http2padZeros[:.PadLength]...)
return .endWrite()
}
func ( *http2Framer) ( http2FrameType, http2Flags, uint32, []byte) error {
.startWrite(, , )
.writeBytes()
return .endWrite()
}
func ( []byte) ( []byte, byte, error) {
if len() == 0 {
return nil, 0, io.ErrUnexpectedEOF
}
return [1:], [0], nil
}
func ( []byte) ( []byte, uint32, error) {
if len() < 4 {
return nil, 0, io.ErrUnexpectedEOF
}
return [4:], binary.BigEndian.Uint32([: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 ( *http2MetaHeadersFrame) ( string) string {
for , := range .Fields {
if !.IsPseudo() {
return ""
}
if .Name[1:] == {
return .Value
}
}
return ""
}
func ( *http2MetaHeadersFrame) () []hpack.HeaderField {
for , := range .Fields {
if !.IsPseudo() {
return .Fields[:]
}
}
return nil
}
func ( *http2MetaHeadersFrame) () []hpack.HeaderField {
for , := range .Fields {
if !.IsPseudo() {
return .Fields[:]
}
}
return .Fields
}
func ( *http2MetaHeadersFrame) () error {
var , bool
:= .PseudoFields()
for , := range {
switch .Name {
case ":method", ":path", ":scheme", ":authority":
= true
case ":status":
= true
default:
return http2pseudoHeaderError(.Name)
}
for , := range [:] {
if .Name == .Name {
return http2duplicatePseudoHeaderError(.Name)
}
}
}
if && {
return http2errMixPseudoHeaderTypes
}
return nil
}
func ( *http2Framer) () int {
:= .maxHeaderListSize()
if uint32(int()) == {
return int()
}
return 0
}
func ( *http2Framer) ( *http2HeadersFrame) (*http2MetaHeadersFrame, error) {
if .AllowIllegalReads {
return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
}
:= &http2MetaHeadersFrame{
http2HeadersFrame: ,
}
var = .maxHeaderListSize()
var bool
var error
:= .ReadMetaHeaders
.SetEmitEnabled(true)
.SetMaxStringLength(.maxHeaderStringLen())
.SetEmitFunc(func( hpack.HeaderField) {
if http2VerboseLogs && .logReads {
.debugReadLoggerf("http2: decoded hpack field %+v", )
}
if !httpguts.ValidHeaderFieldValue(.Value) {
= http2headerFieldValueError(.Name)
}
:= strings.HasPrefix(.Name, ":")
if {
if {
= http2errPseudoAfterRegular
}
} else {
= true
if !http2validWireHeaderFieldName(.Name) {
= http2headerFieldNameError(.Name)
}
}
if != nil {
.SetEmitEnabled(false)
return
}
:= .Size()
if > {
.SetEmitEnabled(false)
.Truncated = true
return
}
-=
.Fields = append(.Fields, )
})
defer .SetEmitFunc(func( hpack.HeaderField) {})
var http2headersOrContinuation =
for {
:= .HeaderBlockFragment()
if , := .Write(); != nil {
return nil, http2ConnectionError(http2ErrCodeCompression)
}
if .HeadersEnded() {
break
}
if , := .ReadFrame(); != nil {
return nil,
} else {
= .(*http2ContinuationFrame)
}
}
.http2HeadersFrame.headerFragBuf = nil
.http2HeadersFrame.invalidate()
if := .Close(); != nil {
return nil, http2ConnectionError(http2ErrCodeCompression)
}
if != nil {
.errDetail =
if http2VerboseLogs {
log.Printf("http2: invalid header: %v", )
}
return nil, http2StreamError{.StreamID, http2ErrCodeProtocol, }
}
if := .checkPseudos(); != nil {
.errDetail =
if http2VerboseLogs {
log.Printf("http2: invalid pseudo headers: %v", )
}
return nil, http2StreamError{.StreamID, http2ErrCodeProtocol, }
}
return , nil
}
func ( http2Frame) string {
var bytes.Buffer
.Header().writeDebug(&)
switch f := .(type) {
case *http2SettingsFrame:
:= 0
.ForeachSetting(func( http2Setting) error {
++
if == 1 {
.WriteString(", settings:")
}
fmt.Fprintf(&, " %v=%v,", .ID, .Val)
return nil
})
if > 0 {
.Truncate(.Len() - 1)
}
case *http2DataFrame:
:= .Data()
const = 256
if len() > {
= [:]
}
fmt.Fprintf(&, " data=%q", )
if len(.Data()) > {
fmt.Fprintf(&, " (%d bytes omitted)", len(.Data())-)
}
case *http2WindowUpdateFrame:
if .StreamID == 0 {
.WriteString(" (conn)")
}
fmt.Fprintf(&, " incr=%v", .Increment)
case *http2PingFrame:
fmt.Fprintf(&, " ping=%q", .Data[:])
case *http2GoAwayFrame:
fmt.Fprintf(&, " LastStreamID=%v ErrCode=%v Debug=%q",
.LastStreamID, .ErrCode, .debugData)
case *http2RSTStreamFrame:
fmt.Fprintf(&, " ErrCode=%v", .ErrCode)
}
return .String()
}
func ( *httptrace.ClientTrace) bool {
return != nil && .WroteHeaderField != nil
}
func ( *httptrace.ClientTrace, , string) {
if != nil && .WroteHeaderField != nil {
.WroteHeaderField(, []string{})
}
}
func ( *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
if != nil {
return .Got1xxResponse
}
return nil
}
func ( *http2Transport) ( context.Context, , string, *tls.Config) (*tls.Conn, error) {
:= &tls.Dialer{
Config: ,
}
, := .DialContext(, , )
if != nil {
return nil,
}
:= .(*tls.Conn)
return , nil
}
func ( *tls.Conn) net.Conn {
return .NetConn()
}
var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
type http2goroutineLock uint64
func () http2goroutineLock {
if !http2DebugGoroutines {
return 0
}
return http2goroutineLock(http2curGoroutineID())
}
func ( http2goroutineLock) () {
if !http2DebugGoroutines {
return
}
if http2curGoroutineID() != uint64() {
panic("running on the wrong goroutine")
}
}
func ( http2goroutineLock) () {
if !http2DebugGoroutines {
return
}
if http2curGoroutineID() == uint64() {
panic("running on the wrong goroutine")
}
}
var http2goroutineSpace = []byte("goroutine ")
func () uint64 {
:= http2littleBuf.Get().(*[]byte)
defer http2littleBuf.Put()
:= *
= [:runtime.Stack(, false)]
= bytes.TrimPrefix(, http2goroutineSpace)
:= bytes.IndexByte(, ' ')
if < 0 {
panic(fmt.Sprintf("No space found in %q", ))
}
= [:]
, := http2parseUintBytes(, 10, 64)
if != nil {
panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", , ))
}
return
}
var http2littleBuf = sync.Pool{
New: func() interface{} {
:= make([]byte, 64)
return &
},
}
func ( []byte, int, int) ( uint64, error) {
var , uint64
if == 0 {
= int(strconv.IntSize)
}
:=
switch {
case len() < 1:
= strconv.ErrSyntax
goto
case 2 <= && <= 36:
case == 0:
switch {
case [0] == '0' && len() > 1 && ([1] == 'x' || [1] == 'X'):
= 16
= [2:]
if len() < 1 {
= strconv.ErrSyntax
goto
}
case [0] == '0':
= 8
default:
= 10
}
default:
= errors.New("invalid base " + strconv.Itoa())
goto
}
= 0
= http2cutoff64()
= 1<<uint() - 1
for := 0; < len(); ++ {
var byte
:= []
switch {
case '0' <= && <= '9':
= - '0'
case 'a' <= && <= 'z':
= - 'a' + 10
case 'A' <= && <= 'Z':
= - 'A' + 10
default:
= 0
= strconv.ErrSyntax
goto
}
if int() >= {
= 0
= strconv.ErrSyntax
goto
}
if >= {
= 1<<64 - 1
= strconv.ErrRange
goto
}
*= uint64()
:= + uint64()
if < || > {
= 1<<64 - 1
= strconv.ErrRange
goto
}
=
}
return , nil
:
return , &strconv.NumError{Func: "ParseUint", Num: string(), Err: }
}
func ( int) uint64 {
if < 2 {
return 0
}
return (1<<64-1)/uint64() + 1
}
var (
http2commonBuildOnce sync.Once
http2commonLowerHeader map[string]string
http2commonCanonHeader map[string]string
)
func () {
http2commonBuildOnce.Do(http2buildCommonHeaderMaps)
}
func () {
:= []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())
http2commonCanonHeader = make(map[string]string, len())
for , := range {
:= CanonicalHeaderKey()
http2commonLowerHeader[] =
http2commonCanonHeader[] =
}
}
func ( string) ( string, bool) {
http2buildCommonHeaderMapsOnce()
if , := http2commonLowerHeader[]; {
return , true
}
return http2asciiToLower()
}
func ( string) string {
http2buildCommonHeaderMapsOnce()
if , := http2commonCanonHeader[]; {
return
}
return CanonicalHeaderKey()
}
var (
http2VerboseLogs bool
http2logFrameWrites bool
http2logFrameReads bool
http2inTests bool
)
func () {
:= os.Getenv("GODEBUG")
if strings.Contains(, "http2debug=1") {
http2VerboseLogs = true
}
if strings.Contains(, "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 ( http2streamState) () string {
return http2stateName[]
}
type http2Setting struct {
ID http2SettingID
Val uint32
}
func ( http2Setting) () string {
return fmt.Sprintf("[%v = %d]", .ID, .Val)
}
func ( http2Setting) () error {
switch .ID {
case http2SettingEnablePush:
if .Val != 1 && .Val != 0 {
return http2ConnectionError(http2ErrCodeProtocol)
}
case http2SettingInitialWindowSize:
if .Val > 1<<31-1 {
return http2ConnectionError(http2ErrCodeFlowControl)
}
case http2SettingMaxFrameSize:
if .Val < 16384 || .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 ( http2SettingID) () string {
if , := http2settingName[]; {
return
}
return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16())
}
func ( string) bool {
if len() == 0 {
return false
}
for , := range {
if !httpguts.IsTokenRune() {
return false
}
if 'A' <= && <= 'Z' {
return false
}
}
return true
}
func ( int) string {
switch {
case 200:
return "200"
case 404:
return "404"
}
return strconv.Itoa()
}
type http2stringWriter interface {
WriteString(s string) (n int, err error)
}
type http2gate chan struct{}
func ( http2gate) () { <- struct{}{} }
func ( http2gate) () { <- }
type http2closeWaiter chan struct{}
func ( *http2closeWaiter) () {
* = make(chan struct{})
}
func ( http2closeWaiter) () {
close()
}
func ( http2closeWaiter) () {
<-
}
type http2bufferedWriter struct {
_ http2incomparable
w io.Writer
bw *bufio.Writer
}
func ( io.Writer) *http2bufferedWriter {
return &http2bufferedWriter{w: }
}
const http2bufWriterPoolBufferSize = 4 << 10
var http2bufWriterPool = sync.Pool{
New: func() interface{} {
return bufio.NewWriterSize(nil, http2bufWriterPoolBufferSize)
},
}
func ( *http2bufferedWriter) () int {
if .bw == nil {
return http2bufWriterPoolBufferSize
}
return .bw.Available()
}
func ( *http2bufferedWriter) ( []byte) ( int, error) {
if .bw == nil {
:= http2bufWriterPool.Get().(*bufio.Writer)
.Reset(.w)
.bw =
}
return .bw.Write()
}
func ( *http2bufferedWriter) () error {
:= .bw
if == nil {
return nil
}
:= .Flush()
.Reset(nil)
http2bufWriterPool.Put()
.bw = nil
return
}
func ( int32) uint32 {
if < 0 || > 2147483647 {
panic("out of range")
}
return uint32()
}
func ( int) bool {
switch {
case >= 100 && <= 199:
return false
case == 204:
return false
case == 304:
return false
}
return true
}
type http2httpError struct {
_ http2incomparable
msg string
timeout bool
}
func ( *http2httpError) () string { return .msg }
func ( *http2httpError) () bool { return .timeout }
func ( *http2httpError) () 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 ( *http2sorter) () int { return len(.v) }
func ( *http2sorter) (, int) { .v[], .v[] = .v[], .v[] }
func ( *http2sorter) (, int) bool { return .v[] < .v[] }
func ( *http2sorter) ( Header) []string {
:= .v[:0]
for := range {
= append(, )
}
.v =
sort.Sort()
return
}
func ( *http2sorter) ( []string) {
:= .v
.v =
sort.Sort()
.v =
}
func ( string) bool {
return (len() > 0 && [0] == '/') || == "*"
}
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 ( *http2pipe) ( http2pipeBuffer) {
.mu.Lock()
defer .mu.Unlock()
if .err != nil || .breakErr != nil {
return
}
.b =
}
func ( *http2pipe) () int {
.mu.Lock()
defer .mu.Unlock()
if .b == nil {
return .unread
}
return .b.Len()
}
func ( *http2pipe) ( []byte) ( int, error) {
.mu.Lock()
defer .mu.Unlock()
if .c.L == nil {
.c.L = &.mu
}
for {
if .breakErr != nil {
return 0, .breakErr
}
if .b != nil && .b.Len() > 0 {
return .b.Read()
}
if .err != nil {
if .readFn != nil {
.readFn()
.readFn = nil
}
.b = nil
return 0, .err
}
.c.Wait()
}
}
var http2errClosedPipeWrite = errors.New("write on closed buffer")
func ( *http2pipe) ( []byte) ( int, error) {
.mu.Lock()
defer .mu.Unlock()
if .c.L == nil {
.c.L = &.mu
}
defer .c.Signal()
if .err != nil || .breakErr != nil {
return 0, http2errClosedPipeWrite
}
return .b.Write()
}
func ( *http2pipe) ( error) { .closeWithError(&.err, , nil) }
func ( *http2pipe) ( error) { .closeWithError(&.breakErr, , nil) }
func ( *http2pipe) ( error, func()) { .closeWithError(&.err, , ) }
func ( *http2pipe) ( *error, error, func()) {
if == nil {
panic("err must be non-nil")
}
.mu.Lock()
defer .mu.Unlock()
if .c.L == nil {
.c.L = &.mu
}
defer .c.Signal()
if * != nil {
return
}
.readFn =
if == &.breakErr {
if .b != nil {
.unread += .b.Len()
}
.b = nil
}
* =
.closeDoneLocked()
}
func ( *http2pipe) () {
if .donec == nil {
return
}
select {
case <-.donec:
default:
close(.donec)
}
}
func ( *http2pipe) () error {
.mu.Lock()
defer .mu.Unlock()
if .breakErr != nil {
return .breakErr
}
return .err
}
func ( *http2pipe) () <-chan struct{} {
.mu.Lock()
defer .mu.Unlock()
if .donec == nil {
.donec = make(chan struct{})
if .err != nil || .breakErr != nil {
.closeDoneLocked()
}
}
return .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{} {
:= &http2responseWriterState{}
.bw = bufio.NewWriterSize(http2chunkWriter{}, http2handlerChunkWriteSize)
return
},
}
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 ( *http2Server) () int32 {
if .MaxUploadBufferPerConnection >= http2initialWindowSize {
return .MaxUploadBufferPerConnection
}
return 1 << 20
}
func ( *http2Server) () int32 {
if .MaxUploadBufferPerStream > 0 {
return .MaxUploadBufferPerStream
}
return 1 << 20
}
func ( *http2Server) () uint32 {
if := .MaxReadFrameSize; >= http2minMaxFrameSize && <= http2maxFrameSize {
return
}
return http2defaultMaxReadFrameSize
}
func ( *http2Server) () uint32 {
if := .MaxConcurrentStreams; > 0 {
return
}
return http2defaultMaxStreams
}
func ( *http2Server) () uint32 {
if := .MaxDecoderHeaderTableSize; > 0 {
return
}
return http2initialHeaderTableSize
}
func ( *http2Server) () uint32 {
if := .MaxEncoderHeaderTableSize; > 0 {
return
}
return http2initialHeaderTableSize
}
func ( *http2Server) () int {
return http2maxQueuedControlFrames
}
type http2serverInternalState struct {
mu sync.Mutex
activeConns map[*http2serverConn]struct{}
}
func ( *http2serverInternalState) ( *http2serverConn) {
if == nil {
return
}
.mu.Lock()
.activeConns[] = struct{}{}
.mu.Unlock()
}
func ( *http2serverInternalState) ( *http2serverConn) {
if == nil {
return
}
.mu.Lock()
delete(.activeConns, )
.mu.Unlock()
}
func ( *http2serverInternalState) () {
if == nil {
return
}
.mu.Lock()
for := range .activeConns {
.startGracefulShutdown()
}
.mu.Unlock()
}
func ( *Server, *http2Server) error {
if == nil {
panic("nil *http.Server")
}
if == nil {
= new(http2Server)
}
.state = &http2serverInternalState{activeConns: make(map[*http2serverConn]struct{})}
if , := , ; .IdleTimeout == 0 {
if .IdleTimeout != 0 {
.IdleTimeout = .IdleTimeout
} else {
.IdleTimeout = .ReadTimeout
}
}
.RegisterOnShutdown(.state.startGracefulShutdown)
if .TLSConfig == nil {
.TLSConfig = new(tls.Config)
} else if .TLSConfig.CipherSuites != nil && .TLSConfig.MinVersion < tls.VersionTLS13 {
:= false
for , := range .TLSConfig.CipherSuites {
switch {
case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
= true
}
}
if ! {
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)")
}
}
.TLSConfig.PreferServerCipherSuites = true
if !http2strSliceContains(.TLSConfig.NextProtos, http2NextProtoTLS) {
.TLSConfig.NextProtos = append(.TLSConfig.NextProtos, http2NextProtoTLS)
}
if !http2strSliceContains(.TLSConfig.NextProtos, "http/1.1") {
.TLSConfig.NextProtos = append(.TLSConfig.NextProtos, "http/1.1")
}
if .TLSNextProto == nil {
.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){}
}
:= func( *Server, *tls.Conn, Handler) {
if http2testHookOnConn != nil {
http2testHookOnConn()
}
var context.Context
type interface {
() context.Context
}
if , := .(); {
= .()
}
.ServeConn(, &http2ServeConnOpts{
Context: ,
Handler: ,
BaseConfig: ,
})
}
.TLSNextProto[http2NextProtoTLS] =
return nil
}
type http2ServeConnOpts struct {
Context context.Context
BaseConfig *Server
Handler Handler
UpgradeRequest *Request
Settings []byte
SawClientPreface bool
}
func ( *http2ServeConnOpts) () context.Context {
if != nil && .Context != nil {
return .Context
}
return context.Background()
}
func ( *http2ServeConnOpts) () *Server {
if != nil && .BaseConfig != nil {
return .BaseConfig
}
return new(Server)
}
func ( *http2ServeConnOpts) () Handler {
if != nil {
if .Handler != nil {
return .Handler
}
if .BaseConfig != nil && .BaseConfig.Handler != nil {
return .BaseConfig.Handler
}
}
return DefaultServeMux
}
func ( *http2Server) ( net.Conn, *http2ServeConnOpts) {
, := http2serverConnBaseContext(, )
defer ()
:= &http2serverConn{
srv: ,
hs: .baseConfig(),
conn: ,
baseCtx: ,
remoteAddrStr: .RemoteAddr().String(),
bw: http2newBufferedWriter(),
handler: .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: .maxConcurrentStreams(),
initialStreamSendWindowSize: http2initialWindowSize,
maxFrameSize: http2initialMaxFrameSize,
serveG: http2newGoroutineLock(),
pushEnabled: true,
sawClientPreface: .SawClientPreface,
}
.state.registerConn()
defer .state.unregisterConn()
if .hs.WriteTimeout != 0 {
.conn.SetWriteDeadline(time.Time{})
}
if .NewWriteScheduler != nil {
.writeSched = .NewWriteScheduler()
} else {
.writeSched = http2newRoundRobinWriteScheduler()
}
.flow.add(http2initialWindowSize)
.inflow.init(http2initialWindowSize)
.hpackEncoder = hpack.NewEncoder(&.headerWriteBuf)
.hpackEncoder.SetMaxDynamicTableSizeLimit(.maxEncoderHeaderTableSize())
:= http2NewFramer(.bw, )
if .CountError != nil {
.countError = .CountError
}
.ReadMetaHeaders = hpack.NewDecoder(.maxDecoderHeaderTableSize(), nil)
.MaxHeaderListSize = .maxHeaderListSize()
.SetMaxReadFrameSize(.maxReadFrameSize())
.framer =
if , := .(http2connectionStater); {
.tlsState = new(tls.ConnectionState)
*.tlsState = .ConnectionState()
if .tlsState.Version < tls.VersionTLS12 {
.rejectConn(http2ErrCodeInadequateSecurity, "TLS version too low")
return
}
if .tlsState.ServerName == "" {
}
if !.PermitProhibitedCipherSuites && http2isBadCipher(.tlsState.CipherSuite) {
.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", .tlsState.CipherSuite))
return
}
}
if .Settings != nil {
:= &http2SettingsFrame{
http2FrameHeader: http2FrameHeader{valid: true},
p: .Settings,
}
if := .ForeachSetting(.processSetting); != nil {
.