aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/server.go
diff options
context:
space:
mode:
authorNiklas Schnelle <niklas.schnelle@gmail.com>2017-03-13 07:43:16 +0530
committerBrad Fitzpatrick <bradfitz@golang.org>2017-06-08 17:45:27 +0000
commit0b77d3eb009335aaa72205c6642409a5e4a408d6 (patch)
tree5bd864887e6157d1c78fa92f934c7ad5de550725 /src/net/http/server.go
parentfab47f7b3a9d8ad91b96bf80f0b9dff2feda31d2 (diff)
downloadgo-0b77d3eb009335aaa72205c6642409a5e4a408d6.tar.xz
net/http: add Server.ServeTLS method
Server.ServeTLS wraps Server.Serve with added TLS support. This is particularly useful for serving on manually initialized listeners. Example use-case includes ability to serve with TLS on listener provided by systemd's socket activation. A matching test heavily based on TestAutomaticHTTP2_ListenAndServe is also included. Original code by Gurpartap Singh as https://go-review.googlesource.com/c/38114/ Fixes #13228 Change-Id: I73bb703f501574a84d261c2d7b9243a89fa52d62 Reviewed-on: https://go-review.googlesource.com/44074 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/http/server.go')
-rw-r--r--src/net/http/server.go92
1 files changed, 64 insertions, 28 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go
index add05c24ed..c1b98daabf 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -2314,12 +2314,27 @@ func Serve(l net.Listener, handler Handler) error {
return srv.Serve(l)
}
+// Serve accepts incoming HTTPS connections on the listener l,
+// creating a new service goroutine for each. The service goroutines
+// read requests and then call handler to reply to them.
+//
+// Handler is typically nil, in which case the DefaultServeMux is used.
+//
+// Additionally, files containing a certificate and matching private key
+// for the server must be provided. If the certificate is signed by a
+// certificate authority, the certFile should be the concatenation
+// of the server's certificate, any intermediates, and the CA's certificate.
+func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
+ srv := &Server{Handler: handler}
+ return srv.ServeTLS(l, certFile, keyFile)
+}
+
// A Server defines parameters for running an HTTP server.
// The zero value for Server is a valid configuration.
type Server struct {
Addr string // TCP address to listen on, ":http" if empty
Handler Handler // handler to invoke, http.DefaultServeMux if nil
- TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS
+ TLSConfig *tls.Config // optional TLS config, used by ServeTLS and ListenAndServeTLS
// ReadTimeout is the maximum duration for reading the entire
// request, including the body.
@@ -2636,7 +2651,7 @@ func (srv *Server) shouldConfigureHTTP2ForServe() bool {
return strSliceContains(srv.TLSConfig.NextProtos, http2NextProtoTLS)
}
-// ErrServerClosed is returned by the Server's Serve, ListenAndServe,
+// ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe,
// and ListenAndServeTLS methods after a call to Shutdown or Close.
var ErrServerClosed = errors.New("http: Server closed")
@@ -2697,6 +2712,49 @@ func (srv *Server) Serve(l net.Listener) error {
}
}
+// ServeTLS accepts incoming connections on the Listener l, creating a
+// new service goroutine for each. The service goroutines read requests and
+// then call srv.Handler to reply to them.
+//
+// Additionally, files containing a certificate and matching private key for
+// the server must be provided if neither the Server's TLSConfig.Certificates
+// nor TLSConfig.GetCertificate are populated.. If the certificate is signed by
+// a certificate authority, the certFile should be the concatenation of the
+// server's certificate, any intermediates, and the CA's certificate.
+//
+// For HTTP/2 support, srv.TLSConfig should be initialized to the
+// provided listener's TLS Config before calling Serve. If
+// srv.TLSConfig is non-nil and doesn't include the string "h2" in
+// Config.NextProtos, HTTP/2 support is not enabled.
+//
+// ServeTLS always returns a non-nil error. After Shutdown or Close, the
+// returned error is ErrServerClosed.
+func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
+ // Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig
+ // before we clone it and create the TLS Listener.
+ if err := srv.setupHTTP2_ServeTLS(); err != nil {
+ return err
+ }
+
+ config := cloneTLSConfig(srv.TLSConfig)
+ if !strSliceContains(config.NextProtos, "http/1.1") {
+ config.NextProtos = append(config.NextProtos, "http/1.1")
+ }
+
+ configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
+ if !configHasCert || certFile != "" || keyFile != "" {
+ var err error
+ config.Certificates = make([]tls.Certificate, 1)
+ config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+ if err != nil {
+ return err
+ }
+ }
+
+ tlsListener := tls.NewListener(l, config)
+ return srv.Serve(tlsListener)
+}
+
func (s *Server) trackListener(ln net.Listener, add bool) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -2868,47 +2926,25 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
addr = ":https"
}
- // Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig
- // before we clone it and create the TLS Listener.
- if err := srv.setupHTTP2_ListenAndServeTLS(); err != nil {
- return err
- }
-
- config := cloneTLSConfig(srv.TLSConfig)
- if !strSliceContains(config.NextProtos, "http/1.1") {
- config.NextProtos = append(config.NextProtos, "http/1.1")
- }
-
- configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
- if !configHasCert || certFile != "" || keyFile != "" {
- var err error
- config.Certificates = make([]tls.Certificate, 1)
- config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
- return err
- }
- }
-
ln, err := net.Listen("tcp", addr)
if err != nil {
return err
}
- tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
- return srv.Serve(tlsListener)
+ return srv.ServeTLS(tcpKeepAliveListener{ln.(*net.TCPListener)}, certFile, keyFile)
}
-// setupHTTP2_ListenAndServeTLS conditionally configures HTTP/2 on
+// setupHTTP2_ServeTLS conditionally configures HTTP/2 on
// srv and returns whether there was an error setting it up. If it is
// not configured for policy reasons, nil is returned.
-func (srv *Server) setupHTTP2_ListenAndServeTLS() error {
+func (srv *Server) setupHTTP2_ServeTLS() error {
srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults)
return srv.nextProtoErr
}
// setupHTTP2_Serve is called from (*Server).Serve and conditionally
// configures HTTP/2 on srv using a more conservative policy than
-// setupHTTP2_ListenAndServeTLS because Serve may be called
+// setupHTTP2_ServeTLS because Serve may be called
// concurrently.
//
// The tests named TestTransportAutomaticHTTP2* and