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