...
Run Format

Source file src/net/http/h2_bundle.go

Documentation: net/http

  // Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
  //go:generate bundle -o h2_bundle.go -prefix http2 -underscore golang.org/x/net/http2
  
  // Package http2 implements the HTTP/2 protocol.
  //
  // This package is low-level and intended to be used directly by very
  // few people. Most users will use it indirectly through the automatic
  // use by the net/http package (from Go 1.6 and later).
  // For use in earlier Go versions see ConfigureServer. (Transport support
  // requires Go 1.6 or later)
  //
  // See https://http2.github.io/ for more information on HTTP/2.
  //
  // See https://http2.golang.org/ for a test server running this code.
  //
  
  package http
  
  import (
  	"bufio"
  	"bytes"
  	"compress/gzip"
  	"context"
  	"crypto/rand"
  	"crypto/tls"
  	"encoding/binary"
  	"errors"
  	"fmt"
  	"io"
  	"io/ioutil"
  	"log"
  	"math"
  	"net"
  	"net/http/httptrace"
  	"net/textproto"
  	"net/url"
  	"os"
  	"reflect"
  	"runtime"
  	"sort"
  	"strconv"
  	"strings"
  	"sync"
  	"time"
  
  	"golang_org/x/net/http2/hpack"
  	"golang_org/x/net/idna"
  	"golang_org/x/net/lex/httplex"
  )
  
  // A list of the possible cipher suite ids. Taken from
  // http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
  
  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
  	// Reserved uint16 =  0x001C-1D
  	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
  	// Reserved uint16 =  0x0047-4F
  	// Reserved uint16 =  0x0050-58
  	// Reserved uint16 =  0x0059-5C
  	// Unassigned uint16 =  0x005D-5F
  	// Reserved uint16 =  0x0060-66
  	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
  	// Unassigned uint16 =  0x006E-83
  	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
  	// Unassigned uint16 =  0x00C6-FE
  	http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF
  	// Unassigned uint16 =  0x01-55,*
  	http2cipher_TLS_FALLBACK_SCSV uint16 = 0x5600
  	// Unassigned                                   uint16 = 0x5601 - 0xC000
  	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
  	// Unassigned uint16 =  0xC0B0-FF
  	// Unassigned uint16 =  0xC1-CB,*
  	// Unassigned uint16 =  0xCC00-A7
  	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
  )
  
  // isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
  // References:
  // https://tools.ietf.org/html/rfc7540#appendix-A
  // Reject cipher suites from Appendix A.
  // "This list includes those cipher suites that do not
  // offer an ephemeral key exchange and those that are
  // based on the TLS null, stream or block cipher type"
  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
  	}
  }
  
  // ClientConnPool manages a pool of HTTP/2 client connections.
  type http2ClientConnPool interface {
  	GetClientConn(req *Request, addr string) (*http2ClientConn, error)
  	MarkDead(*http2ClientConn)
  }
  
  // clientConnPoolIdleCloser is the interface implemented by ClientConnPool
  // implementations which can close their idle connections.
  type http2clientConnPoolIdleCloser interface {
  	http2ClientConnPool
  	closeIdleConnections()
  }
  
  var (
  	_ http2clientConnPoolIdleCloser = (*http2clientConnPool)(nil)
  	_ http2clientConnPoolIdleCloser = http2noDialClientConnPool{}
  )
  
  // TODO: use singleflight for dialing and addConnCalls?
  type http2clientConnPool struct {
  	t *http2Transport
  
  	mu sync.Mutex // TODO: maybe switch to RWMutex
  	// TODO: add support for sharing conns based on cert names
  	// (e.g. share conn for googleapis.com and appspot.com)
  	conns        map[string][]*http2ClientConn // key is host:port
  	dialing      map[string]*http2dialCall     // currently in-flight dials
  	keys         map[*http2ClientConn][]string
  	addConnCalls map[string]*http2addConnCall // in-flight addConnIfNeede calls
  }
  
  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 {
  		// It gets its own connection.
  		const singleUse = true
  		cc, err := p.t.dialClientConn(addr, singleUse)
  		if err != nil {
  			return nil, err
  		}
  		return cc, nil
  	}
  	p.mu.Lock()
  	for _, cc := range p.conns[addr] {
  		if cc.CanTakeNewRequest() {
  			p.mu.Unlock()
  			return cc, nil
  		}
  	}
  	if !dialOnMiss {
  		p.mu.Unlock()
  		return nil, http2ErrNoCachedConn
  	}
  	call := p.getStartDialLocked(addr)
  	p.mu.Unlock()
  	<-call.done
  	return call.res, call.err
  }
  
  // dialCall is an in-flight Transport dial call to a host.
  type http2dialCall struct {
  	p    *http2clientConnPool
  	done chan struct{}    // closed when done
  	res  *http2ClientConn // valid after done is closed
  	err  error            // valid after done is closed
  }
  
  // requires p.mu is held.
  func (p *http2clientConnPool) getStartDialLocked(addr string) *http2dialCall {
  	if call, ok := p.dialing[addr]; ok {
  		// A dial is already in-flight. Don't start another.
  		return call
  	}
  	call := &http2dialCall{p: p, done: make(chan struct{})}
  	if p.dialing == nil {
  		p.dialing = make(map[string]*http2dialCall)
  	}
  	p.dialing[addr] = call
  	go call.dial(addr)
  	return call
  }
  
  // run in its own goroutine.
  func (c *http2dialCall) dial(addr string) {
  	const singleUse = false // shared conn
  	c.res, c.err = c.p.t.dialClientConn(addr, singleUse)
  	close(c.done)
  
  	c.p.mu.Lock()
  	delete(c.p.dialing, addr)
  	if c.err == nil {
  		c.p.addConnLocked(addr, c.res)
  	}
  	c.p.mu.Unlock()
  }
  
  // addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
  // already exist. It coalesces concurrent calls with the same key.
  // This is used by the http1 Transport code when it creates a new connection. Because
  // the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
  // the protocol), it can get into a situation where it has multiple TLS connections.
  // This code decides which ones live or die.
  // The return value used is whether c was used.
  // c is never closed.
  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 {
  	p    *http2clientConnPool
  	done chan struct{} // closed when done
  	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 {
  		p.addConnLocked(key, cc)
  	}
  	delete(p.addConnCalls, key)
  	p.mu.Unlock()
  	close(c.done)
  }
  
  func (p *http2clientConnPool) addConn(key string, cc *http2ClientConn) {
  	p.mu.Lock()
  	p.addConnLocked(key, cc)
  	p.mu.Unlock()
  }
  
  // p.mu must be held
  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()
  	// TODO: don't close a cc if it was just added to the pool
  	// milliseconds ago and has never been used. There's currently
  	// a small race window with the HTTP/1 Transport's integration
  	// where it can add an idle conn just before using it, and
  	// somebody else can concurrently call CloseIdleConns and
  	// break some caller's RoundTrip.
  	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 we filtered it out, zero out the last item to prevent
  	// the GC from seeing it.
  	if len(in) != len(out) {
  		in[len(in)-1] = nil
  	}
  	return out
  }
  
  // noDialClientConnPool is an implementation of http2.ClientConnPool
  // which never dials. We let the HTTP/1.1 client dial and use its TLS
  // connection instead.
  type http2noDialClientConnPool struct{ *http2clientConnPool }
  
  func (p http2noDialClientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
  	return p.getClientConn(req, addr, http2noDialOnMiss)
  }
  
  func http2configureTransport(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 {
  			// Turns out we don't need this c.
  			// For example, two goroutines made requests to the same host
  			// at the same time, both kicking off TCP dials. (since protocol
  			// was unknown)
  			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
  }
  
  // registerHTTPSProtocol calls Transport.RegisterProtocol but
  // converting panics into errors.
  func http2registerHTTPSProtocol(t *Transport, rt RoundTripper) (err error) {
  	defer func() {
  		if e := recover(); e != nil {
  			err = fmt.Errorf("%v", e)
  		}
  	}()
  	t.RegisterProtocol("https", rt)
  	return nil
  }
  
  // noDialH2RoundTripper is a RoundTripper which only tries to complete the request
  // if there's already has a cached connection to the host.
  type http2noDialH2RoundTripper struct{ t *http2Transport }
  
  func (rt http2noDialH2RoundTripper) RoundTrip(req *Request) (*Response, error) {
  	res, err := rt.t.RoundTrip(req)
  	if err == http2ErrNoCachedConn {
  		return nil, ErrSkipAltProtocol
  	}
  	return res, err
  }
  
  // Buffer chunks are allocated from a pool to reduce pressure on GC.
  // The maximum wasted space per dataBuffer is 2x the largest size class,
  // which happens when the dataBuffer has multiple chunks and there is
  // one unread byte in both the first and last chunks. We use a few size
  // classes to minimize overheads for servers that typically receive very
  // small request bodies.
  //
  // TODO: Benchmark to determine if the pools are necessary. The GC may have
  // improved enough that we can instead allocate chunks like this:
  // make([]byte, max(16<<10, expectedBytesRemaining))
  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)))
  }
  
  // dataBuffer is an io.ReadWriter backed by a list of data chunks.
  // Each dataBuffer is used to read DATA frames on a single stream.
  // The buffer is divided into chunks so the server can limit the
  // total memory used by a single connection without limiting the
  // request body size on any single stream.
  type http2dataBuffer struct {
  	chunks   [][]byte
  	r        int   // next byte to read is chunks[0][r]
  	w        int   // next byte to write is chunks[len(chunks)-1][w]
  	size     int   // total buffered bytes
  	expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)
  }
  
  var http2errReadEmpty = errors.New("read from empty dataBuffer")
  
  // Read copies bytes from the buffer into p.
  // It is an error to read when no data is available.
  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 the first chunk has been consumed, advance to the next chunk.
  		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:]
  }
  
  // Len returns the number of bytes of the unread portion of the buffer.
  func (b *http2dataBuffer) Len() int {
  	return b.size
  }
  
  // Write appends p to the buffer.
  func (b *http2dataBuffer) Write(p []byte) (int, error) {
  	ntotal := len(p)
  	for len(p) > 0 {
  		// If the last chunk is empty, allocate a new chunk. Try to allocate
  		// enough to fully copy p plus any additional bytes we expect to
  		// receive. However, this may allocate less than len(p).
  		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
  }
  
  // An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
  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))
  }
  
  // ConnectionError is an error that results in the termination of the
  // entire connection.
  type http2ConnectionError http2ErrCode
  
  func (e http2ConnectionError) Error() string {
  	return fmt.Sprintf("connection error: %s", http2ErrCode(e))
  }
  
  // StreamError is an error that only affects one stream within an
  // HTTP/2 connection.
  type http2StreamError struct {
  	StreamID uint32
  	Code     http2ErrCode
  	Cause    error // optional additional detail
  }
  
  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)
  }
  
  // 6.9.1 The Flow Control Window
  // "If a sender receives a WINDOW_UPDATE that causes a flow control
  // window to exceed this maximum it MUST terminate either the stream
  // or the connection, as appropriate. For streams, [...]; for the
  // connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
  type http2goAwayFlowError struct{}
  
  func (http2goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
  
  // connError represents an HTTP/2 ConnectionError error code, along
  // with a string (for debugging) explaining why.
  //
  // Errors of this type are only returned by the frame parser functions
  // and converted into ConnectionError(Code), after stashing away
  // the Reason into the Framer's errDetail field, accessible via
  // the (*Framer).ErrorDetail method.
  type http2connError struct {
  	Code   http2ErrCode // the ConnectionError error code
  	Reason string       // additional reason
  }
  
  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 %q", string(e))
  }
  
  var (
  	http2errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
  	http2errPseudoAfterRegular   = errors.New("pseudo header field after regular")
  )
  
  // flow is the flow control window's size.
  type http2flow struct {
  	// n is the number of DATA bytes we're allowed to send.
  	// A flow is kept both on a conn and a per-stream.
  	n int32
  
  	// conn points to the shared connection-level flow that is
  	// shared by all streams on that conn. It is nil for the flow
  	// that's on the conn directly.
  	conn *http2flow
  }
  
  func (f *http2flow) setConnFlow(cf *http2flow) { f.conn = cf }
  
  func (f *http2flow) available() int32 {
  	n := f.n
  	if f.conn != nil && f.conn.n < n {
  		n = f.conn.n
  	}
  	return n
  }
  
  func (f *http2flow) take(n int32) {
  	if n > f.available() {
  		panic("internal error: took too much")
  	}
  	f.n -= n
  	if f.conn != nil {
  		f.conn.n -= n
  	}
  }
  
  // add adds n bytes (positive or negative) to the flow control window.
  // It returns false if the sum would exceed 2^31-1.
  func (f *http2flow) add(n int32) bool {
  	remain := (1<<31 - 1) - f.n
  	if n > remain {
  		return false
  	}
  	f.n += n
  	return true
  }
  
  const http2frameHeaderLen = 9
  
  var http2padZeros = make([]byte, 255) // zeros for padding
  
  // A FrameType is a registered frame type as defined in
  // http://http2.github.io/http2-spec/#rfc.section.11.2
  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))
  }
  
  // Flags is a bitmask of HTTP/2 flags.
  // The meaning of flags varies depending on the frame type.
  type http2Flags uint8
  
  // Has reports whether f contains all (0 or more) flags in v.
  func (f http2Flags) Has(v http2Flags) bool {
  	return (f & v) == v
  }
  
  // Frame-specific FrameHeader flag bits.
  const (
  	// Data Frame
  	http2FlagDataEndStream http2Flags = 0x1
  	http2FlagDataPadded    http2Flags = 0x8
  
  	// Headers Frame
  	http2FlagHeadersEndStream  http2Flags = 0x1
  	http2FlagHeadersEndHeaders http2Flags = 0x4
  	http2FlagHeadersPadded     http2Flags = 0x8
  	http2FlagHeadersPriority   http2Flags = 0x20
  
  	// Settings Frame
  	http2FlagSettingsAck http2Flags = 0x1
  
  	// Ping Frame
  	http2FlagPingAck http2Flags = 0x1
  
  	// Continuation Frame
  	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",
  	},
  }
  
  // a frameParser parses a frame given its FrameHeader and payload
  // bytes. The length of payload will always equal fh.Length (which
  // might be 0).
  type http2frameParser func(fc *http2frameCache, fh http2FrameHeader, 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
  }
  
  // A FrameHeader is the 9 byte header of all HTTP/2 frames.
  //
  // See http://http2.github.io/http2-spec/#FrameHeader
  type http2FrameHeader struct {
  	valid bool // caller can access []byte fields in the Frame
  
  	// Type is the 1 byte frame type. There are ten standard frame
  	// types, but extension frame types may be written by WriteRawFrame
  	// and will be returned by ReadFrame (as UnknownFrame).
  	Type http2FrameType
  
  	// Flags are the 1 byte of 8 potential bit flags per frame.
  	// They are specific to the frame type.
  	Flags http2Flags
  
  	// Length is the length of the frame, not including the 9 byte header.
  	// The maximum size is one byte less than 16MB (uint24), but only
  	// frames up to 16KB are allowed without peer agreement.
  	Length uint32
  
  	// StreamID is which stream this frame is for. Certain frames
  	// are not stream-specific, in which case this field is 0.
  	StreamID uint32
  }
  
  // Header returns h. It exists so FrameHeaders can be embedded in other
  // specific frame types and implement the Frame interface.
  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 }
  
  // frame header bytes.
  // Used only by ReadFrameHeader.
  var http2fhBytes = sync.Pool{
  	New: func() interface{} {
  		buf := make([]byte, http2frameHeaderLen)
  		return &buf
  	},
  }
  
  // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
  // Most users should use Framer.ReadFrame instead.
  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
  }
  
  // A Frame is the base interface implemented by all frame types.
  // Callers will generally type-assert the specific frame type:
  // *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
  //
  // Frames are only valid until the next call to Framer.ReadFrame.
  type http2Frame interface {
  	Header() http2FrameHeader
  
  	// invalidate is called by Framer.ReadFrame to make this
  	// frame's buffers as being invalid, since the subsequent
  	// frame will reuse them.
  	invalidate()
  }
  
  // A Framer reads and writes Frames.
  type http2Framer struct {
  	r         io.Reader
  	lastFrame http2Frame
  	errDetail error
  
  	// lastHeaderStream is non-zero if the last frame was an
  	// unfinished HEADERS/CONTINUATION.
  	lastHeaderStream uint32
  
  	maxReadSize uint32
  	headerBuf   [http2frameHeaderLen]byte
  
  	// TODO: let getReadBuf be configurable, and use a less memory-pinning
  	// allocator in server.go to minimize memory pinned for many idle conns.
  	// Will probably also need to make frame invalidation have a hook too.
  	getReadBuf func(size uint32) []byte
  	readBuf    []byte // cache for default getReadBuf
  
  	maxWriteSize uint32 // zero means unlimited; TODO: implement
  
  	w    io.Writer
  	wbuf []byte
  
  	// AllowIllegalWrites permits the Framer's Write methods to
  	// write frames that do not conform to the HTTP/2 spec. This
  	// permits using the Framer to test other HTTP/2
  	// implementations' conformance to the spec.
  	// If false, the Write methods will prefer to return an error
  	// rather than comply.
  	AllowIllegalWrites bool
  
  	// AllowIllegalReads permits the Framer's ReadFrame method
  	// to return non-compliant frames or frame orders.
  	// This is for testing and permits using the Framer to test
  	// other HTTP/2 implementations' conformance to the spec.
  	// It is not compatible with ReadMetaHeaders.
  	AllowIllegalReads bool
  
  	// ReadMetaHeaders if non-nil causes ReadFrame to merge
  	// HEADERS and CONTINUATION frames together and return
  	// MetaHeadersFrame instead.
  	ReadMetaHeaders *hpack.Decoder
  
  	// MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
  	// It's used only if ReadMetaHeaders is set; 0 means a sane default
  	// (currently 16MB)
  	// If the limit is hit, MetaHeadersFrame.Truncated is set true.
  	MaxHeaderListSize uint32
  
  	// TODO: track which type of frame & with which flags was sent
  	// last. Then return an error (unless AllowIllegalWrites) if
  	// we're in the middle of a header block and a
  	// non-Continuation or Continuation on a different stream is
  	// attempted to be written.
  
  	logReads, logWrites bool
  
  	debugFramer       *http2Framer // only use for logging written writes
  	debugFramerBuf    *bytes.Buffer
  	debugReadLoggerf  func(string, ...interface{})
  	debugWriteLoggerf func(string, ...interface{})
  
  	frameCache *http2frameCache // nil if frames aren't reused (default)
  }
  
  func (fr *http2Framer) maxHeaderListSize() uint32 {
  	if fr.MaxHeaderListSize == 0 {
  		return 16 << 20 // sane default, per docs
  	}
  	return fr.MaxHeaderListSize
  }
  
  func (f *http2Framer) startWrite(ftype http2FrameType, flags http2Flags, streamID uint32) {
  	// Write the FrameHeader.
  	f.wbuf = append(f.wbuf[:0],
  		0, // 3 bytes of length, filled in in endWrite
  		0,
  		0,
  		byte(ftype),
  		byte(flags),
  		byte(streamID>>24),
  		byte(streamID>>16),
  		byte(streamID>>8),
  		byte(streamID))
  }
  
  func (f *http2Framer) endWrite() error {
  	// Now that we know the final size, fill in the FrameHeader in
  	// the space previously reserved for it. Abuse append.
  	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 // we log it ourselves, saying "wrote" below
  		// Let us read anything, even if we accidentally wrote it
  		// in the wrong order:
  		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
  )
  
  // SetReuseFrames allows the Framer to reuse Frames.
  // If called on a Framer, Frames returned by calls to ReadFrame are only
  // valid until the next call to ReadFrame.
  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
  }
  
  // NewFramer returns a Framer that writes frames to w and reads them from r.
  func http2NewFramer(w io.Writer, r io.Reader) *http2Framer {
  	fr := &http2Framer{
  		w:                 w,
  		r:                 r,
  		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
  }
  
  // SetMaxReadFrameSize sets the maximum size of a frame
  // that will be read by a subsequent call to ReadFrame.
  // It is the caller's responsibility to advertise this
  // limit with a SETTINGS frame.
  func (fr *http2Framer) SetMaxReadFrameSize(v uint32) {
  	if v > http2maxFrameSize {
  		v = http2maxFrameSize
  	}
  	fr.maxReadSize = v
  }
  
  // ErrorDetail returns a more detailed error of the last error
  // returned by Framer.ReadFrame. For instance, if ReadFrame
  // returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
  // will say exactly what was invalid. ErrorDetail is not guaranteed
  // to return a non-nil value and like the rest of the http2 package,
  // its return value is not protected by an API compatibility promise.
  // ErrorDetail is reset after the next call to ReadFrame.
  func (fr *http2Framer) ErrorDetail() error {
  	return fr.errDetail
  }
  
  // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
  // sends a frame that is larger than declared with SetMaxReadFrameSize.
  var http2ErrFrameTooLarge = errors.New("http2: frame too large")
  
  // terminalReadFrameError reports whether err is an unrecoverable
  // error from ReadFrame and no other frames should be read.
  func http2terminalReadFrameError(err error) bool {
  	if _, ok := err.(http2StreamError); ok {
  		return false
  	}
  	return err != nil
  }
  
  // ReadFrame reads a single frame. The returned Frame is only valid
  // until the next call to ReadFrame.
  //
  // If the frame is larger than previously set with SetMaxReadFrameSize, the
  // returned error is ErrFrameTooLarge. Other errors may be of type
  // ConnectionError, StreamError, or anything else from the underlying
  // reader.
  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, 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
  }
  
  // connError returns ConnectionError(code) but first
  // stashes away a public reason to the caller can optionally relay it
  // to the peer before hanging up on them. This might help others debug
  // their implementations.
  func (fr *http2Framer) connError(code http2ErrCode, reason string) error {
  	fr.errDetail = errors.New(reason)
  	return http2ConnectionError(code)
  }
  
  // checkFrameOrder reports an error if f is an invalid frame to return
  // next from ReadFrame. Mostly it checks whether HEADERS and
  // CONTINUATION frames are contiguous.
  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
  }
  
  // A DataFrame conveys arbitrary, variable-length sequences of octets
  // associated with a stream.
  // See http://http2.github.io/http2-spec/#rfc.section.6.1
  type http2DataFrame struct {
  	http2FrameHeader
  	data []byte
  }
  
  func (f *http2DataFrame) StreamEnded() bool {
  	return f.http2FrameHeader.Flags.Has(http2FlagDataEndStream)
  }
  
  // Data returns the frame's data octets, not including any padding
  // size byte or padding suffix bytes.
  // The caller must not retain the returned memory past the next
  // call to ReadFrame.
  func (f *http2DataFrame) Data() []byte {
  	f.checkValid()
  	return f.data
  }
  
  func http2parseDataFrame(fc *http2frameCache, fh http2FrameHeader, payload []byte) (http2Frame, error) {
  	if fh.StreamID == 0 {
  		// DATA frames MUST be associated with a stream. If a
  		// DATA frame is received whose stream identifier
  		// field is 0x0, the recipient MUST respond with a
  		// connection error (Section 5.4.1) of type
  		// PROTOCOL_ERROR.
  		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 {
  			return nil, err
  		}
  	}
  	if int(padSize) > len(payload) {
  		// If the length of the padding is greater than the
  		// length of the frame payload, the recipient MUST
  		// treat this as a connection error.
  		// Filed: https://github.com/http2/http2-spec/issues/610
  		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
  }
  
  // WriteData writes a DATA frame.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility not to violate the maximum frame size
  // and to not call other Write methods concurrently.
  func (f *http2Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
  	return f.WriteDataPadded(streamID, endStream, data, nil)
  }
  
  // WriteData writes a DATA frame with optional padding.
  //
  // If pad is nil, the padding bit is not sent.
  // The length of pad must not exceed 255 bytes.
  // The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility not to violate the maximum frame size
  // and to not call other Write methods concurrently.
  func (f *http2Framer) WriteDataPadded(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 {
  					// "Padding octets MUST be set to zero when sending."
  					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 f.endWrite()
  }
  
  // A SettingsFrame conveys configuration parameters that affect how
  // endpoints communicate, such as preferences and constraints on peer
  // behavior.
  //
  // See http://http2.github.io/http2-spec/#SETTINGS
  type http2SettingsFrame struct {
  	http2FrameHeader
  	p []byte
  }
  
  func http2parseSettingsFrame(_ *http2frameCache, fh http2FrameHeader, p []byte) (http2Frame, error) {
  	if fh.Flags.Has(http2FlagSettingsAck) && fh.Length > 0 {
  		// When this (ACK 0x1) bit is set, the payload of the
  		// SETTINGS frame MUST be empty. Receipt of a
  		// SETTINGS frame with the ACK flag set and a length
  		// field value other than 0 MUST be treated as a
  		// connection error (Section 5.4.1) of type
  		// FRAME_SIZE_ERROR.
  		return nil, http2ConnectionError(http2ErrCodeFrameSize)
  	}
  	if fh.StreamID != 0 {
  		// SETTINGS frames always apply to a connection,
  		// never a single stream. The stream identifier for a
  		// SETTINGS frame MUST be zero (0x0).  If an endpoint
  		// receives a SETTINGS frame whose stream identifier
  		// field is anything other than 0x0, the endpoint MUST
  		// respond with a connection error (Section 5.4.1) of
  		// type PROTOCOL_ERROR.
  		return nil, http2ConnectionError(http2ErrCodeProtocol)
  	}
  	if len(p)%6 != 0 {
  		// Expecting even number of 6 byte settings.
  		return nil, http2ConnectionError(http2ErrCodeFrameSize)
  	}
  	f := &http2SettingsFrame{http2FrameHeader: fh, p: p}
  	if v, ok := f.Value(http2SettingInitialWindowSize); ok && v > (1<<31)-1 {
  		// Values above the maximum flow control window size of 2^31 - 1 MUST
  		// be treated as a connection error (Section 5.4.1) of type
  		// FLOW_CONTROL_ERROR.
  		return nil, http2ConnectionError(http2ErrCodeFlowControl)
  	}
  	return f, nil
  }
  
  func (f *http2SettingsFrame) IsAck() bool {
  	return f.http2FrameHeader.Flags.Has(http2FlagSettingsAck)
  }
  
  func (f *http2SettingsFrame) Value(s http2SettingID) (v uint32, ok bool) {
  	f.checkValid()
  	buf := f.p
  	for len(buf) > 0 {
  		settingID := http2SettingID(binary.BigEndian.Uint16(buf[:2]))
  		if settingID == s {
  			return binary.BigEndian.Uint32(buf[2:6]), true
  		}
  		buf = buf[6:]
  	}
  	return 0, false
  }
  
  // ForeachSetting runs fn for each setting.
  // It stops and returns the first error.
  func (f *http2SettingsFrame) ForeachSetting(fn func(http2Setting) error) error {
  	f.checkValid()
  	buf := f.p
  	for len(buf) > 0 {
  		if err := fn(http2Setting{
  			http2SettingID(binary.BigEndian.Uint16(buf[:2])),
  			binary.BigEndian.Uint32(buf[2:6]),
  		}); err != nil {
  			return err
  		}
  		buf = buf[6:]
  	}
  	return nil
  }
  
  // WriteSettings writes a SETTINGS frame with zero or more settings
  // specified and the ACK bit not set.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  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()
  }
  
  // WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  func (f *http2Framer) WriteSettingsAck() error {
  	f.startWrite(http2FrameSettings, http2FlagSettingsAck, 0)
  	return f.endWrite()
  }
  
  // A PingFrame is a mechanism for measuring a minimal round trip time
  // from the sender, as well as determining whether an idle connection
  // is still functional.
  // See http://http2.github.io/http2-spec/#rfc.section.6.7
  type http2PingFrame struct {
  	http2FrameHeader
  	Data [8]byte
  }
  
  func (f *http2PingFrame) IsAck() bool { return f.Flags.Has(http2FlagPingAck) }
  
  func http2parsePingFrame(_ *http2frameCache, fh http2FrameHeader, payload []byte) (http2Frame, error) {
  	if len(payload) != 8 {
  		return nil, http2ConnectionError(http2ErrCodeFrameSize)
  	}
  	if fh.StreamID != 0 {
  		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()
  }
  
  // A GoAwayFrame informs the remote peer to stop creating streams on this connection.
  // See http://http2.github.io/http2-spec/#rfc.section.6.8
  type http2GoAwayFrame struct {
  	http2FrameHeader
  	LastStreamID uint32
  	ErrCode      http2ErrCode
  	debugData    []byte
  }
  
  // DebugData returns any debug data in the GOAWAY frame. Its contents
  // are not defined.
  // The caller must not retain the returned memory past the next
  // call to ReadFrame.
  func (f *http2GoAwayFrame) DebugData() []byte {
  	f.checkValid()
  	return f.debugData
  }
  
  func http2parseGoAwayFrame(_ *http2frameCache, fh http2FrameHeader, p []byte) (http2Frame, error) {
  	if fh.StreamID != 0 {
  		return nil, http2ConnectionError(http2ErrCodeProtocol)
  	}
  	if len(p) < 8 {
  		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()
  }
  
  // An UnknownFrame is the frame type returned when the frame type is unknown
  // or no specific frame type parser exists.
  type http2UnknownFrame struct {
  	http2FrameHeader
  	p []byte
  }
  
  // Payload returns the frame's payload (after the header).  It is not
  // valid to call this method after a subsequent call to
  // Framer.ReadFrame, nor is it valid to retain the returned slice.
  // The memory is owned by the Framer and is invalidated when the next
  // frame is read.
  func (f *http2UnknownFrame) Payload() []byte {
  	f.checkValid()
  	return f.p
  }
  
  func http2parseUnknownFrame(_ *http2frameCache, fh http2FrameHeader, p []byte) (http2Frame, error) {
  	return &http2UnknownFrame{fh, p}, nil
  }
  
  // A WindowUpdateFrame is used to implement flow control.
  // See http://http2.github.io/http2-spec/#rfc.section.6.9
  type http2WindowUpdateFrame struct {
  	http2FrameHeader
  	Increment uint32 // never read with high bit set
  }
  
  func http2parseWindowUpdateFrame(_ *http2frameCache, fh http2FrameHeader, p []byte) (http2Frame, error) {
  	if len(p) != 4 {
  		return nil, http2ConnectionError(http2ErrCodeFrameSize)
  	}
  	inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
  	if inc == 0 {
  		// A receiver MUST treat the receipt of a
  		// WINDOW_UPDATE frame with an flow control window
  		// increment of 0 as a stream error (Section 5.4.2) of
  		// type PROTOCOL_ERROR; errors on the connection flow
  		// control window MUST be treated as a connection
  		// error (Section 5.4.1).
  		if fh.StreamID == 0 {
  			return nil, http2ConnectionError(http2ErrCodeProtocol)
  		}
  		return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
  	}
  	return &http2WindowUpdateFrame{
  		http2FrameHeader: fh,
  		Increment:        inc,
  	}, nil
  }
  
  // WriteWindowUpdate writes a WINDOW_UPDATE frame.
  // The increment value must be between 1 and 2,147,483,647, inclusive.
  // If the Stream ID is zero, the window update applies to the
  // connection as a whole.
  func (f *http2Framer) WriteWindowUpdate(streamID, incr uint32) error {
  	// "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
  	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()
  }
  
  // A HeadersFrame is used to open a stream and additionally carries a
  // header block fragment.
  type http2HeadersFrame struct {
  	http2FrameHeader
  
  	// Priority is set if FlagHeadersPriority is set in the FrameHeader.
  	Priority http2PriorityParam
  
  	headerFragBuf []byte // not owned
  }
  
  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, p []byte) (_ http2Frame, err error) {
  	hf := &http2HeadersFrame{
  		http2FrameHeader: fh,
  	}
  	if fh.StreamID == 0 {
  		// HEADERS frames MUST be associated with a stream. If a HEADERS frame
  		// is received whose stream identifier field is 0x0, the recipient MUST
  		// respond with a connection error (Section 5.4.1) of type
  		// PROTOCOL_ERROR.
  		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 {
  			return
  		}
  	}
  	if fh.Flags.Has(http2FlagHeadersPriority) {
  		var v uint32
  		p, v, err = http2readUint32(p)
  		if err != nil {
  			return nil, err
  		}
  		hf.Priority.StreamDep = v & 0x7fffffff
  		hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
  		p, hf.Priority.Weight, err = http2readByte(p)
  		if err != nil {
  			return nil, err
  		}
  	}
  	if len(p)-int(padLength) <= 0 {
  		return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
  	}
  	hf.headerFragBuf = p[:len(p)-int(padLength)]
  	return hf, nil
  }
  
  // HeadersFrameParam are the parameters for writing a HEADERS frame.
  type http2HeadersFrameParam struct {
  	// StreamID is the required Stream ID to initiate.
  	StreamID uint32
  	// BlockFragment is part (or all) of a Header Block.
  	BlockFragment []byte
  
  	// EndStream indicates that the header block is the last that
  	// the endpoint will send for the identified stream. Setting
  	// this flag causes the stream to enter one of "half closed"
  	// states.
  	EndStream bool
  
  	// EndHeaders indicates that this frame contains an entire
  	// header block and is not followed by any
  	// CONTINUATION frames.
  	EndHeaders bool
  
  	// PadLength is the optional number of bytes of zeros to add
  	// to this frame.
  	PadLength uint8
  
  	// Priority, if non-zero, includes stream priority information
  	// in the HEADER frame.
  	Priority http2PriorityParam
  }
  
  // WriteHeaders writes a single HEADERS frame.
  //
  // This is a low-level header writing method. Encoding headers and
  // splitting them into any necessary CONTINUATION frames is handled
  // elsewhere.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  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()
  }
  
  // A PriorityFrame specifies the sender-advised priority of a stream.
  // See http://http2.github.io/http2-spec/#rfc.section.6.3
  type http2PriorityFrame struct {
  	http2FrameHeader
  	http2PriorityParam
  }
  
  // PriorityParam are the stream prioritzation parameters.
  type http2PriorityParam struct {
  	// StreamDep is a 31-bit stream identifier for the
  	// stream that this stream depends on. Zero means no
  	// dependency.
  	StreamDep uint32
  
  	// Exclusive is whether the dependency is exclusive.
  	Exclusive bool
  
  	// Weight is the stream's zero-indexed weight. It should be
  	// set together with StreamDep, or neither should be set. Per
  	// the spec, "Add one to the value to obtain a weight between
  	// 1 and 256."
  	Weight uint8
  }
  
  func (p http2PriorityParam) IsZero() bool {
  	return p == http2PriorityParam{}
  }
  
  func http2parsePriorityFrame(_ *http2frameCache, fh http2FrameHeader, payload []byte) (http2Frame, error) {
  	if fh.StreamID == 0 {
  		return nil, http2connError{http2ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
  	}
  	if len(payload) != 5 {
  		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 // mask off high bit
  	return &http2PriorityFrame{
  		http2FrameHeader: fh,
  		http2PriorityParam: http2PriorityParam{
  			Weight:    payload[4],
  			StreamDep: streamID,
  			Exclusive: streamID != v, // was high bit set?
  		},
  	}, nil
  }
  
  // WritePriority writes a PRIORITY frame.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  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()
  }
  
  // A RSTStreamFrame allows for abnormal termination of a stream.
  // See http://http2.github.io/http2-spec/#rfc.section.6.4
  type http2RSTStreamFrame struct {
  	http2FrameHeader
  	ErrCode http2ErrCode
  }
  
  func http2parseRSTStreamFrame(_ *http2frameCache, fh http2FrameHeader, p []byte) (http2Frame, error) {
  	if len(p) != 4 {
  		return nil, http2ConnectionError(http2ErrCodeFrameSize)
  	}
  	if fh.StreamID == 0 {
  		return nil, http2ConnectionError(http2ErrCodeProtocol)
  	}
  	return &http2RSTStreamFrame{fh, http2ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
  }
  
  // WriteRSTStream writes a RST_STREAM frame.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  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()
  }
  
  // A ContinuationFrame is used to continue a sequence of header block fragments.
  // See http://http2.github.io/http2-spec/#rfc.section.6.10
  type http2ContinuationFrame struct {
  	http2FrameHeader
  	headerFragBuf []byte
  }
  
  func http2parseContinuationFrame(_ *http2frameCache, fh http2FrameHeader, p []byte) (http2Frame, error) {
  	if fh.StreamID == 0 {
  		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)
  }
  
  // WriteContinuation writes a CONTINUATION frame.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  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()
  }
  
  // A PushPromiseFrame is used to initiate a server stream.
  // See http://http2.github.io/http2-spec/#rfc.section.6.6
  type http2PushPromiseFrame struct {
  	http2FrameHeader
  	PromiseID     uint32
  	headerFragBuf []byte // not owned
  }
  
  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, p []byte) (_ http2Frame, err error) {
  	pp := &http2PushPromiseFrame{
  		http2FrameHeader: fh,
  	}
  	if pp.StreamID == 0 {
  		// PUSH_PROMISE frames MUST be associated with an existing,
  		// peer-initiated stream. The stream identifier of a
  		// PUSH_PROMISE frame indicates the stream it is associated
  		// with. If the stream identifier field specifies the value
  		// 0x0, a recipient MUST respond with a connection error
  		// (Section 5.4.1) of type PROTOCOL_ERROR.
  		return nil, http2ConnectionError(http2ErrCodeProtocol)
  	}
  	// The PUSH_PROMISE frame includes optional padding.
  	// Padding fields and flags are identical to those defined for DATA frames
  	var padLength uint8
  	if fh.Flags.Has(http2FlagPushPromisePadded) {
  		if p, padLength, err = http2readByte(p); err != nil {
  			return
  		}
  	}
  
  	p, pp.PromiseID, err = http2readUint32(p)
  	if err != nil {
  		return
  	}
  	pp.PromiseID = pp.PromiseID & (1<<31 - 1)
  
  	if int(padLength) > len(p) {
  		// like the DATA frame, error out if padding is longer than the body.
  		return nil, http2ConnectionError(http2ErrCodeProtocol)
  	}
  	pp.headerFragBuf = p[:len(p)-int(padLength)]
  	return pp, nil
  }
  
  // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
  type http2PushPromiseParam struct {
  	// StreamID is the required Stream ID to initiate.
  	StreamID uint32
  
  	// PromiseID is the required Stream ID which this
  	// Push Promises
  	PromiseID uint32
  
  	// BlockFragment is part (or all) of a Header Block.
  	BlockFragment []byte
  
  	// EndHeaders indicates that this frame contains an entire
  	// header block and is not followed by any
  	// CONTINUATION frames.
  	EndHeaders bool
  
  	// PadLength is the optional number of bytes of zeros to add
  	// to this frame.
  	PadLength uint8
  }
  
  // WritePushPromise writes a single PushPromise Frame.
  //
  // As with Header Frames, This is the low level call for writing
  // individual frames. Continuation frames are handled elsewhere.
  //
  // It will perform exactly one Write to the underlying Writer.
  // It is the caller's responsibility to not call other Write methods concurrently.
  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()
  }
  
  // WriteRawFrame writes a raw frame. This can be used to write
  // extension frames unknown to this package.
  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
  }
  
  // A MetaHeadersFrame is the representation of one HEADERS frame and
  // zero or more contiguous CONTINUATION frames and the decoding of
  // their HPACK-encoded contents.
  //
  // This type of frame does not appear on the wire and is only returned
  // by the Framer when Framer.ReadMetaHeaders is set.
  type http2MetaHeadersFrame struct {
  	*http2HeadersFrame
  
  	// Fields are the fields contained in the HEADERS and
  	// CONTINUATION frames. The underlying slice is owned by the
  	// Framer and must not be retained after the next call to
  	// ReadFrame.
  	//
  	// Fields are guaranteed to be in the correct http2 order and
  	// not have unknown pseudo header fields or invalid header
  	// field names or values. Required pseudo header fields may be
  	// missing, however. Use the MetaHeadersFrame.Pseudo accessor
  	// method access pseudo headers.
  	Fields []hpack.HeaderField
  
  	// Truncated is whether the max header list size limit was hit
  	// and Fields is incomplete. The hpack decoder state is still
  	// valid, however.
  	Truncated bool
  }
  
  // PseudoValue returns the given pseudo header field's value.
  // The provided pseudo field should not contain the leading colon.
  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 ""
  }
  
  // RegularFields returns the regular (non-pseudo) header fields of mh.
  // The caller does not own the returned slice.
  func (mh *http2MetaHeadersFrame) RegularFields() []hpack.HeaderField {
  	for i, hf := range mh.Fields {
  		if !hf.IsPseudo() {
  			return mh.Fields[i:]
  		}
  	}
  	return nil
  }
  
  // PseudoFields returns the pseudo header fields of mh.
  // The caller does not own the returned slice.
  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)
  		}
  		// Check for duplicates.
  		// This would be a bad algorithm, but N is 4.
  		// And this doesn't allocate.
  		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)
  	}
  	// They had a crazy big number for MaxHeaderBytes anyway,
  	// so give them unlimited header lengths:
  	return 0
  }
  
  // readMetaFrame returns 0 or more CONTINUATION frames from fr and
  // merge them into into the provided hf and returns a MetaHeadersFrame
  // with the decoded hpack values.
  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 // pseudo header field errors
  	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 !httplex.ValidHeaderFieldValue(hf.Value) {
  			invalid = http2headerFieldValueError(hf.Value)
  		}
  		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)
  	})
  	// Lose reference to MetaHeadersFrame:
  	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) // guaranteed by checkFrameOrder
  		}
  	}
  
  	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) // remove trailing comma
  		}
  	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 http2transportExpectContinueTimeout(t1 *Transport) time.Duration {
  	return t1.ExpectContinueTimeout
  }
  
  type http2contextContext interface {
  	context.Context
  }
  
  func http2serverConnBaseContext(c net.Conn, opts *http2ServeConnOpts) (ctx http2contextContext, cancel func()) {
  	ctx, cancel = context.WithCancel(context.Background())
  	ctx = context.WithValue(ctx, LocalAddrContextKey, c.LocalAddr())
  	if hs := opts.baseConfig(); hs != nil {
  		ctx = context.WithValue(ctx, ServerContextKey, hs)
  	}
  	return
  }
  
  func http2contextWithCancel(ctx http2contextContext) (_ http2contextContext, cancel func()) {
  	return context.WithCancel(ctx)
  }
  
  func http2requestWithContext(req *Request, ctx http2contextContext) *Request {
  	return req.WithContext(ctx)
  }
  
  type http2clientTrace httptrace.ClientTrace
  
  func http2reqContext(r *Request) context.Context { return r.Context() }
  
  func (t *http2Transport) idleConnTimeout() time.Duration {
  	if t.t1 != nil {
  		return t.t1.IdleConnTimeout
  	}
  	return 0
  }
  
  func http2setResponseUncompressed(res *Response) { res.Uncompressed = true }
  
  func http2traceGotConn(req *Request, cc *http2ClientConn) {
  	trace := httptrace.ContextClientTrace(req.Context())
  	if trace == nil || trace.GotConn == nil {
  		return
  	}
  	ci := httptrace.GotConnInfo{Conn: cc.tconn}
  	cc.mu.Lock()
  	ci.Reused = cc.nextStreamID > 1
  	ci.WasIdle = len(cc.streams) == 0 && ci.Reused
  	if ci.WasIdle && !cc.lastActive.IsZero() {
  		ci.IdleTime = time.Now().Sub(cc.lastActive)
  	}
  	cc.mu.Unlock()
  
  	trace.GotConn(ci)
  }
  
  func http2traceWroteHeaders(trace *http2clientTrace) {
  	if trace != nil && trace.WroteHeaders != nil {
  		trace.WroteHeaders()
  	}
  }
  
  func http2traceGot100Continue(trace *http2clientTrace) {
  	if trace != nil && trace.Got100Continue != nil {
  		trace.Got100Continue()
  	}
  }
  
  func http2traceWait100Continue(trace *http2clientTrace) {
  	if trace != nil && trace.Wait100Continue != nil {
  		trace.Wait100Continue()
  	}
  }
  
  func http2traceWroteRequest(trace *http2clientTrace, err error) {
  	if trace != nil && trace.WroteRequest != nil {
  		trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
  	}
  }
  
  func http2traceFirstResponseByte(trace *http2clientTrace) {
  	if trace != nil && trace.GotFirstResponseByte != nil {
  		trace.GotFirstResponseByte()
  	}
  }
  
  func http2requestTrace(req *Request) *http2clientTrace {
  	trace := httptrace.ContextClientTrace(req.Context())
  	return (*http2clientTrace)(trace)
  }
  
  // Ping sends a PING frame to the server and waits for the ack.
  func (cc *http2ClientConn) Ping(ctx context.Context) error {
  	return cc.ping(ctx)
  }
  
  func http2cloneTLSConfig(c *tls.Config) *tls.Config {
  	c2 := c.Clone()
  	c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264
  	return c2
  }
  
  var _ Pusher = (*http2responseWriter)(nil)
  
  // Push implements http.Pusher.
  func (w *http2responseWriter) Push(target string, opts *PushOptions) error {
  	internalOpts := http2pushOptions{}
  	if opts != nil {
  		internalOpts.Method = opts.Method
  		internalOpts.Header = opts.Header
  	}
  	return w.push(target, internalOpts)
  }
  
  func http2configureServer18(h1 *Server, h2 *http2Server) error {
  	if h2.IdleTimeout == 0 {
  		if h1.IdleTimeout != 0 {
  			h2.IdleTimeout = h1.IdleTimeout
  		} else {
  			h2.IdleTimeout = h1.ReadTimeout
  		}
  	}
  	return nil
  }
  
  func http2shouldLogPanic(panicValue interface{}) bool {
  	return panicValue != nil && panicValue != ErrAbortHandler
  }
  
  func http2reqGetBody(req *Request) func() (io.ReadCloser, error) {
  	return req.GetBody
  }
  
  func http2reqBodyIsNoBody(body io.ReadCloser) bool {
  	return body == NoBody
  }
  
  func http2go18httpNoBody() io.ReadCloser { return NoBody } // for tests only
  
  func http2configureServer19(s *Server, conf *http2Server) error {
  	s.RegisterOnShutdown(conf.state.startGracefulShutdown)
  	return nil
  }
  
  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)]
  	// Parse the 4707 out of "goroutine 4707 ["
  	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
  	},
  }
  
  // parseUintBytes is like strconv.ParseUint, but using a []byte.
  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:
  		// valid base; nothing to do
  
  	case base == 0:
  		// Look for octal, hex prefix.
  		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*base overflows
  			n = 1<<64 - 1
  			err = strconv.ErrRange
  			goto Error
  		}
  		n *= uint64(base)
  
  		n1 := n + uint64(v)
  		if n1 < n || n1 > maxVal {
  			// n+v overflows
  			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}
  }
  
  // Return the first number n such that n*base >= 1<<64.
  func http2cutoff64(base int) uint64 {
  	if base < 2 {
  		return 0
  	}
  	return (1<<64-1)/uint64(base) + 1
  }
  
  var (
  	http2commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
  	http2commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
  )
  
  func init() {
  	for _, v := range []string{
  		"accept",
  		"accept-charset",
  		"accept-encoding",
  		"accept-language",
  		"accept-ranges",
  		"age",
  		"access-control-allow-origin",
  		"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",
  		"proxy-authenticate",
  		"proxy-authorization",
  		"range",
  		"referer",
  		"refresh",
  		"retry-after",
  		"server",
  		"set-cookie",
  		"strict-transport-security",
  		"trailer",
  		"transfer-encoding",
  		"user-agent",
  		"vary",
  		"via",
  		"www-authenticate",
  	} {
  		chk := CanonicalHeaderKey(v)
  		http2commonLowerHeader[chk] = v
  		http2commonCanonHeader[v] = chk
  	}
  }
  
  func http2lowerHeader(v string) string {
  	if s, ok := http2commonLowerHeader[v]; ok {
  		return s
  	}
  	return strings.ToLower(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 (
  	// ClientPreface is the string that must be sent by new
  	// connections from clients.
  	http2ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
  
  	// SETTINGS_MAX_FRAME_SIZE default
  	// http://http2.github.io/http2-spec/#rfc.section.6.5.2
  	http2initialMaxFrameSize = 16384
  
  	// NextProtoTLS is the NPN/ALPN protocol negotiated during
  	// HTTP/2's TLS setup.
  	http2NextProtoTLS = "h2"
  
  	// http://http2.github.io/http2-spec/#SettingValues
  	http2initialHeaderTableSize = 4096
  
  	http2initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
  
  	http2defaultMaxReadFrameSize = 1 << 20
  )
  
  var (
  	http2clientPreface = []byte(http2ClientPreface)
  )
  
  type http2streamState int
  
  // HTTP/2 stream states.
  //
  // See http://tools.ietf.org/html/rfc7540#section-5.1.
  //
  // For simplicity, the server code merges "reserved (local)" into
  // "half-closed (remote)". This is one less state transition to track.
  // The only downside is that we send PUSH_PROMISEs slightly less
  // liberally than allowable. More discussion here:
  // https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
  //
  // "reserved (remote)" is omitted since the client code does not
  // support server push.
  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]
  }
  
  // Setting is a setting parameter: which setting it is, and its value.
  type http2Setting struct {
  	// ID is which setting is being set.
  	// See http://http2.github.io/http2-spec/#SettingValues
  	ID http2SettingID
  
  	// Val is the value.
  	Val uint32
  }
  
  func (s http2Setting) String() string {
  	return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
  }
  
  // Valid reports whether the setting is valid.
  func (s http2Setting) Valid() error {
  	// Limits and error codes from 6.5.2 Defined SETTINGS Parameters
  	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
  }
  
  // A SettingID is an HTTP/2 setting as defined in
  // http://http2.github.io/http2-spec/#iana-settings
  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))
  }
  
  var (
  	http2errInvalidHeaderFieldName  = errors.New("http2: invalid header field name")
  	http2errInvalidHeaderFieldValue = errors.New("http2: invalid header field value")
  )
  
  // validWireHeaderFieldName reports whether v is a valid header field
  // name (key). See httplex.ValidHeaderName for the base rules.
  //
  // Further, http2 says:
  //   "Just as in HTTP/1.x, header field names are strings of ASCII
  //   characters that are compared in a case-insensitive
  //   fashion. However, header field names MUST be converted to
  //   lowercase prior to their encoding in HTTP/2. "
  func http2validWireHeaderFieldName(v string) bool {
  	if len(v) == 0 {
  		return false
  	}
  	for _, r := range v {
  		if !httplex.IsTokenRune(r) {
  			return false
  		}
  		if 'A' <= r && r <= 'Z' {
  			return false
  		}
  	}
  	return true
  }
  
  var http2httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
  
  func init() {
  	for i := 100; i <= 999; i++ {
  		if v := StatusText(i); v != "" {
  			http2httpCodeStringCommon[i] = strconv.Itoa(i)
  		}
  	}
  }
  
  func http2httpCodeString(code int) string {
  	if s, ok := http2httpCodeStringCommon[code]; ok {
  		return s
  	}
  	return strconv.Itoa(code)
  }
  
  // from pkg io
  type http2stringWriter interface {
  	WriteString(s string) (n int, err error)
  }
  
  // A gate lets two goroutines coordinate their activities.
  type http2gate chan struct{}
  
  func (g http2gate) Done() { g <- struct{}{} }
  
  func (g http2gate) Wait() { <-g }
  
  // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
  type http2closeWaiter chan struct{}
  
  // Init makes a closeWaiter usable.
  // It exists because so a closeWaiter value can be placed inside a
  // larger struct and have the Mutex and Cond's memory in the same
  // allocation.
  func (cw *http2closeWaiter) Init() {
  	*cw = make(chan struct{})
  }
  
  // Close marks the closeWaiter as closed and unblocks any waiters.
  func (cw http2closeWaiter) Close() {
  	close(cw)
  }
  
  // Wait waits for the closeWaiter to become closed.
  func (cw http2closeWaiter) Wait() {
  	<-cw
  }
  
  // bufferedWriter is a buffered writer that writes to w.
  // Its buffered writer is lazily allocated as needed, to minimize
  // idle memory usage with many connections.
  type http2bufferedWriter struct {
  	w  io.Writer     // immutable
  	bw *bufio.Writer // non-nil when data is buffered
  }
  
  func http2newBufferedWriter(w io.Writer) *http2bufferedWriter {
  	return &http2bufferedWriter{w: w}
  }
  
  // bufWriterPoolBufferSize is the size of bufio.Writer's
  // buffers created using bufWriterPool.
  //
  // TODO: pick a less arbitrary value? this is a bit under
  // (3 x typical 1500 byte MTU) at least. Other than that,
  // not much thought went into it.
  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)
  }
  
  // bodyAllowedForStatus reports whether a given response status code
  // permits a body. See RFC 2616, section 4.4.
  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 {
  	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 // owned by sorter
  }
  
  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] }
  
  // Keys returns the sorted keys of h.
  //
  // The returned slice is only valid until s used again or returned to
  // its pool.
  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) {
  	// Our sorter works on s.v, which sorter owns, so
  	// stash it away while we sort the user's buffer.
  	save := s.v
  	s.v = ss
  	sort.Sort(s)
  	s.v = save
  }
  
  // validPseudoPath reports whether v is a valid :path pseudo-header
  // value. It must be either:
  //
  //     *) a non-empty string starting with '/'
  //     *) the string '*', for OPTIONS requests.
  //
  // For now this is only used a quick check for deciding when to clean
  // up Opaque URLs before sending requests from the Transport.
  // See golang.org/issue/16847
  //
  // We used to enforce that the path also didn't start with "//", but
  // Google's GFE accepts such paths and Chrome sends them, so ignore
  // that part of the spec. See golang.org/issue/19103.
  func http2validPseudoPath(v string) bool {
  	return (len(v) > 0 && v[0] == '/') || v == "*"
  }
  
  // pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
  // io.Pipe except there are no PipeReader/PipeWriter halves, and the
  // underlying buffer is an interface. (io.Pipe is always unbuffered)
  type http2pipe struct {
  	mu       sync.Mutex
  	c        sync.Cond       // c.L lazily initialized to &p.mu
  	b        http2pipeBuffer // nil when done reading
  	err      error           // read error once empty. non-nil means closed.
  	breakErr error           // immediate read error (caller doesn't see rest of b)
  	donec    chan struct{}   // closed on error
  	readFn   func()          // optional code to run in Read before error
  }
  
  type http2pipeBuffer interface {
  	Len() int
  	io.Writer
  	io.Reader
  }
  
  func (p *http2pipe) Len() int {
  	p.mu.Lock()
  	defer p.mu.Unlock()
  	if p.b == nil {
  		return 0
  	}
  	return p.b.Len()
  }
  
  // Read waits until data is available and copies bytes
  // from the buffer into p.
  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()     // e.g. copy trailers
  				p.readFn = nil // not sticky like p.err
  			}
  			p.b = nil
  			return 0, p.err
  		}
  		p.c.Wait()
  	}
  }
  
  var http2errClosedPipeWrite = errors.New("write on closed buffer")
  
  // Write copies bytes from p into the buffer and wakes a reader.
  // It is an error to write more data than the buffer can hold.
  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 {
  		return 0, http2errClosedPipeWrite
  	}
  	if p.breakErr != nil {
  		return len(d), nil // discard when there is no reader
  	}
  	return p.b.Write(d)
  }
  
  // CloseWithError causes the next Read (waking up a current blocked
  // Read if needed) to return the provided err after all data has been
  // read.
  //
  // The error must be non-nil.
  func (p *http2pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
  
  // BreakWithError causes the next Read (waking up a current blocked
  // Read if needed) to return the provided err immediately, without
  // waiting for unread data.
  func (p *http2pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
  
  // closeWithErrorAndCode is like CloseWithError but also sets some code to run
  // in the caller's goroutine before returning the error.
  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 {
  		// Already been done.
  		return
  	}
  	p.readFn = fn
  	if dst == &p.breakErr {
  		p.b = nil
  	}
  	*dst = err
  	p.closeDoneLocked()
  }
  
  // requires p.mu be held.
  func (p *http2pipe) closeDoneLocked() {
  	if p.donec == nil {
  		return
  	}
  	// Close if unclosed. This isn't racy since we always
  	// hold p.mu while closing.
  	select {
  	case <-p.donec:
  	default:
  		close(p.donec)
  	}
  }
  
  // Err returns the error (if any) first set by BreakWithError or CloseWithError.
  func (p *http2pipe) Err() error {
  	p.mu.Lock()
  	defer p.mu.Unlock()
  	if p.breakErr != nil {
  		return p.breakErr
  	}
  	return p.err
  }
  
  // Done returns a channel which is closed if and when this pipe is closed
  // with CloseWithError.
  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 {
  			// Already hit an error.
  			p.closeDoneLocked()
  		}
  	}
  	return p.donec
  }
  
  const (
  	http2prefaceTimeout        = 10 * time.Second
  	http2firstSettingsTimeout  = 2 * time.Second // should be in-flight with preface anyway
  	http2handlerChunkWriteSize = 4 << 10
  	http2defaultMaxStreams     = 250 // TODO: make this 100 as the GFE seems to?
  )
  
  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
  	},
  }
  
  // Test hooks.
  var (
  	http2testHookOnConn        func()
  	http2testHookGetServerConn func(*http2serverConn)
  	http2testHookOnPanicMu     *sync.Mutex // nil except in tests
  	http2testHookOnPanic       func(sc *http2serverConn, panicVal interface{}) (rePanic bool)
  )
  
  // Server is an HTTP/2 server.
  type http2Server struct {
  	// MaxHandlers limits the number of http.Handler ServeHTTP goroutines
  	// which may run at a time over all connections.
  	// Negative or zero no limit.
  	// TODO: implement
  	MaxHandlers int
  
  	// MaxConcurrentStreams optionally specifies the number of
  	// concurrent streams that each client may have open at a
  	// time. This is unrelated to the number of http.Handler goroutines
  	// which may be active globally, which is MaxHandlers.
  	// If zero, MaxConcurrentStreams defaults to at least 100, per
  	// the HTTP/2 spec's recommendations.
  	MaxConcurrentStreams uint32
  
  	// MaxReadFrameSize optionally specifies the largest frame
  	// this server is willing to read. A valid value is between
  	// 16k and 16M, inclusive. If zero or otherwise invalid, a
  	// default value is used.
  	MaxReadFrameSize uint32
  
  	// PermitProhibitedCipherSuites, if true, permits the use of
  	// cipher suites prohibited by the HTTP/2 spec.
  	PermitProhibitedCipherSuites bool
  
  	// IdleTimeout specifies how long until idle clients should be
  	// closed with a GOAWAY frame. PING frames are not considered
  	// activity for the purposes of IdleTimeout.
  	IdleTimeout time.Duration
  
  	// MaxUploadBufferPerConnection is the size of the initial flow
  	// control window for each connections. The HTTP/2 spec does not
  	// allow this to be smaller than 65535 or larger than 2^32-1.
  	// If the value is outside this range, a default value will be
  	// used instead.
  	MaxUploadBufferPerConnection int32
  
  	// MaxUploadBufferPerStream is the size of the initial flow control
  	// window for each stream. The HTTP/2 spec does not allow this to
  	// be larger than 2^32-1. If the value is zero or larger than the
  	// maximum, a default value will be used instead.
  	MaxUploadBufferPerStream int32
  
  	// NewWriteScheduler constructs a write scheduler for a connection.
  	// If nil, a default scheduler is chosen.
  	NewWriteScheduler func() http2WriteScheduler
  
  	// Internal state. This is a pointer (rather than embedded directly)
  	// so that we don't embed a Mutex in this struct, which will make the
  	// struct non-copyable, which might break some callers.
  	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
  }
  
  type http2serverInternalState struct {
  	mu          sync.Mutex
  	activeConns map[*http2serverConn]struct{}
  }
  
  func (s *http2serverInternalState) registerConn(sc *http2serverConn) {
  	if s == nil {
  		return // if the Server was used without calling ConfigureServer
  	}
  	s.mu.Lock()
  	s.activeConns[sc] = struct{}{}
  	s.mu.Unlock()
  }
  
  func (s *http2serverInternalState) unregisterConn(sc *http2serverConn) {
  	if s == nil {
  		return // if the Server was used without calling ConfigureServer
  	}
  	s.mu.Lock()
  	delete(s.activeConns, sc)
  	s.mu.Unlock()
  }
  
  func (s *http2serverInternalState) startGracefulShutdown() {
  	if s == nil {
  		return // if the Server was used without calling ConfigureServer
  	}
  	s.mu.Lock()
  	for sc := range s.activeConns {
  		sc.startGracefulShutdown()
  	}
  	s.mu.Unlock()
  }
  
  // ConfigureServer adds HTTP/2 support to a net/http Server.
  //
  // The configuration conf may be nil.
  //
  // ConfigureServer must be called before s begins serving.
  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 err := http2configureServer18(s, conf); err != nil {
  		return err
  	}
  	if err := http2configureServer19(s, conf); err != nil {
  		return err
  	}
  
  	if s.TLSConfig == nil {
  		s.TLSConfig = new(tls.Config)
  	} else if s.TLSConfig.CipherSuites != nil {
  		// If they already provided a CipherSuite list, return
  		// an error if it has a bad order or is missing
  		// ECDHE_RSA_WITH_AES_128_GCM_SHA256.
  		const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  		haveRequired := false
  		sawBad := false
  		for i, cs := range s.TLSConfig.CipherSuites {
  			if cs == requiredCipher {
  				haveRequired = true
  			}
  			if http2isBadCipher(cs) {
  				sawBad = true
  			} else if sawBad {
  				return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
  			}
  		}
  		if !haveRequired {
  			return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
  		}
  	}
  
  	// Note: not setting MinVersion to tls.VersionTLS12,
  	// as we don't want to interfere with HTTP/1.1 traffic
  	// on the user's server. We enforce TLS 1.2 later once
  	// we accept a connection. Ideally this should be done
  	// during next-proto selection, but using TLS <1.2 with
  	// HTTP/2 is still the client's bug.
  
  	s.TLSConfig.PreferServerCipherSuites = true
  
  	haveNPN := false
  	for _, p := range s.TLSConfig.NextProtos {
  		if p == http2NextProtoTLS {
  			haveNPN = true
  			break
  		}
  	}
  	if !haveNPN {
  		s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, http2NextProtoTLS)
  	}
  
  	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()
  		}
  		conf.ServeConn(c, &http2ServeConnOpts{
  			Handler:    h,
  			BaseConfig: hs,
  		})
  	}
  	s.TLSNextProto[http2NextProtoTLS] = protoHandler
  	return nil
  }
  
  // ServeConnOpts are options for the Server.ServeConn method.
  type http2ServeConnOpts struct {
  	// BaseConfig optionally sets the base configuration
  	// for values. If nil, defaults are used.
  	BaseConfig *Server
  
  	// Handler specifies which handler to use for processing
  	// requests. If nil, BaseConfig.Handler is used. If BaseConfig
  	// or BaseConfig.Handler is nil, http.DefaultServeMux is used.
  	Handler Handler
  }
  
  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
  }
  
  // ServeConn serves HTTP/2 requests on the provided connection and
  // blocks until the connection is no longer readable.
  //
  // ServeConn starts speaking HTTP/2 assuming that c has not had any
  // reads or writes. It writes its initial settings frame and expects
  // to be able to read the preface and settings frame from the
  // client. If c has a ConnectionState method like a *tls.Conn, the
  // ConnectionState is used to verify the TLS ciphersuite and to set
  // the Request.TLS field in Handlers.
  //
  // ServeConn does not support h2c by itself. Any h2c support must be
  // implemented in terms of providing a suitably-behaving net.Conn.
  //
  // The opts parameter is optional. If nil, default values are used.
  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), // buffered; one send in writeFrameAsync
  		bodyReadCh:                  make(chan http2bodyReadMsg),         // buffering doesn't matter either way
  		doneServing:                 make(chan struct{}),
  		clientMaxStreams:            math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
  		advMaxStreams:               s.maxConcurrentStreams(),
  		initialStreamSendWindowSize: http2initialWindowSize,
  		maxFrameSize:                http2initialMaxFrameSize,
  		headerTableSize:             http2initialHeaderTableSize,
  		serveG:                      http2newGoroutineLock(),
  		pushEnabled:                 true,
  	}
  
  	s.state.registerConn(sc)
  	defer s.state.unregisterConn(sc)
  
  	// The net/http package sets the write deadline from the
  	// http.Server.WriteTimeout during the TLS handshake, but then
  	// passes the connection off to us with the deadline already set.
  	// Write deadlines are set per stream in serverConn.newStream.
  	// Disarm the net.Conn write deadline here.
  	if sc.hs.WriteTimeout != 0 {
  		sc.conn.SetWriteDeadline(time.Time{})
  	}
  
  	if s.NewWriteScheduler != nil {
  		sc.writeSched = s.NewWriteScheduler()
  	} else {
  		sc.writeSched = http2NewRandomWriteScheduler()
  	}
  
  	// These start at the RFC-specified defaults. If there is a higher
  	// configured value for inflow, that will be updated when we send a
  	// WINDOW_UPDATE shortly after sending SETTINGS.
  	sc.flow.add(http2initialWindowSize)
  	sc.inflow.add(http2initialWindowSize)
  	sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
  
  	fr := http2NewFramer(sc.bw, c)
  	fr.ReadMetaHeaders = hpack.NewDecoder(http2initialHeaderTableSize, 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()
  		// 9.2 Use of TLS Features
  		// An implementation of HTTP/2 over TLS MUST use TLS
  		// 1.2 or higher with the restrictions on feature set
  		// and cipher suite described in this section. Due to
  		// implementation limitations, it might not be
  		// possible to fail TLS negotiation. An endpoint MUST
  		// immediately terminate an HTTP/2 connection that
  		// does not meet the TLS requirements described in
  		// this section with a connection error (Section
  		// 5.4.1) of type INADEQUATE_SECURITY.
  		if sc.tlsState.Version < tls.VersionTLS12 {
  			sc.rejectConn(http2ErrCodeInadequateSecurity, "TLS version too low")
  			return
  		}
  
  		if sc.tlsState.ServerName == "" {
  			// Client must use SNI, but we don't enforce that anymore,
  			// since it was causing problems when connecting to bare IP
  			// addresses during development.
  			//
  			// TODO: optionally enforce? Or enforce at the time we receive
  			// a new request, and verify the the ServerName matches the :authority?
  			// But that precludes proxy situations, perhaps.
  			//
  			// So for now, do nothing here again.
  		}
  
  		if !s.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) {
  			// "Endpoints MAY choose to generate a connection error
  			// (Section 5.4.1) of type INADEQUATE_SECURITY if one of
  			// the prohibited cipher suites are negotiated."
  			//
  			// We choose that. In my opinion, the spec is weak
  			// here. It also says both parties must support at least
  			// TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
  			// excuses here. If we really must, we could allow an
  			// "AllowInsecureWeakCiphers" option on the server later.
  			// Let's see how it plays out first.
  			sc.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
  			return
  		}
  	}
  
  	if hook := http2testHookGetServerConn; hook != nil {
  		hook(sc)
  	}
  	sc.serve()
  }
  
  func (sc *http2serverConn) rejectConn(err http2ErrCode, debug string) {
  	sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
  	// ignoring errors. hanging up anyway.
  	sc.framer.WriteGoAway(0, err, []byte(debug))
  	sc.bw.Flush()
  	sc.conn.Close()
  }
  
  type http2serverConn struct {
  	// Immutable:
  	srv              *http2Server
  	hs               *Server
  	conn             net.Conn
  	bw               *http2bufferedWriter // writing to conn
  	handler          Handler
  	baseCtx          http2contextContext
  	framer           *http2Framer
  	doneServing      chan struct{}               // closed when serverConn.serve ends
  	readFrameCh      chan http2readFrameResult   // written by serverConn.readFrames
  	wantWriteFrameCh chan http2FrameWriteRequest // from handlers -> serve
  	wroteFrameCh     chan http2frameWriteResult  // from writeFrameAsync -> serve, tickles more frame writes
  	bodyReadCh       chan http2bodyReadMsg       // from handlers -> serve
  	serveMsgCh       chan interface{}            // misc messages & code to send to / run on the serve loop
  	flow             http2flow                   // conn-wide (not stream-specific) outbound flow control
  	inflow           http2flow                   // conn-wide inbound flow control
  	tlsState         *tls.ConnectionState        // shared by all handlers, like net/http
  	remoteAddrStr    string
  	writeSched       http2WriteScheduler
  
  	// Everything following is owned by the serve loop; use serveG.check():
  	serveG                      http2goroutineLock // used to verify funcs are on serve()
  	pushEnabled                 bool
  	sawFirstSettings            bool // got the initial SETTINGS frame after the preface
  	needToSendSettingsAck       bool
  	unackedSettings             int    // how many SETTINGS have we sent without ACKs?
  	clientMaxStreams            uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
  	advMaxStreams               uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
  	curClientStreams            uint32 // number of open streams initiated by the client
  	curPushedStreams            uint32 // number of open streams initiated by server push
  	maxClientStreamID           uint32 // max ever seen from client (odd), or 0 if there have been no client requests
  	maxPushPromiseID            uint32 // ID of the last push promise (even), or 0 if there have been no pushes
  	streams                     map[uint32]*http2stream
  	initialStreamSendWindowSize int32
  	maxFrameSize                int32
  	headerTableSize             uint32
  	peerMaxHeaderListSize       uint32            // zero means unknown (default)
  	canonHeader                 map[string]string // http2-lower-case -> Go-Canonical-Case
  	writingFrame                bool              // started writing a frame (on serve goroutine or separate)
  	writingFrameAsync           bool              // started a frame on its own goroutine but haven't heard back on wroteFrameCh
  	needsFrameFlush             bool              // last frame write wasn't a flush
  	inGoAway                    bool              // we've started to or sent GOAWAY
  	inFrameScheduleLoop         bool              // whether we're in the scheduleFrameWrite loop
  	needToSendGoAway            bool              // we need to schedule a GOAWAY frame write
  	goAwayCode                  http2ErrCode
  	shutdownTimer               *time.Timer // nil until used
  	idleTimer                   *time.Timer // nil if unused
  
  	// Owned by the writeFrameAsync goroutine:
  	headerWriteBuf bytes.Buffer
  	hpackEncoder   *hpack.Encoder
  
  	// Used by startGracefulShutdown.
  	shutdownOnce sync.Once
  }
  
  func (sc *http2serverConn) maxHeaderListSize() uint32 {
  	n := sc.hs.MaxHeaderBytes
  	if n <= 0 {
  		n = DefaultMaxHeaderBytes
  	}
  	// http2's count is in a slightly different unit and includes 32 bytes per pair.
  	// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
  	const perFieldOverhead = 32 // per http2 spec
  	const typicalHeaders = 10   // conservative
  	return uint32(n + typicalHeaders*perFieldOverhead)
  }
  
  func (sc *http2serverConn) curOpenStreams() uint32 {
  	sc.serveG.check()
  	return sc.curClientStreams + sc.curPushedStreams
  }
  
  // stream represents a stream. This is the minimal metadata needed by
  // the serve goroutine. Most of the actual stream state is owned by
  // the http.Handler's goroutine in the responseWriter. Because the
  // responseWriter's responseWriterState is recycled at the end of a
  // handler, this struct intentionally has no pointer to the
  // *responseWriter{,State} itself, as the Handler ending nils out the
  // responseWriter's state field.
  type http2stream struct {
  	// immutable:
  	sc        *http2serverConn
  	id        uint32
  	body      *http2pipe       // non-nil if expecting DATA frames
  	cw        http2closeWaiter // closed wait stream transitions to closed state
  	ctx       http2contextContext
  	cancelCtx func()
  
  	// owned by serverConn's serve loop:
  	bodyBytes        int64        // body bytes seen so far
  	declBodyBytes    int64        // or -1 if undeclared
  	flow             http2flow    // limits writing from Handler to client
  	inflow           http2flow    // what the client is allowed to POST/etc to us
  	parent           *http2stream // or nil
  	numTrailerValues int64
  	weight           uint8
  	state            http2streamState
  	resetQueued      bool        // RST_STREAM queued for write; set by sc.resetStream
  	gotTrailerHeader bool        // HEADER frame for trailers was seen
  	wroteHeaders     bool        // whether we wrote headers (not status 100)
  	writeDeadline    *time.Timer // nil if unused
  
  	trailer    Header // accumulated trailers
  	reqTrailer Header // handler's Request.Trailer
  }
  
  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()
  	// http://tools.ietf.org/html/rfc7540#section-5.1
  	if st, ok := sc.streams[streamID]; ok {
  		return st.state, st
  	}
  	// "The first use of a new stream identifier implicitly closes all
  	// streams in the "idle" state that might have been initiated by
  	// that peer with a lower-valued stream identifier. For example, if
  	// a client sends a HEADERS frame on stream 7 without ever sending a
  	// frame on stream 5, then stream 5 transitions to the "closed"
  	// state when the first frame for stream 7 is sent or received."
  	if streamID%2 == 1 {
  		if streamID <= sc.maxClientStreamID {
  			return http2stateClosed, nil
  		}
  	} else {
  		if streamID <= sc.maxPushPromiseID {
  			return http2stateClosed, nil
  		}
  	}
  	return http2stateIdle, nil
  }
  
  // setConnState calls the net/http ConnState hook for this connection, if configured.
  // Note that the net/http package does StateNew and StateClosed for us.
  // There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
  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...)
  	}
  }
  
  // errno returns v's underlying uintptr, else 0.
  //
  // TODO: remove this helper function once http2 can use build
  // tags. See comment in isClosedConnError.
  func http2errno(v error) uintptr {
  	if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
  		return uintptr(rv.Uint())
  	}
  	return 0
  }
  
  // isClosedConnError reports whether err is an error from use of a closed
  // network connection.
  func http2isClosedConnError(err error) bool {
  	if err == nil {
  		return false
  	}
  
  	// TODO: remove this string search and be more like the Windows
  	// case below. That might involve modifying the standard library
  	// to return better error types.
  	str := err.Error()
  	if strings.Contains(str, "use of closed network connection") {
  		return true
  	}
  
  	// TODO(bradfitz): x/tools/cmd/bundle doesn't really support
  	// build tags, so I can't make an http2_windows.go file with
  	// Windows-specific stuff. Fix that and move this, once we
  	// have a way to bundle this into std's net/http somehow.
  	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) {
  		// Boring, expected errors.
  		sc.vlogf(format, args...)
  	} else {
  		sc.logf(format, args...)
  	}
  }
  
  func (sc *http2serverConn) canonicalHeader(v string) string {
  	sc.serveG.check()
  	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)
  	sc.canonHeader[v] = cv
  	return cv
  }
  
  type http2readFrameResult struct {
  	f   http2Frame // valid until readMore is called
  	err error
  
  	// readMore should be called once the consumer no longer needs or
  	// retains f. After readMore, f is invalid and more frames can be
  	// read.
  	readMore func()
  }
  
  // readFrames is the loop that reads incoming frames.
  // It takes care to only read one frame at a time, blocking until the
  // consumer is done with the frame.
  // It's run on its own goroutine.
  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
  		}
  	}
  }
  
  // frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
  type http2frameWriteResult struct {
  	wr  http2FrameWriteRequest // what was written (or attempted)
  	err error                  // result of the writeFrame call
  }
  
  // writeFrameAsync runs in its own goroutine and writes a single frame
  // and then reports when it's done.
  // At most one goroutine can be running writeFrameAsync at a time per
  // serverConn.
  func (sc *http2serverConn) writeFrameAsync(wr http2FrameWriteRequest) {
  	err := wr.write.writeFrame(sc)
  	sc.wroteFrameCh <- http2frameWriteResult{wr, 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() {
  	// Note: this is for serverConn.serve panicking, not http.Handler code.
  	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) // unblocks handlers trying to send
  
  	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()},
  			{http2SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
  		},
  	})
  	sc.unackedSettings++
  
  	// Each connection starts with intialWindowSize inflow tokens.
  	// If a higher value is configured, we add more tokens.
  	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
  	}
  	// Now that we've got the preface, get us out of the
  	// "StateNew" state. We can't go directly to idle, though.
  	// Active means we read some data and anticipate a request. We'll
  	// do another Active when we get a HEADERS frame.
  	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() // closed by defer sc.conn.Close above
  
  	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.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) // for testing
  			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()
  				default:
  					panic("unknown timer")
  				}
  			case *http2startPushRequest:
  				sc.startPush(v)
  			default:
  				panic(fmt.Sprintf("unexpected type %T", v))
  			}
  		}
  
  		if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
  			return
  		}
  	}
  }
  
  func (sc *http2serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
  	select {
  	case <-sc.doneServing:
  	case <-sharedCh:
  		close(privateCh)
  	}
  }
  
  type http2serverMessage int
  
  // Message values sent to serveMsgCh.
  var (
  	http2settingsTimerMsg    = new(http2serverMessage)
  	http2idleTimerMsg        = new(http2serverMessage)
  	http2shutdownTimerMsg    = new(http2serverMessage)
  	http2gracefulShutdownMsg = 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() // NOT
  	select {
  	case sc.serveMsgCh <- msg:
  	case <-sc.doneServing:
  	}
  }
  
  // readPreface reads the ClientPreface greeting from the peer
  // or returns an error on timeout or an invalid greeting.
  func (sc *http2serverConn) readPreface() error {
  	errc := make(chan error, 1)
  	go func() {
  		// Read the client preface
  		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) // TODO: configurable on *Server?
  	defer timer.Stop()
  	select {
  	case <-timer.C:
  		return errors.New("timeout waiting for client preface")
  	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) },
  }
  
  // writeDataFromHandler writes DATA response frames from a handler on
  // the given stream.
  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 // the frame write is done (successfully or not)
  	select {
  	case err = <-ch:
  		frameWriteDone = true
  	case <-sc.doneServing:
  		return http2errClientDisconnected
  	case <-stream.cw:
  		// If both ch and stream.cw were ready (as might
  		// happen on the final Write after an http.Handler
  		// ends), prefer the write result. Otherwise this
  		// might just be us successfully closing the stream.
  		// The writeFrameAsync and serve goroutines guarantee
  		// that the ch send will happen before the stream.cw
  		// close.
  		select {
  		case err = <-ch:
  			frameWriteDone = true
  		default:
  			return http2errStreamClosed
  		}
  	}
  	http2errChanPool.Put(ch)
  	if frameWriteDone {
  		http2writeDataPool.Put(writeArg)
  	}
  	return err
  }
  
  // writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
  // if the connection has gone away.
  //
  // This must not be run from the serve goroutine itself, else it might
  // deadlock writing to sc.wantWriteFrameCh (which is only mildly
  // buffered and is read by serve itself). If you're on the serve
  // goroutine, call writeFrame instead.
  func (sc *http2serverConn) writeFrameFromHandler(wr http2FrameWriteRequest) error {
  	sc.serveG.checkNotOn() // NOT
  	select {
  	case sc.wantWriteFrameCh <- wr:
  		return nil
  	case <-sc.doneServing:
  		// Serve loop is gone.
  		// Client has closed their connection to the server.
  		return http2errClientDisconnected
  	}
  }
  
  // writeFrame schedules a frame to write and sends it if there's nothing
  // already being written.
  //
  // There is no pushback here (the serve goroutine never blocks). It's
  // the http.Handlers that block, waiting for their previous frames to
  // make it onto the wire
  //
  // If you're not on the serve goroutine, use writeFrameFromHandler instead.
  func (sc *http2serverConn) writeFrame(wr http2FrameWriteRequest) {
  	sc.serveG.check()
  
  	// If true, wr will not be written and wr.done will not be signaled.
  	var ignoreWrite bool
  
  	// We are not allowed to write frames on closed streams. RFC 7540 Section
  	// 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
  	// a closed stream." Our server never sends PRIORITY, so that exception
  	// does not apply.
  	//
  	// The serverConn might close an open stream while the stream's handler
  	// is still running. For example, the server might close a stream when it
  	// receives bad data from the client. If this happens, the handler might
  	// attempt to write a frame after the stream has been closed (since the
  	// handler hasn't yet been notified of the close). In this case, we simply
  	// ignore the frame. The handler will notice that the stream is closed when
  	// it waits for the frame to be written.
  	//
  	// As an exception to this rule, we allow sending RST_STREAM after close.
  	// This allows us to immediately reject new streams without tracking any
  	// state for those streams (except for the queued RST_STREAM frame). This
  	// may result in duplicate RST_STREAMs in some cases, but the client should
  	// ignore those.
  	if wr.StreamID() != 0 {
  		_, isReset := wr.write.(http2StreamError)
  		if state, _ := sc.state(wr.StreamID()); state == http2stateClosed && !isReset {
  			ignoreWrite = true
  		}
  	}
  
  	// Don't send a 100-continue response if we've already sent headers.
  	// See golang.org/issue/14030.
  	switch wr.write.(type) {
  	case *http2writeResHeaders:
  		wr.stream.wroteHeaders = true
  	case http2write100ContinueHeadersFrame:
  		if wr.stream.wroteHeaders {
  			// We do not need to notify wr.done because this frame is
  			// never written with wr.done != nil.
  			if wr.done != nil {
  				panic("wr.done != nil for write100ContinueHeadersFrame")
  			}
  			ignoreWrite = true
  		}
  	}
  
  	if !ignoreWrite {
  		sc.writeSched.Push(wr)
  	}
  	sc.scheduleFrameWrite()
  }
  
  // startFrameWrite starts a goroutine to write wr (in a separate
  // goroutine since that might block on the network), and updates the
  // serve goroutine's state about the world, updated from info in wr.
  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:
  				// RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
  				// in this state. (We never send PRIORITY from the server, so that is not checked.)
  			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, err})
  	} else {
  		sc.writingFrameAsync = true
  		go sc.writeFrameAsync(wr)
  	}
  }
  
  // errHandlerPanicked is the error given to any callers blocked in a read from
  // Request.Body when the main goroutine panics. Since most handlers read in the
  // the main ServeHTTP goroutine, this will show up rarely.
  var http2errHandlerPanicked = errors.New("http2: handler panicked")
  
  // wroteFrame is called on the serve goroutine with the result of
  // whatever happened on writeFrameAsync.
  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:
  			// Here we would go to stateHalfClosedLocal in
  			// theory, but since our handler is done and
  			// the net/http package provides no mechanism
  			// for closing a ResponseWriter while still
  			// reading data (see possible TODO at top of
  			// this file), we go into closed state here
  			// anyway, after telling the peer we're
  			// hanging up on them. We'll transition to
  			// stateClosed after the RST_STREAM frame is
  			// written.
  			st.state = http2stateHalfClosedLocal
  			// Section 8.1: a server MAY request that the client abort
  			// transmission of a request without error by sending a
  			// RST_STREAM with an error code of NO_ERROR after sending
  			// a complete response.
  			sc.resetStream(http2streamError(st.id, http2ErrCodeNo))
  		case http2stateHalfClosedRemote:
  			sc.closeStream(st, http2errHandlerComplete)
  		}
  	} else {
  		switch v := wr.write.(type) {
  		case http2StreamError:
  			// st may be unknown if the RST_STREAM was generated to reject bad input.
  			if st, ok := sc.streams[v.StreamID]; ok {
  				sc.closeStream(st, v)
  			}
  		case http2handlerPanicRST:
  			sc.closeStream(wr.stream, http2errHandlerPanicked)
  		}
  	}
  
  	// Reply (if requested) to unblock the ServeHTTP goroutine.
  	wr.replyToWriter(res.err)
  
  	sc.scheduleFrameWrite()
  }
  
  // scheduleFrameWrite tickles the frame writing scheduler.
  //
  // If a frame is already being written, nothing happens. This will be called again
  // when the frame is done being written.
  //
  // If a frame isn't being written we need to send one, the best frame
  // to send is selected, preferring first things that aren't
  // stream-specific (e.g. ACKing settings), and then finding the
  // highest priority stream.
  //
  // If a frame isn't being written and there's nothing else to send, we
  // flush the write buffer.
  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 {
  				sc.startFrameWrite(wr)
  				continue
  			}
  		}
  		if sc.needsFrameFlush {
  			sc.startFrameWrite(http2FrameWriteRequest{write: http2flushFrameWriter{}})
  			sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
  			continue
  		}
  		break
  	}
  	sc.inFrameScheduleLoop = false
  }
  
  // startGracefulShutdown gracefully shuts down a connection. This
  // sends GOAWAY with ErrCodeNo to tell the client we're gracefully
  // shutting down. The connection isn't closed until all current
  // streams are done.
  //
  // startGracefulShutdown returns immediately; it does not wait until
  // the connection has shut down.
  func (sc *http2serverConn) startGracefulShutdown() {
  	sc.serveG.checkNotOn() // NOT
  	sc.shutdownOnce.Do(func() { sc.sendServeMsg(http2gracefulShutdownMsg) })
  }
  
  func (sc *http2serverConn) startGracefulShutdownInternal() {
  	sc.goAwayIn(http2ErrCodeNo, 0)
  }
  
  func (sc *http2serverConn) goAway(code http2ErrCode) {
  	sc.serveG.check()
  	var forceCloseIn time.Duration
  	if code != http2ErrCodeNo {
  		forceCloseIn = 250 * time.Millisecond
  	} else {
  		// TODO: configurable
  		forceCloseIn = 1 * time.Second
  	}
  	sc.goAwayIn(code, forceCloseIn)
  }
  
  func (sc *http2serverConn) goAwayIn(code http2ErrCode, forceCloseIn time.Duration) {
  	sc.serveG.check()
  	if sc.inGoAway {
  		return
  	}
  	if forceCloseIn != 0 {
  		sc.shutDownIn(forceCloseIn)
  	}
  	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
  	}
  }
  
  // processFrameFromReader processes the serve loop's read from readFrameCh from the
  // frame-reading goroutine.
  // processFrameFromReader returns whether the connection should be kept open.
  func (sc *http2serverConn) processFrameFromReader(res http2readFrameResult) bool {
  	sc.serveG.check()
  	err := res.err
  	if err != nil {
  		if err == http2ErrFrameTooLarge {
  			sc.goAway(http2ErrCodeFrameSize)
  			return true // goAway will close the loop
  		}
  		clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err)
  		if clientGone {
  			// TODO: could we also get into this state if
  			// the peer does a half close
  			// (e.g. CloseWrite) because they're done
  			// sending frames but they're still wanting
  			// our open replies?  Investigate.
  			// TODO: add CloseWrite to crypto/tls.Conn first
  			// so we have a way to test this? I suppose
  			// just for testing we could have a non-TLS mode.
  			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 // goAway will handle shutdown
  	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()
  
  	// First frame received must be SETTINGS.
  	if !sc.sawFirstSettings {
  		if _, ok := f.(*http2SettingsFrame); !ok {
  			return http2ConnectionError(http2ErrCodeProtocol)
  		}
  		sc.sawFirstSettings = true
  	}
  
  	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:
  		// A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
  		// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
  		return 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() {
  		// 6.7 PING: " An endpoint MUST NOT respond to PING frames
  		// containing this flag."
  		return nil
  	}
  	if f.StreamID != 0 {
  		// "PING frames are not associated with any individual
  		// stream. If a PING frame is received with a stream
  		// identifier field value other than 0x0, the recipient MUST
  		// respond with a connection error (Section 5.4.1) of type
  		// PROTOCOL_ERROR."
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	if sc.inGoAway && sc.goAwayCode != http2ErrCodeNo {
  		return nil
  	}
  	sc.writeFrame(http2FrameWriteRequest{write: http2writePingAck{f}})
  	return nil
  }
  
  func (sc *http2serverConn) processWindowUpdate(f *http2WindowUpdateFrame) error {
  	sc.serveG.check()
  	switch {
  	case f.StreamID != 0: // stream-level flow control
  		state, st := sc.state(f.StreamID)
  		if state == http2stateIdle {
  			// Section 5.1: "Receiving any frame other than HEADERS
  			// or PRIORITY on a stream in this state MUST be
  			// treated as a connection error (Section 5.4.1) of
  			// type PROTOCOL_ERROR."
  			return http2ConnectionError(http2ErrCodeProtocol)
  		}
  		if st == nil {
  			// "WINDOW_UPDATE can be sent by a peer that has sent a
  			// frame bearing the END_STREAM flag. This means that a
  			// receiver could receive a WINDOW_UPDATE frame on a "half
  			// closed (remote)" or "closed" stream. A receiver MUST
  			// NOT treat this as an error, see Section 5.1."
  			return nil
  		}
  		if !st.flow.add(int32(f.Increment)) {
  			return http2streamError(f.StreamID, http2ErrCodeFlowControl)
  		}
  	default: // connection-level flow control
  		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 {
  		// 6.4 "RST_STREAM frames MUST NOT be sent for a
  		// stream in the "idle" state. If a RST_STREAM frame
  		// identifying an idle stream is received, the
  		// recipient MUST treat this as a connection error
  		// (Section 5.4.1) of type PROTOCOL_ERROR.
  		return 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.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 {
  		// Return any buffered unread bytes worth of conn-level flow control.
  		// See golang.org/issue/16481
  		sc.sendWindowUpdate(nil, p.Len())
  
  		p.CloseWithError(err)
  	}
  	st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
  	sc.writeSched.CloseStream(st.id)
  }
  
  func (sc *http2serverConn) processSettings(f *http2SettingsFrame) error {
  	sc.serveG.check()
  	if f.IsAck() {
  		sc.unackedSettings--
  		if sc.unackedSettings < 0 {
  			// Why is the peer ACKing settings we never sent?
  			// The spec doesn't mention this case, but
  			// hang up on them anyway.
  			return http2ConnectionError(http2ErrCodeProtocol)
  		}
  		return nil
  	}
  	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.headerTableSize = s.Val
  		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) // the maximum valid s.Val is < 2^31
  	case http2SettingMaxHeaderListSize:
  		sc.peerMaxHeaderListSize = s.Val
  	default:
  		// Unknown setting: "An endpoint that receives a SETTINGS
  		// frame with any unknown or unsupported identifier MUST
  		// ignore that setting."
  		if http2VerboseLogs {
  			sc.vlogf("http2: server ignoring unknown setting %v", s)
  		}
  	}
  	return nil
  }
  
  func (sc *http2serverConn) processSettingInitialWindowSize(val uint32) error {
  	sc.serveG.check()
  	// Note: val already validated to be within range by
  	// processSetting's Valid call.
  
  	// "A SETTINGS frame can alter the initial flow control window
  	// size for all current streams. When the value of
  	// SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
  	// adjust the size of all stream flow control windows that it
  	// maintains by the difference between the new value and the
  	// old value."
  	old := sc.initialStreamSendWindowSize
  	sc.initialStreamSendWindowSize = int32(val)
  	growth := int32(val) - old // may be negative
  	for _, st := range sc.streams {
  		if !st.flow.add(growth) {
  			// 6.9.2 Initial Flow Control Window Size
  			// "An endpoint MUST treat a change to
  			// SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
  			// control window to exceed the maximum size as a
  			// connection error (Section 5.4.1) of type
  			// FLOW_CONTROL_ERROR."
  			return http2ConnectionError(http2ErrCodeFlowControl)
  		}
  	}
  	return nil
  }
  
  func (sc *http2serverConn) processData(f *http2DataFrame) error {
  	sc.serveG.check()
  	if sc.inGoAway && sc.goAwayCode != http2ErrCodeNo {
  		return nil
  	}
  	data := f.Data()
  
  	// "If a DATA frame is received whose stream is not in "open"
  	// or "half closed (local)" state, the recipient MUST respond
  	// with a stream error (Section 5.4.2) of type STREAM_CLOSED."
  	id := f.Header().StreamID
  	state, st := sc.state(id)
  	if id == 0 || state == http2stateIdle {
  		// Section 5.1: "Receiving any frame other than HEADERS
  		// or PRIORITY on a stream in this state MUST be
  		// treated as a connection error (Section 5.4.1) of
  		// type PROTOCOL_ERROR."
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued {
  		// This includes sending a RST_STREAM if the stream is
  		// in stateHalfClosedLocal (which currently means that
  		// the http.Handler returned, so it's done reading &
  		// done writing). Try to stop the client from sending
  		// more DATA.
  
  		// But still enforce their connection-level flow control,
  		// and return any flow control bytes since we're not going
  		// to consume them.
  		if sc.inflow.available() < int32(f.Length) {
  			return http2streamError(id, http2ErrCodeFlowControl)
  		}
  		// Deduct the flow control from inflow, since we're
  		// going to immediately add it back in
  		// sendWindowUpdate, which also schedules sending the
  		// frames.
  		sc.inflow.take(int32(f.Length))
  		sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
  
  		if st != nil && st.resetQueued {
  			// Already have a stream error in flight. Don't send another.
  			return nil
  		}
  		return http2streamError(id, http2ErrCodeStreamClosed)
  	}
  	if st.body == nil {
  		panic("internal error: should have a body in this state")
  	}
  
  	// Sender sending more than they'd declared?
  	if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
  		st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
  		return http2streamError(id, http2ErrCodeStreamClosed)
  	}
  	if f.Length > 0 {
  		// Check whether the client has flow control quota.
  		if st.inflow.available() < int32(f.Length) {
  			return http2streamError(id, http2ErrCodeFlowControl)
  		}
  		st.inflow.take(int32(f.Length))
  
  		if len(data) > 0 {
  			wrote, err := st.body.Write(data)
  			if err != nil {
  				return http2streamError(id, http2ErrCodeStreamClosed)
  			}
  			if wrote != len(data) {
  				panic("internal error: bad Writer")
  			}
  			st.bodyBytes += int64(len(data))
  		}
  
  		// Return any padded flow control now, since we won't
  		// refund it later on body reads.
  		if pad := int32(f.Length) - int32(len(data)); pad > 0 {
  			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()
  	// http://tools.ietf.org/html/rfc7540#section-6.8
  	// We should not create any new streams, which means we should disable push.
  	sc.pushEnabled = false
  	return nil
  }
  
  // isPushed reports whether the stream is server-initiated.
  func (st *http2stream) isPushed() bool {
  	return st.id%2 == 0
  }
  
  // endStream closes a Request.Body's pipe. It is called when a DATA
  // frame says a request body is over (or after trailers).
  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
  }
  
  // copyTrailersToHandlerRequest is run in the Handler's goroutine in
  // its Request.Body.Read just before it gets io.EOF.
  func (st *http2stream) copyTrailersToHandlerRequest() {
  	for k, vv := range st.trailer {
  		if _, ok := st.reqTrailer[k]; ok {
  			// Only copy it over it was pre-declared.
  			st.reqTrailer[k] = vv
  		}
  	}
  }
  
  // onWriteTimeout is run on its own goroutine (from time.AfterFunc)
  // when the stream's WriteTimeout has fired.
  func (st *http2stream) onWriteTimeout() {
  	st.sc.writeFrameFromHandler(http2FrameWriteRequest{write: http2streamError(st.id, http2ErrCodeInternal)})
  }
  
  func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
  	sc.serveG.check()
  	id := f.StreamID
  	if sc.inGoAway {
  		// Ignore.
  		return nil
  	}
  	// http://tools.ietf.org/html/rfc7540#section-5.1.1
  	// Streams initiated by a client MUST use odd-numbered stream
  	// identifiers. [...] An endpoint that receives an unexpected
  	// stream identifier MUST respond with a connection error
  	// (Section 5.4.1) of type PROTOCOL_ERROR.
  	if id%2 != 1 {
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	// A HEADERS frame can be used to create a new stream or
  	// send a trailer for an open one. If we already have a stream
  	// open, let it process its own HEADERS frame (trailers at this
  	// point, if it's valid).
  	if st := sc.streams[f.StreamID]; st != nil {
  		if st.resetQueued {
  			// We're sending RST_STREAM to close the stream, so don't bother
  			// processing this frame.
  			return nil
  		}
  		return st.processTrailerHeaders(f)
  	}
  
  	// [...] The identifier of a newly established stream MUST be
  	// numerically greater than all streams that the initiating
  	// endpoint has opened or reserved. [...]  An endpoint that
  	// receives an unexpected stream identifier MUST respond with
  	// a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
  	if id <= sc.maxClientStreamID {
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	sc.maxClientStreamID = id
  
  	if sc.idleTimer != nil {
  		sc.idleTimer.Stop()
  	}
  
  	// http://tools.ietf.org/html/rfc7540#section-5.1.2
  	// [...] Endpoints MUST NOT exceed the limit set by their peer. An
  	// endpoint that receives a HEADERS frame that causes their
  	// advertised concurrent stream limit to be exceeded MUST treat
  	// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
  	// or REFUSED_STREAM.
  	if sc.curClientStreams+1 > sc.advMaxStreams {
  		if sc.unackedSettings == 0 {
  			// They should know better.
  			return http2streamError(id, http2ErrCodeProtocol)
  		}
  		// Assume it's a network race, where they just haven't
  		// received our last SETTINGS update. But actually
  		// this can't happen yet, because we don't yet provide
  		// a way for users to adjust server parameters at
  		// runtime.
  		return http2streamError(id, http2ErrCodeRefusedStream)
  	}
  
  	initialState := http2stateOpen
  	if f.StreamEnded() {
  		initialState = http2stateHalfClosedRemote
  	}
  	st := sc.newStream(id, 0, initialState)
  
  	if f.HasPriority() {
  		if err := http2checkPriority(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 // may be nil
  	st.declBodyBytes = req.ContentLength
  
  	handler := sc.handler.ServeHTTP
  	if f.Truncated {
  		// Their header list was too long. Send a 431 error.
  		handler = http2handleHeaderListTooLong
  	} else if err := http2checkValidHTTP2RequestHeaders(req.Header); err != nil {
  		handler = http2new400Handler(err)
  	}
  
  	// The net/http package sets the read deadline from the
  	// http.Server.ReadTimeout during the TLS handshake, but then
  	// passes the connection off to us with the deadline already
  	// set. Disarm it here after the request headers are read,
  	// similar to how the http1 server works. Here it's
  	// technically more like the http1 Server's ReadHeaderTimeout
  	// (in Go 1.8), though. That's a more sane option anyway.
  	if sc.hs.ReadTimeout != 0 {
  		sc.conn.SetReadDeadline(time.Time{})
  	}
  
  	go sc.runHandler(rw, req, handler)
  	return nil
  }
  
  func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error {
  	sc := st.sc
  	sc.serveG.check()
  	if st.gotTrailerHeader {
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	st.gotTrailerHeader = true
  	if !f.StreamEnded() {
  		return http2streamError(st.id, http2ErrCodeProtocol)
  	}
  
  	if len(f.PseudoFields()) > 0 {
  		return http2streamError(st.id, http2ErrCodeProtocol)
  	}
  	if st.trailer != nil {
  		for _, hf := range f.RegularFields() {
  			key := sc.canonicalHeader(hf.Name)
  			if !http2ValidTrailerHeader(key) {
  				// TODO: send more details to the peer somehow. But http2 has
  				// no way to send debug data at a stream level. Discuss with
  				// HTTP folk.
  				return http2streamError(st.id, http2ErrCodeProtocol)
  			}
  			st.trailer[key] = append(st.trailer[key], hf.Value)
  		}
  	}
  	st.endStream()
  	return nil
  }
  
  func http2checkPriority(streamID uint32, p http2PriorityParam) error {
  	if streamID == p.StreamDep {
  		// Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
  		// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
  		// Section 5.3.3 says that a stream can depend on one of its dependencies,
  		// so it's only self-dependencies that are forbidden.
  		return http2streamError(streamID, http2ErrCodeProtocol)
  	}
  	return nil
  }
  
  func (sc *http2serverConn) processPriority(f *http2PriorityFrame) error {
  	if sc.inGoAway {
  		return nil
  	}
  	if err := http2checkPriority(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 := http2contextWithCancel(sc.baseCtx)
  	st := &http2stream{
  		sc:        sc,
  		id:        id,
  		state:     state,
  		ctx:       ctx,
  		cancelCtx: cancelCtx,
  	}
  	st.cw.Init()
  	st.flow.conn = &sc.flow // link to conn-level counter
  	st.flow.add(sc.initialStreamSendWindowSize)
  	st.inflow.conn = &sc.inflow // link to conn-level counter
  	st.inflow.add(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, http2streamError(f.StreamID, http2ErrCodeProtocol)
  		}
  	} else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
  		// See 8.1.2.6 Malformed Requests and Responses:
  		//
  		// Malformed requests or responses that are detected
  		// MUST be treated as a stream error (Section 5.4.2)
  		// of type PROTOCOL_ERROR."
  		//
  		// 8.1.2.3 Request Pseudo-Header Fields
  		// "All HTTP/2 requests MUST include exactly one valid
  		// value for the :method, :scheme, and :path
  		// pseudo-header fields"
  		return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol)
  	}
  
  	bodyOpen := !f.StreamEnded()
  	if rp.method == "HEAD" && bodyOpen {
  		// HEAD requests can't have bodies
  		return nil, nil, 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
  	}
  	if bodyOpen {
  		if vv, ok := rp.header["Content-Length"]; ok {
  			req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
  		} 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 // nil if not scheme https
  	if rp.scheme == "https" {
  		tlsState = sc.tlsState
  	}
  
  	needsContinue := rp.header.Get("Expect") == "100-continue"
  	if needsContinue {
  		rp.header.Del("Expect")
  	}
  	// Merge Cookie headers into one "; "-delimited value.
  	if cookies := rp.header["Cookie"]; len(cookies) > 1 {
  		rp.header.Set("Cookie", strings.Join(cookies, "; "))
  	}
  
  	// Setup Trailers
  	var trailer Header
  	for _, v := range rp.header["Trailer"] {
  		for _, key := range strings.Split(v, ",") {
  			key = CanonicalHeaderKey(strings.TrimSpace(key))
  			switch key {
  			case "Transfer-Encoding", "Trailer", "Content-Length":
  				// Bogus. (copy of http1 rules)
  				// Ignore.
  			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 // mimic HTTP/1 server behavior
  	} else {
  		var err error
  		url_, err = url.ParseRequestURI(rp.path)
  		if err != nil {
  			return nil, nil, 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 = http2requestWithContext(req, st.ctx)
  
  	rws := http2responseWriterStatePool.Get().(*http2responseWriterState)
  	bwSave := rws.bw
  	*rws = http2responseWriterState{} // zero all the fields
  	rws.conn = sc
  	rws.bw = bwSave
  	rws.bw.Reset(http2chunkWriter{rws})
  	rws.stream = st
  	rws.req = req
  	rws.body = body
  
  	rw := &http2responseWriter{rws: rws}
  	return rw, req, nil
  }
  
  // Run on its own goroutine.
  func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) {
  	didPanic := true
  	defer func() {
  		rw.rws.stream.cancelCtx()
  		if didPanic {
  			e := recover()
  			sc.writeFrameFromHandler(http2FrameWriteRequest{
  				write:  http2handlerPanicRST{rw.rws.stream.id},
  				stream: rw.rws.stream,
  			})
  			// Same as net/http:
  			if http2shouldLogPanic(e) {
  				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) {
  	// 10.5.1 Limits on Header Block Size:
  	// .. "A server that receives a larger header block than it is
  	// willing to handle can send an HTTP 431 (Request Header Fields Too
  	// Large) status code"
  	const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
  	w.WriteHeader(statusRequestHeaderFieldsTooLarge)
  	io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
  }
  
  // called from handler goroutines.
  // h may be nil.
  func (sc *http2serverConn) writeHeaders(st *http2stream, headerData *http2writeResHeaders) error {
  	sc.serveG.checkNotOn() // NOT on
  	var errc chan error
  	if headerData.h != nil {
  		// If there's a header map (which we don't own), so we have to block on
  		// waiting for this frame to be written, so an http.Flush mid-handler
  		// writes out the correct value of keys, before a handler later potentially
  		// mutates it.
  		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
  }
  
  // called from handler goroutines.
  func (sc *http2serverConn) write100ContinueHeaders(st *http2stream) {
  	sc.writeFrameFromHandler(http2FrameWriteRequest{
  		write:  http2write100ContinueHeadersFrame{st.id},
  		stream: st,
  	})
  }
  
  // A bodyReadMsg tells the server loop that the http.Handler read n
  // bytes of the DATA from the client on the given stream.
  type http2bodyReadMsg struct {
  	st *http2stream
  	n  int
  }
  
  // called from handler goroutines.
  // Notes that the handler for the given stream ID read n bytes of its body
  // and schedules flow control tokens to be sent.
  func (sc *http2serverConn) noteBodyReadFromHandler(st *http2stream, n int, err error) {
  	sc.serveG.checkNotOn() // NOT on
  	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) // conn-level
  	if st.state != http2stateHalfClosedRemote && st.state != http2stateClosed {
  		// Don't send this WINDOW_UPDATE if the stream is closed
  		// remotely.
  		sc.sendWindowUpdate(st, n)
  	}
  }
  
  // st may be nil for conn-level
  func (sc *http2serverConn) sendWindowUpdate(st *http2stream, n int) {
  	sc.serveG.check()
  	// "The legal range for the increment to the flow control
  	// window is 1 to 2^31-1 (2,147,483,647) octets."
  	// A Go Read call on 64-bit machines could in theory read
  	// a larger Read than this. Very unlikely, but we handle it here
  	// rather than elsewhere for now.
  	const maxUint31 = 1<<31 - 1
  	for n >= maxUint31 {
  		sc.sendWindowUpdate32(st, maxUint31)
  		n -= maxUint31
  	}
  	sc.sendWindowUpdate32(st, int32(n))
  }
  
  // st may be nil for conn-level
  func (sc *http2serverConn) sendWindowUpdate32(st *http2stream, n int32) {
  	sc.serveG.check()
  	if n == 0 {
  		return
  	}
  	if n < 0 {
  		panic("negative update")
  	}
  	var streamID uint32
  	if st != nil {
  		streamID = st.id
  	}
  	sc.writeFrame(http2FrameWriteRequest{
  		write:  http2writeWindowUpdate{streamID: streamID, n: uint32(n)},
  		stream: st,
  	})
  	var ok bool
  	if st == nil {
  		ok = sc.inflow.add(n)
  	} else {
  		ok = st.inflow.add(n)
  	}
  	if !ok {
  		panic("internal error; sent too many window updates without decrements?")
  	}
  }
  
  // requestBody is the Handler's Request.Body type.
  // Read and Close may be called concurrently.
  type http2requestBody struct {
  	stream        *http2stream
  	conn          *http2serverConn
  	closed        bool       // for use by Close only
  	sawEOF        bool       // for use by Read only
  	pipe          *http2pipe // non-nil if we have a HTTP entity message body
  	needsContinue bool       // need to send a 100-continue
  }
  
  func (b *http2requestBody) Close() error {
  	if b.pipe != nil && !b.closed {
  		b.pipe.BreakWithError(http2errClosedBody)
  	}
  	b.closed = true
  	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
  }
  
  // responseWriter is the http.ResponseWriter implementation. It's
  // intentionally small (1 pointer wide) to minimize garbage. The
  // responseWriterState pointer inside is zeroed at the end of a
  // request (in handlerDone) and calls on the responseWriter thereafter
  // simply crash (caller's mistake), but the much larger responseWriterState
  // and buffers are reused between multiple requests.
  type http2responseWriter struct {
  	rws *http2responseWriterState
  }
  
  // Optional http.ResponseWriter interfaces implemented.
  var (
  	_ CloseNotifier     = (*http2responseWriter)(nil)
  	_ Flusher           = (*http2responseWriter)(nil)
  	_ http2stringWriter = (*http2responseWriter)(nil)
  )
  
  type http2responseWriterState struct {
  	// immutable within a request:
  	stream *http2stream
  	req    *Request
  	body   *http2requestBody // to close at end of request, if DATA frames didn't
  	conn   *http2serverConn
  
  	// TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
  	bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
  
  	// mutated by http.Handler goroutine:
  	handlerHeader Header   // nil until called
  	snapHeader    Header   // snapshot of handlerHeader at WriteHeader time
  	trailers      []string // set in writeChunk
  	status        int      // status code passed to WriteHeader
  	wroteHeader   bool     // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
  	sentHeader    bool     // have we sent the header frame?
  	handlerDone   bool     // handler has finished
  	dirty         bool     // a Write failed; don't reuse this responseWriterState
  
  	sentContentLen int64 // non-zero if handler set a Content-Length header
  	wroteBytes     int64
  
  	closeNotifierMu sync.Mutex // guards closeNotifierCh
  	closeNotifierCh chan bool  // nil until first used
  }
  
  type http2chunkWriter struct{ rws *http2responseWriterState }
  
  func (cw http2chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
  
  func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
  
  // declareTrailer is called for each Trailer header when the
  // response header is written. It notes that a header will need to be
  // written in the trailers at the end of the response.
  func (rws *http2responseWriterState) declareTrailer(k string) {
  	k = CanonicalHeaderKey(k)
  	if !http2ValidTrailerHeader(k) {
  		// Forbidden by RFC 2616 14.40.
  		rws.conn.logf("ignoring invalid trailer %q", k)
  		return
  	}
  	if !http2strSliceContains(rws.trailers, k) {
  		rws.trailers = append(rws.trailers, k)
  	}
  }
  
  // writeChunk writes chunks from the bufio.Writer. But because
  // bufio.Writer may bypass its chunking, sometimes p may be
  // arbitrarily large.
  //
  // writeChunk is also responsible (on the first chunk) for sending the
  // HEADER response.
  func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
  	if !rws.wroteHeader {
  		rws.writeHeader(200)
  	}
  
  	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")
  			clen64, err := strconv.ParseInt(clen, 10, 64)
  			if err == nil && clen64 >= 0 {
  				rws.sentContentLen = clen64
  			} else {
  				clen = ""
  			}
  		}
  		if clen == "" && rws.handlerDone && http2bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
  			clen = strconv.Itoa(len(p))
  		}
  		_, hasContentType := rws.snapHeader["Content-Type"]
  		if !hasContentType && http2bodyAllowedForStatus(rws.status) {
  			ctype = DetectContentType(p)
  		}
  		var date string
  		if _, ok := rws.snapHeader["Date"]; !ok {
  			// TODO(bradfitz): be faster here, like net/http? measure.
  			date = time.Now().UTC().Format(TimeFormat)
  		}
  
  		for _, v := range rws.snapHeader["Trailer"] {
  			http2foreachHeaderElement(v, rws.declareTrailer)
  		}
  
  		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
  	}
  
  	if rws.handlerDone {
  		rws.promoteUndeclaredTrailers()
  	}
  
  	endStream := rws.handlerDone && !rws.hasTrailers()
  	if len(p) > 0 || endStream {
  		// only send a 0 byte DATA frame if we're ending the stream.
  		if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
  			rws.dirty = true
  			return 0, err
  		}
  	}
  
  	if rws.handlerDone && rws.hasTrailers() {
  		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
  }
  
  // TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
  // that, if present, signals that the map entry is actually for
  // the response trailers, and not the response headers. The prefix
  // is stripped after the ServeHTTP call finishes and the values are
  // sent in the trailers.
  //
  // This mechanism is intended only for trailers that are not known
  // prior to the headers being written. If the set of trailers is fixed
  // or known before the header is written, the normal Go trailers mechanism
  // is preferred:
  //    https://golang.org/pkg/net/http/#ResponseWriter
  //    https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
  const http2TrailerPrefix = "Trailer:"
  
  // promoteUndeclaredTrailers permits http.Handlers to set trailers
  // after the header has already been flushed. Because the Go
  // ResponseWriter interface has no way to set Trailers (only the
  // Header), and because we didn't want to expand the ResponseWriter
  // interface, and because nobody used trailers, and because RFC 2616
  // says you SHOULD (but not must) predeclare any trailers in the
  // header, the official ResponseWriter rules said trailers in Go must
  // be predeclared, and then we reuse the same ResponseWriter.Header()
  // map to mean both Headers and Trailers. When it's time to write the
  // Trailers, we pick out the fields of Headers that were declared as
  // trailers. That worked for a while, until we found the first major
  // user of Trailers in the wild: gRPC (using them only over http2),
  // and gRPC libraries permit setting trailers mid-stream without
  // predeclarnig them. So: change of plans. We still permit the old
  // way, but we also permit this hack: if a Header() key begins with
  // "Trailer:", the suffix of that key is a Trailer. Because ':' is an
  // invalid token byte anyway, there is no ambiguity. (And it's already
  // filtered out) It's mildly hacky, but not terrible.
  //
  // This method runs after the Handler is done and promotes any Header
  // fields to be trailers.
  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) Flush() {
  	rws := w.rws
  	if rws == nil {
  		panic("Header called after Handler finished")
  	}
  	if rws.bw.Buffered() > 0 {
  		if err := rws.bw.Flush(); err != nil {
  			// Ignore the error. The frame writer already knows.
  			return
  		}
  	} else {
  		// The bufio.Writer won't call chunkWriter.Write
  		// (writeChunk with zero bytes, so we have to do it
  		// ourselves to force the HTTP response header and/or
  		// final DATA frame (with END_STREAM) to be sent.
  		rws.writeChunk(nil)
  	}
  }
  
  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() // wait for close
  			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 (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 {
  		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
  }
  
  // The Life Of A Write is like this:
  //
  // * Handler calls w.Write or w.WriteString ->
  // * -> rws.bw (*bufio.Writer) ->
  // * (Handler might call Flush)
  // * -> chunkWriter{rws}
  // * -> responseWriterState.writeChunk(p []byte)
  // * -> responseWriterState.writeChunk (most of the magic; see comment there)
  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)
  }
  
  // either dataB or dataS is non-zero.
  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)) // only one can be set
  	if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
  		// TODO: send a RST_STREAM
  		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 {
  		// Only recycle the pool if all prior Write calls to
  		// the serverConn goroutine completed successfully. If
  		// they returned earlier due to resets from the peer
  		// there might still be write goroutines outstanding
  		// from the serverConn referencing the rws memory. See
  		// issue 20704.
  		http2responseWriterStatePool.Put(rws)
  	}
  }
  
  // Push errors.
  var (
  	http2ErrRecursivePush    = errors.New("http2: recursive push not allowed")
  	http2ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
  )
  
  // pushOptions is the internal version of http.PushOptions, which we
  // cannot include here because it's only defined in Go 1.8 and later.
  type http2pushOptions struct {
  	Method string
  	Header Header
  }
  
  func (w *http2responseWriter) push(target string, opts http2pushOptions) error {
  	st := w.rws.stream
  	sc := st.sc
  	sc.serveG.checkNotOn()
  
  	// No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
  	// http://tools.ietf.org/html/rfc7540#section-6.6
  	if st.isPushed() {
  		return http2ErrRecursivePush
  	}
  
  	// Default options.
  	if opts.Method == "" {
  		opts.Method = "GET"
  	}
  	if opts.Header == nil {
  		opts.Header = Header{}
  	}
  	wantScheme := "http"
  	if w.rws.req.TLS != nil {
  		wantScheme = "https"
  	}
  
  	// Validate the request.
  	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)
  		}
  		// These headers are meaningful only if the request has a body,
  		// but PUSH_PROMISE requests cannot have a body.
  		// http://tools.ietf.org/html/rfc7540#section-8.2
  		// Also disallow Host, since the promised URL must be absolute.
  		switch strings.ToLower(k) {
  		case "content-length", "content-encoding", "trailer", "te", "expect", "host":
  			return fmt.Errorf("promised request headers cannot include %q", k)
  		}
  	}
  	if err := http2checkValidHTTP2RequestHeaders(opts.Header); err != nil {
  		return err
  	}
  
  	// The RFC effectively limits promised requests to GET and HEAD:
  	// "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
  	// http://tools.ietf.org/html/rfc7540#section-8.2
  	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()
  
  	// http://tools.ietf.org/html/rfc7540#section-6.6.
  	// PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
  	// is in either the "open" or "half-closed (remote)" state.
  	if msg.parent.state != http2stateOpen && msg.parent.state != http2stateHalfClosedRemote {
  		// responseWriter.Push checks that the stream is peer-initiaed.
  		msg.done <- http2errStreamClosed
  		return
  	}
  
  	// http://tools.ietf.org/html/rfc7540#section-6.6.
  	if !sc.pushEnabled {
  		msg.done <- ErrNotSupported
  		return
  	}
  
  	// PUSH_PROMISE frames must be sent in increasing order by stream ID, so
  	// we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
  	// is written. Once the ID is allocated, we start the request handler.
  	allocatePromisedID := func() (uint32, error) {
  		sc.serveG.check()
  
  		// Check this again, just in case. Technically, we might have received
  		// an updated SETTINGS by the time we got around to writing this frame.
  		if !sc.pushEnabled {
  			return 0, ErrNotSupported
  		}
  		// http://tools.ietf.org/html/rfc7540#section-6.5.2.
  		if sc.curPushedStreams+1 > sc.clientMaxStreams {
  			return 0, http2ErrPushLimitReached
  		}
  
  		// http://tools.ietf.org/html/rfc7540#section-5.1.1.
  		// Streams initiated by the server MUST use even-numbered identifiers.
  		// A server that is unable to establish a new stream identifier can send a GOAWAY
  		// frame so that the client is forced to open a new connection for new streams.
  		if sc.maxPushPromiseID+2 >= 1<<31 {
  			sc.startGracefulShutdownInternal()
  			return 0, http2ErrPushLimitReached
  		}
  		sc.maxPushPromiseID += 2
  		promisedID := sc.maxPushPromiseID
  
  		// http://tools.ietf.org/html/rfc7540#section-8.2.
  		// Strictly speaking, the new stream should start in "reserved (local)", then
  		// transition to "half closed (remote)" after sending the initial HEADERS, but
  		// we start in "half closed (remote)" for simplicity.
  		// See further comments at the definition of stateHalfClosedRemote.
  		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), // clone since handler runs concurrently with writing the PUSH_PROMISE
  		})
  		if err != nil {
  			// Should not happen, since we've already validated msg.url.
  			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,
  	})
  }
  
  // foreachHeaderElement splits v according to the "#rule" construction
  // in RFC 2616 section 2.1 and calls fn for each non-empty element.
  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)
  		}
  	}
  }
  
  // From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
  var http2connHeaders = []string{
  	"Connection",
  	"Keep-Alive",
  	"Proxy-Connection",
  	"Transfer-Encoding",
  	"Upgrade",
  }
  
  // checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
  // per RFC 7540 Section 8.1.2.2.
  // The returned error is reported to users.
  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)
  	}
  }
  
  // ValidTrailerHeader reports whether name is a valid header field name to appear
  // in trailers.
  // See: http://tools.ietf.org/html/rfc7230#section-4.1.2
  func http2ValidTrailerHeader(name string) bool {
  	name = CanonicalHeaderKey(name)
  	if strings.HasPrefix(name, "If-") || http2badTrailer[name] {
  		return false
  	}
  	return true
  }
  
  var http2badTrailer = map[string]bool{
  	"Authorization":       true,
  	"Cache-Control":       true,
  	"Connection":          true,
  	"Content-Encoding":    true,
  	"Content-Length":      true,
  	"Content-Range":       true,
  	"Content-Type":        true,
  	"Expect":              true,
  	"Host":                true,
  	"Keep-Alive":          true,
  	"Max-Forwards":        true,
  	"Pragma":              true,
  	"Proxy-Authenticate":  true,
  	"Proxy-Authorization": true,
  	"Proxy-Connection":    true,
  	"Range":               true,
  	"Realm":               true,
  	"Te":                  true,
  	"Trailer":             true,
  	"Transfer-Encoding":   true,
  	"Www-Authenticate":    true,
  }
  
  // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
  // disabled. See comments on h1ServerShutdownChan above for why
  // the code is written this way.
  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
  }
  
  const (
  	// transportDefaultConnFlow is how many connection-level flow control
  	// tokens we give the server at start-up, past the default 64k.
  	http2transportDefaultConnFlow = 1 << 30
  
  	// transportDefaultStreamFlow is how many stream-level flow
  	// control tokens we announce to the peer, and how many bytes
  	// we buffer per stream.
  	http2transportDefaultStreamFlow = 4 << 20
  
  	// transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
  	// a stream-level WINDOW_UPDATE for at a time.
  	http2transportDefaultStreamMinRefresh = 4 << 10
  
  	http2defaultUserAgent = "Go-http-client/2.0"
  )
  
  // Transport is an HTTP/2 Transport.
  //
  // A Transport internally caches connections to servers. It is safe
  // for concurrent use by multiple goroutines.
  type http2Transport struct {
  	// DialTLS specifies an optional dial function for creating
  	// TLS connections for requests.
  	//
  	// If DialTLS is nil, tls.Dial is used.
  	//
  	// If the returned net.Conn has a ConnectionState method like tls.Conn,
  	// it will be used to set http.Response.TLS.
  	DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
  
  	// TLSClientConfig specifies the TLS configuration to use with
  	// tls.Client. If nil, the default configuration is used.
  	TLSClientConfig *tls.Config
  
  	// ConnPool optionally specifies an alternate connection pool to use.
  	// If nil, the default is used.
  	ConnPool http2ClientConnPool
  
  	// DisableCompression, if true, prevents the Transport from
  	// requesting compression with an "Accept-Encoding: gzip"
  	// request header when the Request contains no existing
  	// Accept-Encoding value. If the Transport requests gzip on
  	// its own and gets a gzipped response, it's transparently
  	// decoded in the Response.Body. However, if the user
  	// explicitly requested gzip it is not automatically
  	// uncompressed.
  	DisableCompression bool
  
  	// AllowHTTP, if true, permits HTTP/2 requests using the insecure,
  	// plain-text "http" scheme. Note that this does not enable h2c support.
  	AllowHTTP bool
  
  	// MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
  	// send in the initial settings frame. It is how many bytes
  	// of response headers are allow. Unlike the http2 spec, zero here
  	// means to use a default limit (currently 10MB). If you actually
  	// want to advertise an ulimited value to the peer, Transport
  	// interprets the highest possible value here (0xffffffff or 1<<32-1)
  	// to mean no limit.
  	MaxHeaderListSize uint32
  
  	// t1, if non-nil, is the standard library Transport using
  	// this transport. Its settings are used (but not its
  	// RoundTrip method, etc).
  	t1 *Transport
  
  	connPoolOnce  sync.Once
  	connPoolOrDef http2ClientConnPool // non-nil version of ConnPool
  }
  
  func (t *http2Transport) maxHeaderListSize() uint32 {
  	if t.MaxHeaderListSize == 0 {
  		return 10 << 20
  	}
  	if t.MaxHeaderListSize == 0xffffffff {
  		return 0
  	}
  	return t.MaxHeaderListSize
  }
  
  func (t *http2Transport) disableCompression() bool {
  	return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
  }
  
  var http2errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
  
  // ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
  // It requires Go 1.6 or later and returns an error if the net/http package is too old
  // or if t1 has already been HTTP/2-enabled.
  func http2ConfigureTransport(t1 *Transport) error {
  	_, err := http2configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
  	return err
  }
  
  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}
  	}
  }
  
  // ClientConn is the state of a single HTTP/2 client connection to an
  // HTTP/2 server.
  type http2ClientConn struct {
  	t         *http2Transport
  	tconn     net.Conn             // usually *tls.Conn, except specialized impls
  	tlsState  *tls.ConnectionState // nil only for specialized impls
  	singleUse bool                 // whether being used for a single http.Request
  
  	// readLoop goroutine fields:
  	readerDone chan struct{} // closed on error
  	readerErr  error         // set before readerDone is closed
  
  	idleTimeout time.Duration // or 0 for never
  	idleTimer   *time.Timer
  
  	mu              sync.Mutex // guards following
  	cond            *sync.Cond // hold mu; broadcast on flow/closed changes
  	flow            http2flow  // our conn-level flow control quota (cs.flow is per stream)
  	inflow          http2flow  // peer's conn-level flow control
  	closed          bool
  	wantSettingsAck bool                          // we sent a SETTINGS frame and haven't heard back
  	goAway          *http2GoAwayFrame             // if non-nil, the GoAwayFrame we received
  	goAwayDebug     string                        // goAway frame's debug data, retained as a string
  	streams         map[uint32]*http2clientStream // client-initiated
  	nextStreamID    uint32
  	pings           map[[8]byte]chan struct{} // in flight ping data to notification channel
  	bw              *bufio.Writer
  	br              *bufio.Reader
  	fr              *http2Framer
  	lastActive      time.Time
  	// Settings from peer: (also guarded by mu)
  	maxFrameSize         uint32
  	maxConcurrentStreams uint32
  	initialWindowSize    uint32
  
  	hbuf    bytes.Buffer // HPACK encoder writes into this
  	henc    *hpack.Encoder
  	freeBuf [][]byte
  
  	wmu  sync.Mutex // held while writing; acquire AFTER mu if holding both
  	werr error      // first write error that has occurred
  }
  
  // clientStream is the state for a single HTTP/2 stream. One of these
  // is created for each Transport.RoundTrip call.
  type http2clientStream struct {
  	cc            *http2ClientConn
  	req           *Request
  	trace         *http2clientTrace // or nil
  	ID            uint32
  	resc          chan http2resAndError
  	bufPipe       http2pipe // buffered pipe with the flow-controlled response payload
  	startedWrite  bool      // started request body write; guarded by cc.mu
  	requestedGzip bool
  	on100         func() // optional code to run if get a 100 continue response
  
  	flow        http2flow // guarded by cc.mu
  	inflow      http2flow // guarded by cc.mu
  	bytesRemain int64     // -1 means unknown; owned by transportResponseBody.Read
  	readErr     error     // sticky read error; owned by transportResponseBody.Read
  	stopReqBody error     // if non-nil, stop writing req body; guarded by cc.mu
  	didReset    bool      // whether we sent a RST_STREAM to the server; guarded by cc.mu
  
  	peerReset chan struct{} // closed on peer reset
  	resetErr  error         // populated before peerReset is closed
  
  	done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
  
  	// owned by clientConnReadLoop:
  	firstByte    bool // got the first response byte
  	pastHeaders  bool // got first MetaHeadersFrame (actual headers)
  	pastTrailers bool // got optional second MetaHeadersFrame (trailers)
  
  	trailer    Header  // accumulated trailers
  	resTrailer *Header // client's Response.Trailer
  }
  
  // awaitRequestCancel runs in its own goroutine and waits for the user
  // to cancel a RoundTrip request, its context to expire, or for the
  // request to be done (any way it might be removed from the cc.streams
  // map: peer reset, successful completion, TCP connection breakage,
  // etc)
  func (cs *http2clientStream) awaitRequestCancel(req *Request) {
  	ctx := http2reqContext(req)
  	if req.Cancel == nil && ctx.Done() == nil {
  		return
  	}
  	select {
  	case <-req.Cancel:
  		cs.cancelStream()
  		cs.bufPipe.CloseWithError(http2errRequestCanceled)
  	case <-ctx.Done():
  		cs.cancelStream()
  		cs.bufPipe.CloseWithError(ctx.Err())
  	case <-cs.done:
  	}
  }
  
  func (cs *http2clientStream) cancelStream() {
  	cs.cc.mu.Lock()
  	didReset := cs.didReset
  	cs.didReset = true
  	cs.cc.mu.Unlock()
  
  	if !didReset {
  		cs.cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
  	}
  }
  
  // checkResetOrDone reports any error sent in a RST_STREAM frame by the
  // server, or errStreamClosed if the stream is complete.
  func (cs *http2clientStream) checkResetOrDone() error {
  	select {
  	case <-cs.peerReset:
  		return cs.resetErr
  	case <-cs.done:
  		return http2errStreamClosed
  	default:
  		return nil
  	}
  }
  
  func (cs *http2clientStream) abortRequestBodyWrite(err error) {
  	if err == nil {
  		panic("nil error")
  	}
  	cc := cs.cc
  	cc.mu.Lock()
  	cs.stopReqBody = err
  	cc.cond.Broadcast()
  	cc.mu.Unlock()
  }
  
  type http2stickyErrWriter struct {
  	w   io.Writer
  	err *error
  }
  
  func (sew http2stickyErrWriter) Write(p []byte) (n int, err error) {
  	if *sew.err != nil {
  		return 0, *sew.err
  	}
  	n, err = sew.w.Write(p)
  	*sew.err = err
  	return
  }
  
  var http2ErrNoCachedConn = errors.New("http2: no cached connection was available")
  
  // RoundTripOpt are options for the Transport.RoundTripOpt method.
  type http2RoundTripOpt struct {
  	// OnlyCachedConn controls whether RoundTripOpt may
  	// create a new TCP connection. If set true and
  	// no cached connection is available, RoundTripOpt
  	// will return ErrNoCachedConn.
  	OnlyCachedConn bool
  }
  
  func (t *http2Transport) RoundTrip(req *Request) (*Response, error) {
  	return t.RoundTripOpt(req, http2RoundTripOpt{})
  }
  
  // authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
  // and returns a host:port. The port 443 is added if needed.
  func http2authorityAddr(scheme string, authority string) (addr string) {
  	host, port, err := net.SplitHostPort(authority)
  	if err != nil { // authority didn't have a port
  		port = "443"
  		if scheme == "http" {
  			port = "80"
  		}
  		host = authority
  	}
  	if a, err := idna.ToASCII(host); err == nil {
  		host = a
  	}
  	// IPv6 address literal, without a port:
  	if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
  		return host + ":" + port
  	}
  	return net.JoinHostPort(host, port)
  }
  
  // RoundTripOpt is like RoundTrip, but takes options.
  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 {
  		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
  		}
  		http2traceGotConn(req, cc)
  		res, err := cc.RoundTrip(req)
  		if err != nil {
  			if req, err = http2shouldRetryRequest(req, err); err == nil {
  				continue
  			}
  		}
  		if err != nil {
  			t.vlogf("RoundTrip failure: %v", err)
  			return nil, err
  		}
  		return res, nil
  	}
  }
  
  // CloseIdleConnections closes any connections which were previously
  // connected from previous requests but are now sitting idle.
  // It does not interrupt any connections currently in use.
  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")
  	http2errClientConnGotGoAwayAfterSomeReqBody = errors.New("http2: Transport received Server's graceful shutdown GOAWAY; some request body already written")
  )
  
  // shouldRetryRequest is called by RoundTrip when a request fails to get
  // response headers. It is always called with a non-nil error.
  // It returns either a request to retry (either the same request, or a
  // modified clone), or an error if the request can't be replayed.
  func http2shouldRetryRequest(req *Request, err error) (*Request, error) {
  	switch err {
  	default:
  		return nil, err
  	case http2errClientConnUnusable, http2errClientConnGotGoAway:
  		return req, nil
  	case http2errClientConnGotGoAwayAfterSomeReqBody:
  		// If the Body is nil (or http.NoBody), it's safe to reuse
  		// this request and its Body.
  		if req.Body == nil || http2reqBodyIsNoBody(req.Body) {
  			return req, nil
  		}
  		// Otherwise we depend on the Request having its GetBody
  		// func defined.
  		getBody := http2reqGetBody(req) // Go 1.8: getBody = req.GetBody
  		if getBody == nil {
  			return nil, errors.New("http2: Transport: peer server initiated graceful shutdown after some of Request.Body was written; define Request.GetBody to avoid this error")
  		}
  		body, err := getBody()
  		if err != nil {
  			return nil, err
  		}
  		newReq := *req
  		newReq.Body = body
  		return &newReq, nil
  	}
  }
  
  func (t *http2Transport) dialClientConn(addr string, singleUse bool) (*http2ClientConn, error) {
  	host, _, err := net.SplitHostPort(addr)
  	if err != nil {
  		return nil, err
  	}
  	tconn, err := t.dialTLS()("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 = *http2cloneTLSConfig(t.TLSClientConfig)
  	}
  	if !http2strSliceContains(cfg.NextProtos, http2NextProtoTLS) {
  		cfg.NextProtos = append([]string{http2NextProtoTLS}, cfg.NextProtos...)
  	}
  	if cfg.ServerName == "" {
  		cfg.ServerName = host
  	}
  	return cfg
  }
  
  func (t *http2Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
  	if t.DialTLS != nil {
  		return t.DialTLS
  	}
  	return t.dialTLSDefault
  }
  
  func (t *http2Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
  	cn, err := tls.Dial(network, addr, cfg)
  	if err != nil {
  		return nil, err
  	}
  	if err := cn.Handshake(); err != nil {
  		return nil, err
  	}
  	if !cfg.InsecureSkipVerify {
  		if err := cn.VerifyHostname(cfg.ServerName); err != nil {
  			return nil, err
  		}
  	}
  	state := cn.ConnectionState()
  	if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
  		return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
  	}
  	if !state.NegotiatedProtocolIsMutual {
  		return nil, errors.New("http2: could not negotiate protocol mutually")
  	}
  	return cn, nil
  }
  
  // disableKeepAlives reports whether connections should be closed as
  // soon as possible after handling the first request.
  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 http2transportExpectContinueTimeout(t.t1)
  }
  
  func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) {
  	return t.newClientConn(c, false)
  }
  
  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, // spec default
  		initialWindowSize:    65535,    // spec default
  		maxConcurrentStreams: 1000,     // "infinite", per spec. 1000 seems good enough.
  		streams:              make(map[uint32]*http2clientStream),
  		singleUse:            singleUse,
  		wantSettingsAck:      true,
  		pings:                make(map[[8]byte]chan struct{}),
  	}
  	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))
  
  	// TODO: adjust this writer size to account for frame size +
  	// MTU + crypto/tls record padding.
  	cc.bw = bufio.NewWriter(http2stickyErrWriter{c, &cc.werr})
  	cc.br = bufio.NewReader(c)
  	cc.fr = http2NewFramer(cc.bw, cc.br)
  	cc.fr.ReadMetaHeaders = hpack.NewDecoder(http2initialHeaderTableSize, nil)
  	cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
  
  	// TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
  	// henc in response to SETTINGS frames?
  	cc.henc = hpack.NewEncoder(&cc.hbuf)
  
  	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.maxHeaderListSize(); max != 0 {
  		initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxHeaderListSize, Val: max})
  	}
  
  	cc.bw.Write(http2clientPreface)
  	cc.fr.WriteSettings(initialSettings...)
  	cc.fr.WriteWindowUpdate(0, http2transportDefaultConnFlow)
  	cc.inflow.add(http2transportDefaultConnFlow + http2initialWindowSize)
  	cc.bw.Flush()
  	if cc.werr != nil {
  		return nil, cc.werr
  	}
  
  	go cc.readLoop()
  	return cc, nil
  }
  
  func (cc *http2ClientConn) setGoAway(f *http2GoAwayFrame) {
  	cc.mu.Lock()
  	defer cc.mu.Unlock()
  
  	old := cc.goAway
  	cc.goAway = f
  
  	// Merge the previous and current GoAway error frames.
  	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 {
  			select {
  			case cs.resc <- http2resAndError{err: http2errClientConnGotGoAway}:
  			default:
  			}
  		}
  	}
  }
  
  func (cc *http2ClientConn) CanTakeNewRequest() bool {
  	cc.mu.Lock()
  	defer cc.mu.Unlock()
  	return cc.canTakeNewRequestLocked()
  }
  
  func (cc *http2ClientConn) canTakeNewRequestLocked() bool {
  	if cc.singleUse && cc.nextStreamID > 1 {
  		return false
  	}
  	return cc.goAway == nil && !cc.closed &&
  		int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
  		cc.nextStreamID < math.MaxInt32
  }
  
  // onIdleTimeout is called from a time.AfterFunc goroutine. It will
  // only be called when we're idle, but because we're coming from a new
  // goroutine, there could be a new request coming in at the same time,
  // so this simply calls the synchronized closeIfIdle to shut down this
  // connection. The timer could just call closeIfIdle, but this is more
  // clear.
  func (cc *http2ClientConn) onIdleTimeout() {
  	cc.closeIfIdle()
  }
  
  func (cc *http2ClientConn) closeIfIdle() {
  	cc.mu.Lock()
  	if len(cc.streams) > 0 {
  		cc.mu.Unlock()
  		return
  	}
  	cc.closed = true
  	nextID := cc.nextStreamID
  	// TODO: do clients send GOAWAY too? maybe? Just Close:
  	cc.mu.Unlock()
  
  	if http2VerboseLogs {
  		cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
  	}
  	cc.tconn.Close()
  }
  
  const http2maxAllocFrameSize = 512 << 10
  
  // frameBuffer returns a scratch buffer suitable for writing DATA frames.
  // They're capped at the min of the peer's max frame size or 512KB
  // (kinda arbitrarily), but definitely capped so we don't allocate 4GB
  // bufers.
  func (cc *http2ClientConn) frameScratchBuffer() []byte {
  	cc.mu.Lock()
  	size := cc.maxFrameSize
  	if size > http2maxAllocFrameSize {
  		size = http2maxAllocFrameSize
  	}
  	for i, buf := range cc.freeBuf {
  		if len(buf) >= int(size) {
  			cc.freeBuf[i] = nil
  			cc.mu.Unlock()
  			return buf[:size]
  		}
  	}
  	cc.mu.Unlock()
  	return make([]byte, size)
  }
  
  func (cc *http2ClientConn) putFrameScratchBuffer(buf []byte) {
  	cc.mu.Lock()
  	defer cc.mu.Unlock()
  	const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate.
  	if len(cc.freeBuf) < maxBufs {
  		cc.freeBuf = append(cc.freeBuf, buf)
  		return
  	}
  	for i, old := range cc.freeBuf {
  		if old == nil {
  			cc.freeBuf[i] = buf
  			return
  		}
  	}
  	// forget about it.
  }
  
  // errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
  // exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
  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 = CanonicalHeaderKey(k)
  		switch k {
  		case "Transfer-Encoding", "Trailer", "Content-Length":
  			return "", &http2badStringError{"invalid Trailer key", 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
  	}
  	// No way to do this (yet?) with just an http2.Transport. Probably
  	// no need. Request.Cancel this is the new way. We only need to support
  	// this for compatibility with the old http.Transport fields when
  	// we're doing transparent http2.
  	return 0
  }
  
  // checkConnHeaders checks whether req has any invalid connection-level headers.
  // per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
  // Certain headers are special-cased as okay but not transmitted later.
  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] != "" && vv[0] != "close" && vv[0] != "keep-alive") {
  		return fmt.Errorf("http2: invalid Connection request header: %q", vv)
  	}
  	return nil
  }
  
  // actualContentLength returns a sanitized version of
  // req.ContentLength, where 0 actually means zero (not unknown) and -1
  // means unknown.
  func http2actualContentLength(req *Request) int64 {
  	if req.Body == nil || http2reqBodyIsNoBody(req.Body) {
  		return 0
  	}
  	if req.ContentLength != 0 {
  		return req.ContentLength
  	}
  	return -1
  }
  
  func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
  	if err := http2checkConnHeaders(req); err != nil {
  		return nil, err
  	}
  	if cc.idleTimer != nil {
  		cc.idleTimer.Stop()
  	}
  
  	trailers, err := http2commaSeparatedTrailers(req)
  	if err != nil {
  		return nil, err
  	}
  	hasTrailers := trailers != ""
  
  	cc.mu.Lock()
  	cc.lastActive = time.Now()
  	if cc.closed || !cc.canTakeNewRequestLocked() {
  		cc.mu.Unlock()
  		return nil, http2errClientConnUnusable
  	}
  
  	body := req.Body
  	contentLen := http2actualContentLength(req)
  	hasBody := contentLen != 0
  
  	// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
  	var requestedGzip bool
  	if !cc.t.disableCompression() &&
  		req.Header.Get("Accept-Encoding") == "" &&
  		req.Header.Get("Range") == "" &&
  		req.Method != "HEAD" {
  		// Request gzip only, not deflate. Deflate is ambiguous and
  		// not as universally supported anyway.
  		// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
  		//
  		// Note that we don't request this for HEAD requests,
  		// due to a bug in nginx:
  		//   http://trac.nginx.org/nginx/ticket/358
  		//   https://golang.org/issue/5522
  		//
  		// We don't request gzip if the request is for a range, since
  		// auto-decoding a portion of a gzipped document will just fail
  		// anyway. See https://golang.org/issue/8923
  		requestedGzip = true
  	}
  
  	// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
  	// sent by writeRequestBody below, along with any Trailers,
  	// again in form HEADERS{1}, CONTINUATION{0,})
  	hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen)
  	if err != nil {
  		cc.mu.Unlock()
  		return nil, err
  	}
  
  	cs := cc.newStream()
  	cs.req = req
  	cs.trace = http2requestTrace(req)
  	cs.requestedGzip = requestedGzip
  	bodyWriter := cc.t.getBodyWriterState(cs, body)
  	cs.on100 = bodyWriter.on100
  
  	cc.wmu.Lock()
  	endStream := !hasBody && !hasTrailers
  	werr := cc.writeHeaders(cs.ID, endStream, hdrs)
  	cc.wmu.Unlock()
  	http2traceWroteHeaders(cs.trace)
  	cc.mu.Unlock()
  
  	if werr != nil {
  		if hasBody {
  			req.Body.Close() // per RoundTripper contract
  			bodyWriter.cancel()
  		}
  		cc.forgetStreamID(cs.ID)
  		// Don't bother sending a RST_STREAM (our write already failed;
  		// no need to keep writing)
  		http2traceWroteRequest(cs.trace, werr)
  		return nil, werr
  	}
  
  	var respHeaderTimer <-chan time.Time
  	if hasBody {
  		bodyWriter.scheduleBodyWrite()
  	} else {
  		http2traceWroteRequest(cs.trace, nil)
  		if d := cc.responseHeaderTimeout(); d != 0 {
  			timer := time.NewTimer(d)
  			defer timer.Stop()
  			respHeaderTimer = timer.C
  		}
  	}
  
  	readLoopResCh := cs.resc
  	bodyWritten := false
  	ctx := http2reqContext(req)
  
  	handleReadLoopResponse := func(re http2resAndError) (*Response, error) {
  		res := re.res
  		if re.err != nil || res.StatusCode > 299 {
  			// On error or status code 3xx, 4xx, 5xx, etc abort any
  			// ongoing write, assuming that the server doesn't care
  			// about our request body. If the server replied with 1xx or
  			// 2xx, however, then assume the server DOES potentially
  			// want our body (e.g. full-duplex streaming:
  			// golang.org/issue/13444). If it turns out the server
  			// doesn't, they'll RST_STREAM us soon enough. This is a
  			// heuristic to avoid adding knobs to Transport. Hopefully
  			// we can keep it.
  			bodyWriter.cancel()
  			cs.abortRequestBodyWrite(http2errStopReqBodyWrite)
  		}
  		if re.err != nil {
  			if re.err == http2errClientConnGotGoAway {
  				cc.mu.Lock()
  				if cs.startedWrite {
  					re.err = http2errClientConnGotGoAwayAfterSomeReqBody
  				}
  				cc.mu.Unlock()
  			}
  			cc.forgetStreamID(cs.ID)
  			return nil, re.err
  		}
  		res.Request = req
  		res.TLS = cc.tlsState
  		return res, nil
  	}
  
  	for {
  		select {
  		case re := <-readLoopResCh:
  			return handleReadLoopResponse(re)
  		case <-respHeaderTimer:
  			cc.forgetStreamID(cs.ID)
  			if !hasBody || bodyWritten {
  				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
  			} else {
  				bodyWriter.cancel()
  				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
  			}
  			return nil, http2errTimeout
  		case <-ctx.Done():
  			cc.forgetStreamID(cs.ID)
  			if !hasBody || bodyWritten {
  				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
  			} else {
  				bodyWriter.cancel()
  				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
  			}
  			return nil, ctx.Err()
  		case <-req.Cancel:
  			cc.forgetStreamID(cs.ID)
  			if !hasBody || bodyWritten {
  				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
  			} else {
  				bodyWriter.cancel()
  				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
  			}
  			return nil, http2errRequestCanceled
  		case <-cs.peerReset:
  			// processResetStream already removed the
  			// stream from the streams map; no need for
  			// forgetStreamID.
  			return nil, cs.resetErr
  		case err := <-bodyWriter.resc:
  			// Prefer the read loop's response, if available. Issue 16102.
  			select {
  			case re := <-readLoopResCh:
  				return handleReadLoopResponse(re)
  			default:
  			}
  			if err != nil {
  				return nil, err
  			}
  			bodyWritten = true
  			if d := cc.responseHeaderTimeout(); d != 0 {
  				timer := time.NewTimer(d)
  				defer timer.Stop()
  				respHeaderTimer = timer.C
  			}
  		}
  	}
  }
  
  // requires cc.wmu be held
  func (cc *http2ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
  	first := true // first frame written (HEADERS is first, then CONTINUATION)
  	frameSize := int(cc.maxFrameSize)
  	for len(hdrs) > 0 && cc.werr == nil {
  		chunk := hdrs
  		if len(chunk) > frameSize {
  			chunk = chunk[:frameSize]
  		}
  		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)
  		}
  	}
  	// TODO(bradfitz): this Flush could potentially block (as
  	// could the WriteHeaders call(s) above), which means they
  	// wouldn't respond to Request.Cancel being readable. That's
  	// rare, but this should probably be in a goroutine.
  	cc.bw.Flush()
  	return cc.werr
  }
  
  // internal error values; they don't escape to callers
  var (
  	// abort request body write; don't send cancel
  	http2errStopReqBodyWrite = errors.New("http2: aborting request body write")
  
  	// abort request body write, but send stream reset of cancel.
  	http2errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
  )
  
  func (cs *http2clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
  	cc := cs.cc
  	sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
  	buf := cc.frameScratchBuffer()
  	defer cc.putFrameScratchBuffer(buf)
  
  	defer func() {
  		http2traceWroteRequest(cs.trace, err)
  		// TODO: write h12Compare test showing whether
  		// Request.Body is closed by the Transport,
  		// and in multiple cases: server replies <=299 and >299
  		// while still writing request body
  		cerr := bodyCloser.Close()
  		if err == nil {
  			err = cerr
  		}
  	}()
  
  	req := cs.req
  	hasTrailers := req.Trailer != nil
  
  	var sawEOF bool
  	for !sawEOF {
  		n, err := body.Read(buf)
  		if err == io.EOF {
  			sawEOF = true
  			err = nil
  		} else if err != nil {
  			return err
  		}
  
  		remain := buf[:n]
  		for len(remain) > 0 && err == nil {
  			var allowed int32
  			allowed, err = cs.awaitFlowControl(len(remain))
  			switch {
  			case err == http2errStopReqBodyWrite:
  				return err
  			case err == http2errStopReqBodyWriteAndCancel:
  				cc.writeStreamReset(cs.ID, http2ErrCodeCancel, nil)
  				return err
  			case 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 {
  				// TODO(bradfitz): this flush is for latency, not bandwidth.
  				// Most requests won't need this. Make this opt-in or
  				// opt-out?  Use some heuristic on the body type? Nagel-like
  				// timers?  Based on 'n'? Only last chunk of this for loop,
  				// unless flow control tokens are low? For now, always.
  				// If we change this, see comment below.
  				err = cc.bw.Flush()
  			}
  			cc.wmu.Unlock()
  		}
  		if err != nil {
  			return err
  		}
  	}
  
  	if sentEnd {
  		// Already sent END_STREAM (which implies we have no
  		// trailers) and flushed, because currently all
  		// WriteData frames above get a flush. So we're done.
  		return nil
  	}
  
  	var trls []byte
  	if hasTrailers {
  		cc.mu.Lock()
  		defer cc.mu.Unlock()
  		trls = cc.encodeTrailers(req)
  	}
  
  	cc.wmu.Lock()
  	defer cc.wmu.Unlock()
  
  	// Two ways to send END_STREAM: either with trailers, or
  	// with an empty DATA frame.
  	if len(trls) > 0 {
  		err = cc.writeHeaders(cs.ID, true, trls)
  	} else {
  		err = cc.fr.WriteData(cs.ID, true, nil)
  	}
  	if ferr := cc.bw.Flush(); ferr != nil && err == nil {
  		err = ferr
  	}
  	return err
  }
  
  // awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
  // control tokens from the server.
  // It returns either the non-zero number of tokens taken or an error
  // if the stream is dead.
  func (cs *http2clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
  	cc := cs.cc
  	cc.mu.Lock()
  	defer cc.mu.Unlock()
  	for {
  		if cc.closed {
  			return 0, http2errClientConnClosed
  		}
  		if cs.stopReqBody != nil {
  			return 0, cs.stopReqBody
  		}
  		if err := cs.checkResetOrDone(); err != nil {
  			return 0, err
  		}
  		if a := cs.flow.available(); a > 0 {
  			take := a
  			if int(take) > maxBytes {
  
  				take = int32(maxBytes) // can't truncate int; take is int32
  			}
  			if take > int32(cc.maxFrameSize) {
  				take = int32(cc.maxFrameSize)
  			}
  			cs.flow.take(take)
  			return take, nil
  		}
  		cc.cond.Wait()
  	}
  }
  
  type http2badStringError struct {
  	what string
  	str  string
  }
  
  func (e *http2badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
  
  // requires cc.mu be held.
  func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
  	cc.hbuf.Reset()
  
  	host := req.Host
  	if host == "" {
  		host = req.URL.Host
  	}
  	host, err := httplex.PunycodeHostPort(host)
  	if err != nil {
  		return nil, err
  	}
  
  	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)
  				}
  			}
  		}
  	}
  
  	// Check for any invalid headers and return an error before we
  	// potentially pollute our hpack state. (We want to be able to
  	// continue to reuse the hpack encoder for future requests)
  	for k, vv := range req.Header {
  		if !httplex.ValidHeaderFieldName(k) {
  			return nil, fmt.Errorf("invalid HTTP header name %q", k)
  		}
  		for _, v := range vv {
  			if !httplex.ValidHeaderFieldValue(v) {
  				return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k)
  			}
  		}
  	}
  
  	// 8.1.2.3 Request Pseudo-Header Fields
  	// The :path pseudo-header field includes the path and query parts of the
  	// target URI (the path-absolute production and optionally a '?' character
  	// followed by the query production (see Sections 3.3 and 3.4 of
  	// [RFC3986]).
  	cc.writeHeader(":authority", host)
  	cc.writeHeader(":method", req.Method)
  	if req.Method != "CONNECT" {
  		cc.writeHeader(":path", path)
  		cc.writeHeader(":scheme", req.URL.Scheme)
  	}
  	if trailers != "" {
  		cc.writeHeader("trailer", trailers)
  	}
  
  	var didUA bool
  	for k, vv := range req.Header {
  		lowKey := strings.ToLower(k)
  		switch lowKey {
  		case "host", "content-length":
  			// Host is :authority, already sent.
  			// Content-Length is automatic, set below.
  			continue
  		case "connection", "proxy-connection", "transfer-encoding", "upgrade", "keep-alive":
  			// Per 8.1.2.2 Connection-Specific Header
  			// Fields, don't send connection-specific
  			// fields. We have already checked if any
  			// are error-worthy so just ignore the rest.
  			continue
  		case "user-agent":
  			// Match Go's http1 behavior: at most one
  			// User-Agent. If set to nil or empty string,
  			// then omit it. Otherwise if not mentioned,
  			// include the default (below).
  			didUA = true
  			if len(vv) < 1 {
  				continue
  			}
  			vv = vv[:1]
  			if vv[0] == "" {
  				continue
  			}
  		}
  		for _, v := range vv {
  			cc.writeHeader(lowKey, v)
  		}
  	}
  	if http2shouldSendReqContentLength(req.Method, contentLength) {
  		cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10))
  	}
  	if addGzipHeader {
  		cc.writeHeader("accept-encoding", "gzip")
  	}
  	if !didUA {
  		cc.writeHeader("user-agent", http2defaultUserAgent)
  	}
  	return cc.hbuf.Bytes(), nil
  }
  
  // shouldSendReqContentLength reports whether the http2.Transport should send
  // a "content-length" request header. This logic is basically a copy of the net/http
  // transferWriter.shouldSendContentLength.
  // The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
  // -1 means unknown.
  func http2shouldSendReqContentLength(method string, contentLength int64) bool {
  	if contentLength > 0 {
  		return true
  	}
  	if contentLength < 0 {
  		return false
  	}
  	// For zero bodies, whether we send a content-length depends on the method.
  	// It also kinda doesn't matter for http2 either way, with END_STREAM.
  	switch method {
  	case "POST", "PUT", "PATCH":
  		return true
  	default:
  		return false
  	}
  }
  
  // requires cc.mu be held.
  func (cc *http2ClientConn) encodeTrailers(req *Request) []byte {
  	cc.hbuf.Reset()
  	for k, vv := range req.Trailer {
  		// Transfer-Encoding, etc.. have already been filter at the
  		// start of RoundTrip
  		lowKey := strings.ToLower(k)
  		for _, v := range vv {
  			cc.writeHeader(lowKey, v)
  		}
  	}
  	return cc.hbuf.Bytes()
  }
  
  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 {
  	res *Response
  	err error
  }
  
  // requires cc.mu be held.
  func (cc *http2ClientConn) newStream() *http2clientStream {
  	cs := &http2clientStream{
  		cc:        cc,
  		ID:        cc.nextStreamID,
  		resc:      make(chan http2resAndError, 1),
  		peerReset: make(chan struct{}),
  		done:      make(chan struct{}),
  	}
  	cs.flow.add(int32(cc.initialWindowSize))
  	cs.flow.setConnFlow(&cc.flow)
  	cs.inflow.add(http2transportDefaultStreamFlow)
  	cs.inflow.setConnFlow(&cc.inflow)
  	cc.nextStreamID += 2
  	cc.streams[cs.ID] = cs
  	return cs
  }
  
  func (cc *http2ClientConn) forgetStreamID(id uint32) {
  	cc.streamByID(id, true)
  }
  
  func (cc *http2ClientConn) streamByID(id uint32, andRemove bool) *http2clientStream {
  	cc.mu.Lock()
  	defer cc.mu.Unlock()
  	cs := cc.streams[id]
  	if andRemove && cs != nil && !cc.closed {
  		cc.lastActive = time.Now()
  		delete(cc.streams, id)
  		if len(cc.streams) == 0 && cc.idleTimer != nil {
  			cc.idleTimer.Reset(cc.idleTimeout)
  		}
  		close(cs.done)
  		cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
  	}
  	return cs
  }
  
  // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
  type http2clientConnReadLoop struct {
  	cc            *http2ClientConn
  	activeRes     map[uint32]*http2clientStream // keyed by streamID
  	closeWhenIdle bool
  }
  
  // readLoop runs in its own goroutine and reads and dispatches frames.
  func (cc *http2ClientConn) readLoop() {
  	rl := &http2clientConnReadLoop{
  		cc:        cc,
  		activeRes: make(map[uint32]*http2clientStream),
  	}
  
  	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()
  	}
  }
  
  // GoAwayError is returned by the Transport when the server closes the
  // TCP connection after sending a GOAWAY frame.
  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
  	defer cc.tconn.Close()
  	defer cc.t.connPool().MarkDead(cc)
  	defer close(cc.readerDone)
  
  	if cc.idleTimer != nil {
  		cc.idleTimer.Stop()
  	}
  
  	// Close any response bodies if the server closes prematurely.
  	// TODO: also do this if we've written the headers but not
  	// gotten a response yet.
  	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
  	}
  	for _, cs := range rl.activeRes {
  		cs.bufPipe.CloseWithError(err)
  	}
  	for _, cs := range cc.streams {
  		select {
  		case cs.resc <- http2resAndError{err: err}:
  		default:
  		}
  		close(cs.done)
  	}
  	cc.closed = true
  	cc.cond.Broadcast()
  	cc.mu.Unlock()
  }
  
  func (rl *http2clientConnReadLoop) run() error {
  	cc := rl.cc
  	rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
  	gotReply := false // ever saw a HEADERS reply
  	gotSettings := false
  	for {
  		f, err := cc.fr.ReadFrame()
  		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 := cc.streamByID(se.StreamID, true /*ended; remove it*/); cs != nil {
  				cs.cc.writeStreamReset(cs.ID, se.Code, err)
  				if se.Cause == nil {
  					se.Cause = cc.fr.errDetail
  				}
  				rl.endStreamError(cs, se)
  			}
  			continue
  		} else if err != nil {
  			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
  		}
  		maybeIdle := false // whether frame might transition us to idle
  
  		switch f := f.(type) {
  		case *http2MetaHeadersFrame:
  			err = rl.processHeaders(f)
  			maybeIdle = true
  			gotReply = true
  		case *http2DataFrame:
  			err = rl.processData(f)
  			maybeIdle = true
  		case *http2GoAwayFrame:
  			err = rl.processGoAway(f)
  			maybeIdle = true
  		case *http2RSTStreamFrame:
  			err = rl.processResetStream(f)
  			maybeIdle = true
  		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
  		}
  		if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
  			cc.closeIfIdle()
  		}
  	}
  }
  
  func (rl *http2clientConnReadLoop) processHeaders(f *http2MetaHeadersFrame) error {
  	cc := rl.cc
  	cs := cc.streamByID(f.StreamID, f.StreamEnded())
  	if cs == nil {
  		// We'd get here if we canceled a request while the
  		// server had its response still in flight. So if this
  		// was just something we canceled, ignore it.
  		return nil
  	}
  	if !cs.firstByte {
  		if cs.trace != nil {
  			// TODO(bradfitz): move first response byte earlier,
  			// when we first read the 9 byte header, not waiting
  			// until all the HEADERS+CONTINUATION frames have been
  			// merged. This works for now.
  			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
  		}
  		// Any other error type is a stream error.
  		cs.cc.writeStreamReset(f.StreamID, http2ErrCodeProtocol, err)
  		cs.resc <- http2resAndError{err: err}
  		return nil // return nil from process* funcs to keep conn alive
  	}
  	if res == nil {
  		// (nil, nil) special case. See handleResponse docs.
  		return nil
  	}
  	if res.Body != http2noBody {
  		rl.activeRes[cs.ID] = cs
  	}
  	cs.resTrailer = &res.Trailer
  	cs.resc <- http2resAndError{res: res}
  	return nil
  }
  
  // may return error types nil, or ConnectionError. Any other error value
  // is a StreamError of type ErrCodeProtocol. The returned error in that case
  // is the detail.
  //
  // As a special case, handleResponse may return (nil, nil) to skip the
  // frame (currently only used for 100 expect continue). This special
  // case is going away after Issue 13851 is fixed.
  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("missing status pseudo header")
  	}
  	statusCode, err := strconv.Atoi(status)
  	if err != nil {
  		return nil, errors.New("malformed non-numeric status pseudo header")
  	}
  
  	if statusCode == 100 {
  		http2traceGot100Continue(cs.trace)
  		if cs.on100 != nil {
  			cs.on100() // forces any write delay timer to fire
  		}
  		cs.pastHeaders = false // do it all again
  		return nil, nil
  	}
  
  	header := make(Header)
  	res := &Response{
  		Proto:      "HTTP/2.0",
  		ProtoMajor: 2,
  		Header:     header,
  		StatusCode: statusCode,
  		Status:     status + " " + StatusText(statusCode),
  	}
  	for _, hf := range f.RegularFields() {
  		key := CanonicalHeaderKey(hf.Name)
  		if key == "Trailer" {
  			t := res.Trailer
  			if t == nil {
  				t = make(Header)
  				res.Trailer = t
  			}
  			http2foreachHeaderElement(hf.Value, func(v string) {
  				t[CanonicalHeaderKey(v)] = nil
  			})
  		} else {
  			header[key] = append(header[key], hf.Value)
  		}
  	}
  
  	streamEnded := f.StreamEnded()
  	isHead := cs.req.Method == "HEAD"
  	if !streamEnded || isHead {
  		res.ContentLength = -1
  		if clens := res.Header["Content-Length"]; len(clens) == 1 {
  			if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
  				res.ContentLength = clen64
  			} else {
  				// TODO: care? unlike http/1, it won't mess up our framing, so it's
  				// more safe smuggling-wise to ignore.
  			}
  		} else if len(clens) > 1 {
  			// TODO: care? unlike http/1, it won't mess up our framing, so it's
  			// more safe smuggling-wise to ignore.
  		}
  	}
  
  	if streamEnded || isHead {
  		res.Body = http2noBody
  		return res, nil
  	}
  
  	cs.bufPipe = http2pipe{b: &http2dataBuffer{expected: res.ContentLength}}
  	cs.bytesRemain = res.ContentLength
  	res.Body = http2transportResponseBody{cs}
  	go cs.awaitRequestCancel(cs.req)
  
  	if cs.requestedGzip && 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}
  		http2setResponseUncompressed(res)
  	}
  	return res, nil
  }
  
  func (rl *http2clientConnReadLoop) processTrailers(cs *http2clientStream, f *http2MetaHeadersFrame) error {
  	if cs.pastTrailers {
  		// Too many HEADERS frames for this stream.
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	cs.pastTrailers = true
  	if !f.StreamEnded() {
  		// We expect that any headers for trailers also
  		// has END_STREAM.
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  	if len(f.PseudoFields()) > 0 {
  		// No pseudo header fields are defined for trailers.
  		// TODO: ConnectionError might be overly harsh? Check.
  		return http2ConnectionError(http2ErrCodeProtocol)
  	}
  
  	trailer := make(Header)
  	for _, hf := range f.RegularFields() {
  		key := CanonicalHeaderKey(hf.Name)
  		trailer[key] = append(trailer[key], hf.Value)
  	}
  	cs.trailer = trailer
  
  	rl.endStream(cs)
  	return nil
  }
  
  // transportResponseBody is the concrete type of Transport.RoundTrip's
  // Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
  // On Close it sends RST_STREAM if EOF wasn't already seen.
  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")
  				cc.writeStreamReset(cs.ID, http2ErrCodeProtocol, 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 {
  		// No flow control tokens to send back.
  		return
  	}
  
  	cc.mu.Lock()
  	defer cc.mu.Unlock()
  
  	var connAdd, streamAdd int32
  	// Check the conn-level first, before the stream-level.
  	if v := cc.inflow.available(); v < http2transportDefaultConnFlow/2 {
  		connAdd = http2transportDefaultConnFlow - v
  		cc.inflow.add(connAdd)
  	}
  	if err == nil { // No need to refresh if the stream is over or failed.
  		// Consider any buffered body data (read from the conn but not
  		// consumed by the client) when computing flow control for this
  		// stream.
  		v := int(cs.inflow.available()) + cs.bufPipe.Len()
  		if v < http2transportDefaultStreamFlow-http2transportDefaultStreamMinRefresh {
  			streamAdd = int32(http2transportDefaultStreamFlow - v)
  			cs.inflow.add(streamAdd)
  		}
  	}
  	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
  
  	serverSentStreamEnd := cs.bufPipe.Err() == io.EOF
  	unread := cs.bufPipe.Len()
  
  	if unread > 0 || !serverSentStreamEnd {
  		cc.mu.Lock()
  		cc.wmu.Lock()
  		if !serverSentStreamEnd {
  			cc.fr.WriteRSTStream(cs.ID, http2ErrCodeCancel)
  			cs.didReset = true
  		}
  		// Return connection-level flow control.
  		if unread > 0 {
  			cc.inflow.add(int32(unread))
  			cc.fr.WriteWindowUpdate(0, uint32(unread))
  		}
  		cc.bw.Flush()
  		cc.wmu.Unlock()
  		cc.mu.Unlock()
  	}
  
  	cs.bufPipe.BreakWithError(http2errClosedResponseBody)
  	return nil
  }
  
  func (rl *http2clientConnReadLoop) processData(f *http2DataFrame) error {
  	cc := rl.cc
  	cs := cc.streamByID(f.StreamID, f.StreamEnded())
  	data := f.Data()
  	if cs == nil {
  		cc.mu.Lock()
  		neverSent := cc.nextStreamID
  		cc.mu.Unlock()
  		if f.StreamID >= neverSent {
  			// We never asked for this.
  			cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
  			return http2ConnectionError(http2ErrCodeProtocol)
  		}
  		// We probably did ask for this, but canceled. Just ignore it.
  		// TODO: be stricter here? only silently ignore things which
  		// we canceled, but not things which were closed normally
  		// by the peer? Tough without accumulating too much state.
  
  		// But at least return their flow control:
  		if f.Length > 0 {
  			cc.mu.Lock()
  			cc.inflow.add(int32(f.Length))
  			cc.mu.Unlock()
  
  			cc.wmu.Lock()
  			cc.fr.WriteWindowUpdate(0, uint32(f.Length))
  			cc.bw.Flush()
  			cc.wmu.Unlock()
  		}
  		return nil
  	}
  	if f.Length > 0 {
  		// Check connection-level flow control.
  		cc.mu.Lock()
  		if cs.inflow.available() >= int32(f.Length) {
  			cs.inflow.take(int32(f.Length))
  		} else {
  			cc.mu.Unlock()
  			return http2ConnectionError(http2ErrCodeFlowControl)
  		}
  		// Return any padded flow control now, since we won't
  		// refund it later on body reads.
  		var refund int
  		if pad := int(f.Length) - len(data); pad > 0 {
  			refund += pad
  		}
  		// Return len(data) now if the stream is already closed,
  		// since data will never be read.
  		didReset := cs.didReset
  		if didReset {
  			refund += len(data)
  		}
  		if refund > 0 {
  			cc.inflow.add(int32(refund))
  			cc.wmu.Lock()
  			cc.fr.WriteWindowUpdate(0, uint32(refund))
  			if !didReset {
  				cs.inflow.add(int32(refund))
  				cc.fr.WriteWindowUpdate(cs.ID, uint32(refund))
  			}
  			cc.bw.Flush()
  			cc.wmu.Unlock()
  		}
  		cc.mu.Unlock()
  
  		if len(data) > 0 && !didReset {
  			if _, err := cs.bufPipe.Write(data); err != nil {
  				rl.endStreamError(cs, err)
  				return err
  			}
  		}
  	}
  
  	if f.StreamEnded() {
  		rl.endStream(cs)
  	}
  	return nil
  }
  
  var http2errInvalidTrailers = errors.New("http2: invalid trailers")
  
  func (rl *http2clientConnReadLoop) endStream(cs *http2clientStream) {
  	// TODO: check that any declared content-length matches, like
  	// server.go's (*stream).endStream method.
  	rl.endStreamError(cs, nil)
  }
  
  func (rl *http2clientConnReadLoop) endStreamError(cs *http2clientStream, err error) {
  	var code func()
  	if err == nil {
  		err = io.EOF
  		code = cs.copyTrailers
  	}
  	cs.bufPipe.closeWithErrorAndCode(err, code)
  	delete(rl.activeRes, cs.ID)
  	if http2isConnectionCloseRequest(cs.req) {
  		rl.closeWhenIdle = true
  	}
  
  	select {
  	case cs.resc <- http2resAndError{err: err}:
  	default:
  	}
  }
  
  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 {
  		// TODO: deal with GOAWAY more. particularly the error code
  		cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
  	}
  	cc.setGoAway(f)
  	return nil
  }
  
  func (rl *http2clientConnReadLoop) processSettings(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)
  	}
  
  	err := f.ForeachSetting(func(s http2Setting) error {
  		switch s.ID {
  		case http2SettingMaxFrameSize:
  			cc.maxFrameSize = s.Val
  		case http2SettingMaxConcurrentStreams:
  			cc.maxConcurrentStreams = s.Val
  		case http2SettingInitialWindowSize:
  			// Values above the maximum flow-control
  			// window size of 2^31-1 MUST be treated as a
  			// connection error (Section 5.4.1) of type
  			// FLOW_CONTROL_ERROR.
  			if s.Val > math.MaxInt32 {
  				return http2ConnectionError(http2ErrCodeFlowControl)
  			}
  
  			// Adjust flow control of currently-open
  			// frames by the difference of the old initial
  			// window size and this one.
  			delta := int32(s.Val) - int32(cc.initialWindowSize)
  			for _, cs := range cc.streams {
  				cs.flow.add(delta)
  			}
  			cc.cond.Broadcast()
  
  			cc.initialWindowSize = s.Val
  		default:
  			// TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
  			cc.vlogf("Unhandled Setting: %v", s)
  		}
  		return nil
  	})
  	if err != nil {
  		return err
  	}
  
  	cc.wmu.Lock()
  	defer cc.wmu.Unlock()
  
  	cc.fr.WriteSettingsAck()
  	cc.bw.Flush()
  	return cc.werr
  }
  
  func (rl *http2clientConnReadLoop) processWindowUpdate(f *http2WindowUpdateFrame) error {
  	cc := rl.cc
  	cs := cc.streamByID(f.StreamID, false)
  	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.cc.streamByID(f.StreamID, true)
  	if cs == nil {
  		// TODO: return error if server tries to RST_STEAM an idle stream
  		return nil
  	}
  	select {
  	case <-cs.peerReset:
  		// Already reset.
  		// This is the only goroutine
  		// which closes this, so there
  		// isn't a race.
  	default:
  		err := http2streamError(cs.ID, f.ErrCode)
  		cs.resetErr = err
  		close(cs.peerReset)
  		cs.bufPipe.CloseWithError(err)
  		cs.cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
  	}
  	delete(rl.activeRes, cs.ID)
  	return nil
  }
  
  // Ping sends a PING frame to the server and waits for the ack.
  // Public implementation is in go17.go and not_go17.go
  func (cc *http2ClientConn) ping(ctx http2contextContext) error {
  	c := make(chan struct{})
  	// Generate a random payload
  	var p [8]byte
  	for {
  		if _, err := rand.Read(p[:]); err != nil {
  			return err
  		}
  		cc.mu.Lock()
  		// check for dup before insert
  		if _, found := cc.pings[p]; !found {
  			cc.pings[p] = c
  			cc.mu.Unlock()
  			break
  		}
  		cc.mu.Unlock()
  	}
  	cc.wmu.Lock()
  	if err := cc.fr.WritePing(false, p); err != nil {
  		cc.wmu.Unlock()
  		return err
  	}
  	if err := cc.bw.Flush(); err != nil {
  		cc.wmu.Unlock()
  		return err
  	}
  	cc.wmu.Unlock()
  	select {
  	case <-c:
  		return nil
  	case <-ctx.Done():
  		return ctx.Err()
  	case <-cc.readerDone:
  		// connection closed
  		return cc.readerErr
  	}
  }
  
  func (rl *http2clientConnReadLoop) processPing(f *http2PingFrame) error {
  	if f.IsAck() {
  		cc := rl.cc
  		cc.mu.Lock()
  		defer cc.mu.Unlock()
  		// If ack, notify listener if any
  		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 {
  	// We told the peer we don't want them.
  	// Spec says:
  	// "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
  	// setting of the peer endpoint is set to 0. An endpoint that
  	// has set this setting and has received acknowledgement MUST
  	// treat the receipt of a PUSH_PROMISE frame as a connection
  	// error (Section 5.4.1) of type PROTOCOL_ERROR."
  	return http2ConnectionError(http2ErrCodeProtocol)
  }
  
  func (cc *http2ClientConn) writeStreamReset(streamID uint32, code http2ErrCode, err error) {
  	// TODO: map err to more interesting error codes, once the
  	// HTTP community comes up with some. But currently for
  	// RST_STREAM there's no equivalent to GOAWAY frame's debug
  	// data, and the error codes are all pretty vague ("cancel").
  	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")
  	http2errPseudoTrailers         = errors.New("http2: invalid pseudo header in trailers")
  )
  
  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 = ioutil.NopCloser(bytes.NewReader(nil))
  
  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) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
  
  // gzipReader wraps a response body so it can lazily
  // call gzip.NewReader on the first call to Read
  type http2gzipReader struct {
  	body io.ReadCloser // underlying Response.Body
  	zr   *gzip.Reader  // lazily-initialized gzip reader
  	zerr error         // sticky 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 {
  	return gz.body.Close()
  }
  
  type http2errorReader struct{ err error }
  
  func (r http2errorReader) Read(p []byte) (int, error) { return 0, r.err }
  
  // bodyWriterState encapsulates various state around the Transport's writing
  // of the request body, particularly regarding doing delayed writes of the body
  // when the request contains "Expect: 100-continue".
  type http2bodyWriterState struct {
  	cs     *http2clientStream
  	timer  *time.Timer   // if non-nil, we're doing a delayed write
  	fnonce *sync.Once    // to call fn with
  	fn     func()        // the code to run in the goroutine, writing the body
  	resc   chan error    // result of fn's execution
  	delay  time.Duration // how long we should delay a delayed write for
  }
  
  func (t *http2Transport) getBodyWriterState(cs *http2clientStream, body io.Reader) (s http2bodyWriterState) {
  	s.cs = cs
  	if body == nil {
  		return
  	}
  	resc := make(chan error, 1)
  	s.resc = resc
  	s.fn = func() {
  		cs.cc.mu.Lock()
  		cs.startedWrite = true
  		cs.cc.mu.Unlock()
  		resc <- cs.writeRequestBody(body, cs.req.Body)
  	}
  	s.delay = t.expectContinueTimeout()
  	if s.delay == 0 ||
  		!httplex.HeaderValuesContainsToken(
  			cs.req.Header["Expect"],
  			"100-continue") {
  		return
  	}
  	s.fnonce = new(sync.Once)
  
  	// Arm the timer with a very large duration, which we'll
  	// intentionally lower later. It has to be large now because
  	// we need a handle to it before writing the headers, but the
  	// s.delay value is defined to not start until after the
  	// request headers were written.
  	const hugeDuration = 365 * 24 * time.Hour
  	s.timer = time.AfterFunc(hugeDuration, func() {
  		s.fnonce.Do(s.fn)
  	})
  	return
  }
  
  func (s http2bodyWriterState) cancel() {
  	if s.timer != nil {
  		s.timer.Stop()
  	}
  }
  
  func (s http2bodyWriterState) on100() {
  	if s.timer == nil {
  		// If we didn't do a delayed write, ignore the server's
  		// bogus 100 continue response.
  		return
  	}
  	s.timer.Stop()
  	go func() { s.fnonce.Do(s.fn) }()
  }
  
  // scheduleBodyWrite starts writing the body, either immediately (in
  // the common case) or after the delay timeout. It should not be
  // called until after the headers have been written.
  func (s http2bodyWriterState) scheduleBodyWrite() {
  	if s.timer == nil {
  		// We're not doing a delayed write (see
  		// getBodyWriterState), so just start the writing
  		// goroutine immediately.
  		go s.fn()
  		return
  	}
  	http2traceWait100Continue(s.cs.trace)
  	if s.timer.Stop() {
  		s.timer.Reset(s.delay)
  	}
  }
  
  // isConnectionCloseRequest reports whether req should use its own
  // connection for a single request and then close the connection.
  func http2isConnectionCloseRequest(req *Request) bool {
  	return req.Close || httplex.HeaderValuesContainsToken(req.Header["Connection"], "close")
  }
  
  // writeFramer is implemented by any type that is used to write frames.
  type http2writeFramer interface {
  	writeFrame(http2writeContext) error
  
  	// staysWithinBuffer reports whether this writer promises that
  	// it will only write less than or equal to size bytes, and it
  	// won't Flush the write context.
  	staysWithinBuffer(size int) bool
  }
  
  // writeContext is the interface needed by the various frame writer
  // types below. All the writeFrame methods below are scheduled via the
  // frame writing scheduler (see writeScheduler in writesched.go).
  //
  // This interface is implemented by *serverConn.
  //
  // TODO: decide whether to a) use this in the client code (which didn't
  // end up using this yet, because it has a simpler design, not
  // currently implementing priorities), or b) delete this and
  // make the server code a bit more concrete.
  type http2writeContext interface {
  	Framer() *http2Framer
  	Flush() error
  	CloseConn() error
  	// HeaderEncoder returns an HPACK encoder that writes to the
  	// returned buffer.
  	HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
  }
  
  // writeEndsStream reports whether w writes a frame that will transition
  // the stream to a half-closed local state. This returns false for RST_STREAM,
  // which closes the entire stream (not just the local half).
  func http2writeEndsStream(w http2writeFramer) bool {
  	switch v := w.(type) {
  	case *http2writeData:
  		return v.endStream
  	case *http2writeResHeaders:
  		return v.endStream
  	case nil:
  		// This can only happen if the caller reuses w after it's
  		// been intentionally nil'ed out to prevent use. Keep this
  		// here to catch future refactoring breaking it.
  		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 // uint16 + uint32
  	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)
  	if p.code != 0 {
  		ctx.Flush() // ignore error: we're hanging up on them anyway
  		time.Sleep(50 * time.Millisecond)
  		ctx.CloseConn()
  	}
  	return err
  }
  
  func (*http2writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes
  
  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
  }
  
  // handlerPanicRST is the message sent from handler goroutines when
  // the handler panics.
  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 }
  
  // splitHeaderBlock splits headerBlock into fragments so that each fragment fits
  // in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true
  // for the first/last fragment, respectively.
  func http2splitHeaderBlock(ctx http2writeContext, headerBlock []byte, fn func(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error) error {
  	// For now we're lazy and just pick the minimum MAX_FRAME_SIZE
  	// that all peers must support (16KB). Later we could care
  	// more and send larger frames if the peer advertised it, but
  	// there's little point. Most headers are small anyway (so we
  	// generally won't have CONTINUATION frames), and extra frames
  	// only waste 9 bytes anyway.
  	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
  }
  
  // writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
  // for HTTP response headers or trailers from a server handler.
  type http2writeResHeaders struct {
  	streamID    uint32
  	httpResCode int      // 0 means no ":status" line
  	h           Header   // may be nil
  	trailers    []string // if non-nil, which keys of h to write. nil means all.
  	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 {
  	// TODO: this is a common one. It'd be nice to return true
  	// here and get into the fast path if we could be clever and
  	// calculate the size fast enough, or at least a conservative
  	// uppper bound that usually fires. (Maybe if w.h and
  	// w.trailers are nil, so we don't need to enumerate it.)
  	// Otherwise I'm afraid that just calculating the length to
  	// answer this question would be slower than the ~2µs benefit.
  	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)
  	}
  }
  
  // writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.
  type http2writePushPromise struct {
  	streamID uint32   // pusher stream
  	method   string   // for :method
  	url      *url.URL // for :scheme, :authority, :path
  	h        Header
  
  	// Creates an ID for a pushed stream. This runs on serveG just before
  	// the frame is written. The returned ID is copied to promisedID.
  	allocatePromisedID func() (uint32, error)
  	promisedID         uint32
  }
  
  func (w *http2writePushPromise) staysWithinBuffer(max int) bool {
  	// TODO: see writeResHeaders.staysWithinBuffer
  	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 {
  	// Sloppy but conservative:
  	return 9+2*(len(":status")+len("100")) <= max
  }
  
  type http2writeWindowUpdate struct {
  	streamID uint32 // or 0 for conn-level
  	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)
  }
  
  // encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
  // is encoded only only if k is in keys.
  func http2encodeHeaders(enc *hpack.Encoder, h Header, keys []string) {
  	if keys == nil {
  		sorter := http2sorterPool.Get().(*http2sorter)
  		// Using defer here, since the returned keys from the
  		// sorter.Keys method is only valid until the sorter
  		// is returned:
  		defer http2sorterPool.Put(sorter)
  		keys = sorter.Keys(h)
  	}
  	for _, k := range keys {
  		vv := h[k]
  		k = http2lowerHeader(k)
  		if !http2validWireHeaderFieldName(k) {
  			// Skip it as backup paranoia. Per
  			// golang.org/issue/14048, these should
  			// already be rejected at a higher level.
  			continue
  		}
  		isTE := k == "transfer-encoding"
  		for _, v := range vv {
  			if !httplex.ValidHeaderFieldValue(v) {
  				// TODO: return an error? golang.org/issue/14048
  				// For now just omit it.
  				continue
  			}
  			// TODO: more of "8.1.2.2 Connection-Specific Header Fields"
  			if isTE && v != "trailers" {
  				continue
  			}
  			http2encKV(enc, k, v)
  		}
  	}
  }
  
  // WriteScheduler is the interface implemented by HTTP/2 write schedulers.
  // Methods are never called concurrently.
  type http2WriteScheduler interface {
  	// OpenStream opens a new stream in the write scheduler.
  	// It is illegal to call this with streamID=0 or with a streamID that is
  	// already open -- the call may panic.
  	OpenStream(streamID uint32, options http2OpenStreamOptions)
  
  	// CloseStream closes a stream in the write scheduler. Any frames queued on
  	// this stream should be discarded. It is illegal to call this on a stream
  	// that is not open -- the call may panic.
  	CloseStream(streamID uint32)
  
  	// AdjustStream adjusts the priority of the given stream. This may be called
  	// on a stream that has not yet been opened or has been closed. Note that
  	// RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:
  	// https://tools.ietf.org/html/rfc7540#section-5.1
  	AdjustStream(streamID uint32, priority http2PriorityParam)
  
  	// Push queues a frame in the scheduler. In most cases, this will not be
  	// called with wr.StreamID()!=0 unless that stream is currently open. The one
  	// exception is RST_STREAM frames, which may be sent on idle or closed streams.
  	Push(wr http2FrameWriteRequest)
  
  	// Pop dequeues the next frame to write. Returns false if no frames can
  	// be written. Frames with a given wr.StreamID() are Pop'd in the same
  	// order they are Push'd.
  	Pop() (wr http2FrameWriteRequest, ok bool)
  }
  
  // OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.
  type http2OpenStreamOptions struct {
  	// PusherID is zero if the stream was initiated by the client. Otherwise,
  	// PusherID names the stream that pushed the newly opened stream.
  	PusherID uint32
  }
  
  // FrameWriteRequest is a request to write a frame.
  type http2FrameWriteRequest struct {
  	// write is the interface value that does the writing, once the
  	// WriteScheduler has selected this frame to write. The write
  	// functions are all defined in write.go.
  	write http2writeFramer
  
  	// stream is the stream on which this frame will be written.
  	// nil for non-stream frames like PING and SETTINGS.
  	stream *http2stream
  
  	// done, if non-nil, must be a buffered channel with space for
  	// 1 message and is sent the return value from write (or an
  	// earlier error) when the frame has been written.
  	done chan error
  }
  
  // StreamID returns the id of the stream this frame will be written to.
  // 0 is used for non-stream frames such as PING and SETTINGS.
  func (wr http2FrameWriteRequest) StreamID() uint32 {
  	if wr.stream == nil {
  		if se, ok := wr.write.(http2StreamError); ok {
  			// (*serverConn).resetStream doesn't set
  			// stream because it doesn't necessarily have
  			// one. So special case this type of write
  			// message.
  			return se.StreamID
  		}
  		return 0
  	}
  	return wr.stream.id
  }
  
  // DataSize returns the number of flow control bytes that must be consumed
  // to write this entire frame. This is 0 for non-DATA frames.
  func (wr http2FrameWriteRequest) DataSize() int {
  	if wd, ok := wr.write.(*http2writeData); ok {
  		return len(wd.p)
  	}
  	return 0
  }
  
  // Consume consumes min(n, available) bytes from this frame, where available
  // is the number of flow control bytes available on the stream. Consume returns
  // 0, 1, or 2 frames, where the integer return value gives the number of frames
  // returned.
  //
  // If flow control prevents consuming any bytes, this returns (_, _, 0). If
  // the entire frame was consumed, this returns (wr, _, 1). Otherwise, this
  // returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and
  // 'rest' contains the remaining bytes. The consumed bytes are deducted from the
  // underlying stream's flow control budget.
  func (wr http2FrameWriteRequest) Consume(n int32) (http2FrameWriteRequest, http2FrameWriteRequest, int) {
  	var empty http2FrameWriteRequest
  
  	// Non-DATA frames are always consumed whole.
  	wd, ok := wr.write.(*http2writeData)
  	if !ok || len(wd.p) == 0 {
  		return wr, empty, 1
  	}
  
  	// Might need to split after applying limits.
  	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],
  				// Even if the original had endStream set, there
  				// are bytes remaining because len(wd.p) > allowed,
  				// so we know endStream is false.
  				endStream: false,
  			},
  			// Our caller is blocking on the final DATA frame, not
  			// this intermediate frame, so no need to wait.
  			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
  	}
  
  	// The frame is consumed whole.
  	// NB: This cast cannot overflow because allowed is <= math.MaxInt32.
  	wr.stream.flow.take(int32(len(wd.p)))
  	return wr, empty, 1
  }
  
  // String is for debugging only.
  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)
  }
  
  // replyToWriter sends err to wr.done and panics if the send must block
  // This does nothing if wr.done is nil.
  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 // prevent use (assume it's tainted after wr.done send)
  }
  
  // writeQueue is used by implementations of WriteScheduler.
  type http2writeQueue struct {
  	s []http2FrameWriteRequest
  }
  
  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]
  	// TODO: less copy-happy queue.
  	copy(q.s, q.s[1:])
  	q.s[len(q.s)-1] = http2FrameWriteRequest{}
  	q.s = q.s[:len(q.s)-1]
  	return wr
  }
  
  // consume consumes up to n bytes from q.s[0]. If the frame is
  // entirely consumed, it is removed from the queue. If the frame
  // is partially consumed, the frame is kept with the consumed
  // bytes removed. Returns true iff any bytes were consumed.
  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
  
  // put inserts an unused writeQueue into the pool.
  
  // put inserts an unused writeQueue into the pool.
  func (p *http2writeQueuePool) put(q *http2writeQueue) {
  	for i := range q.s {
  		q.s[i] = http2FrameWriteRequest{}
  	}
  	q.s = q.s[:0]
  	*p = append(*p, q)
  }
  
  // get returns an empty writeQueue.
  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
  }
  
  // RFC 7540, Section 5.3.5: the default weight is 16.
  const http2priorityDefaultWeight = 15 // 16 = 15 + 1
  
  // PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
  type http2PriorityWriteSchedulerConfig struct {
  	// MaxClosedNodesInTree controls the maximum number of closed streams to
  	// retain in the priority tree. Setting this to zero saves a small amount
  	// of memory at the cost of performance.
  	//
  	// See RFC 7540, Section 5.3.4:
  	//   "It is possible for a stream to become closed while prioritization
  	//   information ... is in transit. ... This potentially creates suboptimal
  	//   prioritization, since the stream could be given a priority that is
  	//   different from what is intended. To avoid these problems, an endpoint
  	//   SHOULD retain stream prioritization state for a period after streams
  	//   become closed. The longer state is retained, the lower the chance that
  	//   streams are assigned incorrect or default priority values."
  	MaxClosedNodesInTree int
  
  	// MaxIdleNodesInTree controls the maximum number of idle streams to
  	// retain in the priority tree. Setting this to zero saves a small amount
  	// of memory at the cost of performance.
  	//
  	// See RFC 7540, Section 5.3.4:
  	//   Similarly, streams that are in the "idle" state can be assigned
  	//   priority or become a parent of other streams. This allows for the
  	//   creation of a grouping node in the dependency tree, which enables
  	//   more flexible expressions of priority. Idle streams begin with a
  	//   default priority (Section 5.3.5).
  	MaxIdleNodesInTree int
  
  	// ThrottleOutOfOrderWrites enables write throttling to help ensure that
  	// data is delivered in priority order. This works around a race where
  	// stream B depends on stream A and both streams are about to call Write
  	// to queue DATA frames. If B wins the race, a naive scheduler would eagerly
  	// write as much data from B as possible, but this is suboptimal because A
  	// is a higher-priority stream. With throttling enabled, we write a small
  	// amount of data from B to minimize the amount of bandwidth that B can
  	// steal from A.
  	ThrottleOutOfOrderWrites bool
  }
  
  // NewPriorityWriteScheduler constructs a WriteScheduler that schedules
  // frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
  // If cfg is nil, default options are used.
  func http2NewPriorityWriteScheduler(cfg *http2PriorityWriteSchedulerConfig) http2WriteScheduler {
  	if cfg == nil {
  		// For justification of these defaults, see:
  		// https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
  		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
  )
  
  // priorityNode is a node in an HTTP/2 priority tree.
  // Each node is associated with a single stream ID.
  // See RFC 7540, Section 5.3.
  type http2priorityNode struct {
  	q            http2writeQueue        // queue of pending frames to write
  	id           uint32                 // id of the stream, or 0 for the root of the tree
  	weight       uint8                  // the actual weight is weight+1, so the value is in [1,256]
  	state        http2priorityNodeState // open | closed | idle
  	bytes        int64                  // number of bytes written by this node, or 0 if closed
  	subtreeBytes int64                  // sum(node.bytes) of all nodes in this subtree
  
  	// These links form the priority tree.
  	parent     *http2priorityNode
  	kids       *http2priorityNode // start of the kids list
  	prev, next *http2priorityNode // doubly-linked list of siblings
  }
  
  func (n *http2priorityNode) setParent(parent *http2priorityNode) {
  	if n == parent {
  		panic("setParent to self")
  	}
  	if n.parent == parent {
  		return
  	}
  	// Unlink from current parent.
  	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
  		}
  	}
  	// Link to new parent.
  	// If parent=nil, remove n from the tree.
  	// Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
  	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
  	}
  }
  
  // walkReadyInOrder iterates over the tree in priority order, calling f for each node
  // with a non-empty write queue. When f returns true, this funcion returns true and the
  // walk halts. tmp is used as scratch space for sorting.
  //
  // f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
  // if any ancestor p of n is still open (ignoring the root node).
  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
  	}
  
  	// Don't consider the root "open" when updating openParent since
  	// we can't send data frames on the root stream (only control frames).
  	if n.id != 0 {
  		openParent = openParent || (n.state == http2priorityNodeOpen)
  	}
  
  	// Common case: only one kid or all kids have the same weight.
  	// Some clients don't use weights; other clients (like web browsers)
  	// use mostly-linear priority trees.
  	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
  	}
  
  	// Uncommon case: sort the child nodes. We remove the kids from the parent,
  	// then re-insert after sorting so we can reuse tmp for future sort calls.
  	*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) // setParent inserts at the head of n.kids
  	}
  	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 {
  	// Prefer the subtree that has sent fewer bytes relative to its weight.
  	// See sections 5.3.2 and 5.3.4.
  	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 is the root of the priority tree, where root.id = 0.
  	// The root queues control frames that are not associated with any stream.
  	root http2priorityNode
  
  	// nodes maps stream ids to priority tree nodes.
  	nodes map[uint32]*http2priorityNode
  
  	// maxID is the maximum stream id in nodes.
  	maxID uint32
  
  	// lists of nodes that have been closed or are idle, but are kept in
  	// the tree for improved prioritization. When the lengths exceed either
  	// maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
  	closedNodes, idleNodes []*http2priorityNode
  
  	// From the config.
  	maxClosedNodesInTree int
  	maxIdleNodesInTree   int
  	writeThrottleLimit   int32
  	enableWriteThrottle  bool
  
  	// tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
  	tmp []*http2priorityNode
  
  	// pool of empty queues for reuse.
  	queuePool http2writeQueuePool
  }
  
  func (ws *http2priorityWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
  	// The stream may be currently idle but cannot be opened or closed.
  	if curr := ws.nodes[streamID]; curr != nil {
  		if curr.state != http2priorityNodeIdle {
  			panic(fmt.Sprintf("stream %d already opened", streamID))
  		}
  		curr.state = http2priorityNodeOpen
  		return
  	}
  
  	// RFC 7540, Section 5.3.5:
  	//  "All streams are initially assigned a non-exclusive dependency on stream 0x0.
  	//  Pushed streams initially depend on their associated stream. In both cases,
  	//  streams are assigned a default weight of 16."
  	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")
  	}
  
  	// If streamID does not exist, there are two cases:
  	// - A closed stream that has been removed (this will have ID <= maxID)
  	// - An idle stream that is being used for "grouping" (this will have ID > maxID)
  	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)
  	}
  
  	// Section 5.3.1: A dependency on a stream that is not currently in the tree
  	// results in that stream being given a default priority (Section 5.3.5).
  	parent := ws.nodes[priority.StreamDep]
  	if parent == nil {
  		n.setParent(&ws.root)
  		n.weight = http2priorityDefaultWeight
  		return
  	}
  
  	// Ignore if the client tries to make a node its own parent.
  	if n == parent {
  		return
  	}
  
  	// Section 5.3.3:
  	//   "If a stream is made dependent on one of its own dependencies, the
  	//   formerly dependent stream is first moved to be dependent on the
  	//   reprioritized stream's previous parent. The moved dependency retains
  	//   its weight."
  	//
  	// That is: if parent depends on n, move parent to depend on n.parent.
  	for x := parent.parent; x != nil; x = x.parent {
  		if x == n {
  			parent.setParent(n.parent)
  			break
  		}
  	}
  
  	// Section 5.3.3: The exclusive flag causes the stream to become the sole
  	// dependency of its parent stream, causing other dependencies to become
  	// dependent on the exclusive stream.
  	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 id := wr.StreamID(); id == 0 {
  		n = &ws.root
  	} else {
  		n = ws.nodes[id]
  		if n == nil {
  			// id is an idle or closed stream. wr should not be a HEADERS or
  			// DATA frame. However, wr can be a RST_STREAM. In this case, we
  			// push wr onto the root, rather than creating a new priorityNode,
  			// since RST_STREAM is tiny and the stream's priority is unknown
  			// anyway. See issue #17919.
  			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 B depends on A and B continuously has data available but A
  		// does not, gradually increase the throttling limit to allow B to
  		// steal more and more bandwidth from A.
  		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 {
  		// Remove the oldest node, then shift left.
  		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)
  }
  
  // NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2
  // priorities. Control frames like SETTINGS and PING are written before DATA
  // frames, but if no control frames are queued and multiple streams have queued
  // HEADERS or DATA frames, Pop selects a ready stream arbitrarily.
  func http2NewRandomWriteScheduler() http2WriteScheduler {
  	return &http2randomWriteScheduler{sq: make(map[uint32]*http2writeQueue)}
  }
  
  type http2randomWriteScheduler struct {
  	// zero are frames not associated with a specific stream.
  	zero http2writeQueue
  
  	// sq contains the stream-specific queues, keyed by stream ID.
  	// When a stream is idle or closed, it's deleted from the map.
  	sq map[uint32]*http2writeQueue
  
  	// pool of empty queues for reuse.
  	queuePool http2writeQueuePool
  }
  
  func (ws *http2randomWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
  	// no-op: idle streams are not tracked
  }
  
  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) {
  	// no-op: priorities are ignored
  }
  
  func (ws *http2randomWriteScheduler) Push(wr http2FrameWriteRequest) {
  	id := wr.StreamID()
  	if id == 0 {
  		ws.zero.push(wr)
  		return
  	}
  	q, ok := ws.sq[id]
  	if !ok {
  		q = ws.queuePool.get()
  		ws.sq[id] = q
  	}
  	q.push(wr)
  }
  
  func (ws *http2randomWriteScheduler) Pop() (http2FrameWriteRequest, bool) {
  	// Control frames first.
  	if !ws.zero.empty() {
  		return ws.zero.shift(), true
  	}
  	// Iterate over all non-idle streams until finding one that can be consumed.
  	for _, q := range ws.sq {
  		if wr, ok := q.consume(math.MaxInt32); ok {
  			return wr, true
  		}
  	}
  	return http2FrameWriteRequest{}, false