http2.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright 2014 The Go Authors.
  2. // See https://code.google.com/p/go/source/browse/CONTRIBUTORS
  3. // Licensed under the same terms as Go itself:
  4. // https://code.google.com/p/go/source/browse/LICENSE
  5. // Package http2 implements the HTTP/2 protocol.
  6. //
  7. // It currently targets draft-13. See http://http2.github.io/
  8. package http2
  9. import (
  10. "bytes"
  11. "crypto/tls"
  12. "io"
  13. "io/ioutil"
  14. "log"
  15. "net/http"
  16. "sync"
  17. )
  18. const (
  19. // ClientPreface is the string that must be sent by new
  20. // connections from clients.
  21. ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
  22. )
  23. var (
  24. clientPreface = []byte(ClientPreface)
  25. )
  26. const npnProto = "h2-13"
  27. // Server is an HTTP2 server.
  28. type Server struct {
  29. // MaxStreams optionally ...
  30. MaxStreams int
  31. mu sync.Mutex
  32. }
  33. func (srv *Server) handleClientConn(hs *http.Server, c *tls.Conn, h http.Handler) {
  34. cc := &clientConn{hs, c, h}
  35. cc.serve()
  36. }
  37. type clientConn struct {
  38. hs *http.Server
  39. c *tls.Conn
  40. h http.Handler
  41. }
  42. func (cc *clientConn) logf(format string, args ...interface{}) {
  43. if lg := cc.hs.ErrorLog; lg != nil {
  44. lg.Printf(format, args...)
  45. } else {
  46. log.Printf(format, args...)
  47. }
  48. }
  49. func (cc *clientConn) serve() {
  50. defer cc.c.Close()
  51. log.Printf("HTTP/2 connection from %v on %p", cc.c.RemoteAddr(), cc.hs)
  52. buf := make([]byte, len(ClientPreface))
  53. // TODO: timeout reading from the client
  54. if _, err := io.ReadFull(cc.c, buf); err != nil {
  55. cc.logf("error reading client preface: %v", err)
  56. return
  57. }
  58. if !bytes.Equal(buf, clientPreface) {
  59. cc.logf("bogus greeting from client: %q", buf)
  60. return
  61. }
  62. log.Printf("client %v said hello", cc.c.RemoteAddr())
  63. var frameReader = io.LimitedReader{
  64. R: cc.c,
  65. }
  66. for {
  67. fh, err := ReadFrameHeader(cc.c)
  68. if err != nil {
  69. if err != io.EOF {
  70. cc.logf("error reading frame: %v", err)
  71. }
  72. return
  73. }
  74. frameReader.N = int64(fh.Length)
  75. f, err := typeFrameParser(fh.Type)(fh, &frameReader)
  76. if h2e, ok := err.(Error); ok {
  77. if h2e.IsConnectionError() {
  78. log.Printf("Disconnection; connection error: %v", err)
  79. return
  80. }
  81. // TODO: stream errors, etc
  82. }
  83. if err != nil {
  84. log.Printf("Disconnection to other error: %v", err)
  85. return
  86. }
  87. if n, _ := io.Copy(ioutil.Discard, &frameReader); n > 0 {
  88. log.Printf("Frame reader for %s failed to read %d bytes", fh.Type, n)
  89. return
  90. }
  91. log.Printf("got frame: %#v", f)
  92. }
  93. }
  94. // ConfigureServer adds HTTP2 support to s as configured by the HTTP/2
  95. // server configuration in conf. The configuration may be nil.
  96. //
  97. // ConfigureServer must be called before s beings serving.
  98. func ConfigureServer(s *http.Server, conf *Server) {
  99. if conf == nil {
  100. conf = new(Server)
  101. }
  102. if s.TLSConfig == nil {
  103. s.TLSConfig = new(tls.Config)
  104. }
  105. haveNPN := false
  106. for _, p := range s.TLSConfig.NextProtos {
  107. if p == npnProto {
  108. haveNPN = true
  109. break
  110. }
  111. }
  112. if !haveNPN {
  113. s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, npnProto)
  114. }
  115. if s.TLSNextProto == nil {
  116. s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
  117. }
  118. s.TLSNextProto[npnProto] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
  119. conf.handleClientConn(hs, c, h)
  120. }
  121. }