h2c.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. // Copyright 2018 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 h2c implements the unencrypted "h2c" form of HTTP/2.
  5. //
  6. // The h2c protocol is the non-TLS version of HTTP/2 which is not available from
  7. // net/http or golang.org/x/net/http2.
  8. package h2c
  9. import (
  10. "bufio"
  11. "bytes"
  12. "encoding/base64"
  13. "encoding/binary"
  14. "errors"
  15. "fmt"
  16. "io"
  17. "log"
  18. "net"
  19. "net/http"
  20. "net/textproto"
  21. "os"
  22. "strings"
  23. "golang.org/x/net/http/httpguts"
  24. "golang.org/x/net/http2"
  25. "golang.org/x/net/http2/hpack"
  26. )
  27. var (
  28. http2VerboseLogs bool
  29. )
  30. func init() {
  31. e := os.Getenv("GODEBUG")
  32. if strings.Contains(e, "http2debug=1") || strings.Contains(e, "http2debug=2") {
  33. http2VerboseLogs = true
  34. }
  35. }
  36. // h2cHandler is a Handler which implements h2c by hijacking the HTTP/1 traffic
  37. // that should be h2c traffic. There are two ways to begin a h2c connection
  38. // (RFC 7540 Section 3.2 and 3.4): (1) Starting with Prior Knowledge - this
  39. // works by starting an h2c connection with a string of bytes that is valid
  40. // HTTP/1, but unlikely to occur in practice and (2) Upgrading from HTTP/1 to
  41. // h2c - this works by using the HTTP/1 Upgrade header to request an upgrade to
  42. // h2c. When either of those situations occur we hijack the HTTP/1 connection,
  43. // convert it to a HTTP/2 connection and pass the net.Conn to http2.ServeConn.
  44. type h2cHandler struct {
  45. Handler http.Handler
  46. s *http2.Server
  47. }
  48. // NewHandler returns an http.Handler that wraps h, intercepting any h2c
  49. // traffic. If a request is an h2c connection, it's hijacked and redirected to
  50. // s.ServeConn. Otherwise the returned Handler just forwards requests to h. This
  51. // works because h2c is designed to be parseable as valid HTTP/1, but ignored by
  52. // any HTTP server that does not handle h2c. Therefore we leverage the HTTP/1
  53. // compatible parts of the Go http library to parse and recognize h2c requests.
  54. // Once a request is recognized as h2c, we hijack the connection and convert it
  55. // to an HTTP/2 connection which is understandable to s.ServeConn. (s.ServeConn
  56. // understands HTTP/2 except for the h2c part of it.)
  57. func NewHandler(h http.Handler, s *http2.Server) http.Handler {
  58. return &h2cHandler{
  59. Handler: h,
  60. s: s,
  61. }
  62. }
  63. // ServeHTTP implement the h2c support that is enabled by h2c.GetH2CHandler.
  64. func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  65. // Handle h2c with prior knowledge (RFC 7540 Section 3.4)
  66. if r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0" {
  67. if http2VerboseLogs {
  68. log.Print("h2c: attempting h2c with prior knowledge.")
  69. }
  70. conn, err := initH2CWithPriorKnowledge(w)
  71. if err != nil {
  72. if http2VerboseLogs {
  73. log.Printf("h2c: error h2c with prior knowledge: %v", err)
  74. }
  75. return
  76. }
  77. defer conn.Close()
  78. s.s.ServeConn(conn, &http2.ServeConnOpts{Handler: s.Handler})
  79. return
  80. }
  81. // Handle Upgrade to h2c (RFC 7540 Section 3.2)
  82. if conn, err := h2cUpgrade(w, r); err == nil {
  83. defer conn.Close()
  84. s.s.ServeConn(conn, &http2.ServeConnOpts{Handler: s.Handler})
  85. return
  86. }
  87. s.Handler.ServeHTTP(w, r)
  88. return
  89. }
  90. // initH2CWithPriorKnowledge implements creating a h2c connection with prior
  91. // knowledge (Section 3.4) and creates a net.Conn suitable for http2.ServeConn.
  92. // All we have to do is look for the client preface that is suppose to be part
  93. // of the body, and reforward the client preface on the net.Conn this function
  94. // creates.
  95. func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) {
  96. hijacker, ok := w.(http.Hijacker)
  97. if !ok {
  98. panic("Hijack not supported.")
  99. }
  100. conn, rw, err := hijacker.Hijack()
  101. if err != nil {
  102. panic(fmt.Sprintf("Hijack failed: %v", err))
  103. }
  104. const expectedBody = "SM\r\n\r\n"
  105. buf := make([]byte, len(expectedBody))
  106. n, err := io.ReadFull(rw, buf)
  107. if string(buf[:n]) == expectedBody {
  108. c := &rwConn{
  109. Conn: conn,
  110. Reader: io.MultiReader(strings.NewReader(http2.ClientPreface), rw),
  111. BufWriter: rw.Writer,
  112. }
  113. return c, nil
  114. }
  115. conn.Close()
  116. if http2VerboseLogs {
  117. log.Printf(
  118. "h2c: missing the request body portion of the client preface. Wanted: %v Got: %v",
  119. []byte(expectedBody),
  120. buf[0:n],
  121. )
  122. }
  123. return nil, errors.New("invalid client preface")
  124. }
  125. // drainClientPreface reads a single instance of the HTTP/2 client preface from
  126. // the supplied reader.
  127. func drainClientPreface(r io.Reader) error {
  128. var buf bytes.Buffer
  129. prefaceLen := int64(len(http2.ClientPreface))
  130. n, err := io.CopyN(&buf, r, prefaceLen)
  131. if err != nil {
  132. return err
  133. }
  134. if n != prefaceLen || buf.String() != http2.ClientPreface {
  135. return fmt.Errorf("Client never sent: %s", http2.ClientPreface)
  136. }
  137. return nil
  138. }
  139. // h2cUpgrade establishes a h2c connection using the HTTP/1 upgrade (Section 3.2).
  140. func h2cUpgrade(w http.ResponseWriter, r *http.Request) (net.Conn, error) {
  141. if !isH2CUpgrade(r.Header) {
  142. return nil, errors.New("non-conforming h2c headers")
  143. }
  144. // Initial bytes we put into conn to fool http2 server
  145. initBytes, _, err := convertH1ReqToH2(r)
  146. if err != nil {
  147. return nil, err
  148. }
  149. hijacker, ok := w.(http.Hijacker)
  150. if !ok {
  151. return nil, errors.New("hijack not supported.")
  152. }
  153. conn, rw, err := hijacker.Hijack()
  154. if err != nil {
  155. return nil, fmt.Errorf("hijack failed: %v", err)
  156. }
  157. rw.Write([]byte("HTTP/1.1 101 Switching Protocols\r\n" +
  158. "Connection: Upgrade\r\n" +
  159. "Upgrade: h2c\r\n\r\n"))
  160. rw.Flush()
  161. // A conforming client will now send an H2 client preface which need to drain
  162. // since we already sent this.
  163. if err := drainClientPreface(rw); err != nil {
  164. return nil, err
  165. }
  166. c := &rwConn{
  167. Conn: conn,
  168. Reader: io.MultiReader(initBytes, rw),
  169. BufWriter: newSettingsAckSwallowWriter(rw.Writer),
  170. }
  171. return c, nil
  172. }
  173. // convert the data contained in the HTTP/1 upgrade request into the HTTP/2
  174. // version in byte form.
  175. func convertH1ReqToH2(r *http.Request) (*bytes.Buffer, []http2.Setting, error) {
  176. h2Bytes := bytes.NewBuffer([]byte((http2.ClientPreface)))
  177. framer := http2.NewFramer(h2Bytes, nil)
  178. settings, err := getH2Settings(r.Header)
  179. if err != nil {
  180. return nil, nil, err
  181. }
  182. if err := framer.WriteSettings(settings...); err != nil {
  183. return nil, nil, err
  184. }
  185. headerBytes, err := getH2HeaderBytes(r, getMaxHeaderTableSize(settings))
  186. if err != nil {
  187. return nil, nil, err
  188. }
  189. maxFrameSize := int(getMaxFrameSize(settings))
  190. needOneHeader := len(headerBytes) < maxFrameSize
  191. err = framer.WriteHeaders(http2.HeadersFrameParam{
  192. StreamID: 1,
  193. BlockFragment: headerBytes,
  194. EndHeaders: needOneHeader,
  195. })
  196. if err != nil {
  197. return nil, nil, err
  198. }
  199. for i := maxFrameSize; i < len(headerBytes); i += maxFrameSize {
  200. if len(headerBytes)-i > maxFrameSize {
  201. if err := framer.WriteContinuation(1,
  202. false, // endHeaders
  203. headerBytes[i:maxFrameSize]); err != nil {
  204. return nil, nil, err
  205. }
  206. } else {
  207. if err := framer.WriteContinuation(1,
  208. true, // endHeaders
  209. headerBytes[i:]); err != nil {
  210. return nil, nil, err
  211. }
  212. }
  213. }
  214. return h2Bytes, settings, nil
  215. }
  216. // getMaxFrameSize returns the SETTINGS_MAX_FRAME_SIZE. If not present default
  217. // value is 16384 as specified by RFC 7540 Section 6.5.2.
  218. func getMaxFrameSize(settings []http2.Setting) uint32 {
  219. for _, setting := range settings {
  220. if setting.ID == http2.SettingMaxFrameSize {
  221. return setting.Val
  222. }
  223. }
  224. return 16384
  225. }
  226. // getMaxHeaderTableSize returns the SETTINGS_HEADER_TABLE_SIZE. If not present
  227. // default value is 4096 as specified by RFC 7540 Section 6.5.2.
  228. func getMaxHeaderTableSize(settings []http2.Setting) uint32 {
  229. for _, setting := range settings {
  230. if setting.ID == http2.SettingHeaderTableSize {
  231. return setting.Val
  232. }
  233. }
  234. return 4096
  235. }
  236. // bufWriter is a Writer interface that also has a Flush method.
  237. type bufWriter interface {
  238. io.Writer
  239. Flush() error
  240. }
  241. // rwConn implements net.Conn but overrides Read and Write so that reads and
  242. // writes are forwarded to the provided io.Reader and bufWriter.
  243. type rwConn struct {
  244. net.Conn
  245. io.Reader
  246. BufWriter bufWriter
  247. }
  248. // Read forwards reads to the underlying Reader.
  249. func (c *rwConn) Read(p []byte) (int, error) {
  250. return c.Reader.Read(p)
  251. }
  252. // Write forwards writes to the underlying bufWriter and immediately flushes.
  253. func (c *rwConn) Write(p []byte) (int, error) {
  254. n, err := c.BufWriter.Write(p)
  255. if err := c.BufWriter.Flush(); err != nil {
  256. return 0, err
  257. }
  258. return n, err
  259. }
  260. // settingsAckSwallowWriter is a writer that normally forwards bytes to it's
  261. // underlying Writer, but swallows the first SettingsAck frame that it sees.
  262. type settingsAckSwallowWriter struct {
  263. Writer *bufio.Writer
  264. buf []byte
  265. didSwallow bool
  266. }
  267. // newSettingsAckSwallowWriter returns a new settingsAckSwallowWriter.
  268. func newSettingsAckSwallowWriter(w *bufio.Writer) *settingsAckSwallowWriter {
  269. return &settingsAckSwallowWriter{
  270. Writer: w,
  271. buf: make([]byte, 0),
  272. didSwallow: false,
  273. }
  274. }
  275. // Write implements io.Writer interface. Normally forwards bytes to w.Writer,
  276. // except for the first Settings ACK frame that it sees.
  277. func (w *settingsAckSwallowWriter) Write(p []byte) (int, error) {
  278. if !w.didSwallow {
  279. w.buf = append(w.buf, p...)
  280. // Process all the frames we have collected into w.buf
  281. for {
  282. // Append until we get full frame header which is 9 bytes
  283. if len(w.buf) < 9 {
  284. break
  285. }
  286. // Check if we have collected a whole frame.
  287. fh, err := http2.ReadFrameHeader(bytes.NewBuffer(w.buf))
  288. if err != nil {
  289. // Corrupted frame, fail current Write
  290. return 0, err
  291. }
  292. fSize := fh.Length + 9
  293. if uint32(len(w.buf)) < fSize {
  294. // Have not collected whole frame. Stop processing buf, and withold on
  295. // forward bytes to w.Writer until we get the full frame.
  296. break
  297. }
  298. // We have now collected a whole frame.
  299. if fh.Type == http2.FrameSettings && fh.Flags.Has(http2.FlagSettingsAck) {
  300. // If Settings ACK frame, do not forward to underlying writer, remove
  301. // bytes from w.buf, and record that we have swallowed Settings Ack
  302. // frame.
  303. w.didSwallow = true
  304. w.buf = w.buf[fSize:]
  305. continue
  306. }
  307. // Not settings ack frame. Forward bytes to w.Writer.
  308. if _, err := w.Writer.Write(w.buf[:fSize]); err != nil {
  309. // Couldn't forward bytes. Fail current Write.
  310. return 0, err
  311. }
  312. w.buf = w.buf[fSize:]
  313. }
  314. return len(p), nil
  315. }
  316. return w.Writer.Write(p)
  317. }
  318. // Flush calls w.Writer.Flush.
  319. func (w *settingsAckSwallowWriter) Flush() error {
  320. return w.Writer.Flush()
  321. }
  322. // isH2CUpgrade returns true if the header properly request an upgrade to h2c
  323. // as specified by Section 3.2.
  324. func isH2CUpgrade(h http.Header) bool {
  325. return httpguts.HeaderValuesContainsToken(h[textproto.CanonicalMIMEHeaderKey("Upgrade")], "h2c") &&
  326. httpguts.HeaderValuesContainsToken(h[textproto.CanonicalMIMEHeaderKey("Connection")], "HTTP2-Settings")
  327. }
  328. // getH2Settings returns the []http2.Setting that are encoded in the
  329. // HTTP2-Settings header.
  330. func getH2Settings(h http.Header) ([]http2.Setting, error) {
  331. vals, ok := h[textproto.CanonicalMIMEHeaderKey("HTTP2-Settings")]
  332. if !ok {
  333. return nil, errors.New("missing HTTP2-Settings header")
  334. }
  335. if len(vals) != 1 {
  336. return nil, fmt.Errorf("expected 1 HTTP2-Settings. Got: %v", vals)
  337. }
  338. settings, err := decodeSettings(vals[0])
  339. if err != nil {
  340. return nil, fmt.Errorf("Invalid HTTP2-Settings: %q", vals[0])
  341. }
  342. return settings, nil
  343. }
  344. // decodeSettings decodes the base64url header value of the HTTP2-Settings
  345. // header. RFC 7540 Section 3.2.1.
  346. func decodeSettings(headerVal string) ([]http2.Setting, error) {
  347. b, err := base64.RawURLEncoding.DecodeString(headerVal)
  348. if err != nil {
  349. return nil, err
  350. }
  351. if len(b)%6 != 0 {
  352. return nil, err
  353. }
  354. settings := make([]http2.Setting, 0)
  355. for i := 0; i < len(b)/6; i++ {
  356. settings = append(settings, http2.Setting{
  357. ID: http2.SettingID(binary.BigEndian.Uint16(b[i*6 : i*6+2])),
  358. Val: binary.BigEndian.Uint32(b[i*6+2 : i*6+6]),
  359. })
  360. }
  361. return settings, nil
  362. }
  363. // getH2HeaderBytes return the headers in r a []bytes encoded by HPACK.
  364. func getH2HeaderBytes(r *http.Request, maxHeaderTableSize uint32) ([]byte, error) {
  365. headerBytes := bytes.NewBuffer(nil)
  366. hpackEnc := hpack.NewEncoder(headerBytes)
  367. hpackEnc.SetMaxDynamicTableSize(maxHeaderTableSize)
  368. // Section 8.1.2.3
  369. err := hpackEnc.WriteField(hpack.HeaderField{
  370. Name: ":method",
  371. Value: r.Method,
  372. })
  373. if err != nil {
  374. return nil, err
  375. }
  376. err = hpackEnc.WriteField(hpack.HeaderField{
  377. Name: ":scheme",
  378. Value: "http",
  379. })
  380. if err != nil {
  381. return nil, err
  382. }
  383. err = hpackEnc.WriteField(hpack.HeaderField{
  384. Name: ":authority",
  385. Value: r.Host,
  386. })
  387. if err != nil {
  388. return nil, err
  389. }
  390. path := r.URL.Path
  391. if r.URL.RawQuery != "" {
  392. path = strings.Join([]string{path, r.URL.RawQuery}, "?")
  393. }
  394. err = hpackEnc.WriteField(hpack.HeaderField{
  395. Name: ":path",
  396. Value: path,
  397. })
  398. if err != nil {
  399. return nil, err
  400. }
  401. // TODO Implement Section 8.3
  402. for header, values := range r.Header {
  403. // Skip non h2 headers
  404. if isNonH2Header(header) {
  405. continue
  406. }
  407. for _, v := range values {
  408. err := hpackEnc.WriteField(hpack.HeaderField{
  409. Name: strings.ToLower(header),
  410. Value: v,
  411. })
  412. if err != nil {
  413. return nil, err
  414. }
  415. }
  416. }
  417. return headerBytes.Bytes(), nil
  418. }
  419. // Connection specific headers listed in RFC 7540 Section 8.1.2.2 that are not
  420. // suppose to be transferred to HTTP/2. The Http2-Settings header is skipped
  421. // since already use to create the HTTP/2 SETTINGS frame.
  422. var nonH2Headers = []string{
  423. "Connection",
  424. "Keep-Alive",
  425. "Proxy-Connection",
  426. "Transfer-Encoding",
  427. "Upgrade",
  428. "Http2-Settings",
  429. }
  430. // isNonH2Header returns true if header should not be transferred to HTTP/2.
  431. func isNonH2Header(header string) bool {
  432. for _, nonH2h := range nonH2Headers {
  433. if header == nonH2h {
  434. return true
  435. }
  436. }
  437. return false
  438. }