http2.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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. // Package http2 implements the HTTP/2 protocol.
  5. //
  6. // This package is low-level and intended to be used directly by very
  7. // few people. Most users will use it indirectly through the automatic
  8. // use by the net/http package (from Go 1.6 and later).
  9. // For use in earlier Go versions see ConfigureServer. (Transport support
  10. // requires Go 1.6 or later)
  11. //
  12. // See https://http2.github.io/ for more information on HTTP/2.
  13. //
  14. // See https://http2.golang.org/ for a test server running this code.
  15. package http2
  16. import (
  17. "bufio"
  18. "fmt"
  19. "io"
  20. "net/http"
  21. "os"
  22. "strconv"
  23. "strings"
  24. "sync"
  25. )
  26. var (
  27. VerboseLogs bool
  28. logFrameWrites bool
  29. logFrameReads bool
  30. )
  31. func init() {
  32. e := os.Getenv("GODEBUG")
  33. if strings.Contains(e, "http2debug=1") {
  34. VerboseLogs = true
  35. }
  36. if strings.Contains(e, "http2debug=2") {
  37. VerboseLogs = true
  38. logFrameWrites = true
  39. logFrameReads = true
  40. }
  41. }
  42. const (
  43. // ClientPreface is the string that must be sent by new
  44. // connections from clients.
  45. ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
  46. // SETTINGS_MAX_FRAME_SIZE default
  47. // http://http2.github.io/http2-spec/#rfc.section.6.5.2
  48. initialMaxFrameSize = 16384
  49. // NextProtoTLS is the NPN/ALPN protocol negotiated during
  50. // HTTP/2's TLS setup.
  51. NextProtoTLS = "h2"
  52. // http://http2.github.io/http2-spec/#SettingValues
  53. initialHeaderTableSize = 4096
  54. initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
  55. defaultMaxReadFrameSize = 1 << 20
  56. )
  57. var (
  58. clientPreface = []byte(ClientPreface)
  59. )
  60. type streamState int
  61. const (
  62. stateIdle streamState = iota
  63. stateOpen
  64. stateHalfClosedLocal
  65. stateHalfClosedRemote
  66. stateResvLocal
  67. stateResvRemote
  68. stateClosed
  69. )
  70. var stateName = [...]string{
  71. stateIdle: "Idle",
  72. stateOpen: "Open",
  73. stateHalfClosedLocal: "HalfClosedLocal",
  74. stateHalfClosedRemote: "HalfClosedRemote",
  75. stateResvLocal: "ResvLocal",
  76. stateResvRemote: "ResvRemote",
  77. stateClosed: "Closed",
  78. }
  79. func (st streamState) String() string {
  80. return stateName[st]
  81. }
  82. // Setting is a setting parameter: which setting it is, and its value.
  83. type Setting struct {
  84. // ID is which setting is being set.
  85. // See http://http2.github.io/http2-spec/#SettingValues
  86. ID SettingID
  87. // Val is the value.
  88. Val uint32
  89. }
  90. func (s Setting) String() string {
  91. return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
  92. }
  93. // Valid reports whether the setting is valid.
  94. func (s Setting) Valid() error {
  95. // Limits and error codes from 6.5.2 Defined SETTINGS Parameters
  96. switch s.ID {
  97. case SettingEnablePush:
  98. if s.Val != 1 && s.Val != 0 {
  99. return ConnectionError(ErrCodeProtocol)
  100. }
  101. case SettingInitialWindowSize:
  102. if s.Val > 1<<31-1 {
  103. return ConnectionError(ErrCodeFlowControl)
  104. }
  105. case SettingMaxFrameSize:
  106. if s.Val < 16384 || s.Val > 1<<24-1 {
  107. return ConnectionError(ErrCodeProtocol)
  108. }
  109. }
  110. return nil
  111. }
  112. // A SettingID is an HTTP/2 setting as defined in
  113. // http://http2.github.io/http2-spec/#iana-settings
  114. type SettingID uint16
  115. const (
  116. SettingHeaderTableSize SettingID = 0x1
  117. SettingEnablePush SettingID = 0x2
  118. SettingMaxConcurrentStreams SettingID = 0x3
  119. SettingInitialWindowSize SettingID = 0x4
  120. SettingMaxFrameSize SettingID = 0x5
  121. SettingMaxHeaderListSize SettingID = 0x6
  122. )
  123. var settingName = map[SettingID]string{
  124. SettingHeaderTableSize: "HEADER_TABLE_SIZE",
  125. SettingEnablePush: "ENABLE_PUSH",
  126. SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
  127. SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
  128. SettingMaxFrameSize: "MAX_FRAME_SIZE",
  129. SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
  130. }
  131. func (s SettingID) String() string {
  132. if v, ok := settingName[s]; ok {
  133. return v
  134. }
  135. return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
  136. }
  137. func validHeader(v string) bool {
  138. if len(v) == 0 {
  139. return false
  140. }
  141. for _, r := range v {
  142. // "Just as in HTTP/1.x, header field names are
  143. // strings of ASCII characters that are compared in a
  144. // case-insensitive fashion. However, header field
  145. // names MUST be converted to lowercase prior to their
  146. // encoding in HTTP/2. "
  147. if r >= 127 || ('A' <= r && r <= 'Z') {
  148. return false
  149. }
  150. }
  151. return true
  152. }
  153. var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
  154. func init() {
  155. for i := 100; i <= 999; i++ {
  156. if v := http.StatusText(i); v != "" {
  157. httpCodeStringCommon[i] = strconv.Itoa(i)
  158. }
  159. }
  160. }
  161. func httpCodeString(code int) string {
  162. if s, ok := httpCodeStringCommon[code]; ok {
  163. return s
  164. }
  165. return strconv.Itoa(code)
  166. }
  167. // from pkg io
  168. type stringWriter interface {
  169. WriteString(s string) (n int, err error)
  170. }
  171. // A gate lets two goroutines coordinate their activities.
  172. type gate chan struct{}
  173. func (g gate) Done() { g <- struct{}{} }
  174. func (g gate) Wait() { <-g }
  175. // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
  176. type closeWaiter chan struct{}
  177. // Init makes a closeWaiter usable.
  178. // It exists because so a closeWaiter value can be placed inside a
  179. // larger struct and have the Mutex and Cond's memory in the same
  180. // allocation.
  181. func (cw *closeWaiter) Init() {
  182. *cw = make(chan struct{})
  183. }
  184. // Close marks the closeWaiter as closed and unblocks any waiters.
  185. func (cw closeWaiter) Close() {
  186. close(cw)
  187. }
  188. // Wait waits for the closeWaiter to become closed.
  189. func (cw closeWaiter) Wait() {
  190. <-cw
  191. }
  192. // bufferedWriter is a buffered writer that writes to w.
  193. // Its buffered writer is lazily allocated as needed, to minimize
  194. // idle memory usage with many connections.
  195. type bufferedWriter struct {
  196. w io.Writer // immutable
  197. bw *bufio.Writer // non-nil when data is buffered
  198. }
  199. func newBufferedWriter(w io.Writer) *bufferedWriter {
  200. return &bufferedWriter{w: w}
  201. }
  202. var bufWriterPool = sync.Pool{
  203. New: func() interface{} {
  204. // TODO: pick something better? this is a bit under
  205. // (3 x typical 1500 byte MTU) at least.
  206. return bufio.NewWriterSize(nil, 4<<10)
  207. },
  208. }
  209. func (w *bufferedWriter) Write(p []byte) (n int, err error) {
  210. if w.bw == nil {
  211. bw := bufWriterPool.Get().(*bufio.Writer)
  212. bw.Reset(w.w)
  213. w.bw = bw
  214. }
  215. return w.bw.Write(p)
  216. }
  217. func (w *bufferedWriter) Flush() error {
  218. bw := w.bw
  219. if bw == nil {
  220. return nil
  221. }
  222. err := bw.Flush()
  223. bw.Reset(nil)
  224. bufWriterPool.Put(bw)
  225. w.bw = nil
  226. return err
  227. }
  228. func mustUint31(v int32) uint32 {
  229. if v < 0 || v > 2147483647 {
  230. panic("out of range")
  231. }
  232. return uint32(v)
  233. }
  234. // bodyAllowedForStatus reports whether a given response status code
  235. // permits a body. See RFC2616, section 4.4.
  236. func bodyAllowedForStatus(status int) bool {
  237. switch {
  238. case status >= 100 && status <= 199:
  239. return false
  240. case status == 204:
  241. return false
  242. case status == 304:
  243. return false
  244. }
  245. return true
  246. }
  247. type httpError struct {
  248. msg string
  249. timeout bool
  250. }
  251. func (e *httpError) Error() string { return e.msg }
  252. func (e *httpError) Timeout() bool { return e.timeout }
  253. func (e *httpError) Temporary() bool { return true }
  254. var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}