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