http2.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Package http2 implements the HTTP/2 protocol.
  2. //
  3. // It currently targets draft-13. See http://http2.github.io/
  4. package http2
  5. import (
  6. "bytes"
  7. "crypto/tls"
  8. "io"
  9. "log"
  10. "net/http"
  11. "sync"
  12. )
  13. const (
  14. // ClientPreface is the string that must be sent by new
  15. // connections from clients.
  16. ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
  17. )
  18. var (
  19. clientPreface = []byte(ClientPreface)
  20. )
  21. const npnProto = "h2-13"
  22. // Server is an HTTP2 server.
  23. type Server struct {
  24. // MaxStreams optionally ...
  25. MaxStreams int
  26. mu sync.Mutex
  27. }
  28. func (srv *Server) handleClientConn(hs *http.Server, c *tls.Conn, h http.Handler) {
  29. cc := &clientConn{hs, c, h}
  30. cc.serve()
  31. }
  32. type clientConn struct {
  33. hs *http.Server
  34. c *tls.Conn
  35. h http.Handler
  36. }
  37. func (cc *clientConn) logf(format string, args ...interface{}) {
  38. if lg := cc.hs.ErrorLog; lg != nil {
  39. lg.Printf(format, args...)
  40. } else {
  41. log.Printf(format, args...)
  42. }
  43. }
  44. func (cc *clientConn) serve() {
  45. defer cc.c.Close()
  46. log.Printf("HTTP/2 connection from %v on %p", cc.c.RemoteAddr(), cc.hs)
  47. buf := make([]byte, len(ClientPreface))
  48. // TODO: timeout reading from the client
  49. if _, err := io.ReadFull(cc.c, buf); err != nil {
  50. cc.logf("error reading client preface: %v", err)
  51. return
  52. }
  53. if !bytes.Equal(buf, clientPreface) {
  54. cc.logf("bogus greeting from client: %q", buf)
  55. return
  56. }
  57. log.Printf("client %v said hello", cc.c.RemoteAddr())
  58. for {
  59. fh, err := ReadFrameHeader(cc.c)
  60. if err != nil {
  61. if err != io.EOF {
  62. cc.logf("error reading frame: %v", err)
  63. }
  64. return
  65. }
  66. log.Printf("read frame: %v", fh)
  67. break
  68. }
  69. }
  70. // ConfigureServer adds HTTP2 support to s as configured by the HTTP/2
  71. // server configuration in conf. The configuration may be nil.
  72. //
  73. // ConfigureServer must be called before s beings serving.
  74. func ConfigureServer(s *http.Server, conf *Server) {
  75. if conf == nil {
  76. conf = new(Server)
  77. }
  78. if s.TLSConfig == nil {
  79. s.TLSConfig = new(tls.Config)
  80. }
  81. haveNPN := false
  82. for _, p := range s.TLSConfig.NextProtos {
  83. if p == npnProto {
  84. haveNPN = true
  85. break
  86. }
  87. }
  88. if !haveNPN {
  89. s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, npnProto)
  90. }
  91. if s.TLSNextProto == nil {
  92. s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
  93. }
  94. s.TLSNextProto[npnProto] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
  95. conf.handleClientConn(hs, c, h)
  96. }
  97. }