Copyright 2014 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
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 http2 // import "golang.org/x/net/http2"

import (
	
	
	
	
	
	
	
	
	
	

	
)

var (
	VerboseLogs    bool
	logFrameWrites bool
	logFrameReads  bool
	inTests        bool
)

func () {
	 := os.Getenv("GODEBUG")
	if strings.Contains(, "http2debug=1") {
		VerboseLogs = true
	}
	if strings.Contains(, "http2debug=2") {
		VerboseLogs = true
		logFrameWrites = true
		logFrameReads = true
	}
}

ClientPreface is the string that must be sent by new connections from clients.
	ClientPreface = "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
NextProtoTLS is the NPN/ALPN protocol negotiated during HTTP/2's TLS setup.
	NextProtoTLS = "h2"
http://http2.github.io/http2-spec/#SettingValues
	initialHeaderTableSize = 4096

	initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size

	defaultMaxReadFrameSize = 1 << 20
)

var (
	clientPreface = []byte(ClientPreface)
)

type streamState 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 (
	stateIdle streamState = iota
	stateOpen
	stateHalfClosedLocal
	stateHalfClosedRemote
	stateClosed
)

var stateName = [...]string{
	stateIdle:             "Idle",
	stateOpen:             "Open",
	stateHalfClosedLocal:  "HalfClosedLocal",
	stateHalfClosedRemote: "HalfClosedRemote",
	stateClosed:           "Closed",
}

func ( streamState) () string {
	return stateName[]
}
Setting is a setting parameter: which setting it is, and its value.
ID is which setting is being set. See http://http2.github.io/http2-spec/#SettingValues
Val is the value.
	Val uint32
}

func ( Setting) () string {
	return fmt.Sprintf("[%v = %d]", .ID, .Val)
}
Valid reports whether the setting is valid.
Limits and error codes from 6.5.2 Defined SETTINGS Parameters
	switch .ID {
	case SettingEnablePush:
		if .Val != 1 && .Val != 0 {
			return ConnectionError(ErrCodeProtocol)
		}
	case SettingInitialWindowSize:
		if .Val > 1<<31-1 {
			return ConnectionError(ErrCodeFlowControl)
		}
	case SettingMaxFrameSize:
		if .Val < 16384 || .Val > 1<<24-1 {
			return ConnectionError(ErrCodeProtocol)
		}
	}
	return nil
}
A SettingID is an HTTP/2 setting as defined in http://http2.github.io/http2-spec/#iana-settings
type SettingID uint16

const (
	SettingHeaderTableSize      SettingID = 0x1
	SettingEnablePush           SettingID = 0x2
	SettingMaxConcurrentStreams SettingID = 0x3
	SettingInitialWindowSize    SettingID = 0x4
	SettingMaxFrameSize         SettingID = 0x5
	SettingMaxHeaderListSize    SettingID = 0x6
)

var settingName = map[SettingID]string{
	SettingHeaderTableSize:      "HEADER_TABLE_SIZE",
	SettingEnablePush:           "ENABLE_PUSH",
	SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
	SettingInitialWindowSize:    "INITIAL_WINDOW_SIZE",
	SettingMaxFrameSize:         "MAX_FRAME_SIZE",
	SettingMaxHeaderListSize:    "MAX_HEADER_LIST_SIZE",
}

func ( SettingID) () string {
	if ,  := settingName[];  {
		return 
	}
	return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16())
}
validWireHeaderFieldName reports whether v is a valid header field name (key). See httpguts.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 ( string) bool {
	if len() == 0 {
		return false
	}
	for ,  := range  {
		if !httpguts.IsTokenRune() {
			return false
		}
		if 'A' <=  &&  <= 'Z' {
			return false
		}
	}
	return true
}

func ( int) string {
	switch  {
	case 200:
		return "200"
	case 404:
		return "404"
	}
	return strconv.Itoa()
}
from pkg io
type stringWriter interface {
	WriteString(s string) (n int, err error)
}
A gate lets two goroutines coordinate their activities.
type gate chan struct{}

func ( gate) () {  <- struct{}{} }
func ( gate) () { <- }
A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
type closeWaiter 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 ( *closeWaiter) () {
	* = make(chan struct{})
}
Close marks the closeWaiter as closed and unblocks any waiters.
func ( closeWaiter) () {
	close()
}
Wait waits for the closeWaiter to become closed.
func ( closeWaiter) () {
	<-
}
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 bufferedWriter struct {
	_  incomparable
	w  io.Writer     // immutable
	bw *bufio.Writer // non-nil when data is buffered
}

func ( io.Writer) *bufferedWriter {
	return &bufferedWriter{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 bufWriterPoolBufferSize = 4 << 10

var bufWriterPool = sync.Pool{
	New: func() interface{} {
		return bufio.NewWriterSize(nil, bufWriterPoolBufferSize)
	},
}

func ( *bufferedWriter) () int {
	if .bw == nil {
		return bufWriterPoolBufferSize
	}
	return .bw.Available()
}

func ( *bufferedWriter) ( []byte) ( int,  error) {
	if .bw == nil {
		 := bufWriterPool.Get().(*bufio.Writer)
		.Reset(.w)
		.bw = 
	}
	return .bw.Write()
}

func ( *bufferedWriter) () error {
	 := .bw
	if  == nil {
		return nil
	}
	 := .Flush()
	.Reset(nil)
	bufWriterPool.Put()
	.bw = nil
	return 
}

func ( int32) uint32 {
	if  < 0 ||  > 2147483647 {
		panic("out of range")
	}
	return uint32()
}
bodyAllowedForStatus reports whether a given response status code permits a body. See RFC 7230, section 3.3.
func ( int) bool {
	switch {
	case  >= 100 &&  <= 199:
		return false
	case  == 204:
		return false
	case  == 304:
		return false
	}
	return true
}

type httpError struct {
	_       incomparable
	msg     string
	timeout bool
}

func ( *httpError) () string   { return .msg }
func ( *httpError) () bool   { return .timeout }
func ( *httpError) () bool { return true }

var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}

type connectionStater interface {
	ConnectionState() tls.ConnectionState
}

var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}

type sorter struct {
	v []string // owned by sorter
}

func ( *sorter) () int           { return len(.v) }
func ( *sorter) (,  int)      { .v[], .v[] = .v[], .v[] }
func ( *sorter) (,  int) bool { return .v[] < .v[] }
Keys returns the sorted keys of h. The returned slice is only valid until s used again or returned to its pool.
func ( *sorter) ( http.Header) []string {
	 := .v[:0]
	for  := range  {
		 = append(, )
	}
	.v = 
	sort.Sort()
	return 
}

Our sorter works on s.v, which sorter owns, so stash it away while we sort the user's buffer.
	 := .v
	.v = 
	sort.Sort()
	.v = 
}
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 ( string) bool {
	return (len() > 0 && [0] == '/') ||  == "*"
}
incomparable is a zero-width, non-comparable type. Adding it to a struct makes that struct also non-comparable, and generally doesn't add any size (as long as it's first).