From b4cab78bec6e5817a2196c297d8653ca4900bb00 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Wed, 13 Jan 2016 00:29:22 -0700 Subject: [PATCH] Starting transition to Go 1.6 (http2 compatibility) I've built this on Go 1.6 beta 1 and made some changes to be more compatible. Namely, I removed the use of the /x/net/http2 package and let net/http enable h2 by default; updated the way h2 is disabled (if the user requires it); moved TLS_FALLBACK_SCSV to the front of the cipher suites list (all values not accepted by http2 must go after those allowed by it); removed the NextProto default of http/1.1; set the http.Server.TLSConfig value to the TLS config used by the listener (we left it nil before, but this prevents automatic enabling of h2). It is very likely there is more to do, but at least already Caddy uses HTTP/2 when built with Go 1.6. --- caddy/setup/tls.go | 3 ++- server/server.go | 11 +++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/caddy/setup/tls.go b/caddy/setup/tls.go index 5b6c086e..cf45278c 100644 --- a/caddy/setup/tls.go +++ b/caddy/setup/tls.go @@ -95,7 +95,8 @@ func SetDefaultTLSParams(c *server.Config) { } // Not a cipher suite, but still important for mitigating protocol downgrade attacks - c.TLS.Ciphers = append(c.TLS.Ciphers, tls.TLS_FALLBACK_SCSV) + // (prepend since having it at end breaks http2 due to non-h2-approved suites before it) + c.TLS.Ciphers = append([]uint16{tls.TLS_FALLBACK_SCSV}, c.TLS.Ciphers...) // Set default protocol min and max versions - must balance compatibility and security if c.TLS.ProtocolMinVersion == 0 { diff --git a/server/server.go b/server/server.go index 4fe12b36..5794c167 100644 --- a/server/server.go +++ b/server/server.go @@ -15,8 +15,6 @@ import ( "runtime" "sync" "time" - - "golang.org/x/net/http2" ) // Server represents an instance of a server, which serves @@ -179,9 +177,8 @@ func (s *Server) serve(ln ListenerFile) error { // called just before the listener announces itself on the network // and should only be called when the server is just starting up. func (s *Server) setup() error { - if s.HTTP2 { - // TODO: This call may not be necessary after HTTP/2 is merged into std lib - http2.ConfigureServer(s.Server, nil) + if !s.HTTP2 { + s.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler)) } // Execute startup functions now @@ -206,9 +203,6 @@ func (s *Server) setup() error { // client authentication, and our custom Server type. func serveTLSWithSNI(s *Server, ln net.Listener, tlsConfigs []TLSConfig) error { config := cloneTLSConfig(s.TLSConfig) - if config.NextProtos == nil { - config.NextProtos = []string{"http/1.1"} - } // Here we diverge from the stdlib a bit by loading multiple certs/key pairs // then we map the server names to their certs @@ -236,6 +230,7 @@ func serveTLSWithSNI(s *Server, ln net.Listener, tlsConfigs []TLSConfig) error { defer close(s.startChan) return err } + s.TLSConfig = config // Create TLS listener - note that we do not replace s.listener // with this TLS listener; tls.listener is unexported and does