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