gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

http2.go (9765B)


      1 // Copyright 2014 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Package http2 implements the HTTP/2 protocol.
      6 //
      7 // This package is low-level and intended to be used directly by very
      8 // few people. Most users will use it indirectly through the automatic
      9 // use by the net/http package (from Go 1.6 and later).
     10 // For use in earlier Go versions see ConfigureServer. (Transport support
     11 // requires Go 1.6 or later)
     12 //
     13 // See https://http2.github.io/ for more information on HTTP/2.
     14 //
     15 // See https://http2.golang.org/ for a test server running this code.
     16 package http2 // import "golang.org/x/net/http2"
     17 
     18 import (
     19 	"bufio"
     20 	"crypto/tls"
     21 	"fmt"
     22 	"io"
     23 	"net/http"
     24 	"os"
     25 	"sort"
     26 	"strconv"
     27 	"strings"
     28 	"sync"
     29 
     30 	"golang.org/x/net/http/httpguts"
     31 )
     32 
     33 var (
     34 	VerboseLogs    bool
     35 	logFrameWrites bool
     36 	logFrameReads  bool
     37 	inTests        bool
     38 )
     39 
     40 func init() {
     41 	e := os.Getenv("GODEBUG")
     42 	if strings.Contains(e, "http2debug=1") {
     43 		VerboseLogs = true
     44 	}
     45 	if strings.Contains(e, "http2debug=2") {
     46 		VerboseLogs = true
     47 		logFrameWrites = true
     48 		logFrameReads = true
     49 	}
     50 }
     51 
     52 const (
     53 	// ClientPreface is the string that must be sent by new
     54 	// connections from clients.
     55 	ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
     56 
     57 	// SETTINGS_MAX_FRAME_SIZE default
     58 	// https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2
     59 	initialMaxFrameSize = 16384
     60 
     61 	// NextProtoTLS is the NPN/ALPN protocol negotiated during
     62 	// HTTP/2's TLS setup.
     63 	NextProtoTLS = "h2"
     64 
     65 	// https://httpwg.org/specs/rfc7540.html#SettingValues
     66 	initialHeaderTableSize = 4096
     67 
     68 	initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
     69 
     70 	defaultMaxReadFrameSize = 1 << 20
     71 )
     72 
     73 var (
     74 	clientPreface = []byte(ClientPreface)
     75 )
     76 
     77 type streamState int
     78 
     79 // HTTP/2 stream states.
     80 //
     81 // See http://tools.ietf.org/html/rfc7540#section-5.1.
     82 //
     83 // For simplicity, the server code merges "reserved (local)" into
     84 // "half-closed (remote)". This is one less state transition to track.
     85 // The only downside is that we send PUSH_PROMISEs slightly less
     86 // liberally than allowable. More discussion here:
     87 // https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
     88 //
     89 // "reserved (remote)" is omitted since the client code does not
     90 // support server push.
     91 const (
     92 	stateIdle streamState = iota
     93 	stateOpen
     94 	stateHalfClosedLocal
     95 	stateHalfClosedRemote
     96 	stateClosed
     97 )
     98 
     99 var stateName = [...]string{
    100 	stateIdle:             "Idle",
    101 	stateOpen:             "Open",
    102 	stateHalfClosedLocal:  "HalfClosedLocal",
    103 	stateHalfClosedRemote: "HalfClosedRemote",
    104 	stateClosed:           "Closed",
    105 }
    106 
    107 func (st streamState) String() string {
    108 	return stateName[st]
    109 }
    110 
    111 // Setting is a setting parameter: which setting it is, and its value.
    112 type Setting struct {
    113 	// ID is which setting is being set.
    114 	// See https://httpwg.org/specs/rfc7540.html#SettingFormat
    115 	ID SettingID
    116 
    117 	// Val is the value.
    118 	Val uint32
    119 }
    120 
    121 func (s Setting) String() string {
    122 	return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
    123 }
    124 
    125 // Valid reports whether the setting is valid.
    126 func (s Setting) Valid() error {
    127 	// Limits and error codes from 6.5.2 Defined SETTINGS Parameters
    128 	switch s.ID {
    129 	case SettingEnablePush:
    130 		if s.Val != 1 && s.Val != 0 {
    131 			return ConnectionError(ErrCodeProtocol)
    132 		}
    133 	case SettingInitialWindowSize:
    134 		if s.Val > 1<<31-1 {
    135 			return ConnectionError(ErrCodeFlowControl)
    136 		}
    137 	case SettingMaxFrameSize:
    138 		if s.Val < 16384 || s.Val > 1<<24-1 {
    139 			return ConnectionError(ErrCodeProtocol)
    140 		}
    141 	}
    142 	return nil
    143 }
    144 
    145 // A SettingID is an HTTP/2 setting as defined in
    146 // https://httpwg.org/specs/rfc7540.html#iana-settings
    147 type SettingID uint16
    148 
    149 const (
    150 	SettingHeaderTableSize      SettingID = 0x1
    151 	SettingEnablePush           SettingID = 0x2
    152 	SettingMaxConcurrentStreams SettingID = 0x3
    153 	SettingInitialWindowSize    SettingID = 0x4
    154 	SettingMaxFrameSize         SettingID = 0x5
    155 	SettingMaxHeaderListSize    SettingID = 0x6
    156 )
    157 
    158 var settingName = map[SettingID]string{
    159 	SettingHeaderTableSize:      "HEADER_TABLE_SIZE",
    160 	SettingEnablePush:           "ENABLE_PUSH",
    161 	SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
    162 	SettingInitialWindowSize:    "INITIAL_WINDOW_SIZE",
    163 	SettingMaxFrameSize:         "MAX_FRAME_SIZE",
    164 	SettingMaxHeaderListSize:    "MAX_HEADER_LIST_SIZE",
    165 }
    166 
    167 func (s SettingID) String() string {
    168 	if v, ok := settingName[s]; ok {
    169 		return v
    170 	}
    171 	return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
    172 }
    173 
    174 // validWireHeaderFieldName reports whether v is a valid header field
    175 // name (key). See httpguts.ValidHeaderName for the base rules.
    176 //
    177 // Further, http2 says:
    178 //
    179 //	"Just as in HTTP/1.x, header field names are strings of ASCII
    180 //	characters that are compared in a case-insensitive
    181 //	fashion. However, header field names MUST be converted to
    182 //	lowercase prior to their encoding in HTTP/2. "
    183 func validWireHeaderFieldName(v string) bool {
    184 	if len(v) == 0 {
    185 		return false
    186 	}
    187 	for _, r := range v {
    188 		if !httpguts.IsTokenRune(r) {
    189 			return false
    190 		}
    191 		if 'A' <= r && r <= 'Z' {
    192 			return false
    193 		}
    194 	}
    195 	return true
    196 }
    197 
    198 func httpCodeString(code int) string {
    199 	switch code {
    200 	case 200:
    201 		return "200"
    202 	case 404:
    203 		return "404"
    204 	}
    205 	return strconv.Itoa(code)
    206 }
    207 
    208 // from pkg io
    209 type stringWriter interface {
    210 	WriteString(s string) (n int, err error)
    211 }
    212 
    213 // A gate lets two goroutines coordinate their activities.
    214 type gate chan struct{}
    215 
    216 func (g gate) Done() { g <- struct{}{} }
    217 func (g gate) Wait() { <-g }
    218 
    219 // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
    220 type closeWaiter chan struct{}
    221 
    222 // Init makes a closeWaiter usable.
    223 // It exists because so a closeWaiter value can be placed inside a
    224 // larger struct and have the Mutex and Cond's memory in the same
    225 // allocation.
    226 func (cw *closeWaiter) Init() {
    227 	*cw = make(chan struct{})
    228 }
    229 
    230 // Close marks the closeWaiter as closed and unblocks any waiters.
    231 func (cw closeWaiter) Close() {
    232 	close(cw)
    233 }
    234 
    235 // Wait waits for the closeWaiter to become closed.
    236 func (cw closeWaiter) Wait() {
    237 	<-cw
    238 }
    239 
    240 // bufferedWriter is a buffered writer that writes to w.
    241 // Its buffered writer is lazily allocated as needed, to minimize
    242 // idle memory usage with many connections.
    243 type bufferedWriter struct {
    244 	_  incomparable
    245 	w  io.Writer     // immutable
    246 	bw *bufio.Writer // non-nil when data is buffered
    247 }
    248 
    249 func newBufferedWriter(w io.Writer) *bufferedWriter {
    250 	return &bufferedWriter{w: w}
    251 }
    252 
    253 // bufWriterPoolBufferSize is the size of bufio.Writer's
    254 // buffers created using bufWriterPool.
    255 //
    256 // TODO: pick a less arbitrary value? this is a bit under
    257 // (3 x typical 1500 byte MTU) at least. Other than that,
    258 // not much thought went into it.
    259 const bufWriterPoolBufferSize = 4 << 10
    260 
    261 var bufWriterPool = sync.Pool{
    262 	New: func() interface{} {
    263 		return bufio.NewWriterSize(nil, bufWriterPoolBufferSize)
    264 	},
    265 }
    266 
    267 func (w *bufferedWriter) Available() int {
    268 	if w.bw == nil {
    269 		return bufWriterPoolBufferSize
    270 	}
    271 	return w.bw.Available()
    272 }
    273 
    274 func (w *bufferedWriter) Write(p []byte) (n int, err error) {
    275 	if w.bw == nil {
    276 		bw := bufWriterPool.Get().(*bufio.Writer)
    277 		bw.Reset(w.w)
    278 		w.bw = bw
    279 	}
    280 	return w.bw.Write(p)
    281 }
    282 
    283 func (w *bufferedWriter) Flush() error {
    284 	bw := w.bw
    285 	if bw == nil {
    286 		return nil
    287 	}
    288 	err := bw.Flush()
    289 	bw.Reset(nil)
    290 	bufWriterPool.Put(bw)
    291 	w.bw = nil
    292 	return err
    293 }
    294 
    295 func mustUint31(v int32) uint32 {
    296 	if v < 0 || v > 2147483647 {
    297 		panic("out of range")
    298 	}
    299 	return uint32(v)
    300 }
    301 
    302 // bodyAllowedForStatus reports whether a given response status code
    303 // permits a body. See RFC 7230, section 3.3.
    304 func bodyAllowedForStatus(status int) bool {
    305 	switch {
    306 	case status >= 100 && status <= 199:
    307 		return false
    308 	case status == 204:
    309 		return false
    310 	case status == 304:
    311 		return false
    312 	}
    313 	return true
    314 }
    315 
    316 type httpError struct {
    317 	_       incomparable
    318 	msg     string
    319 	timeout bool
    320 }
    321 
    322 func (e *httpError) Error() string   { return e.msg }
    323 func (e *httpError) Timeout() bool   { return e.timeout }
    324 func (e *httpError) Temporary() bool { return true }
    325 
    326 var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}
    327 
    328 type connectionStater interface {
    329 	ConnectionState() tls.ConnectionState
    330 }
    331 
    332 var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}
    333 
    334 type sorter struct {
    335 	v []string // owned by sorter
    336 }
    337 
    338 func (s *sorter) Len() int           { return len(s.v) }
    339 func (s *sorter) Swap(i, j int)      { s.v[i], s.v[j] = s.v[j], s.v[i] }
    340 func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
    341 
    342 // Keys returns the sorted keys of h.
    343 //
    344 // The returned slice is only valid until s used again or returned to
    345 // its pool.
    346 func (s *sorter) Keys(h http.Header) []string {
    347 	keys := s.v[:0]
    348 	for k := range h {
    349 		keys = append(keys, k)
    350 	}
    351 	s.v = keys
    352 	sort.Sort(s)
    353 	return keys
    354 }
    355 
    356 func (s *sorter) SortStrings(ss []string) {
    357 	// Our sorter works on s.v, which sorter owns, so
    358 	// stash it away while we sort the user's buffer.
    359 	save := s.v
    360 	s.v = ss
    361 	sort.Sort(s)
    362 	s.v = save
    363 }
    364 
    365 // validPseudoPath reports whether v is a valid :path pseudo-header
    366 // value. It must be either:
    367 //
    368 //   - a non-empty string starting with '/'
    369 //   - the string '*', for OPTIONS requests.
    370 //
    371 // For now this is only used a quick check for deciding when to clean
    372 // up Opaque URLs before sending requests from the Transport.
    373 // See golang.org/issue/16847
    374 //
    375 // We used to enforce that the path also didn't start with "//", but
    376 // Google's GFE accepts such paths and Chrome sends them, so ignore
    377 // that part of the spec. See golang.org/issue/19103.
    378 func validPseudoPath(v string) bool {
    379 	return (len(v) > 0 && v[0] == '/') || v == "*"
    380 }
    381 
    382 // incomparable is a zero-width, non-comparable type. Adding it to a struct
    383 // makes that struct also non-comparable, and generally doesn't add
    384 // any size (as long as it's first).
    385 type incomparable [0]func()